Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>A few things first</p> <ul> <li>Decide how you want to encode your data - JSON or url-encoding are a good start.</li> <li>Decide upon a return value - will it be 1, TRUE or 0, FALSE, or even YES/non-nil nothing/nil. </li> <li>Read up on the <a href="https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html#//apple_ref/doc/uid/20001836-BAJEAIEE">URL Loading System</a>, it's your friend. </li> </ul> <p>Aim to make all your url connections asynchronous so your UI remains responsive. You can do this with NSURLConnectionDelegate callbacks. NSURLConnection has a small drawback: your code must be decoupled. Any variables you want available in the delegate functions will need to be saved to ivars or in your request's userInfo dict. </p> <p>Alternatively you can use GCD, which, when coupled with the __block qualifiers, allows you to specify error/return code at the point you declare it - useful for one off fetches. </p> <p>Without further ado, here's a quick and dirty url-encoder: </p> <pre><code>- (NSData*)encodeDictionary:(NSDictionary*)dictionary { NSMutableArray *parts = [[NSMutableArray alloc] init]; for (NSString *key in dictionary) { NSString *encodedValue = [[dictionary objectForKey:key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSString *encodedKey = [key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSString *part = [NSString stringWithFormat: @"%@=%@", encodedKey, encodedValue]; [parts addObject:part]; } NSString *encodedDictionary = [parts componentsJoinedByString:@"&amp;"]; return [encodedDictionary dataUsingEncoding:NSUTF8StringEncoding]; } </code></pre> <p>Using a JSON library like <a href="https://github.com/johnezang/JSONKit">JSONKit</a> makes encoding things easier, consider it!</p> <h2>Method 1 - NSURLConnectionDelegate async callbacks:</h2> <pre><code>// .h @interface ViewController : UIViewController&lt;NSURLConnectionDelegate&gt; @end // .m @interface ViewController () { NSMutableData *receivedData_; } @end ... - (IBAction)asyncButtonPushed:(id)sender { NSURL *url = [NSURL URLWithString:@"http://localhost/"]; NSDictionary *postDict = [NSDictionary dictionaryWithObjectsAndKeys:@"user", @"username", @"password", @"password", nil]; NSData *postData = [self encodeDictionary:postDict]; // Create the request NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; [request setHTTPMethod:@"POST"]; [request setValue:[NSString stringWithFormat:@"%d", postData.length] forHTTPHeaderField:@"Content-Length"]; [request setValue:@"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:@"Content-Type"]; [request setHTTPBody:postData]; NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; [connection start]; } - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { [receivedData_ setLength:0]; } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [receivedData_ appendData:data]; } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { NSLog(@"Succeeded! Received %d bytes of data", [receivedData_ length]); NSString *responeString = [[NSString alloc] initWithData:receivedData_ encoding:NSUTF8StringEncoding]; // Assume lowercase if ([responeString isEqualToString:@"true"]) { // Deal with true return; } // Deal with an error } </code></pre> <h2>Method 2 - Grand Central Dispatch async function:</h2> <pre><code>// .m - (IBAction)dispatchButtonPushed:(id)sender { NSURL *url = [NSURL URLWithString:@"http://www.apple.com/"]; NSDictionary *postDict = [NSDictionary dictionaryWithObjectsAndKeys:@"user", @"username", @"password", @"password", nil]; NSData *postData = [self encodeDictionary:postDict]; // Create the request NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; [request setHTTPMethod:@"POST"]; [request setValue:[NSString stringWithFormat:@"%d", postData.length] forHTTPHeaderField:@"Content-Length"]; [request setValue:@"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:@"Content-Type"]; [request setHTTPBody:postData]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // Peform the request NSURLResponse *response; NSError *error = nil; NSData *receivedData = [NSURLConnection sendSynchronousRequest:request returningResponse:&amp;response error:&amp;error]; if (error) { // Deal with your error if ([response isKindOfClass:[NSHTTPURLResponse class]]) { NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response; NSLog(@"HTTP Error: %d %@", httpResponse.statusCode, error); return; } NSLog(@"Error %@", error); return; } NSString *responeString = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding]; // Assume lowercase if ([responeString isEqualToString:@"true"]) { // Deal with true return; } // Deal with an error // When dealing with UI updates, they must be run on the main queue, ie: // dispatch_async(dispatch_get_main_queue(), ^(void){ // // }); }); } </code></pre> <h2>Method 3 - Use an NSURLConnection convenience function</h2> <pre><code>+ (void)sendAsynchronousRequest:(NSURLRequest *)request queue:(NSOperationQueue *)queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler </code></pre> <p>Hope this helps.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload