6

共有拡張機能を使用してギャラリーから画像の配列を共有することに取り組んでいます。を使用して共有拡張機能内の画像を取得できます

- (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]]);
                        });
                    }
                }];
            }
        });
    }
}

私が実際に必要としているのは、画像の URL をコンテナ アプリケーションに渡す必要があるということです。しかし、そのURLから画像を取得できません。URL の形式は次のとおりです。file:///var/mobile/Media/DCIM/101APPLE/IMG_1705.JPG

この URL からのデータは常に null です。この URL から画像を取得する方法

4

1 に答える 1

4

おそらくgetImageFromExtensionから呼び出しますdidSelectPost。最後に、結果項目の配列を使用してアプリ拡張要求を完了するようにホスト アプリに指示するdidSelectPostために呼び出す必要があります。completeRequestReturningItems:completionHandler:そのメソッドが呼び出されると、ShareViewController 全体が破棄され、割り当てが解除されます。の最後でこれを呼び出すと、 が画像 URL を取得するdidSelectPost前に実行されます。NSItemProviderそれは非同期で行われるからです。これを修正するには、imageURL を取得したcompleteRequestReturningItems:completionHandler:後に呼び出す必要があります。NSItemProvider

これがどのように機能するかは次のとおりです。

- (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];
                              }];
    }
}

ちなみに、dispatch_asyncプロバイダーはすでに非同期で作業を行っているため、NSItemProvider を使用する場合は使用する必要はありません。

これについては、ブログ記事を書いています。

編集

取得したファイル パスを使用してイメージをロードできるようになりました。これは拡張機能でのみ機能します。含まれているアプリから画像にアクセスする場合、取得したばかりのファイル URL を使用することはできません。共有拡張機能は、選択した画像を、含まれているアプリからアクセスできないフォルダーに保存します。

含まれているアプリでイメージを使用できるようにするには、含まれているApp Groupsアプリと拡張機能でアクティブ化する必要があります。次に、拡張機能が画像を共有コンテナーに保存し、それを含むアプリがそれを取得できるようにします。

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
        }
    }
}
于 2015-10-16T06:35:52.037 に答える