Generic parameter 'Result' could not be inferred with RxSwift
In order for type inference to work in closures, you generally need either the outer scope to know the type or the closure itself needs to be one line. This is a limitation in the Swift type system. So either:
htmlHelper.fetchHtmlObservable(url) // this one is an Observable<String> function
.subscribeOn(ConcurrentDispatchQueueScheduler.init(qos: .background))
.map {
ParsingTypeFactory.getParsingType(parsingType: self.parsingType).parseActionItems(document: $0)
}
or
let myItems: Observable<[MyItem]> = htmlHelper.fetchHtmlObservable(url) // this one is an Observable<String> function
.subscribeOn(ConcurrentDispatchQueueScheduler.init(qos: .background))
.map {
let parsingHelper = ParsingTypeFactory.getParsingType(parsingType: self.parsingType)
return parsingHelper.parseActionItems(document: $0)
}
Other options:
Note that in all of the cases discussed so far, you are holding a strong reference to self and likely causing a memory cycle/leak. You can avoid that by making a helper function that isn't part of the class:
// do NOT put this in the class, make it a free function (possibly private to avoid namespace pollution.)
func parser(for parsingType: ParsingType) -> (Document) -> [MyItem] {
return { document in
let parsingHelper = ParsingTypeFactory.getParsingType(parsingType: parsingType)
return parsingHelper.parseActionItems(document: document)
}
}
And now the code in question becomes:
let myItems = htmlHelper.fetchHtmlObservable(url) // this one is an Observable<String> function
.subscribeOn(ConcurrentDispatchQueueScheduler.init(qos: .background))
.map(parser(for: parsingType))
If you don't like the idea of a free function, or you don't like a function that returns a function, you can put the function in an extension on ParserType:
extension ParsingType {
func parser(document: Document) -> [MyItem] {
let parsingHelper = ParsingTypeFactory.getParsingType(parsingType: self)
return parsingHelper.parseActionItems(document: document)
}
}
and now the original code becomes:
let myItems = htmlHelper.fetchHtmlObservable(url) // this one is an Observable<String> function
.subscribeOn(ConcurrentDispatchQueueScheduler.init(qos: .background))
.map(parsingType.parser(document:))
This also avoids keeping a reference to self.
RxSwift - Generic parameter 'Self' could not be inferred
I would suggest you to use the latest version of RxSwift. What you're using right now is deprecated. Your error may be related to it.
There are two ways to do what you're doing:
let countryArray = ["Bangladesh", "India", "Pakistan", "Nepal", "Bhutan", "China", "Malaysia", "Myanmar", "Sri Lanka", "Saudi Arabia"]
let countries = Observable.of(countryArray)
// Be sure to register the cell
tableView.register(UINib(nibName: "MyCell", bundle: nil), forCellReuseIdentifier: "myCell")
To provide the cell type in the
items(cellIdentifier:cellType:)
, that's basically what you are doing:countries
.bind(to: tableView.rx.items(cellIdentifier: "myCell", cellType: MyCell.self)) { (row, element, cell) in
// configure cell
}
.disposed(by: disposeBag)To provide the cell factory closure, in other words dequeue the cell in the closure and return it:
countries
.bind(to: tableView.rx.items) { (tableView, row, element) in
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: IndexPath(row: row, section: 0)) as! MyCell
// configure cell
return cell
}
.disposed(by: disposeBag)
Both have pros and cons. The second one has a reference to the tableView
which sometimes can be very handy.
RxDataSources `Generic parameter 'Self' could not be inferred`
The Rx stream you bind to your RxTableViewSectionedReloadDataSource
has to be of type Observable<[ActiveOrdersSection]>
. I don't know exactly what your types are in this example because the code you provided is not enough but
I think that by using .map { Observable.just($0.items) }
the result stream will be of type Observable<Observable<[Order]>>
.
Try to change it to:.map { [ActiveOrdersSection(header: "Your Header", orders: 0.items)] }
error: generic parameter 'T' could not be inferred in swift
You have to tell the compiler the type of T.
func makeFlatArrayGeneric<T>(_ array: [Any]) -> [T] {
var flatArray = [T]()
for item in array {
if let item = item as? T {
flatArray.append(item)
} else if let item = item as? [Any] {
let result: [T] = makeFlatArrayGeneric(item)
flatArray += result
}
}
return flatArray
}
let array: [Any] = [1, 2, [3], [4, [5]]]
let items: [Int] = makeFlatArrayGeneric(array) //[1, 2, 3, 4, 5]
A more functional approach to solving your problem.
extension Array {
func flatten() -> Array<Element> {
return self.flatMap({ element -> [Element] in
if let array = element as? Array {
return array.flatten()
} else {
return [element]
}
})
}
}
let items: [Int] = array.flatten() //[1, 2, 3, 4, 5]
RxSwift - optional issue on binding to tableView
You see this error because the compiler cannot infer the type of the Optional
variable users
passed into the following functions which work on generics and need to be able to infer the type.
An Optional
in Swift is actually implemented as shown below. I guess in case of an Optional
being potentially nil
aka .none
the compiler cannot infer the type for methods like e.g. items
and bind(to:)
which work on generics.
public enum Optional<Wrapped> : ExpressibleByNilLiteral {
/// The absence of a value.
///
/// In code, the absence of a value is typically written using the `nil`
/// literal rather than the explicit `.none` enumeration case.
case none
/// The presence of a value, stored as `Wrapped`.
case some(Wrapped)
/// Creates an instance that stores the given value.
public init(_ some: Wrapped)
//...
}
Workaround 1.): You could just use filterNil()
(RxOptionals
lib) to avoid the problem.
private func bind() {
users.asObservable().filterNil().bind(to:
tableView.rx.items(cellIdentifier: "UserCell",
cellType: UITableViewCell.self)) { (index, user, cell) in
// Cell setup.
}.disposed(by: disposeBag)
}
Workaround 2.): Make users
non-optional. If you have no users just set an empty array as value.
let users: Variable<[User]> = Variable<[User]>([])
Workaround 3.): Use Nil-Coalescing Operator ??
in map
function like
private func bind() {
users.asObservable().map { optionalUsers -> [User] in
return optionalUsers ?? []
}
.bind(to:
tableView.rx.items(cellIdentifier: "UserCell",
cellType: UITableViewCell.self)) { (index, user, cell) in
// Cell setup.
}.disposed(by: disposeBag)
}
Sidenote: Variable
is deprecated in the latest version of RxSwift
Just for reference:
Implementation of items
public func items<S: Sequence, Cell: UITableViewCell, O : ObservableType>
(cellIdentifier: String, cellType: Cell.Type = Cell.self)
-> (_ source: O)
-> (_ configureCell: @escaping (Int, S.Iterator.Element, Cell) -> Void)
-> Disposable
where O.E == S {
return { source in
return { configureCell in
let dataSource = RxTableViewReactiveArrayDataSourceSequenceWrapper<S> { (tv, i, item) in
let indexPath = IndexPath(item: i, section: 0)
let cell = tv.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! Cell
configureCell(i, item, cell)
return cell
}
return self.items(dataSource: dataSource)(source)
}
}
}
Implementation of bind(to:)
public func bind<O: ObserverType>(to observer: O) -> Disposable where O.E == E {
return self.subscribe(observer)
}
Related Topics
Xcode 11 Archive Gives Phasescriptexecution Failed
Game Exits from Pause State After Resuming It from Background in Swift
How to Add Two or More Buttons to Annotationview: Mkannotationview
How to Draw a Simple Rounded Rect in Swift (Rounded Corners)
iOS Swift Flood Fill Algorithm
Navigationlink Inside Lazyvgrid Cycles All Entries on Back, Swiftui
Setting Default Tab in Uitabbar in Swift
How to Read References Given by Ptr_Refs in iOS
iOS Firebase Database Get Key of Value
Wkwebview Is Showing Only Background
Problems with Cropping a Uiimage in Swift
How to Find the Index of a Tuple Element from an Tuple Array? iOS, Swift
Showing Hidden View Really Slow
Creating a Custom UI View Class to Use as a Map Annotation
How to Set Up Array for Multi Annotations with Swift