Принудительная развертка внутри flatMap в Combine Swift

Я пытаюсь выполнить принудительную развертку внутри моей функции flatMap, но получаю следующую ошибку при возврате нулевой строки:

'nil' требует контекстного типа

Ниже приведен мой код:

func fetchOrgs() -> AnyPublisher<[THOrganizationV2?], THError> {
    let locale = userInformationProvider.defaultOrganizationLocale
    let orgID = organizationProvider.currentOrganizationID ?? ""
    
    return thProvider.fetchTHOrgs(locale: locale, orgID: orgID).flatMap { orgs in
        guard let org = orgs.first else {
            return nil// error here
        }
        if org.type == .xpert {
            return self.prepareThURL(with: org, orgID: orgID)
        }
        return THOrganizationV2(serviceURL: URL(string: org.url), type: OrganizationType(rawValue: (org.type)!.rawValue) ?? .aaa, authenticationToken: org.authenticationToken)
    }.eraseToAnyPublisher()
}

Сигнатура вызываемой выше функции в thProvider:

func fetchTHOrgs(locale: String, orgID: String?) -> AnyPublisher<[thOrganizationEntityV2], THError>

Я пробовал разные комбинации карты и flatMap, но у меня ничего не работает.

Редактировать: Моя цель здесь — преобразовать массив thOrganizationEntityV2 в массив THOrganizationV2, а также выполнить принудительную распаковку.

Подпись для prepareThURL:

private func prepareThURL(with org: THOrganizationEntityV2, orgID: String?) -> THOrganizationV2?

Можете ли вы описать на английском языке, что вы хотите, чтобы ваш код делал? Также, пожалуйста, покажите подпись prepareThURL.

Sweeper 17.05.2023 03:40

Вы хотели использовать compactMap вместо flatMap? Почему ваш издатель публикует множество опций? Разве это не должен быть просто массив THOrganizationV2?

Paulw11 17.05.2023 03:48

Ну тогда зачем вы заявили fetchOrgs вернуть издателя [THOrganizationV2?] тогда? Почему бы и нет [THOrganizationV2], без опциона? Кроме того, вы до сих пор не показали подпись prepareThURL.

Sweeper 17.05.2023 10:10

Я добавил подпись для prepareTHURL, также я изначально хотел, чтобы она возвращала издателя [THOrganizationV2], но для управления принудительной распаковкой я попробовал это.

pankaj 17.05.2023 11:33
flatmap обычно используется для выравнивания массива массивов. Обычно я ожидаю, что это будет применяться к типу коллекции, и закрытие выведет массив чего-то. Вероятно, в Combine это не работает, но семантика должна быть похожей. Кажется, ваш тип возврата в вашем закрытии — THOrganizationV2?, поэтому попробуйте заменить flatMap на compactMap
JeremyP 17.05.2023 12:18
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Компилятор просматривает блок в flatMap и не может определить, какой тип представляет nil.

Оператор flatMap ожидает, что его закрытие вернет какой-то Publisher, а не необязательный. В вашем случае flatMap кажется неправильным оператором. Похоже, ваш код возвращает THOrganizationV2?, который не является Publisher.

В блоке компилятор заходит так далеко:

.flatMap { orgs in
    guard let org = orgs.first else { return nil }

и говорит: «Хммм... Я нахожусь в замыкании, которое не имеет объявленного возвращаемого типа, и вы даете мне nil. Я не знаю, что это за вкус nil. Это Int?, Float?, OmpaLoompa? ... У меня нет контекста, чтобы выяснить, какому типу соответствует этот конкретный nil».

Вы можете исправить это, объявив возвращаемый тип для закрытия:

.flatMap { orgs -> THOrganizationV2? in
    guard let org = orgs.first else { return nil }

или напрямую предоставив контекстуальный тип для nil:

.flatMap { orgs in
    guard let org = orgs.first else { return nil as THOrganizationV2? }

Но опять же, оператор издателя flatMap ожидает, что возвращаемый тип будет издателем. Я не думаю, что ваша THOrganizationV2 — это Publisher.

Глядя на сигнатуры типов в вашем коде, кажется, что вам может понадобиться что-то вроде этого:

   return thProvider
     .fetchTHOrgs(locale: locale, orgID: orgID)
     .map { orgs in
        return orgs.map { org -> THOrganizationV2? in
            guard let org = orgs.first else { nil }

            if org.type == .xpert {
                return self.prepareThURL(with: org, orgID: orgID)
            }

            return THOrganizationV2(
              serviceURL: URL(string: org.url), 
              type: OrganizationType(rawValue: (org.type)!.rawValue) ?? .aaa,
              authenticationToken: org.authenticationToken
            )
        }
    }

(Я набрал это в редакторе ответов, а не в компиляторе, поэтому может потребоваться некоторая работа)

Я заменил flatMap на map. Для каждого поступающего массива orgs система сопоставляет его с массивом THOrganizationV2?, и они становятся выходными данными издателя, поэтому fetchOrgs должен соответствовать сигнатуре своего типа.

Спасибо за ответ и столь подробное объяснение

pankaj 22.05.2023 12:35

Другие вопросы по теме