2015-10-16 13 views
5

Ich arbeite daran, ein Array von Bildern aus einer Galerie mithilfe der Freigabeerweiterung freizugeben. ich kann Bild innerhalb Aktie Erweiterung bekommenSo erhalten Sie die URL des Bildformulars, die von der Freigabeerweiterung an eine App übergeben wird

- (void)getImageFromExtension:(NSExtensionItem *)extensionItem 
{ 
    for(NSItemProvider *attachment in extensionItem.attachments) 
    { 
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
      if([attachment hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage]) 
      { 
       [attachment loadItemForTypeIdentifier:(NSString *)kUTTypeImage options:nil completionHandler:^(id<NSSecureCoding> item, NSError *error) { 
        NSURL *image = (NSURL *)item; 
        if(error) 
        { 
         NSLog(@"Error retrieving image"); 
        } else { 
         dispatch_async(dispatch_get_main_queue(), ^{ 
          NSLog(@"*** ### %@",[UIImage imageWithData:[NSData dataWithContentsOfURL:image]]); 
         }); 
        } 
       }]; 
      } 
     }); 
    } 
} 

Was ich mit wirklich brauchen, ist, ich brauche Bild-URL zu Container applciation passieren. Aber nicht in der Lage, Bild von dieser URL zu erhalten. Das URL-Format ist file:///var/mobile/Media/DCIM/101APPLE/IMG_1705.JPG

Die Daten von dieser URL sind immer null. Wie bekomme ich das Bild von dieser URL?

Antwort

3

Sie rufen wahrscheinlich getImageFromExtension von didSelectPost. Am Ende von didSelectPost sollten Sie completeRequestReturningItems:completionHandler: anrufen, um der Host-App mitzuteilen, die App-Erweiterungsanforderung mit einem Array von Ergebniselementen abzuschließen. Wenn diese Methode aufgerufen wird, wird der gesamte ShareViewController beendet und die Zuordnung aufgehoben. Wenn Sie dies am Ende von didSelectPost aufrufen, wird es ausgeführt, bevor die NSItemProvider die Image-URL abrufen konnte. Weil das asynchron geschieht. Um dies zu beheben, müssen Sie completeRequestReturningItems:completionHandler: aufrufen, nachdem NSItemProvider die imageURL abgerufen hat.

Hier ist, wie es funktionieren soll:

- (void)didSelectPost { 
    NSString *typeIdentifier = (NSString *)kUTTypeImage 
    NSExtensionItem *item = self.extensionContext.inputItems.firstObject; 
    NSItemProvider *itemProvider = item.attachments.firstObject; 
    if ([itemProvider hasItemConformingToTypeIdentifier:typeIdentifier]) { 
     [itemProvider loadItemForTypeIdentifier:typeIdentifier 
             options:nil 
           completionHandler:^(NSURL *url, NSError *error) { 
            NSURL *imageURL = (NSURL *)item 
            self.saveImage(imageURL) 
            [self.extensionContext completeRequestReturningItems:@[]   
                    completionHandler:nil]; 
           }]; 
    } 
} 

By the way, gibt es keine Notwendigkeit dispatch_async zu verwenden, wenn mit NSItemProvider arbeiten als der Anbieter bereits seine Arbeit asynchron zu tun.

Ich habe eine blog post darüber geschrieben, wenn Sie ein wenig mehr darüber lesen möchten.

EDIT

Sie können nun das Bild mit dem Dateipfad laden, die Sie gerade abgerufen werden. Dies funktioniert nur in der Erweiterung! Wenn Sie auf das Bild von der enthaltenden App zugreifen möchten, können Sie die soeben abgerufene Datei-URL nicht verwenden. Die Freigabeerweiterung speichert das ausgewählte Bild in einem Ordner, auf den die zugehörige App nicht zugreifen kann.

Um das Bild der enthaltenen App zur Verfügung zu stellen, müssen Sie App Groups in Ihnen aktivieren, das die App und die Erweiterung enthält. Dann speichert die Erweiterung um das Bild auf den gemeinsam genutzten Container und die enthaltenden App kann es abrufen:

func saveImage(url: NSURL) { 
    guard let imageData = NSData(contentsOfURL: url) else { return } 
    let selectedImage = UIImage(data: imageData) 

    let fileManager = NSFileManager.defaultManager() 
    if let sharedContainer = fileManager.containerURLForSecurityApplicationGroupIdentifier("YOUR_GROUP_IDENTIFIER") { 
     if let dirPath = sharedContainer.path { 
      let sharedImageFilePath = dirPath + "/image.png" 
      let binaryImageData = UIImagePNGRepresentation(selectedImage!) 
      binaryImageData?.writeToFile(sharedImageFilePath, atomically: true) 
      // send the sharedImageFilePath to the containing app 
     } 
    } 
} 
+0

dank @joren, im eine Frage ist, warum die URL (in Aktien Erweiterung generiert) 'file: /// var/mobile/Media/DCIM/101APPLE/IMG_1705.JPG' kann in der Host-Anwendung nicht bewertet werden? –

+0

Erhalten Sie eine Fehlermeldung? Was sagt es? – joern

+0

Ich habe gerade versucht, die NSData von URL zu bekommen. Die Daten werden auf null zurückgesetzt –