Я пытаюсь выполнить принудительную развертку внутри моей функции 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?
Вы хотели использовать compactMap вместо flatMap? Почему ваш издатель публикует множество опций? Разве это не должен быть просто массив THOrganizationV2?
Ну тогда зачем вы заявили fetchOrgs вернуть издателя [THOrganizationV2?] тогда? Почему бы и нет [THOrganizationV2], без опциона? Кроме того, вы до сих пор не показали подпись prepareThURL.
Я добавил подпись для prepareTHURL, также я изначально хотел, чтобы она возвращала издателя [THOrganizationV2], но для управления принудительной распаковкой я попробовал это.
flatmap обычно используется для выравнивания массива массивов. Обычно я ожидаю, что это будет применяться к типу коллекции, и закрытие выведет массив чего-то. Вероятно, в Combine это не работает, но семантика должна быть похожей. Кажется, ваш тип возврата в вашем закрытии — THOrganizationV2?, поэтому попробуйте заменить flatMap на compactMap




Компилятор просматривает блок в 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 должен соответствовать сигнатуре своего типа.
Спасибо за ответ и столь подробное объяснение
Можете ли вы описать на английском языке, что вы хотите, чтобы ваш код делал? Также, пожалуйста, покажите подпись
prepareThURL.