使用可选的结构变量组合
Combine using optional struct variable
我正在尝试使用 Combine 将 SCEvent
的数组加载到 EventModel
的数组中。变量 imagePath
是可选的,我想在其对应的 EventModel.imageData
变量中将其转换为空 Data()
。
struct SCEvent {
let name: String
let imagePath: String?
}
struct EventModel {
let name: String
let imageData: Data
}
下面的代码似乎可行,但我不禁想知道这是否是最佳的实现方式:
func loadEvents(_ events: [SCEvent]) -> AnyPublisher<[EventModel], Error> {
events.publisher
.flatMap(loadEvent(_:))
.collect()
.eraseToAnyPublisher()
}
func loadEvent(_ event: SCEvent) -> AnyPublisher<EventModel, Error> {
if let imagePath = event.imagePath {
return DataDownloader.downloadData(fromPath: imagePath)
.map { EventModel(name: event.name, imageData: [=12=]) }
.eraseToAnyPublisher()
}
return Just(EventModel(name: event.name, imageData: Data())
.eraseToAnyPublisher()
}
理想情况下,我想在 loadEvent
函数中使用单个发布者。也许是这样的(不起作用,但作为我期望的例子):
func loadEvent(_ event: SCEvent) -> AnyPublisher<[EventModel], Error> {
event.imagePath
.flatMap(DataDownloader.downloadData(_:))
.replaceNil(with: Data())
.map {
EventModel(name: event.name, imageData: [=13=])
}
.eraseToAnyPublisher()
}
这不起作用,因为 .replaceNil
应该在 event.imagePath
之后使用来替换 nil
字符串。另一种可能的方法是:
func loadEvent(_ event: SCEvent) -> AnyPublisher<[EventModel], Error> {
event.imagePath
.replaceNil(with: "")
.flatMap(
DataDownloader.downloadData(_:)
.replaceError(with: Data())
)
.map {
EventModel(name: event.name, imageData: [=14=])
}
.eraseToAnyPublisher()
}
不过好像是被逼的。 Combine甚至有可能吗?我的初始方法是唯一有效的解决方案吗?
您可以使用 Optional
的 publisher
,如果可选值不为零,它会为您提供一个发布一个元素的发布者,否则为一个空发布者。
然后您可以 replaceEmpty(with: Data())
,然后 map
到 EventModel
。
func loadEvent(_ event: SCEvent) -> AnyPublisher<EventModel, Error> {
event.imagePath.publisher
.flatMap(DataDownloader.downloadData(fromPath:))
.replaceEmpty(with: Data())
.map {
EventModel(name: event.name, imageData: [=10=])
}
.eraseToAnyPublisher()
}
不过,我认为用 Data()
替换不是个好主意。更好的设计是替换为 nil
,在这种情况下,您必须首先映射到一个可选的:
struct EventModel {
let name: String
let imageData: Data?
}
...
.flatMap(DataDownloader.downloadData(fromPath:))
.map { [=11=] as Data? } // here
.replaceEmpty(with: nil)
我正在尝试使用 Combine 将 SCEvent
的数组加载到 EventModel
的数组中。变量 imagePath
是可选的,我想在其对应的 EventModel.imageData
变量中将其转换为空 Data()
。
struct SCEvent {
let name: String
let imagePath: String?
}
struct EventModel {
let name: String
let imageData: Data
}
下面的代码似乎可行,但我不禁想知道这是否是最佳的实现方式:
func loadEvents(_ events: [SCEvent]) -> AnyPublisher<[EventModel], Error> {
events.publisher
.flatMap(loadEvent(_:))
.collect()
.eraseToAnyPublisher()
}
func loadEvent(_ event: SCEvent) -> AnyPublisher<EventModel, Error> {
if let imagePath = event.imagePath {
return DataDownloader.downloadData(fromPath: imagePath)
.map { EventModel(name: event.name, imageData: [=12=]) }
.eraseToAnyPublisher()
}
return Just(EventModel(name: event.name, imageData: Data())
.eraseToAnyPublisher()
}
理想情况下,我想在 loadEvent
函数中使用单个发布者。也许是这样的(不起作用,但作为我期望的例子):
func loadEvent(_ event: SCEvent) -> AnyPublisher<[EventModel], Error> {
event.imagePath
.flatMap(DataDownloader.downloadData(_:))
.replaceNil(with: Data())
.map {
EventModel(name: event.name, imageData: [=13=])
}
.eraseToAnyPublisher()
}
这不起作用,因为 .replaceNil
应该在 event.imagePath
之后使用来替换 nil
字符串。另一种可能的方法是:
func loadEvent(_ event: SCEvent) -> AnyPublisher<[EventModel], Error> {
event.imagePath
.replaceNil(with: "")
.flatMap(
DataDownloader.downloadData(_:)
.replaceError(with: Data())
)
.map {
EventModel(name: event.name, imageData: [=14=])
}
.eraseToAnyPublisher()
}
不过好像是被逼的。 Combine甚至有可能吗?我的初始方法是唯一有效的解决方案吗?
您可以使用 Optional
的 publisher
,如果可选值不为零,它会为您提供一个发布一个元素的发布者,否则为一个空发布者。
然后您可以 replaceEmpty(with: Data())
,然后 map
到 EventModel
。
func loadEvent(_ event: SCEvent) -> AnyPublisher<EventModel, Error> {
event.imagePath.publisher
.flatMap(DataDownloader.downloadData(fromPath:))
.replaceEmpty(with: Data())
.map {
EventModel(name: event.name, imageData: [=10=])
}
.eraseToAnyPublisher()
}
不过,我认为用 Data()
替换不是个好主意。更好的设计是替换为 nil
,在这种情况下,您必须首先映射到一个可选的:
struct EventModel {
let name: String
let imageData: Data?
}
...
.flatMap(DataDownloader.downloadData(fromPath:))
.map { [=11=] as Data? } // here
.replaceEmpty(with: nil)