Pas De Données Renvoyées À L'Aide De NSURLConnection De Manière Asynchrone
-
16-09-2019 - |
Question
Je vais avoir un diable de temps avec quelque chose qui semble plutôt
simple, mais je n'arrive pas à se mettre au travail.Je suis de la construction d'une
application iPhone qui permet d'extraire des données à partir d'un hôte web.Je suis en train de
établir une connexion asynchrone à l'hôte que je veux garder la
appareil libéré lors de la connexion.(sendSynchronousRequest gèle
le téléphone jusqu'à ce que la demande est faite.) Voici mon code de connexion:
//temp url to see if data is returned:
NSURL *theURL = [NSURL URLWithString:@"http://www.theappleblog.com/feed"];
NSURLRequest *dataRequest = [NSURLRequest requestWithURL:theURL
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:60];
/* establish the connection */
theConnection = [[NSURLConnection alloc]
initWithRequest:dataRequest
delegate:self
startImmediately:YES];
if (theConnection == nil) {
NSLog(@"Connection Failure!");
self.urlData = nil;
} else {
self.urlData = [[NSMutableData data] retain];
}
J'ai toutes les délégué méthodes de mise en place:
-(void)connection:(NSURLConnection *)connection
didReceiveResponse:(NSURLResponse*)response
{
[urlData setLength:0];
UIApplication *application = [UIApplication sharedApplication];
application.networkActivityIndicatorVisible = YES;
NSLog(@"Received Response!");
}
-(void)connection:(NSURLConnection *)connection
didReceiveData:(NSData*)incrementalData
{
[self.urlData appendData:incrementalData];
NSNumber *resourceLength = [NSNumber
numberWithUnsignedInteger:[self.urlData length]];
NSLog(@"resourceData length: %d", [resourceLength intValue]);
NSLog(@"filesize: %d", self.urlDataSize);
NSLog(@"float filesize: %f", [self.urlDataSize floatValue]);
}
-(void)connectionDidFinishLoading:(NSURLConnection*)connection
{
NSLog(@"Connection finished loading\n");
NSLog(@"Succeeded! Received %d bytes of data",[urlData length]);
_isFinished = YES;
UIApplication *application = [UIApplication sharedApplication];
application.networkActivityIndicatorVisible = NO;
}
- (void)connection:(NSURLConnection *)connection
didFailWithError:(NSError *)error
{
NSLog(@"Error: %@",[error localizedDescription]);
}
Comme vous pouvez le voir, j'ai un bateau de charge des messages de journal parce que je voulais
pour voir si rien est à venir à travers à tous.Mon test de connexion
revient comme VRAI, mais aucune donnée n'est jamais chargé.Comme je l'ai dit, j'en suis sûr
Je dois être en train de faire (ou ne pas faire) quelque chose vraiment stupide.Mais quoi?
Toute aide serait grandement appréciée.
Merci, Laurent
La solution
Cela ne répond pas directement à votre question, mais vous pourriez envisager de regarder dans Ben Copsey la bibliothèque de ASIHTTPRequest
, qui s'enroule autour des classes de CFNetwork
et comprend asynchrone, le code de demande filetée qui prend beaucoup de travail de le faire correctement.
Autres conseils
Le problème était que je continuais le déroulement du programme et ne pas arrêter pour permettre la connexion pour terminer le téléchargement. Merci pour toutes les suggestions.
Quelques suggestions:
-
Dans votre premier extrait, au lieu de
theConnection
essayez d'affecter àself.theConnection
pour vous assurer que les accesseurs de propriété sont appelés. Dans divers endroits que vous interchanger aussiself.urlData
eturlData
. Pourrait vouloir les faire tous en accord en passant parself
. -
Vous pouvez faire la
dataRequest
une propriété aussi bien et passer parself
pour vous assurer qu'il se conserve. -
self.urlData = [[NSMutableData data] retain];
- vous ne devriez pas avoir besoin que retenir supplémentaire. En passant parself
fait pour vous. Le supplémentaire conserve le fera donc l'objet collera autour de fuite et même quand tout est fait. -
Sur le même sujet, dans vos NSLogs assurez-vous d'imprimer le nombre de conserver pour chaque objet. , Vous pouvez aussi avoir une routine de nettoyage général autour de libérer ces structures (ou ensembles
self.foo = nil
) donc à tout moment si elle vomit sur vous pouvez appeler la routine pour faire avancer les choses nettoyées. -
Obtenir une copie de Charles ou Wireshark (ou lancez tcpdump dans la console) et regarder le trafic réseau. Il va aider à repérer à quel stade dans le flux, il est défaillant.
Première pensée - est l'objet qui a tout ce code étant retenu correctement? Il pourrait être qu'il est d'être libéré, et désaffecter ainsi la connexion ...
Sinon, vous devriez au moins voir la réponse.
Rien évidemment fausse, là-haut.J'ai un code qui est sensiblement la même et fonctionne très bien.Les seules différences que je vois sont:
J'utilise NSURLRequestUseProtocolCachePolicy au lieu de NSURLRequestReloadIgnoringLocalCachedata
J'ai utiliser la connexion=[[NSURLConnection alloc] initWithRequest:theRequest délégué:self];au lieu de spécifier startImmediately:OUI (puisque c'est la valeur par défaut)
Il serait utile de connaître, le cas échéant, de votre délégué méthodes sont appelé.À tout le moins, vous devriez obtenir au moins l'un ou l'autre de connectionDidFinishLoading ou connectionDidFail d'être appelé.Si pas, alors quelque chose est probablement faux avec votre délégué de l'installation - êtes-vous ABSOLUMENT sûr que le délégué signatures de méthode sont exactes et que vous êtes de passage dans l'élément de droite comme le délégué?
Il est difficile de zéro sur quoi que ce soit, car il ne sait pas de votre question, si l'une des déclarations NSLog exécute. S'il vous plaît être un peu plus clair sur les résultats que vous obtenez.
D'un coup d'oeil rapide, la seule chose qui ressemble à un problème potentiel est que vous avez une condition de course lorsque vous configurez la connexion. Si le réseau est particulièrement rapide, il y a une chance mince, mais non nul -connection: didReceiveData: sera appelée avant self.urlData a été alloué. Je suggère l'attribution urlData soit avant de lancer la connexion ou -connection: didReceiveResponse:. Pour éviter ce
Si cela ne résout pas, plus d'informations de vous est nécessaire.
Vous dites que ce code fonctionne très bien en utilisant la méthode asynchrone? Test de cette URL, il redirige vers une autre, de sorte que si vous mettre en œuvre les méthodes de délégué de redirection? Que faire si vous essayez des URL différentes?
est l'application autrement sensible? le runloop est en cours d'exécution? Qu'est-ce que l'application après le démarrage faire la demande - t-il revenir de son gestionnaire d'événements retour au runloop? (Sinon, vous ne serez jamais l'un de vos callbacks, parce qu'ils sont livrés par l'runloop.)
NSURLConnection est conçu pour fonctionner avec tout type de protocole, non seulement HTTP. Cela signifie que la connexion: didFail: withError est appelé à Connexion erreurs, mais pas pour protocole erreurs. Vous n'êtes pas la vérification des erreurs de protocole - vous devez les attraper dans le cadre: didReceiveResponse :. L'astuce est que l'objet de réponse qui est transmis est en fait un objet NSHTTPURLResponse. Si vous cochez la statusCode de la réponse, je parie que vous obtenez une erreur HTTP telle que 404 ou 500 serveur.