【问题标题】:RxSwift minimal Observable.create exampleRxSwift 最小 Observable.create 示例
【发布时间】:2016-04-18 18:28:47
【问题描述】:

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

【问题讨论】:

    标签: swift rx-swift


    【解决方案1】:

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

    好的,让我们尝试使用AlamofireRxSwift 发送简单的请求。首先我们编写请求函数:

     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 发送请求并从服务器获取响应。我使用RxSwiftobserver 发送成功或错误消息。其次,我们必须调用这个函数。您可以使用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

    【讨论】:

      【解决方案2】:

      这个实现在 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()
              }
          }
      

      【讨论】:

        【解决方案3】:

        尽可能使用 Traits 是个好主意,我建议您查看 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()
            }
        }
        

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

        【讨论】:

          【解决方案4】:

          Swift 3 及以上版本: 使用Observable.create 使用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
              }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-09-08
            • 1970-01-01
            • 2021-08-19
            • 2014-12-12
            • 2020-10-14
            • 1970-01-01
            相关资源
            最近更新 更多