46

目前我正在尝试让 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)
4

4 回答 4

73

您可以使用RxExamples更好的理解RxSwift。我在RxSwift repo中找到了它。它帮助我理解了 RxSwift。

好的,让我们尝试使用Alamofireand发送简单的请求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_tapfor 按钮:

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

于 2016-01-14T12:15:57.113 回答
35

这个实现在Swift 3中略有改变:

    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()
        }
    }
于 2017-03-02T00:37:03.203 回答
18

尽可能使用 Traits 是个好主意,我建议您在此处查看 RxSwift 文档和 Traits 文档

例如,当您创建 API 调用方法时,它通常会返回一个SingleTrait。

然后可以做这样的事情:

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()
    }
}

这是您可以在不同情况下通过不同方法使用的许多其他特征。

于 2018-02-28T20:14:20.510 回答
1

Swift 3 及更高版本:Observable.create使用using的简单示例URLSession

func createObservableExample() -> Observable<[ToDo]> {
        return Observable.create { observer -> Disposable in
            let dataTask = self.getTodos(from: "https://jsonplaceholder.typicode.com/todos/1") { result in
                switch result {
                case .success(let todos):
                    observer.onNext(todos)
                    observer.onCompleted()
                case .failure(let error):
                    observer.onError(error)
                }
            }
            return Disposables.create {
                dataTask.cancel()
            }
        }
    }
    
    func getTodos(from url: String, completion: @escaping ((Result<[ToDo], Error>) -> Void)) -> URLSessionDataTask {
        let task = URLSession.shared.dataTask(with: URL(string: url)!) { (data, response, error) in
            if let error = error {
                completion(.failure(error)); return
            }
            guard let data = data else {
                let error = NSError(domain: "dataNilError", code: -10001, userInfo: nil)
                completion(.failure(error)); return
            }
            do {
                let todos = try JSONDecoder().decode([ToDo].self, from: data)
                completion(.success(todos))
            } catch {
                completion(.failure(error))
            }
        }
        task.resume()
        return task
    }
于 2018-11-30T10:52:37.463 回答