patternswiftMinor
Save token id into a database in Swift
Viewed 0 times
swiftintotokensavedatabase
Problem
I want to save my users tokens id into my database using POST request in Swift (here PHP code here). I am a bit confused about synchronous and asynchronous request.
- Is this code the right way to do it?
- would the app crash if there is a connection problem while it is sending the synchronous request
- shall I use an api key (not sure is the correct word) to "identify" the user
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
var userId = "001" //I just use it as USER number 1
// prepare the tolen to be saved from to xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
var token = NSString(format: "%@", deviceToken)
token = token.stringByReplacingOccurrencesOfString(
"",
withString: "")
token = token.stringByReplacingOccurrencesOfString(" ", withString: "")
dispatch_async(dispatch_get_main_queue(), { () -> Void in
var postBody = NSString(format: "user=%@&token=%@", userId, token)
var endBody = NSURL(string: "http://www.myServer.com/api/v1.0/saveToken.php")
var request = NSMutableURLRequest(URL: endBody!, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: 30.0)
request.HTTPMethod = "POST";
request.HTTPBody = postBody.dataUsingEncoding(NSUTF8StringEncoding)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
var response: NSURLResponse?
var error: NSError?
NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error)
println(response)
println(error)
})
}Solution
This:
is actually a bad method to convert an
(containing the bytes in hexadecimal). It relies on
having the format
which is not officially documented. In most cases, the
an object is only suitable for debugging purposes, but not for further
processing.
I would convert all data bytes explicitly to create the string. Here is a possible implementation as an
which can be used as
With
you dispatch the URL request to the main queue where it blocks the
UI. You can use
it to a background thread, or simply use
Now the request is done in the background and then the completion
handler called on the main thread.
In the case of an connection problem, the completion handler is called
with
problem.
shall I use an api key (not sure is the correct word) to "identify" the user
This question is a bit broad and depends on what you are trying to
achieve. Here are some comparisons of the available methods:
which might serve as a starting point for your further research.
var token = NSString(format: "%@", deviceToken)
token = token.stringByReplacingOccurrencesOfString("", withString: "")
token = token.stringByReplacingOccurrencesOfString(" ", withString: "")is actually a bad method to convert an
NSData object to an NSString(containing the bytes in hexadecimal). It relies on
descriptionhaving the format
which is not officially documented. In most cases, the
description ofan object is only suitable for debugging purposes, but not for further
processing.
I would convert all data bytes explicitly to create the string. Here is a possible implementation as an
NSData extension method:extension NSData {
func hexString() -> String {
// "Array" of all bytes:
let bytes = UnsafeBufferPointer(start: UnsafePointer(self.bytes), count:self.length)
// Array of hex strings, one for each byte:
let hexBytes = map(bytes) { String(format: "%02hhx", $0) }
// Concatenate all hex strings:
return "".join(hexBytes)
}
}which can be used as
let token = deviceToken.hexString()With
dispatch_async(dispatch_get_main_queue(), { ... }you dispatch the URL request to the main queue where it blocks the
UI. You can use
dispatch_get_global_queue() instead to dispatchit to a background thread, or simply use
sendAsynchronousRequest():NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {
(response, data, error) -> Void in
if data != nil {
println("data: \(data)")
} else {
println("failed: \(error.localizedDescription)")
}
}Now the request is done in the background and then the completion
handler called on the main thread.
In the case of an connection problem, the completion handler is called
with
data == nil and error != nil containing information about theproblem.
shall I use an api key (not sure is the correct word) to "identify" the user
This question is a bit broad and depends on what you are trying to
achieve. Here are some comparisons of the available methods:
- CFUUID Vs. advertisingIdentifier Vs. identifierForVendor
- The Developer’s Guide to Unique Identifiers
which might serve as a starting point for your further research.
Code Snippets
var token = NSString(format: "%@", deviceToken)
token = token.stringByReplacingOccurrencesOfString("<", withString: "")
token = token.stringByReplacingOccurrencesOfString(">", withString: "")
token = token.stringByReplacingOccurrencesOfString(" ", withString: "")<01020304 05060708 090a0b0c 0d0e0f10>extension NSData {
func hexString() -> String {
// "Array" of all bytes:
let bytes = UnsafeBufferPointer<UInt8>(start: UnsafePointer(self.bytes), count:self.length)
// Array of hex strings, one for each byte:
let hexBytes = map(bytes) { String(format: "%02hhx", $0) }
// Concatenate all hex strings:
return "".join(hexBytes)
}
}let token = deviceToken.hexString()dispatch_async(dispatch_get_main_queue(), { ... }Context
StackExchange Code Review Q#86611, answer score: 7
Revisions (0)
No revisions yet.