Reputation: 5407
I have in a viewmodel a reactive closure to return and sort data from a network call based on type (shipping or billing).
Observable.combineLatest(input.headerRefresh, type).flatMapLatest({ (header, type) -> Observable<[AddressItemViewModel]> in
var els : Observable<[AddressItemViewModel]>
els = self.request()
.trackActivity(self.loading)
.trackActivity(self.headerLoading)
.trackError(self.error)
return els.map{
$0.map {
print(type)
var item : AddressItemViewModel!
switch(type){
case .shipping:
if($0.address.isShipping){
item = AddressItemViewModel(with: $0.address)
}
case .billing:
if($0.address.isBilling){
item = AddressItemViewModel(with: $0.address)
}
}
return item // error
}
}
}).subscribe(onNext: { (items) in
elements.accept(items)
}).disposed(by: rx.disposeBag)
When subscribed to elements
in the view controller, the app crash at return item
.
So my question is how to sort items without using nullable objects? Thanks.
The error :
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
Upvotes: 0
Views: 881
Reputation: 1741
The problem might be this line:
var item : AddressItemViewModel!
Using implicitly unwrapped variable can lead to fatal error. Think what happens when your type
is set to .shipping
and $0.address.isShipping
is set to false
(or type
is billing
and $0.address.isBilling
is false
)? The item
variable will be set to nil
, but the type of item
require to be a non-nil. I think the best option will be to use compactMap
instead of map
to pass only non-nil values:
$0.compactMap {
switch(type){
case .shipping where $0.address.isShipping:
fallthrough
case .billing where $0.address.isBilling:
return AddressItemViewModel(with: $0.address)
default:
return nil
}
}
Upvotes: 1