Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/100.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios RxSwift:UISwitch切换回初始状态_Ios_Swift_Rx Swift_Reactive_Rx Cocoa - Fatal编程技术网

Ios RxSwift:UISwitch切换回初始状态

Ios RxSwift:UISwitch切换回初始状态,ios,swift,rx-swift,reactive,rx-cocoa,Ios,Swift,Rx Swift,Reactive,Rx Cocoa,我正在为我面临的问题寻找解决方案。我有一个TableView,它有多个单元格,每个单元格都有一个ui开关,该开关的状态(开/关)设置如下: viewModel.permissions .drive(tblMessageTypes.rx.items(cellIdentifier: "PermissionCellIdentifier", cellType: PermissionTableViewCell.self)) { [switchSubject] _, item, cell i

我正在为我面临的问题寻找解决方案。我有一个TableView,它有多个单元格,每个单元格都有一个ui开关,该开关的状态(开/关)设置如下:

viewModel.permissions
        .drive(tblMessageTypes.rx.items(cellIdentifier: "PermissionCellIdentifier", cellType: PermissionTableViewCell.self)) { [switchSubject] _, item, cell in
            cell.backgroundColor = .clear
            cell.lblTitle.text = item.permissionTitle
            cell.lblDetail.text = item.permissionDescirption
            cell.selectionStyle = .none
            cell.switchPermission.isOn = item.permissionValue
            cell.switchPermission.isEnabled = !item.isPermissionReadOnly

            cell.switchPermission.rx.controlEvent(.valueChanged)
                .withLatestFrom(cell.switchPermission.rx.value)
                .map { isOn in
                    var newPermission = item
                    newPermission.permissionValue = isOn
                    return newPermission
                }
                .bind(to: switchSubject)
                .disposed(by: cell.disposeBag)
        }
        .disposed(by: disposeBag)
因此,当切换开关时,我将传递一个当前单元格值和更新开关状态,并基于此在VM中调用api,如下所示:

let serverReponse =  inputs.switchToggle
        .map { permission in
            let dicto = permission.toDictionary()
            let parameters = ["permissions": [dicto]]
            return parameters
        } .flatMapLatest { parameters in
            userService.updateUserPermission(parameters: parameters)
                .trackActivity(inputs.indicator)
                .materialize()
        }
        .share()

现在我遇到的问题是,如果api由于任何原因而失败,那么UISwitch应该如何回退到初始状态,即如果它处于关闭状态,用户将其切换到打开状态,而api失败,它应该回退到关闭状态。

我希望看到如下内容。有关此代码的注意事项:

  • 所有“权限”对象都有某种唯一标识每个单元格的方法,我在这里使用UUID,但您可能已经有某种ID
  • ViewModel中可观察到的“权限”用于更新每个单元格。所有的单元格都订阅了它,映射出它们自己的权限对象并显示它
  • 正如您在视图控制器中所做的那样,所有单元格都会通过
    switchToggle
    Observable发送更新的权限
下面的代码根据需要编译和重置单元格。我依靠
zip
操作符来确保我将发送到请求的权限与服务器的响应相结合。如果服务器出错,字典中相应对象中的permissionValue将设置为与发送到服务器的值相反的值

下面代码的观察者越敏锐(双关语),您就会注意到当服务器请求失败时,
permissions
对象将发出,但实际上不会改变状态,因为切换的是开关,而不是字典中的
permissionValue
。但是,该发射将被开关拾取,从而使其自行复位

struct Inputs {
    let initialPermissions: [Permission]
    let switchToggle: Observable<Permission>
}

struct ViewModel {

    let permissions: Observable<[UUID: Permission]>

    init(_ inputs: Inputs, userService: UserService) {
        let serverReponse =  inputs.switchToggle
            .map { permission in
                let dicto = permission.toDictionary()
                let parameters = ["permissions": [dicto]]
                return parameters
            }
            .flatMapLatest { parameters in
                userService.updateUserPermission(parameters: parameters)
                    .materialize()
            }
            .share()

        let perms = Dictionary(grouping: inputs.initialPermissions, by: { $0.id })
            .mapValues { $0.first! }

        permissions = Observable.zip(inputs.switchToggle, serverReponse)
            .filter { $0.1.error != nil }
            .map { Permission(id: $0.0.id, permissionValue: !$0.0.permissionValue) }
            .scan(into: perms, accumulator: { state, update in
                state[update.id] = update
            })
            .startWith(perms)
    }
}
struct输入{
让我们初始化权限:[权限]
让开关切换:可观察
}
结构视图模型{
让权限:可观察
init(输入:输入,用户服务:用户服务){
让ServerResponse=inputs.switchToggle
.map{中的权限
让dicto=permission.toDictionary()
let参数=[“权限”:[dicto]]
返回参数
}
.flatmap中最新的{参数
userService.updateUserPermission(参数:参数)
.具体化
}
.share()
设perms=Dictionary(分组:inputs.initialPermissions,by:{$0.id})
.mapValues{$0.first!}
权限=Observable.zip(inputs.switchToggle、serverReponse)
.filter{$0.1.error!=nil}
.map{权限(id:$0.0.id,permissionValue:!$0.0.permissionValue)}
.scan(进入:perms,累加器:{state,在中更新
状态[update.id]=更新
})
.startWith(perms)
}
}

我尝试了您提供的解决方案,但我无法做到这一点:
让perms=Dictionary(分组:inputs.initialPermissions,by:{$0.id}).mapValues{$0.first!}
,因为我没有从VC传递[Permission],因为我在VM中有可观察到的[Permission]。你能告诉我如何重构上面的代码来解决这个问题吗。