Skip to content

Commit

Permalink
Merge pull request #131 from meteochu/nsurlsession
Browse files Browse the repository at this point in the history
Conversion from NSURLConnection to NSURLSession
  • Loading branch information
mattdonnelly committed Feb 22, 2016
2 parents c578517 + 795fb75 commit f8c1ece
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 79 deletions.
56 changes: 19 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,76 +35,58 @@ let swifter = Swifter(consumerKey: "", consumerSecret: "", appOnly: true)
####OAuth Authorization:

```swift
swifter.authorizeWithCallbackURL(callbackURL, success: {
(accessToken: SwifterCredential.OAuthAccessToken?, response: NSURLResponse) in

swifter.authorizeWithCallbackURL(callbackURL, success: { accessToken, response in
// ...

},
failure: {
(error: NSError) in
}, failure: { error in

// ...
// ...

})
})
```

####Get Home Timeline:

```swift
swifter.getStatusesHomeTimelineWithCount(20, success: {
(statuses: JSONValue[]?) in

swifter.getStatusesHomeTimelineWithCount(20, success: { statuses in
// ...

}, failure: {
(error: NSError) in

// ...
}, failure: { error in
// ...

})
})
```

####Streaming API:

```swift
swifter.getStatusesSampleDelimited(progress: {
(status: Dictionary<String, JSONValue>?) in

swifter.getStatusesSampleDelimited(progress: { status in
// ...

}, stallWarnings: {
(code: String?, message: String?, percentFull: Int?) in

// ...

}, failure: {
(error: NSError) in
}, stallWarnings: { code, message, percentFull in
// ...

// ...
}, failure: { error in
// ...

})
})
```

####Status Update:

```swift
swifter.postStatusUpdate("Hello, world", success: {
(status: Dictionary<String, JSONValue>?) in

swifter.postStatusUpdate("Hello, world", success: { status in
// ...

}, failure: {
(error: NSError) in

// ...
}, failure: { error in
// ...

})
})
```

##JSON Handling

To make accessing data returned by twitter requests, Swifter provides a class for representing JSON which you interact with similarly to a dictionary. The main advantage of using this instead of a Dictionary<String, AnyObject> is that it works better with Swift's strict typing system and doesnt require you to constantly downcast accessed objects. It also removes the need for lots optional chaining, making your code much cleaner and easier to read.
To make accessing data returned by twitter requests, Swifter provides a class for representing JSON which you interact with similarly to a dictionary. The main advantage of using this instead of a Dictionary<String, AnyObject> is that it works better with Swift's strict typing system and doesn't require you to constantly downcast accessed objects. It also removes the need for lots optional chaining, making your code much cleaner and easier to read.

Here's an example of how you would access the text of the first element in list of statuses:

Expand Down
76 changes: 35 additions & 41 deletions Swifter/SwifterHTTPRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public enum HTTPMethodType: String {
case CONNECT
}

