简体   繁体   中英

Return Observer.create Not returning and code next to it not working using RxSwift

Well i am pretty much new to reactive programming. problem is, I have a function(A) which returns an object, now I have another function(B) which subscribes returning object from function A and I make function B also as returning an other object in that subscribe, now this whole return this is not work. I have no idea why is happening. Any help would be appreciated. Thanks Function A

func getClassById(classId: Int) -> Observable<Bool> {
    return Observable.create{[weak self] observer -> Disposable in            Alamofire.request("URL", method:.get, parameters: nil, encoding: JSONEncoding.default, headers: self!.getRequestHeader())
            .validate()
            .responseJSON{ response in
                switch response.result {
                    do {
                        let assingnedClass = try JSONDecoder().decode(AssignedClassModel.self, from: data)
                        observer.onNext(true)
                    } catch {
                        observer.onError(error)
                    }
                case .failure(let error):
                    observer.onError(error)
                }
        }
        return Disposables.create()
    }
}

Function B

func getAssignedClassData(classId: Int) -> Observable<[StudentModel]>  { 
    return Observable.create{[weak self] observer -> Disposable in // from here code is not going further.
    APIService.singelton
        .getClassById(classId: classId)
        .asObservable()
        .subscribe(onNext: { [weak self] assingnedClass in
            let studentsData = Array(Database.singleton.fetchStudents(byCLassId: classId))
            print(studentsData)
            observer.onNext(studentsData)
            }, onError: { error in
                print(error)
        }).disposed(by: self!.disposeBag)
        return Disposables.create()
        }
}

Function B2

    func getAssignedClassData(classId: Int) -> Observable<[StudentModel]>  {
        return APIService.singelton
            .getClassById(classId: classId)
            .do(onError: { error in
                print(error)
            })
            .map({ [weak self] assingnedClass in
                return Array(Database.singleton.fetchStudents(byCLassId: classId))
// this code will not be triggered as it is after return. 
                let vc = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "tabBarVC") as? TabBarViewController
                let transition = CATransition()
                transition.duration = 0.5
                transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.default)
                transition.type = CATransitionType.fade
                self?.navigationController?.view.layer.add(transition, forKey: nil)
                self?.navigationController?.pushViewController(vc!, animated: true)

            })
    }
  1. There is no Observable creation needed in Function B. If you want to transform one observable to another you can use map operator .

  2. There is an error handling trouble in Function B. Error will be caught, but Observable will never be completed. In my example I used just side effect for printing error, so error will be propagated and map will not run. There are some strategies forerror handling in RxSwift .

  3. Function B doesn't need asObservable .

  4. The result of Function A ( assingnedClass ) is not used. Probably the real code was simplified.

  5. There is no observer.onCompleted() after observer.onNext() in Function A. Your observable will not be completed and disposed at time.

Here is my example:

class StudentService {
    ...
    func getAssignedClassData(classId: Int) -> Observable<[StudentModel]> {
        return APIService.singelton
            .getClassById(classId: classId)
            .do(onError: { error in
                print(error)
            })
            .map { _ in Array(Database.singelton.fetchStudents(byCLassId: classId)) }
    }
}

class SomeController: UIViewController {
    ...
    func fetchStudentsAndPushViewController() {
        studentService
            .getAssignedClassData(classId: classId)
            .observeOn(MainScheduler.instance)
            .subscribe(onNext: { [weak self] _ in
                let vc = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "tabBarVC") as? TabBarViewController
                let transition = CATransition()
                transition.duration = 0.5
                transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.default)
                transition.type = CATransitionType.fade
                self?.navigationController?.view.layer.add(transition, forKey: nil)
                self?.navigationController?.pushViewController(vc!, animated: true)
            })
            .disposed(by: self!.disposeBag)
    }
}

BTW. You can try RxAlamofire for you APIService so you won't need to wrap the request into Observable by yourself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM