Closed david-gettins closed 4 months ago
There's nothing wrong with the code you posted. However, I think this is a bit cleaner:
guard let url = URL(string: "\(baseUrl)/\(path)") else {
return .empty()
}
Use .empty()
rather than Observable.create(_:)
when you just want to emit a completed
event.
Change that and see what happens.
Thank you that is a nice suggestion. Unfortunately it hasn't resolved the issue. Here is a screenshot of what I am seeing:
// HttpClient.swift
public func request(
path: String,
method: String? = nil,
headers: Dictionary<String, String>? = nil,
body: Data? = nil
) -> Observable<Data> {
guard let url = URL(string: "\(self.baseUrl)/\(path)") else {
return .empty()
}
var request = URLRequest(url: url)
request.httpMethod = method ?? "GET"
if let headers = headers {
headers.forEach { key, value in
request.setValue(value, forHTTPHeaderField: key)
}
}
if let body = body {
request.httpBody = body
}
return URLSession.shared.rx.data(request: request)
}
// SomeClient.swift request func
guard let data = try? JSONEncoder().encode(streamable) else {
return .empty()
}
return httpClient
.request(
path: "api/something",
method: "POST",
headers: [
"Content-Type" : "application/json",
"Authorization" : "Bearer \(self.configuration.apiKey)"
],
body: data
)
.take(1)
.map { try JSONDecoder().decode(SomeObject.self, from: $0) }
// SomeReactNativeModule.swift
let sub = someClient
.request(input: input)
.map { $0.toWritable() }
.subscribe(
onNext: { writable in
resolve(writable)
},
onError: { error in
reject("SomeCode", error.localizedDescription, error)
sub.dispose()
},
onCompleted: {
sub.dispose()
}
)
Try this:
_ = someClient
.request(input: input)
.map { $0.toWritable() }
.subscribe(
onNext: { writable in
resolve(writable)
},
onError: { error in
reject("SomeCode", error.localizedDescription, error)
}
)
It is wholly unnecessary to store the disposable and call dispose() on an error or on completed because disposal is automatic in those instances.
Remember, a Disposable is not like a Combine Cancellable. You don't need to hold it in order to keep the subscription alive.
The information you provided is unfortunately not enough to truly help. The code you pasted seems to work fine in an empty project so I can only assume something in the RN project itself is causing it, and we do not officially support RN at the moment.
If you provide a small reproducible example it'll provide us a few more options to try and assist
Thanks both. I'll knock together a reproduction repo next week. @danielt1263 I'll give your suggestion a go, but i think I tried that already. None the less, if dispose is unnecessary in those circumstances I'll remove it anyway.
@freak4pc I wouldn't be surprised if you're right about it being down to it being in a React Native environment. In unit tests the code works completely fine.
@danielt1263 You were right. Thank you. I feel slightly embarrassed as I have worked with RXJS in the past and did not make such a silly mistake.
Thanks for your help, on a Saturday too.
@david-gettins Glad to hear it helped. Likely what was going on was that your manual dispose and the automatic dispose were executing on different threads and that caused some internal clash. This wouldn't show itself in a test harness unless you wrote the test in a very specific, unusual, way.
Short description of the issue:
I am attempting to use this in an iOS Native Module for React Native. I am using the URLSession RXCocoa extension for making calls to an API. As soon as my function is called, the app crashes. The final line in the stack trace is
outlined init with copy of Disposable
.Is this a bug, or have I not set things up correctly?
Expected outcome:
Does not crash.
What actually happens:
Crashes.
Self contained code example that reproduces the issue:
Here is the function:
Here is its usage:
While debugging, the error shows on the map.
Platform/Environment
How easy is to reproduce? (chances of successful reproduce after running the self contained code)
Xcode version:
Installation method:
I have multiple versions of Xcode installed: (so we can know if this is a potential cause of your issue)
Level of RxSwift knowledge: (this is so we can understand your level of knowledge and formulate the response in an appropriate manner)