[实例方法'驱动器'要求类型'NotificationItem'和'[NotificationItem]'是等效的]

问题描述 投票:2回答:2

我创建了一个称为通知项的类,并从模型类RTVNotification中解析数据

导入基金会导入RTVModel

公共类NotificationItem:NSObject {

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()
}

}

扩展名NotificationItem {静态函数实例化(带有通知:RTVNotification)-> NotificationItem? {

    return NotificationItem(
        id: notification.id,
        title: notification.title,
        comment: notification.comment,
        publishStartDateString: notification.publishStartDateString)

}

}

ViewModel

公共类SettingsViewModel:ViewModel {

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}

-----> .map {NotificationItem.instantiate(with:$ 0)}

}

}

[得到一个错误,提示无法将类型[RTVNotification]的值转换为预期的参数类型'RTVNotification'我该怎么解决。

swift rx-swift
2个回答
1
投票

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:)函数采用RTVNotificationnot

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数组的数组。


0
投票

您的问题在这里:fetchedNotifications: Driver<NotificationItem>应该为fetchedNotifications: Driver<[NotificationItem]>,并且.map {NotificationItem.instantiate(with: $0)}行需要另一个映射。您正在处理Observable<Array<RTVNotification>>。您在容器类型中有一个容器类型,因此在地图中需要一个地图:

© www.soinside.com 2019 - 2024. All rights reserved.