web-dev-qa-db-fra.com

RxSwift minimal Observable.create exemple

Actuellement, j'essaie de faire fonctionner RxSwift. Et je veux créer un observable personnalisé. Mais je pense que je fais quelque chose de mal.

J'ai distillé ce que je fais à cet échantillon minimal:

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

Est-ce correct? Dans la méthode run, la méthode subscribeNext est complétée automatiquement de cette façon par XCode.

Example

Mais quand je le lance, j'obtiens l'erreur de compilation suivante:

Cannot Invoke 'substribeNext' with an argument list of type ((String) -> Void)
39
Matthijn

Vous pouvez utiliser RxExamples pour une meilleure compréhension RxSwift. Je l'ai trouvé dans RxSwiftrepo . Cela m'a aidé à comprendre RxSwift.

Ok, essayons d’envoyer une requête simple en utilisant Alamofire et RxSwift. Tout d'abord, nous écrivons une fonction de requête:

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

La méthode getApi() envoie une requête et obtient une réponse du serveur à l'aide de Alamofire. J'ai utilisé RxSwift observateur pour envoyer des messages de réussite ou d'erreur. Deuxièmement, nous devons appeler cette fonction. Vous pouvez utiliser rx_tap Pour le bouton:

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

Ceci est mon exemple simple. J'espère que cela vous aide. ReactiveX est une opportunité énorme. Bonne chance dans apprendre RxSwift!

68
Svyatoslav

Cette implémentation a légèrement changé avec 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()
        }
    }
25
Gregg

C'est une bonne idée d'utiliser les traits chaque fois que vous le pouvez. Je vous suggère de jeter un coup d'œil à la documentation de RxSwift et à celle de Traits Ici.

Par exemple, lorsque vous créez une méthode d'appel d'API, elle retourne généralement un trait Single.

Alors peut peut faire quelque chose comme ceci:

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

Ce sont beaucoup d'autres caractéristiques que vous pouvez utiliser dans différents cas avec différentes approches.

7
GOrozco58

Je suggère de mettre en place un terrain de jeu. Le plug-in de jeux CocoaPods fournit un moyen facile de configurer un terrain de jeux

gem install cocoapods-playgrounds
pod playgrounds RxSwift

Cela simplifie et accélère la tâche avec RxSwift et permet d’essayer plus rapidement. D'après mon expérience personnelle, c'est le meilleur moyen de peaufiner votre compréhension.

1
TheiOSChap

Swift 3 et supérieur: Exemple simple d'utilisation de Observable.create en utilisant URLSession

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()
        }
    }
}
0
Suhit Patil