2011-02-10 823 views
18

Estoy usando UIDocumentInteractionController para mostrar el menú emergente "Abrir en ..." para que el usuario pueda abrir un documento en otra aplicación.¿Cómo comprobar si UIDocumentInteractionController no podrá abrir el documento debido a la aplicación externa faltante en el iPad?

Método presentOpenInMenuFromBarButtonItem:animated: devuelve NO en caso de que no haya ninguna aplicación habilitada para abrir un documento determinado (el menú no se mostrará). Pero ya es demasiado tarde para esperar hasta llegar tan lejos. Me gustaría desactivar el botón que inicia esa apertura si no es posible en lugar de aumentar las expectativas de un usuario y luego decir "lo siento, no es posible abrirlo".

¿Es posible consultar el sistema para ver si hay al menos una aplicación registrada para un tipo de documento particular? He comprobado canPreviewItem: en QLPreviewController, pero parece que no admite los mismos tipos de documento que UIDocumentInteractionController puede manejar.

Respuesta

10

[editar] No se trabaja para iOS 6.0 (ver comentario)

Parece que dismissMenuAnimated (sin animación en absoluto) es la clave:

-(BOOL)canOpenDocumentWithURL:(NSURL*)url inView:(UIView*)view { 
    BOOL canOpen = NO; 
    UIDocumentInteractionController* docController = [UIDocumentInteractionController 
                interactionControllerWithURL:url]; 
    if (docController) 
    { 
     docController.delegate = self; 
     canOpen = [docController presentOpenInMenuFromRect:CGRectZero 
            inView:self.view animated:NO];     
     [docController dismissMenuAnimated:NO]; 
    } 
    return canOpen; 
} 

Se volverá SÍ si al al menos una aplicación puede abrir el archivo señalado por url. Al menos está funcionando en mi caso (archivos KMZ), probando con/sin la aplicación Dropbox en iPhone iOS 4.3.
En realidad, parece funcionar incluso si url no apunta a un archivo real (es decir, @ "test.kmz"), pero no confiaría en él para todos los tipos de archivos.

+0

Esta fue la solución que adopté anteriormente, pero una palabra de advertencia para iOS 6. Parece que presentar y descartar el controlador de esta manera causa algunos efectos secundarios en UITabBar, específicamente, el 'UITabBarButton's (API privada) que compone la pestaña bar están ocultos pero no están ocultos. A partir de un poco de excavación, parece ser que los botones están configurados en 0 alfa, luego se ocultan en un bloque de finalización de animación al invocar el método 'presente'. Lamentablemente, el bloque de finalización de la animación se ejecuta después de que se llame al método 'descartar' para que los botones permanezcan ocultos. – Weaverfish

+0

Tienes razón. Has encontrado una solución ? – FKDev

+0

Cualquier solución a este problema ..? –

-4

-[UIApplication canOpenURL:] debería hacer el trabajo.

+2

Parece que canOpenURL resuelve solo los esquemas de URL. En este caso, siempre he archivado: // y me gustaría comprobar diferentes tipos de documentos (pdf, jpeg, ...) – palob

+0

En cualquier caso, no canOpenURL: determine si su aplicación puede abrir el documento, no si OTROS las aplicaciones que ha instalado pueden hacerlo? – Roger

+0

Uh, sabemos qué archivos puede abrir nuestro programa que estamos escribiendo, ¿verdad? Porque somos nosotros quienes estamos escribiendo la aplicación?'canOpenURL:' determina si hay OTRAS aplicaciones que pueden abrir el esquema; consulte el comentario en la documentación oficial vinculada anteriormente. En OS X, esta funcionalidad está en 'NSWorkspace' y está separada de' NSApplication'. Pero de alguna manera, Apple decidió combinarlos en iOS. Extraño. – Yuji

5

Se me ocurrió una forma menos hacky de hacer las cosas, pero existe la limitación de que solo puede detectar si hay una aplicación compatible después de que el usuario haya seleccionado abrir en una aplicación. Esto le permitirá proporcionar la misma experiencia de usuario que la aplicación de Dropbox.

Todo lo que necesita hacer es configurar el UIDocumentInteractionControllerDelegate y crear una propiedad de indicador booleano que contenga si el menú fue presentado o no.

En la interfaz:

/** 
The document interaction controller used to present the 'Open with' dialogue. 
*/ 
@property (nonatomic,strong) UIDocumentInteractionController *documentInteractionController; 

/** 
Boolen that holds whether or not there are apps installed that can open the URL. 
*/ 
@property (nonatomic) BOOL hasCompatibleApps; 

En la implementación:

espero que ayuda a algunas personas.

3

Esto funciona para mí:

self.docController = [UIDocumentInteractionController interactionControllerWithURL:url]; 
    UIView *v = [[UIView alloc] init]; 
    BOOL isAnAppAvalaible = [self.docController presentOpenInMenuFromRect:CGRectZero inView:v animated:NO]; 
0
NSURL *url = [NSURL URLWithString:@"path_to_the_file"]; 
UIDocumentInteractionController *controller = 
    [UIDocumentInteractionController interactionControllerWithURL:url]; 
BOOL openResult = [controller presentPreviewAnimated:NO]; 

Si utiliza presentPreviewAnimated: para mostrar archivos que se pueden utilizar openResult para detectar si se ha abierto satisfactoriamente.

+0

presentPreviewAnimated: siempre devuelve NO para mí. Me quedaré con presentOpenInMenuFromRect: inView: animado: donde se muestra en la vista movido fuera de la pantalla. – palob

Cuestiones relacionadas