0

J'essaie de faire une application qui télécharge un fichier pdf à partir d'un serveur en ligne. Ce que j'ai fait, c'est que j'ai créé 3 boutons qui ont 3 URL différentes et l'enregistrer dans le bac à sable de l'application et l'ouvrir dans iBooks.Objectif C: Téléchargements multiples

Mais il bloque l'application et j'ai cette erreur en disant ...

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSURL initFileURLWithPath:]: nil string parameter' *** 

Voici mon code: Sur CLICK:

 if (sender.tag == 1) { 
     pdfTag = 1; 
     pdfSource1 = @"http://myweb.com/folder/folderagain/file1.pdf"; 
     NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:pdfSource1]]; 
     NSURLConnection *conn = [[NSURLConnection alloc] init]; 
     (void)[conn initWithRequest:request delegate:self]; 

     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
     dispatch_async(queue, ^{ 
      dataSource1 = [NSData dataWithContentsOfURL:[NSURL URLWithString:pdfSource1]]; 
      dispatch_sync(dispatch_get_main_queue(), ^{ 
      }); 
      pdfSourcePath1 = [[self applicationDocumentsDirectory] stringByAppendingPathComponent:@"myPDF1.pdf"]; 
      NSLog(@"PDF path: %@",pdfSourcePath1); 
      [dataSource1 writeToFile:pdfSourcePath1 atomically:YES]; 
     }); 

    } else if (sender.tag == 2) { 
     pdfTag = 2; 
     pdfSource2 = @"http://myweb.com/folder/folderagain/file2.pdf"; 
     NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:pdfSource2]]; 
     NSURLConnection *conn = [[NSURLConnection alloc] init]; 
     (void)[conn initWithRequest:request delegate:self]; 

     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
     dispatch_async(queue, ^{ 
      dataSource2 = [NSData dataWithContentsOfURL:[NSURL URLWithString:pdfSource2]]; 
      dispatch_sync(dispatch_get_main_queue(), ^{ 
      }); 
      pdfSourcePath2 = [[self applicationDocumentsDirectory] stringByAppendingPathComponent:@"myPDF2.pdf"]; 
      NSLog(@"PDF path: %@",pdfSourcePath2); 
      [dataSource2 writeToFile:pdfSourcePath2 atomically:YES]; 
     }); 
    } else if (sender.tag == 3) { 
     pdfTag = 3; 
     pdfSource3 = @"http://myweb.com/folder/folderagain/file3.pdf"; 
     NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:pdfSource3]]; 
     NSURLConnection *conn = [[NSURLConnection alloc] init]; 
     (void)[conn initWithRequest:request delegate:self]; 

     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
     dispatch_async(queue, ^{ 
      dataSource3 = [NSData dataWithContentsOfURL:[NSURL URLWithString:pdfSource3]]; 
      dispatch_sync(dispatch_get_main_queue(), ^{ 
      }); 
      pdfSourcePath3 = [[self applicationDocumentsDirectory] stringByAppendingPathComponent:@"myPDF3.pdf"]; 
      NSLog(@"PDF path: %@",pdfSourcePath3); 
      [dataSource3 writeToFile:pdfSourcePath3 atomically:YES]; 
     }); 
    } 

Pour ouvrir le fichier:

 if (pdfTag == 1) { 
    NSURL *url = [NSURL fileURLWithPath:pdfSourcePath1]; 
    docController1 = [UIDocumentInteractionController interactionControllerWithURL:url]; 

    docController1.delegate = self; 

    [docController1 presentOpenInMenuFromRect:btn1.frame inView:self.view animated:YES]; 
    } else if (pdfTag == 2) { 
     NSURL *url = [NSURL fileURLWithPath:pdfSourcePath2]; 
     docController2 = [UIDocumentInteractionController interactionControllerWithURL:url]; 

     docController2.delegate = self; 

     [docController2 presentOpenInMenuFromRect:btn2.frame inView:self.view animated:YES]; 
    } else if (pdfTag == 3) { 
     NSURL *url = [NSURL fileURLWithPath:pdfSourcePath3]; 
     docController2 = [UIDocumentInteractionController interactionControllerWithURL:url]; 

     docController2.delegate = self; 

     [docController2 presentOpenInMenuFromRect:btn3.frame inView:self.view animated:YES]; 
    } 

J'espère que je pourrais trouver la réponse.

+0

Selon moi 'pdfSourcePath1, pdfSourcePath2, pdfSourcePath3' sont' nil'. La méthode de fichier ouvert est appelée avant que le chemin de la source pdf ne soit défini dans le code de bloc. Essayez de placer des points de débogage. –

+0

L'erreur se produit-elle en essayant d'ouvrir le fichier ou en téléchargement? Pouvez-vous vous connecter le pdfSourcePath1,2,3 avant de construire le NSURL pour l'ouverture. Enfin, votre utilisation de GCD directement pour faire les demandes est étrange et difficile à lire. Recherchez NSURLConnection sendAsynchronousRequest: .... – danh

+0

@Deepesh mon code pour le fichier d'ouverture est à l'intérieur connectionDidFinishLoading: (NSURLConnection *) connexion –

Répondre

0

Dans votre code je ne pouvais pas en mesure de voir l'API initFileURLWithPath que vous avez utilisé partout ..

Juste au-dessous est ma suggestion pour votre tâche,

Le dessous est le code pour obtenir le PDF à distance comme NSData en utilisant le chemin du fichier du serveur et le stocker dans le sandbox de l'application.

 NSData *pdfData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:bookUrlString]]; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"myPDF.pdf"]; 
    [pdfData writeToFile:filePath atomically:YES 

Selon ma compréhension à cet effet, cela ne nécessite pas NSURLRequest ou NSURLConnection ...

+0

Le code utilise à la fois NSURLRequest et NSURLConnection indirectement en utilisant initWithContentsOfURL (ce qui est probablement imprudent). Si le PO a l'intention de publier l'application, une requête asynchrone devrait presque certainement être utilisée pour aller chercher un pdf à partir d'un service web. – danh

0

Le réseautage est une tâche complexe, je ne vous suggère de télécharger ou de télécharger un fichier en utilisant le -initWithURL méthode, car n'est pas asynchrone et va bloquer le thread principal. Vous devriez aller avec la classe NSURLConnection et ses méthodes de délégué, ou la méthode de classe étonnante qui n'accepte qu'une file d'attente et un bloc d'achèvement.
Vous faites des choses bizarres que vous utilisez NSURLConnection mais vous utilisez une méthode ..WithURL, vous devriez aller avec un d'entre eux.
Il existe différents gestionnaires de téléchargement sur le Web qui pourraient vous aider dans l'ensemble du processus, car ils enveloppent la classe NSURLConnection et les méthodes de délégation.
Il y a:

  1. AFNetworking link
  2. MKNetworking (mon préféré) link
0

NSData dataWithContentsOfURL fonctionne bien aussi longtemps que la taille du fichier est petit.

Je ne vais pas vous suggérer de télécharger un fichier volumineux en utilisant cette méthode, utilisez plutôt NSURLConnection ou AFNetworking.

Comment utiliser NSURLConnection et AFNetworking télécharger un fichier sont expliqués dans la réponse suivante: https://stackoverflow.com/a/16454923/2548707

+0

'dataWithContentsOfURL:' devrait _never_ être utilisé pour récupérer des informations sur le réseau, quel que soit le montant. Il bloque le fil; les problèmes de réseau ont de fortes chances de bloquer votre application. –

+0

@JoshCaswell c'est vrai. – SahilS