public class SwifterHTTPRequest: NSObject, NSURLConnectionDataDelegate {
public class SwifterHTTPRequest: NSObject, NSURLSessionDataDelegate {

public typealias UploadProgressHandler = (bytesWritten: Int, totalBytesWritten: Int, totalBytesExpectedToWrite: Int) -> Void
public typealias DownloadProgressHandler = (data: NSData, totalBytesReceived: Int, totalBytesExpectedToReceive: Int, response: NSHTTPURLResponse) -> Void
Expand All @@ -60,7 +60,7 @@ public class SwifterHTTPRequest: NSObject, NSURLConnectionDataDelegate {
let HTTPMethod: HTTPMethodType

var request: NSMutableURLRequest?
var connection: NSURLConnection!
var dataTask: NSURLSessionDataTask!

var headers: Dictionary<String, String>
var parameters: Dictionary<String, Any>
Expand All @@ -82,11 +82,7 @@ public class SwifterHTTPRequest: NSObject, NSURLConnectionDataDelegate {
var successHandler: SuccessHandler?
var failureHandler: FailureHandler?

public convenience init(URL: NSURL) {
self.init(URL: URL, method: .GET, parameters: [:])
}

public init(URL: NSURL, method: HTTPMethodType, parameters: Dictionary<String, Any>) {
public init(URL: NSURL, method: HTTPMethodType = .GET, parameters: Dictionary<String, Any> = [:]) {
self.URL = URL
self.HTTPMethod = method
self.headers = [:]
Expand Down Expand Up @@ -178,17 +174,18 @@ public class SwifterHTTPRequest: NSObject, NSURLConnectionDataDelegate {
}

dispatch_async(dispatch_get_main_queue()) {
self.connection = NSURLConnection(request: self.request!, delegate: self)
self.connection.start()

let session = NSURLSession(configuration: .defaultSessionConfiguration(), delegate: self, delegateQueue: .mainQueue())
self.dataTask = session.dataTaskWithRequest(self.request!)
self.dataTask.resume()

#if os(iOS)
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
#endif
}
}

public func stop() {
self.connection.cancel()
self.dataTask.cancel()
}

public func addMultipartData(data: NSData, parameterName: String, mimeType: String?, fileName: String?) -> Void {
Expand All @@ -214,39 +211,16 @@ public class SwifterHTTPRequest: NSObject, NSURLConnectionDataDelegate {
return tempData
}

public func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse) {
self.response = response as? NSHTTPURLResponse

self.responseData.length = 0
}

public func connection(connection: NSURLConnection, didSendBodyData bytesWritten: Int, totalBytesWritten: Int, totalBytesExpectedToWrite: Int) {
self.uploadProgressHandler?(bytesWritten: bytesWritten, totalBytesWritten: totalBytesWritten, totalBytesExpectedToWrite: totalBytesExpectedToWrite)
}

public func connection(connection: NSURLConnection, didReceiveData data: NSData) {
self.responseData.appendData(data)

let expectedContentLength = Int(self.response!.expectedContentLength)
let totalBytesReceived = self.responseData.length

guard data.length > 0 else { return }
self.downloadProgressHandler?(data: data, totalBytesReceived: totalBytesReceived, totalBytesExpectedToReceive: expectedContentLength, response: self.response)
}

public func connection(connection: NSURLConnection, didFailWithError error: NSError) {
#if os(iOS)
UIApplication.sharedApplication().networkActivityIndicatorVisible = false
#endif

self.failureHandler?(error: error)
}

public func connectionDidFinishLoading(connection: NSURLConnection) {
public func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
#if os(iOS)
UIApplication.sharedApplication().networkActivityIndicatorVisible = false
#endif

if let error = error {
self.failureHandler?(error: error)
return
}

if self.response.statusCode >= 400 {
let responseString = NSString(data: self.responseData, encoding: self.dataEncoding)
let responseErrorCode = SwifterHTTPRequest.responseErrorCode(self.responseData) ?? 0
Expand All @@ -259,9 +233,29 @@ public class SwifterHTTPRequest: NSObject, NSURLConnectionDataDelegate {
self.failureHandler?(error: error)
return
}

self.successHandler?(data: self.responseData, response: self.response)
}

public func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
self.responseData.appendData(data)

let expectedContentLength = Int(self.response!.expectedContentLength)
let totalBytesReceived = self.responseData.length

guard data.length > 0 else { return }
self.downloadProgressHandler?(data: data, totalBytesReceived: totalBytesReceived, totalBytesExpectedToReceive: expectedContentLength, response: self.response)
}

public func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void) {
self.response = response as? NSHTTPURLResponse
self.responseData.length = 0
completionHandler(.Allow)
}

public func URLSession(session: NSURLSession, task: NSURLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
self.uploadProgressHandler?(bytesWritten: Int(bytesSent), totalBytesWritten: Int(totalBytesSent), totalBytesExpectedToWrite: Int(totalBytesExpectedToSend))
}

class func stringWithData(data: NSData, encodingName: String?) -> String {
var encoding: UInt = NSUTF8StringEncoding
Expand Down
2 changes: 1 addition & 1 deletion SwifterDemoMac/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="10102" systemVersion="15E39c" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="10102" systemVersion="15E39d" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10102"/>
</dependencies>
Expand Down

0 comments on commit f8c1ece

Please sign in to comment.