現在、RxSwiftを機能させようとしています。そして、カスタムObservableを作成したいと思います。しかし、私は何か間違ったことをしていると思います。
私はこの最小限のサンプルに行うことを蒸留しました:
import Foundation
import RxSwift
class Example
{
let exampleObservable : Observable<String> = Observable.create { (observer) in
observer.on(.Next("hello"))
observer.on(.Completed)
return AnonymousDisposable { }
}
let exampleObserver : AnyObserver<String>?
func run()
{
self.exampleObserver = exampleObservable.subscribeNext({ (text) -> Void in
print(text)
})
}
}
let ex = Example()
ex.run()
これは正しいです? runメソッドでは、subscribeNextメソッドはXCodeによってそのように自動補完されます。
しかし、実行すると、次のコンパイルエラーが発生します。
Cannot Invoke 'substribeNext' with an argument list of type ((String) -> Void)
RxExamples
をよりよく理解するには、RxSwift
を使用できます。 RxSwift
repo で見つけました。 RxSwiftを理解するのに役立ちました。
では、Alamofire
とRxSwift
を使用して簡単なリクエストを送信してみましょう。最初にリクエスト関数を書きます:
_ func getApi() -> Observable<AnyObject?> {
return create{ observer in
let request = Alamofire.request(.GET, "http://someapiurl.com", parameters: nil)
.response(completionHandler: { request, response, data, error in
if ((error) != nil) {
observer.on(.Error(error!))
} else {
observer.on(.Next(data))
observer.on(.Completed)
}
});
return AnonymousDisposable {
request.cancel()
}
}
}
_
getApi()
メソッドは、Alamofire
を使用して要求を送信し、サーバーから応答を取得します。成功またはエラーメッセージの送信にRxSwift
オブザーバーを使用しました。次に、この関数を呼び出す必要があります。ボタンに_rx_tap
_を使用できます。
_class ViewController: UIViewController {
var disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
getApi()
// Set 3 attempts to get response
.retry(3)
// Set 2 seconds timeout
.timeout(2, MainScheduler.sharedInstance)
// Subscribe in background thread
.subscribeOn(Dependencies.sharedDependencies.backgroundWorkScheduler)
// Observe in main thread
.observeOn(Dependencies.sharedDependencies.mainScheduler)
// Subscribe on observer
.subscribe(
onNext: { data in
do {
let post = try NSJSONSerialization.JSONObjectWithData(data as! NSData, options: []) as! NSDictionary
print(post)
} catch {
print(NSString(data: data as! NSData, encoding: NSUTF8StringEncoding))
return
}
},
onError: { error in
print(error)
},
onCompleted: {
print("Completed")
},
onDisposed: {
print("Disposed")
}
)
.addDisposableTo(disposeBag)
}
}
_
これは私の簡単な例です。これがお役に立てば幸いです。 ReactiveX
は大きなチャンスです。学ぶことに頑張ってくださいRxSwift
!
この実装はSwiftで少し変更されました:
func observableFunc() -> Observable<Bool> {
return Observable.create { observer in
self.apiClient.fetchData(callback: { results, error in
if let error = error {
observer.onError(error)
}
if let results = results {
observer.onNext(true)
observer.onCompleted()
}
})
return Disposables.create()
}
}
できる限りトレイトを使用することをお勧めします。RxSwiftのドキュメントとTraitsのドキュメントをご覧になることをお勧めします Here。
たとえば、API呼び出しメソッドを作成すると、通常はSingle
Traitを返します。
その後、次のようなことができます:
func getSomething() -> Single<YourType> {
return Single<YourType>.create { single in
//perform API call
//Then emmit success event
single(.success(YourType))
//Or error event
single(.error(Error))
return Disposables.create()
}
}
それは、さまざまなアプローチでさまざまなケースで使用できる他の多くの特性です。
遊び場を設置することをお勧めします。 CocoaPodsプレイグラウンドプラグインは、プレイグラウンドを簡単にセットアップする方法を提供します
gem install cocoapods-playgrounds
pod playgrounds RxSwift
これにより、RxSwiftをすばやく簡単にいじくり回すことができ、物事をより速く試すことができます。私の個人的な経験では、あなたの理解を磨く最良の方法です
Swift 3以降:URLSession
を使用してObservable.create
を使用する簡単な例
func createObservableExample() -> Observable<Any> {
return Observable.create { observer -> Disposable in
let dataTask: URLSessionDataTask = URLSession.shared.dataTask(with: URL(string: "https://jsonplaceholder.typicode.com/todos/1")!) { (data, response, error) in
if let error = error {
observer.onError(error)
return
}
guard let data = data else {
return observer.onError(NSError(domain: "dataNilError", code: -10001, userInfo: nil))
}
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
observer.onNext(json)
observer.onCompleted()
} catch {
observer.onError(error)
}
}
return Disposables.create {
dataTask.cancel()
}
}
}