ReactiveX / RxSwift

Reactive Programming in Swift
MIT License
24.38k stars 4.17k forks source link

Request into Observable.create #912

Closed apoloa closed 8 years ago

apoloa commented 8 years ago

Short description of the issue:

Problem using Rx to do a Request into Observable.create. Always receive Error Domain=NSURLErrorDomain Code=-999 "cancelled", I added the App Transport Security Settings but the error are the same.

Self contained code example that reproduces the issue:

func getEvents() -> Observable<Data> {
        return Observable.create { observer in
            let url = URL(string: "URL")
            var request = URLRequest(url: url!)
            request.httpMethod = "GET"

            let session = URLSession(configuration: URLSessionConfiguration.default)

            let task = session.dataTask(with: request) { data, response, error in
                if error != nil {
                    fatalError("OPSS: \(error)") // Always receive an error
                }
                observer.onNext(data!)
                let infomation = String(describing: data!)
                print(infomation)
            }

            task.resume()
            return Disposables.create {
                task.cancel()
            }
        }
    }

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        let disposeBag = DisposeBag()

        getEvents().subscribe { (Data) in
            print("OK")
        }.addDisposableTo(disposeBag)

        return true

    }

Xcode version:

Version 8.0 (8A218a)

Installation method:

I have multiple versions of Xcode installed: (so we can know if this is a potential cause of your issue)

Level of RxSwift knowledge: (this is so we can understand your level of knowledge and formulate the response in an appropriate manner)

ikesyo commented 8 years ago

A URLSession instance must be alived until a task get completed. Otherwise the resumed task will be cancelled immediately when the session instance is deinited.

apoloa commented 8 years ago

I changed the URLSession and put globally, but the process return the same error

import UIKit
import RxSwift
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    let session = URLSession(configuration: URLSessionConfiguration.default)
    func getEvents() -> Observable<Data> {
        return Observable.create { observer in
            let url = URL(string: "URL")
            var request = URLRequest(url: url!)
            request.httpMethod = "GET"
            let task = self.session.dataTask(with: request) { data, response, error in
                if error != nil {
                    fatalError("OPSS: \(error)")
                }
                observer.onNext(data!)
                let infomation = String(describing: data!)
                print(infomation)
            }

            task.resume()
            return Disposables.create {
                task.cancel()
            }
        }
    }

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        let disposeBag = DisposeBag()

        getEvents().subscribe { (Data) in
            print("OK")
        }.addDisposableTo(disposeBag)

        return true

    }

}
apoloa commented 8 years ago

Solved, The problem is relationship with the DisposableBag, the disposableBag are defined in the function and this will be dealloc when the function finish. Moving the scope of the DisposeBagto class scope, solve the problems.