Question en deux parties
Première partie: J'essaie de créer une requête ASynchrone dans ma base de données. Je le fais actuellement de manière synchrone, mais je veux apprendre les deux façons d'améliorer ma compréhension de ce qui se passe.
Actuellement, j'ai configuré mon appel synchrone comme ceci.
- (IBAction)setRequestString:(NSString *)string
{
//Set database address
NSMutableString *databaseURL = [[NSMutableString alloc] initWithString:@"http://127.0.0.1:8778/instacodeData/"]; // iMac development
//PHP file name is being set from the parent view
[databaseURL appendString:string];
//call ASIHTTP delegates (Used to connect to database)
NSURL *url = [NSURL URLWithString:databaseURL];
//SynchronousRequest to grab the data
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSError *error;
NSURLResponse *response;
NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (!result) {
//Display error message here
NSLog(@"Error");
} else {
//TODO: set up stuff that needs to work on the data here.
NSString* newStr = [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
NSLog(@"%@", newStr);
}
}
Je pense que ce que je dois faire est de remplacer l'appel
NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
avec la version ASynchrone
sendAsynchronousRequest:queue:completionHandler:
cependant, je ne suis pas sûr de ce qu'il faut transmettre à la file d'attente ou d'achèvementHandler ... Tous les exemples/solutions seraient grandement appréciés.
Deuxième partie: Je lisais sur le multitâche et je voudrais le soutenir en veillant à ce que mes demandes de connexion soient complètes s'il y a une interruption. J'ai suivi cette exemple
Dans ce document, il explique comment gagner plus de temps si une interruption se produit, je comprends ce qu’il fait. Mais comment l’appliquer à cette connexion? Si vous avez des exemples/tutoriels pour m'aider à comprendre comment l'appliquer, ce serait génial!
Partie 1:
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
if ([data length] > 0 && error == nil)
[delegate receivedData:data];
else if ([data length] == 0 && error == nil)
[delegate emptyReply];
else if (error != nil && error.code == ERROR_CODE_TIMEOUT)
[delegate timedOut];
else if (error != nil)
[delegate downloadError:error];
}];
Voici un échantillon:
NSString *urlAsString = @"http://www.cnn.com";
NSURL *url = [NSURL URLWithString:urlAsString];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[NSURLConnection
sendAsynchronousRequest:urlRequest
queue:[[NSOperationQueue alloc] init]
completionHandler:^(NSURLResponse *response,
NSData *data,
NSError *error)
{
if ([data length] >0 && error == nil)
{
// DO YOUR WORK HERE
}
else if ([data length] == 0 && error == nil)
{
NSLog(@"Nothing was downloaded.");
}
else if (error != nil){
NSLog(@"Error = %@", error);
}
}];
Pour le paramètre queue, essayez cette magie:
[NSOperationQueue mainQueue]
Cela fonctionne très bien si vous mettez à jour l'interface utilisateur à la fin de la demande car la file d'attente principale est le fil principal. Cela vous indique essentiellement le comportement précédent de NSURLConnection. Si, toutefois, vous envisagez d'écrire dans un fichier ou de décompresser, vous pouvez terminer dans une file d'attente en arrière-plan, puis renvoyer asynchrone vers la file principale pour les mises à jour de l'interface utilisateur.
J'ai travaillé sur un problème similaire, j'ai posté cette question et obtenu une réponse claire ici , j'espère que cela aidera avec la partie 2.
Pour la partie 1 ce que les autres mentionnés ici sont bons mais vous devez ajouter un autre chèque (j'ai modifié une réponse ci-dessous). Il est possible que votre demande renvoie une erreur 404 (page non trouvée), auquel cas vous n'obtiendrez pas d'erreur et les données seront> 0. Le 200 est une bonne réponse, vous pouvez également vérifier le code d'état pour 404 ou autre. .
[NSURLConnection
sendAsynchronousRequest:urlRequest
queue:[[NSOperationQueue alloc] init]
completionHandler:^(NSURLResponse *response,
NSData *data,
NSError *error)
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if ([data length] >0 && error == nil && [httpResponse statusCode] == 200)
{
// DO YOUR WORK HERE
}
Puisque sendAsynchronousRequest:urlRequest queue:queue completionHandler:
est obsolète dans iOS 9 et il sera suggéré d'utiliser NSURLSession
's -dataTaskWithRequest:completionHandler:
à la place. Il est disponible depuis iOS 7 et versions ultérieures .
NSURL *URL = [NSURL URLWithString:@"http://example.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// ...
}];
NSURL *URL = [NSURL URLWithString:@"http://example.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
// ...
}];
[task resume];
sendAsynchronousRequest
est obsolète dans Swift. Déplacer vers dataTaskWithRequest
, heureusement, il est utilisé à peu près de la même manière.
if let url = NSURL(string:"http://your_url") {
let request:NSURLRequest = NSURLRequest(URL: url)
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config)
let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
});
task.resume()
}