web-dev-qa-db-fra.com

UIActivityViewController ne fonctionne pas dans iOS 11

J'utilise UIActivityViewController pour partager une URL d'article, en utilisant le code ci-dessous,

UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:shareItemArray applicationActivities:nil];

activityVC.excludedActivityTypes = @[UIActivityTypePrint, UIActivityTypeCopyToPasteboard, UIActivityTypeAssignToContact, UIActivityTypeSaveToCameraRoll, UIActivityTypeAirDrop]; 

[self presentViewController:activityVC animated:YES completion:nil];

Le code ci-dessus fonctionne dans iOS 9 et 10, mais ne fonctionne pas dans iOS 11

Je l'ai débogué, le code s'exécute bien, après cela, je reçois un journal des erreurs dans la console comme ci-dessous

[ShareSheet] ERROR: délai d'attente pour établir une connexion avec l'extension de service de visualisation ShareUI.

Y a-t-il des personnes confrontées à ce problème? Y at-il un travail autour?

EDIT: Après avoir nettoyé et exécuté le projet, j'ai essayé de faire de même, après 2 ou 3 fois l'UIActivityViewController s'est ouvert, encore une fois, j'ai essayé, pour la première fois que j'obtiens la même erreur ci-dessus, la deuxième fois, seul l'UIActivityViewController est ouvert .

13
R. Mohan

Tout le code qui modifie l'interface utilisateur doit être exécuté dans la file d'attente principale, ce qui est normal. Donc tout ce que vous devez faire est ceci:

UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:shareItemArray applicationActivities:nil];

activityVC.excludedActivityTypes = @[UIActivityTypePrint, UIActivityTypeCopyToPasteboard, UIActivityTypeAssignToContact, UIActivityTypeSaveToCameraRoll, UIActivityTypeAirDrop]; 

dispatch_async(dispatch_get_main_queue(), ^{
    [self presentViewController:activityVC animated:YES completion:nil];
});

Un peu plus d'explication: dispatch_async() mettra en file d'attente le bloc que vous lui transmettez pour s'exécuter dans un proche avenir, lorsqu'il sera alors prudent de mettre à jour l'interface utilisateur. Si vous ne le faites pas dans la file d'attente principale, des choses étranges peuvent se produire (parfois, l'interface utilisateur ne change tout simplement pas, ou les anciennes modifications peuvent être appliquées après les nouvelles, ou quelque chose comme ça).

Les méthodes transmises par les actions des utilisateurs dans l'interface utilisateur (par exemple, dans IBAction lorsque vous appuyez sur un bouton) sont déjà exécutées sur la file d'attente principale, de sorte que dispatch_async() n'est pas nécessaire ici (bien sûr, en supposant que vous n'appelez pas ces IBActions manuellement depuis un autre queue).

Notez que alloc/init et setExcludedActivityTypes: ne mettent pas à jour l'interface utilisateur. Il n'est donc pas nécessaire d'appeler ceux de la file d'attente principale.

8
Alejandro Iván

Pour Swift 4.0

let activityViewController: UIActivityViewController = UIActivityViewController(activityItems: [shareItem], applicationActivities:nil)
activityViewController.excludedActivityTypes = [.print, .copyToPasteboard, .assignToContact, .saveToCameraRoll, .airDrop]

DispatchQueue.main.async {
   self.present(activityViewController, animated: true, completion: nil);
}
7
vp2698

Essaye ça:

    dispatch_async(dispatch_get_main_queue(), ^{
         UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:shareItemArray applicationActivities:nil];

         activityVC.excludedActivityTypes = @[UIActivityTypePrint, UIActivityTypeCopyToPasteboard, UIActivityTypeAssignToContact, UIActivityTypeSaveToCameraRoll, UIActivityTypeAirDrop]; 
         dispatch_async(dispatch_get_main_queue(), ^{
               [self presentViewController:activityVC animated:YES completion:nil];
         });
    });

J'ai eu le même problème, mais dans Swift3 et cela fonctionne bien.

1
Xande Rasta Moura

J'avais le même problème et j'ai compris que je n'appelais pas dans UI Thread. Essayez de vous lancer dans le fil de l'interface utilisateur et voyez si le problème est résolu.