UIDocumentInteractionController & delegate

août 2014 modifié dans API UIKit #1

Bonjour à  tous,


 


J'ai un problème, je n'ai aucun retour avec les delegate de UIDocumentInteractionController.


 


J'ai ceci :



self.docIntShare = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:filePath]];
[self.docIntShare presentOptionsMenuFromRect:CGRectMake(0, 0, [self.view bounds].size.width, [self.view bounds].size.height) inView:self.view animated:YES];

Cela s'affiche très bien quand mon fichier est téléchargé. Le problème, c'est que aucun des delegates suivants sont appelés :



- (void)documentInteractionControllerDidDismissOptionsMenu:(UIDocumentInteractionController *)controller
{
NSLog(@DISMISS);
}

- (void)documentInteractionControllerDidDismissOpenInMenu:(UIDocumentInteractionController *)controller
{
NSLog(@DISMISS2);
}

- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller
{
NSLog(@ -- documentInteractionControllerViewControllerForPreview);
return self;
}

- (UIView *)documentInteractionControllerViewForPreview:(UIDocumentInteractionController *)controller
{
NSLog(@ -- documentInteractionControllerViewForPreview);
return self.view;
}

- (CGRect)documentInteractionControllerRectForPreview:(UIDocumentInteractionController *)controller
{
NSLog(@ -- documentInteractionControllerRectForPreview);
return CGRectMake(0, 0, [self.view bounds].size.width, [self.view bounds].size.height);
}

- (void)documentInteractionControllerWillBeginPreview:(UIDocumentInteractionController *)controller
{
NSLog(@ -- documentInteractionControllerWillBeginPreview);
}

- (void)documentInteractionController:(UIDocumentInteractionController *)controller willBeginSendingToApplication:(NSString *)application
{
NSLog(@WILL);
}

- (void)documentInteractionController:(UIDocumentInteractionController *)controller didEndSendingToApplication:(NSString *)application
{
NSLog(@FINISH);
}

Pourtant j'ai bien UIDocumentInteractionControllerDelegate déclaré dans mon .h


 


Une petite idée ?


 


J'ai lu la doc Document Interaction Programming Topics for iOS mais qui ne m'aide pas vraiment.


 


Merci.


