extensión extension cual aplicaciones ios ios8 ios-app-extension

extension - cual es la extensión de ios



Compartiendo la extensión en IOS8 beta (7)

Debe buscar un archivo adjunto de tipo kUTTypePropertyList. Haga algo como esto con el primer archivo adjunto del primer elemento de extensión en su extensión:

NSExtensionItem *extensionItem = self.extensionContext.extensionItems.firstObject; NSItemProvider *itemProvider = self.extensionItem.attachments.firstObject; [itemProvider loadItemForTypeIdentifier:kUTTypePropertyList options:nil completionHandler:^(NSDictionary *item, NSError *error) { // Unpack items from "item" in here }];

También necesitará configurar JavaScript para recoger todos los datos que necesita del DOM. Consulte la segunda sesión de extensiones de WWDC 14 para obtener más detalles.

Intento crear una extensión para compartir usando las nuevas extensiones de la aplicación iOS 8. Traté de obtener la URL actual de un sitio Safari para mostrarlo en un UILabel. Suficientemente simple.

Estaba trabajando a través de la guía de extensión oficial de apple aquí https://developer.apple.com/library/content/documentation/General/Conceptual/ExtensibilityPG/Share.html#//apple_ref/doc/uid/TP40014214-CH12-SW1 pero algunas cosas no funcionan como se esperaba. Sé que solo está en beta, pero tal vez solo estoy haciendo algo mal.

Aquí está mi código para obtener la URL de safari dentro de las extensiones ViewController:

-(void)viewDidAppear:(BOOL)animated{ NSExtensionContext *myExtensionContext = [self extensionContext]; NSArray *inputItems = [myExtensionContext inputItems]; NSMutableString* mutableString = [[NSMutableString alloc]init]; for(NSExtensionItem* item in inputItems){ NSMutableString* temp = [NSMutableString stringWithFormat:@"%@, %@, %lu, %lu - ",item.attributedTitle,[item.attributedContentText string], (unsigned long)[item.userInfo count],[item.attachments count]]; for(NSString* key in [item.userInfo allKeys]){ NSArray* array = [item.userInfo objectForKey:@"NSExtensionItemAttachmentsKey"]; [temp appendString:[NSString stringWithFormat:@" in array:%lu@",[array count]]]; } [mutableString appendString:temp]; } self.myLabel.text = mutableString; }

Y este es el contenido de mi archivo Info.plist de mi extensión:

<dict> <key>NSExtensionMainStoryboard</key> <string>MainInterface</string> <key>NSExtensionPointIdentifier</key> <string>com.apple.share-services</string> <key>NSExtensionActivationRule</key> <dict> <key>NSExtensionActivationSupportsWebURLWithMaxCount</key> <integer>200</integer> </dict> </dict>

Cuando visito la página de Apple iPod Support en Safari y trato de compartirla en mi extensión, obtengo los siguientes valores, pero no la URL:

item.attributedTitle = (null) item.attributedContentText = "iPod - Apple Support" item.userInfo.count = 2 (two keys: NSExtensionAttributedContentTextKey and NSExtensionItemAttachmentsKey) item.attachments.count = 0

Las matrices dentro de los objetos del diccionario están siempre vacías.

Cuando comparto el sitio apple con la aplicación de correo del sistema, la URL se publica en el mensaje. Entonces, ¿por qué no hay una URL en mi extensión?


A continuación se muestra cómo puede obtener la url. Observe que el identificador de tipo es kUTTypeURL y el argumento de bloque es NSURL. Además, el plist necesita ser correcto como el mío también. Faltaba la documentación y recibí ayuda del número 4 en los foros de desarrollo de Apple . (deberá estar registrado e iniciar sesión para verlo).

Código:

NSExtensionItem *item = self.extensionContext.inputItems.firstObject; NSItemProvider *itemProvider = item.attachments.firstObject; if ([itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeURL]) { [itemProvider loadItemForTypeIdentifier:(NSString *)kUTTypeURL options:nil completionHandler:^(NSURL *url, NSError *error) { self.urlString = url.absoluteString; }]; }

Info.plist

<key>NSExtension</key> <dict> <key>NSExtensionAttributes</key> <dict> <key>NSExtensionActivationRule</key> <dict> <key>NSExtensionActivationSupportsWebURLWithMaxCount</key> <integer>1</integer> </dict> <key>NSExtensionPointName</key> <string>com.apple.share-services</string> <key>NSExtensionPointVersion</key> <string>1.0</string> </dict> <key>NSExtensionPointIdentifier</key> <string>com.apple.share-services</string> <key>NSExtensionMainStoryboard</key> <string>MainInterface</string> </dict>


Su controlador de vista de extensión debe adoptar el protocolo NSExtensionRequestHandling . Uno de los métodos de este protocolo es:

- (void)beginRequestWithExtensionContext:(NSExtensionContext *)context

Debería esperar a que se llame antes de intentar obtener el NSExtensionContext . Incluso proporciona el contexto en el método como el parámetro de context .

Esto fue descrito en este documento .


Lo he resuelto por mí mismo. Lo estaba intentando con Sharing Image.

- (void)didSelectPost { // This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments. // Inform the host that we''re done, so it un-blocks its UI. Note: Alternatively you could call super''s -didSelectPost, which will similarly complete the extension context. // Verify that we have a valid NSExtensionItem NSExtensionItem *imageItem = [self.extensionContext.inputItems firstObject]; if(!imageItem){ return; } // Verify that we have a valid NSItemProvider NSItemProvider *imageItemProvider = [[imageItem attachments] firstObject]; if(!imageItemProvider){ return; } // Look for an image inside the NSItemProvider if([imageItemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage]){ [imageItemProvider loadItemForTypeIdentifier:(NSString *)kUTTypeImage options:nil completionHandler:^(UIImage *image, NSError *error) { if(image){ NSLog(@"image %@", image); // do your stuff here... } }]; } // this line should not be here. Cos it''s called before the block finishes. // and this is why the console log or any other task won''t work inside the block [self.extensionContext completeRequestReturningItems:nil completionHandler:nil]; }

Entonces, lo que hice fue mover el [self.extensionContext completeRequestReturningItems: nil completionHandler: nil]; dentro del bloque al final de otras tareas. La versión final de trabajo se ve así (Xcode 6 beta 5 en Mavericks OS X 10.9.4):

- (void)didSelectPost { // This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments. // Inform the host that we''re done, so it un-blocks its UI. Note: Alternatively you could call super''s -didSelectPost, which will similarly complete the extension context. // Verify that we have a valid NSExtensionItem NSExtensionItem *imageItem = [self.extensionContext.inputItems firstObject]; if(!imageItem){ return; } // Verify that we have a valid NSItemProvider NSItemProvider *imageItemProvider = [[imageItem attachments] firstObject]; if(!imageItemProvider){ return; } // Look for an image inside the NSItemProvider if([imageItemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage]){ [imageItemProvider loadItemForTypeIdentifier:(NSString *)kUTTypeImage options:nil completionHandler:^(UIImage *image, NSError *error) { if(image){ NSLog(@"image %@", image); // do your stuff here... // complete and return [self.extensionContext completeRequestReturningItems:nil completionHandler:nil]; } }]; } // this line should not be here. Cos it''s called before the block finishes. // and this is why the console log or any other task won''t work inside the block // [self.extensionContext completeRequestReturningItems:nil completionHandler:nil]; }

Espero que funcione también para compartir URL.


Todas esas respuestas anteriores son realmente buenas, pero me topé con este problema en Swift y sentí que era un poco tímido extraer la URL de un NSExtensionContext dado especialmente en el proceso de conversión de CFString a String y el hecho de que el completionHandler en loadItemForTypeIdentifier no es ejecutado en el hilo principal.

import MobileCoreServices extension NSExtensionContext { private var kTypeURL:String { get { return kUTTypeURL as NSString as String } } func extractURL(completion: ((url:NSURL?) -> Void)?) -> Void { var processed:Bool = false for item in self.inputItems ?? [] { if let item = item as? NSExtensionItem, let attachments = item.attachments, let provider = attachments.first as? NSItemProvider where provider.hasItemConformingToTypeIdentifier(kTypeURL) == true { provider.loadItemForTypeIdentifier(kTypeURL, options: nil, completionHandler: { (output, error) -> Void in dispatch_async(dispatch_get_main_queue(), { () -> Void in processed = true if let url = output as? NSURL { completion?(url: url) } else { completion?(url: nil) } }) }) } } // make sure the completion block is called even if no url could be extracted if (processed == false) { completion?(url: nil) } } }

De esa manera, ahora puede simplemente usarlo así en su subclase UIViewController :

self.extensionContext?.extractURL({ (url) -> Void in self.urlLabel.text = url?.absoluteString println(url?.absoluteString) })



Las otras respuestas son todas complicadas e incompletas. Solo funcionan en Safari y no funcionan en Google Chrome. Esto funciona tanto en Google Chrome como en Safari:

override func viewDidLoad() { super.viewDidLoad() for item in extensionContext!.inputItems { if let attachments = item.attachments { for itemProvider in attachments! { itemProvider.loadItemForTypeIdentifier("public.url", options: nil, completionHandler: { (object, error) -> Void in if object != nil { if let url = object as? NSURL { print(url.absoluteString) //This is your URL } } }) } } } }