我创建了一个称为通知项目的类,并从模型类RTVNotification中解析数据
导入基金会 导入RTVModel
公共类NotificationItem:NSObject {
class Foo {
constructor (private foo = 1, public bar = 2) {}
}
}
扩展NotificationItem { 静态函数实例化(带有通知:RTVNotification)-> NotificationItem? {
public var id: String
public var title: String
public var comment: String
public var publishStartDateString: String
init(id: String,
title: String,
comment: String,
publishStartDateString: String) {
self.id = id
self.title = title
self.comment = comment
self.publishStartDateString = publishStartDateString
super.init()
}
}
ViewModel
公共类SettingsViewModel:ViewModel {
return NotificationItem(
id: notification.id,
title: notification.title,
comment: notification.comment,
publishStartDateString: notification.publishStartDateString)
}
-----> .map {NotificationItem.instantiate(with:$ 0)}
var item = [NotificationItem]()
public var fetchedNotifications: Driver<NotificationItem> = .empty()
public var apiErrorEvents: Driver<RTVAPIError> = .empty()
public var notificationCount: Driver<Int> = .empty()
public func bindNotificationEvents(with trigger: Driver<Void>) {
let webService: Driver<RTVInformationListWebService> = trigger
.map { RTVInformationListParameters() }
.webService()
let result = webService.request()
apiErrorEvents = Driver.merge(apiErrorEvents, result.error())
notificationCount = result.success().map {$0.informationList.maxCount }
fetchedNotifications =
result.success()
.map {$0.informationList.notifications}
}
收到一条错误消息,提示无法将类型“ [RTVNotification]”的值转换为预期的参数类型“ RTVNotification” 我该怎么办才能解决这个问题。
答案 0 :(得分:2)
map()
函数的目的是迭代输入数组的元素,并将变换函数应用于这些元素中的每个元素。转换后的元素将添加到map()
返回的新输出数组中。重要的是要了解输出数组的长度与输入数组的长度相同。
例如:
let inputArray = ["red", "white", "blue"]
let outputArray = inputArray.map { $0.count } // outputArray is [3, 5, 4]
在您的代码中,您正在调用:
result.success().map { $0.informationList.notifications }
我一点都不了解RxSwift,所以在这里我将进行疯狂的猜测。
首先,我不完全知道result.success()
返回什么,但是您可以在其上调用map()
的事实意味着result.success()
返回一个数组(这很奇怪,但是好吧,我们会去的。)
第二,我们知道result.success()
返回的数组包含具有informationList
属性的元素,而informationList
属性具有名为notifications
的属性。我的猜测是notifications
是复数,表示notifications
属性类型是一个数组,可能是[RTVNotification]
。
所以这段代码:
result.success().map { $0.informationList.notifications }
将success()
数组转换为新数组。根据我的假设notifications
的类型为[RTVNotification]
,并进一步假设success()
数组仅包含一个元素,我期望得到的结果
result.success().map { $0.informationList.notifications }
成为[[RTVNotification]]
类型的数组,即具有一个元素的数组,其中该元素是RTVNotification
s的数组。
然后,您将[[RTVNotification]]
数组输入另一个map()
函数中:
.map { NotificationItem.instantiate(with: $0) }
从该答案的开头回想起map()
遍历数组的元素。由于此映射的输入数组为[[RTVNotification]]
,因此其元素将为[RTVNotification]
类型。这就是您通话中的$0
-[RTVNotification]
。但是instantiate(with:)
函数采用RTVNotification
,而不是RTVNotification
的数组,因此会出现错误:
无法将类型“ [RTVNotification]”的值转换为预期的参数类型“ RTVNotification”
那你怎么做才能解决?
我可能会做这样的事情(您必须根据使用情况对其进行调整):
guard let successResponse = webService.request().success().first else {
print("no success response received")
return nil // basically report up an error here if not successful
}
// get the list of notifications, this will be type [RTVNotification]
let notifications = successResponse.informationList.notifications
// Now you can create an array of `[NotificationItem]` like you want:
let notificationItems = notifications.map { NotificationItem.instantiate(with: $0) }
// do something with notificationItems...
上面的警告是,如果您需要遍历success()
数组中的每个元素,则可以这样做:
let successResponses = webService.result().success()
// successNotifications is of type [[RTVNotification]]
let successNotifications = successResponses.map { $0.informationList.notifications }
// successItems will be of type [[NotificationItem]]
let successItems = successNotifications.map { notifications in
notifications.map { NotificationItem.instantiate(with: $0) }
}
换句话说,在最后一种情况下,您将获得一个包含NotificationItem
数组的数组。
答案 1 :(得分:2)
您的问题在这里:
fetchedNotifications: Driver<NotificationItem>
应该是fetchedNotifications: Driver<[NotificationItem]>
,并且行.map {NotificationItem.instantiate(with: $0)}
需要另一张地图您正在处理Observable<Array<RTVNotification>>
。您在容器类型中有一个容器类型,因此在地图中需要一个地图:
.map { $0.map { NotificationItem.instantiate(with: $0) } }
如果类型不匹配,则需要更改类型。
代码的其他问题...
驱动程序,可观察变量,主题和中继不应使用var
进行定义,它们应始终为let
。在调用绑定之前预订属性的对象将连接到.empty()
可观察对象,并且永远不会获得任何值。毕竟,这是功能反应式编程。
您的NotificationItem
类型应该是struct
,或者它的所有属性都应该是let。
请务必阅读并理解@par对这个问题的回答。他写了一个非常好的解释,浪费知识转移将是可耻的。