Réponses

  • À quel moment est fait :



    self.docIntShare.delegate = self

    ou toute ligne de code assimilée ?


  • Dans cette méthode :



    - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
    {}

    ou celle-ci :



    - (void)connectionDidFinishLoading:(NSURLConnection *)connection
    {}

    En fonction de la version de l'OS j'appel NSURLSession ou NSURLConnection.


  • Juste après :



    [self.docIntShare presentOptionsMenuFromRect:CGRectMake(0, 0, [self.view bounds].size.width, [self.view bounds].size.height) inView:self.view animated:YES];

    Que dit ?



    NSLog(@docIntShare delegate : %, self.docIntShare.delegate);

  • août 2014 modifié #5

    null...


     


    Faut que j'initialise la propriété docIntShare dans le init de l'App je suppose ? :)


     


    EDIT : enfin y a pas de init a proprement parler. Le problème c'est comment récupérer mon fichier ?


     


    EDIT 2 : ou alors je fais ceci 



    self.docIntShare = [UIDocumentInteractionController interactionControllerWithURL:nil]];

    et quand j'ai besoin :



    [self.docIntShare setURL:filePath];

    ?


  • Si l'objet n'est pas créé, faire un setting de son delegate ne va pas servir à  grand chose.

    Je suggère donc ceci :



    self.docIntShare = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:filePath]];
    self.docIntShare.delegate = self;
    [self.docIntShare presentOptionsMenuFromRect:CGRectMake(0, 0, [self.view bounds].size.width, [self.view bounds].size.height) inView:self.view animated:YES];
  • Un grand merci :)


  • août 2014 modifié #8

    Je ré-ouvre ce sujet car j'ai une question en relation avec le UIDocumentInteractionController.


     


    Actuellement, je supprime un fichier (qui vient d'être télécharger) quand on fais un dismiss d'un UIDocumentInteractionController. Hors, quand on sélectionne l'option Quick Look, il supprime ce fichier.


     


    Est-il possible, dans ce cas, de supprimer le bouton Quick Look d'un UIDocumentInteractionController ?


     


    Merci.


     


    EDIT : actuellement j'utilise presentOptionsMenuFromRect. Si je prends presentOpenInMenuFromRect j'ai plus QuickLook mais du coup je perds aussi les mails.


     


    EDIT 2 : sinon, est-il possible d'identifier l'action de faire cancel, donc cliquer sur le bouton ou en dehors du UIDocumentInteractionController. Je suis en train de chercher une solution mais pour le moment, rien de concluant. A part de ne pas effacer le fichier mais dans ce cas, a quel moment ? L'App n'a pas de gestion de fichier et donc ils peuvent s'accumuler dans l'Application si on ne les supprimes pas a certaines actions.


     


    EDIT 3 : sans les delegates je n'ai plus Quick Look mais le problème reste le même (au dissmiss de UIDocumentInteractionController, j'entre dans le delegate, impossible de savoir qu'elle action l'utilisateur à  demandé).


  • août 2014 modifié #9

    Je reviens sur ce post parce que je suis en phase de test de l'application et cela fonctionne très bien sur nos iPhones. Le problème est sur le iPad, la fenêtre ne s'affiche tout simplement pas. J'ai regardé la classe et le guide lié au UIDocumentInteractionController mais je n'ai rien trouvé.


     


    Est-ce que quelqu'un aurait une idée ?


     


    Merci.


     


    EDIT : J'ai ce long message d'erreur :



    Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
    (
    "<NSLayoutConstraint:0x170092610 H:|-(0)-[UIView:0x170368940] (Names: '|':UIActivityGroupView:0x170368700 )>",
    "<NSLayoutConstraint:0x170092660 H:[UIView:0x170368940]-(0)-| (Names: '|':UIActivityGroupView:0x170368700 )>",
    "<NSLayoutConstraint:0x178095d10 H:|-(0)-[SFAirDropActiveIconView:0x15f665010](LTR) (Names: '|':UIView:0x170368940 )>",
    "<NSLayoutConstraint:0x178095e00 H:[SFAirDropActiveIconView:0x15f665010]-(15)-[UILabel:0x15f6656d0](LTR)>",
    "<NSLayoutConstraint:0x178095e50 UILabel:0x15f6656d0.right == UIView:0x170368940.right - 15>",
    "<NSLayoutConstraint:0x178095c20 H:[SFAirDropActiveIconView:0x15f665010(76)]>",
    "<NSLayoutConstraint:0x1780960d0 H:|-(0)-[UIView:0x170361680] (Names: '|':UIView:0x170365700 )>",
    "<NSLayoutConstraint:0x178096120 H:[UIView:0x170361680]-(0)-| (Names: '|':UIView:0x170365700 )>",
    "<NSLayoutConstraint:0x1780961c0 UIActivityGroupView:0x170368700.width == UIView:0x170361680.width>",
    "<NSAutoresizingMaskLayoutConstraint:0x17809d600 h=-&- v=-&- UIView:0x170365700.width == UIView:0x17836bac0.width>",
    "<NSAutoresizingMaskLayoutConstraint:0x17809da60 h=-&- v=-&- UIView:0x17836bac0.width == UIView:0x170364a40.width>",
    "<NSAutoresizingMaskLayoutConstraint:0x17809dec0 h=--& v=--& H:[UIView:0x170364a40(0)]>"
    )

    Will attempt to recover by breaking constraint
    <NSLayoutConstraint:0x178095c20 H:[SFAirDropActiveIconView:0x15f665010(76)]>

    Break on objc_exception_throw to catch this in the debugger.
    The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
    2014-08-22 10:55:23.855 monApp[2137:60b] Unable to simultaneously satisfy constraints.

  • Joanna CarterJoanna Carter Membre, Modérateur

    Avant d'ajouter le SFAirDropActiveIconView à  son superview, il faut apeller ...view.translatesAutoresizingMaskIntoConstraints = NO;

  • Joanna, je cherche sur le net mais je ne trouve pas d'infos. Le SFAirDropActiveIconView dont tu me parles, je ne sais même pas ce que c'est, je ne l'utilise pas, directement en tout cas.


     


    Voici mon code pour l'appel de la fenêtre :



    - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
    {
    NSData *data = [[NSData alloc] initWithContentsOfURL:location];

    self.filePath = [self.resourceDocPath stringByAppendingPathComponent:self.fileNameFromDownload];
    [data writeToFile:self.filePath atomically:YES];

    [self openFileWithDocumentInteractionController];
    }

    - (void)openFileWithDocumentInteractionController
    {
    [self.alertCancelDownload dismissWithClickedButtonIndex:0 animated:YES];

    [self hideAndResetProgressBar];

    self.docIntShare = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:self.filePath]];
    self.docIntShare.delegate = self;
    [self.docIntShare presentOptionsMenuFromRect:CGRectMake(0, 0, [self.view bounds].size.width, [self.view bounds].size.height) inView:self.view animated:YES];
    }

     

  • Joanna CarterJoanna Carter Membre, Modérateur

    Tu bosses sous iOS 8 ? C'est peut-être une "fonctionnalité imprévue"  xd


  • août 2014 modifié #13

    Non non iOS 7 :)


     


    EDIT : sinon je cherche pour afficher les options dans une "dropdown" mais pour le moment ... rien (comme dans les applications Documents ou GoodReader quand tu veux envoyer ton document dans une autre App)


     


    EDIT 2 : je viens de faire le test avec le simulateur et iOS 6.1 et 7.1, même problème. Par contre j'ai moins de messages d'erreur et j'ai ceci :



    Unable to get data for URL: The operation couldn't be completed. (Cocoa error 260.)
    Launch Services: Registering unknown app identifier com.apple.mobilemail failed
    Launch Services: Unable to find app identifier com.apple.mobilemail

    Etrange pour l'erreur 260.


     


    EDIT 3 : test à  nouveau sur le vrai iPad, je n'ai pas cette erreur et je peux vérifier avec l'aide de l'Organiser que mon fichier ce trouve bien dans le dossier Documents.


  • Joanna CarterJoanna Carter Membre, Modérateur
    août 2014 modifié #14

    Auparavant tu le testais sur le simulateur ?


     


    Tu as vu ce tuto http://code.tutsplus.com/tutorials/ios-sdk-previewing-and-opening-documents--mobile-15130 ?


  • Avec simulateur et devices iPhones pendant le développement mais c'est vrai que j'ai pas fais de tests sur iPad (simulateur ou device).


     


    Hier j'ai fais toute la session de test sur iPhone 4S, 5C et 5S, tout fonctionne très bien (j'ai juste fais une modifications sur un truc pour que cela passe sur le 4S). Tous les devices sont sur iOS 7.


     


    Sur iPad, tout fonctionne, sauf cette action qui est la plus importante de l'application :)


  • août 2014 modifié #16

    Le problème viens de cette ligne :



    [self.docIntShare presentOptionsMenuFromRect:CGRectMake(0, 0, [self.view bounds].size.width, [self.view bounds].size.height) inView:self.view animated:YES];

    Plus précisément du CGRectMake mais je ne sais pas quoi faire pour l'instant. (les dimensions ? la position ?).


     


    EDIT : c'est bon le menu s'affiche mais pas à  l'endroit cliquez. Comment vous faites pour récupérer la position du toucher par l'utilisateur et de l'utiliser pour construire un CGRect ? La solution est là  (je continu de chercher).


     


    EDIT 2 : je n'avais pas vu ton lien, comme j'ai une UIWebView je cherche un remplaçant à  son [button frame]


  • Joanna CarterJoanna Carter Membre, Modérateur
    août 2014 modifié #17

    C'est quoi que l'utilisateur touche pour provoquer l'interaction ?


  • Et bien c'est une UIWebView qui prends tout l'écran, donc ce sont des liens HTML et c'est pour cette raison que je cherche la position du doigt.


  • Joanna CarterJoanna Carter Membre, Modérateur

    Est-ce que tu a penser d'ajouter un item au menu contextuel des liens ?


  • C'est à  dire ? Il y a un vrai fichier derrière que l'on télécharge.


  • Joanna CarterJoanna Carter Membre, Modérateur

    Bien entendu. Qu'est-ce qui se produit lorsqu'on fait un long press sur un lien ?


  • Joanna CarterJoanna Carter Membre, Modérateur


    Le problème viens de cette ligne :



    [self.docIntShare presentOptionsMenuFromRect:CGRectMake(0, 0, [self.view bounds].size.width, [self.view bounds].size.height) inView:self.view animated:YES];



     


    Il paraà®t que tu prends le rectangle du web view ; du coup, le popover tentera d'apparaà®tre dehors ce rectangle, centré sur un de ses côtés. Tu pourrais construire un petit rectangle autour le point de la touche et le passer à  la méthode

  • août 2014 modifié #23

    J'ai pas compris le fonctionnement du FromRect dans ce genre de cas (je pense). Il l'utilise pour avoir la position de la fenêtre, ok mais quel endroit exactement ? Parce que si j'ai 0 et 0 en valeur de x et y, en changeant le width et height, alors ma fenêtre change de position. Je sais pas si c'est clair :)


     


    Par contre, pour le moment, je met des valeurs en dur. L'idée c'est justement de les remplacer par la position du doigt, lors du toucher. Ma fenêtre s'affiche correctement maintenant, je n'ai plus le problème de ce matin mais pas a l'endroit voulu.


     


    Une longue pression affiche le menu de l'OS qui demande si tu veux copier ou autre. Centrer sur l'élément sélectionné.


  • Joanna CarterJoanna Carter Membre, Modérateur


    J'ai pas compris le fonctionnement du FromRect dans ce genre de cas (je pense). Il l'utilise pour avoir la position de la fenêtre, ok mais quel endroit exactement ? Parce que si j'ai 0 et 0 en valeur de x et y, en changeant le width et height, alors ma fenêtre change de position. Je sais pas si c'est clair :)




     


    Peux-tu prendre un capture de l'écran ?


     




    Une longue pression affiche le menu de l'OS qui demande si tu veux copier ou autre. Centrer sur l'élément sélectionné.




     


    Je sais qu'il est possible d'ajouter tes propres items au menu mais je ne sais pas encore comment y arriver sans le rechercher

  • Là  je ne peux pas faire de capture d'écran mais je pourrais le faire demain.


     


    Par contre, j'ai lu ça dans la doc Apple (View Programmer Guide) :


     



     


    To handle touch-based events, do the following:





    Attach any suitable gesture recognizers to the view by using the addGestureRecognizer: method.


    For situations where you want to process the touches yourself, override the touchesBegan:withEvent:, touchesMoved:withEvent:, touchesEnded:withEvent:, and touchesCancelled:withEvent: methods. (Remember that you should always override the touchesCancelled:withEvent: method, regardless of which other touch-related methods you override.) 






     


    Le addGestureRecognizer: c'est en passant par Interface Builder ? En tout cas sur mon prototype (et donc sans Cordova) les touchesBegan et autres fonctionnent sans problèmes.


  • août 2014 modifié #26

    Voilà  une capture d'écran : https://lut.im/U7hZkHah/i18Q2RI6


     


    Désolé j'ai dû faire le ménage mais on vois bien la fenêtre du UIDocumentInteractionController apparaà®tre à  l'endroit demandé, pour rappel :



    self.docIntShare = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:self.filePath]];
    self.docIntShare.delegate = self;
    [self.docIntShare presentOptionsMenuFromRect:CGRectMake(0, 0, 1000, 500) inView:self.view animated:YES];

    Sinon, est-ce possible de faire disparaà®tre la petite flèche de la fenêtre ?


Connectez-vous ou Inscrivez-vous pour répondre.