Changes NSURLSession interface.

This commit is contained in:
Krunoslav Zaher 2015-04-20 01:22:08 +02:00
parent 0116d489fc
commit e0146da47c
3 changed files with 49 additions and 53 deletions

View File

@ -61,7 +61,7 @@ func convertResponseToString(data: NSData!, response: NSURLResponse!, error: NSE
}
extension NSURLSession {
public func rx_observableRequest(request: NSURLRequest) -> Observable<(NSData!, NSURLResponse!, NSError!)> {
public func rx_observableRequest(request: NSURLRequest) -> Observable<(NSData!, NSURLResponse!)> {
return create { observer in
// smart compiler should be able to optimize this out
@ -79,8 +79,16 @@ extension NSURLSession {
println(convertResponseToString(data, response, error, interval))
}
handleObserverResult(observer.on(.Next(Box(data, response, error))))
handleObserverResult(observer.on(.Completed))
if let error = error {
observer.on(.Error(error))
}
else {
observer.on(.Next(Box(data ?? nil, response ?? nil))) >>> {
observer.on(.Completed)
} >>! { e in
observer.on(.Error(e))
}
}
}
task.resume()
@ -91,12 +99,8 @@ extension NSURLSession {
}
}
public func rx_observableDataRequest(request: NSURLRequest) -> Observable<Result<NSData>> {
return rx_observableRequest(request) >- map { (data, response, e) -> Result<NSData> in
if e != nil {
return .Error(e)
}
public func rx_observableDataRequest(request: NSURLRequest) -> Observable<NSData> {
return rx_observableRequest(request) >- mapOrDie { (data, response) -> Result<NSData> in
if let response = response as? NSHTTPURLResponse {
if 200 ..< 300 ~= response.statusCode {
return success(data!)
@ -113,23 +117,21 @@ extension NSURLSession {
}
}
public func rx_observableJSONWithRequest(request: NSURLRequest) -> Observable<Result<AnyObject!>> {
return rx_observableDataRequest(request) >- map { (maybeData) -> Result<AnyObject!> in
maybeData >== { data in
var serializationError: NSError?
let result: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: &serializationError)
if let result: AnyObject = result {
return success(result)
}
else {
return .Error(serializationError!)
}
public func rx_observableJSONWithRequest(request: NSURLRequest) -> Observable<AnyObject!> {
return rx_observableDataRequest(request) >- mapOrDie { (data) -> Result<AnyObject!> in
var serializationError: NSError?
let result: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: &serializationError)
if let result: AnyObject = result {
return success(result)
}
else {
return .Error(serializationError!)
}
}
}
public func rx_observableJSONWithURL(URL: NSURL) -> Observable<Result<AnyObject!>> {
public func rx_observableJSONWithURL(URL: NSURL) -> Observable<AnyObject!> {
return rx_observableJSONWithRequest(NSURLRequest(URL: URL))
}
}

View File

@ -38,53 +38,47 @@ class DefaultImageService: ImageService {
self.imageCache.countLimit = 20
}
func decodeImage(imageData: Observable<Result<NSData>>) -> Observable<Result<UIImage>> {
return imageData >- observeSingleOn($.imageDecodeScheduler) >- map { maybeData in
return maybeData >== { data in
let maybeImage = UIImage(data: data)
if maybeImage == nil {
// some error
return .Error(apiError("Decoding image error"))
}
let image = maybeImage!
return success(image)
func decodeImage(imageData: Observable<NSData>) -> Observable<UIImage> {
return imageData >- observeSingleOn($.imageDecodeScheduler) >- mapOrDie { data in
let maybeImage = UIImage(data: data)
if maybeImage == nil {
// some error
return .Error(apiError("Decoding image error"))
}
let image = maybeImage!
return success(image)
} >- observeSingleOn($.callbackScheduler)
}
func imageFromURL(URL: NSURL) -> Observable<Result<UIImage>> {
let maybeImage = self.imageDataCache.objectForKey(URL) as? UIImage
let decodedImage: Observable<Result<UIImage>>
let decodedImage: Observable<UIImage>
// best case scenario, it's already decoded an in memory
if let image = maybeImage {
decodedImage = returnElement(success(image))
decodedImage = returnElement(image)
}
else {
let cachedData = self.imageDataCache.objectForKey(URL) as? NSData
// does image data cache contain anything
if let cachedData = cachedData {
decodedImage = returnElement(success(cachedData)) >- decodeImage
decodedImage = returnElement(cachedData) >- decodeImage
}
else {
// fetch from network
decodedImage = $.URLSession.rx_observableDataRequest(NSURLRequest(URL: URL)) >- doOnNext { maybeData in
_ = maybeData >== { data in
self.imageDataCache.setObject(data, forKey: URL)
}
decodedImage = $.URLSession.rx_observableDataRequest(NSURLRequest(URL: URL)) >- doOnNext { data in
self.imageDataCache.setObject(data, forKey: URL)
} >- decodeImage
}
}
return decodedImage >- doOnNext { maybeImage in
if let image = maybeImage.value {
self.imageCache.setObject(image, forKey: URL)
}
}
return decodedImage >- doOnNext { image in
self.imageCache.setObject(image, forKey: URL)
} >- catchToResult
}
}

View File

@ -44,11 +44,11 @@ class DefaultWikipediaAPI: WikipediaAPI {
let urlContent = "http://en.wikipedia.org/w/api.php?action=opensearch&search=\(escapedQuery)"
let url = NSURL(string: urlContent)!
return $.URLSession.rx_observableJSONWithURL(url) >- observeSingleOn($.backgroundScheduler) >- map { json in
return json >== castOrFail >== { (json: [AnyObject]) in
return $.URLSession.rx_observableJSONWithURL(url) >- observeSingleOn($.backgroundScheduler) >- mapOrDie { json in
return castOrFail(json) >== { (json: [AnyObject]) in
return WikipediaSearchResult.parseJSON(json)
}
} >- observeSingleOn($.callbackScheduler)
} >- observeSingleOn($.callbackScheduler) >- catchToResult
}
// http://en.wikipedia.org/w/api.php?action=parse&page=rx&format=json
@ -60,10 +60,10 @@ class DefaultWikipediaAPI: WikipediaAPI {
return returnElement(.Error(apiError("Can't create url")))
}
return $.URLSession.rx_observableJSONWithURL(url!) >- map { jsonResult in
return jsonResult >== castOrFail >== { (json: NSDictionary) in
return $.URLSession.rx_observableJSONWithURL(url!) >- mapOrDie { jsonResult in
return castOrFail(jsonResult) >== { (json: NSDictionary) in
return WikipediaPage.parseJSON(json)
}
} >- observeSingleOn($.callbackScheduler)
} >- observeSingleOn($.callbackScheduler) >- catchToResult
}
}