8

我正在开发一个使用照片共享扩展的 iOS 应用程序,其中处理图像并触发我们的主要功能。

在 Photo 应用程序的模拟器中,效果很好。我决定从 Photo 的应用程序在设备上运行,它也很好用,但是当我截屏并尝试从 iOS 11 的新“快速截屏”分享时,扩展崩溃了,有什么想法吗?

扩展获取图像,将其发送到服务器,获取响应并显示该响应(全部在扩展中)。这让我很恼火,因为从快速截图访问 Messenger 和 Snapchat 共享扩展仍然有效!!

Xcode 9 也没有从共享扩展中给我任何日志。还值得注意的是,我每次在设备上重新安装应用程序时都需要“信任”一个开发者帐户。

代码:

// App Group keys

let suiteName = "group.suite.id"

override func viewDidLoad() {
    print("Styling views..")
    styleViews()
    print("Styled views")
    print("Adding notifications..")
    addNotifications()
    print("Added notifications")
    print("Fetching image..")
    fetchSharedImage()
}

func styleViews(){
    // Set up main view
    mainView.layer.cornerRadius = 8
    mainShadowView.addShadow()

    // Set up views and buttons
    // Code hidden, applies shadows etc.

    // Code hidden, moves constraints of a view
}

func addNotifications(){
    // Helps views tell their parent (this view controller) to navigate to another form
    NotificationCenter.default.addObserver(forName: NotificationDisplayFetchedLink, object: nil, queue: nil){ notification in
        // Handles user info in lambda block
        guard let userInfo = notification.userInfo,
            let link = userInfo["link"] as? String
            else {
                print("No userInfo found in notification")
                return
            }
        self.displayResult(with: link)
    }
}

func fetchSharedImage(){
    // Make sure we have a valid extension item
    if let content = extensionContext!.inputItems[0] as? NSExtensionItem {
        let contentType = kUTTypeImage as String

        // Verify the provider is valid
        if let contents = content.attachments as? [NSItemProvider] {
            // look for images
            for attachment in contents {
                if attachment.hasItemConformingToTypeIdentifier(contentType) {
                    attachment.loadItem(forTypeIdentifier: contentType, options: nil) { data, error in
                        let url = data as! URL
                        if let imageData = try? Data(contentsOf: url) {
                            self.selectedImage = UIImage(data: imageData)

                            DispatchQueue.main.async {
                                self.selectedImageView.layer.cornerRadius = 8
                                self.selectedImageView.image = self.selectedImage
                            }
                            self.makeWebRequest()

                        }
                    }
                }
            }
        }
    }
}

func makeWebRequest(){
    let url = URL(string: "url.json")
    let task = URLSession.shared.dataTask(with: url!) { data, response, error in
        guard error == nil else {
            return
        }
        guard let data = data else {
            // Data is empty
            return
        }

        let json = try! JSONSerialization.jsonObject(with: data, options: []) as! NSDictionary
        guard let dict = json as? [String:Any] else { return }
        let item = dict["item"]
        guard let itemData = item as? [[String:Any]] else { return }
        let link = itemData[0]["url"]
        NotificationCenter.default.post(name: NotificationDisplayFetchedLink, object: nil, userInfo: [link: link!])
    }
    task.resume()
}

编辑:

所以解决方案(正如 Owen Zhao 所说)是 iOS 11 截图编辑器返回一个 UIImage,而像照片这样的应用程序将返回 URL。

我优雅地处理此问题的解决方案是将 UIImage 或转换为 UIImage 的 URL 保存到 iOS 临时目录(3 天后删除),然后将该目录中图像的 URL 返回到共享扩展。

4

2 回答 2

8

let url = data as! URL if let imageData = try? Data(contentsOf: url) {

问题是因为这里的数据不是 URL。它是一个“public.image”,尝试转换为 UIImage 而不是 Data。

于 2017-09-14T08:23:11.287 回答
2

在 Objective C 中,您可以将以下代码用于共享为屏幕截图的图像。具有 .png 扩展名的屏幕截图,因此请使用public.png而不是public.jpeg

if ([itemProvider hasItemConformingToTypeIdentifier:@"public.png"]){
            [itemProvider loadItemForTypeIdentifier:@"public.png" options:nil completionHandler: ^(id<NSSecureCoding> item, NSError *error) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    NSData *imgData;
                    if([(NSObject*)item isKindOfClass:[NSURL class]]) {
                        imgData = [NSData dataWithContentsOfURL:(NSURL*)item];
                    }
                    if([(NSObject*)item isKindOfClass:[UIImage class]]) {
                        imgData = UIImagePNGRepresentation((UIImage*)item);
                    }
 UIImage *image=[UIImage imageWithData:imgData];
});

            }];
于 2018-03-21T05:31:19.497 回答