iOS CoreSpotlight:从URL获取缩略图图片

7

我正在尝试构建一个测试应用程序,使用CoreSpotlight使内容在iOS Spotlight中可搜索。目前,每当用户点击刷新按钮时,它都会进行服务器请求,然后使用deleteAllSearchableItemsindexSearchableItems(可能不是最好的方法,但现在对我来说是最简单的,因为我仍然处于开始阶段)。

以下是我执行该操作的代码。

var searchableItems: [CSSearchableItem] = []
for i in 0 ..< self._ids.count {
    let attributeSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeItem as String)

    attributeSet.title = self._titles[i]
    attributeSet.contentDescription = self._descriptions[i]

    let searchableItem = CSSearchableItem(uniqueIdentifier: self._ids[i], domainIdentifier: "com.domain.appname", attributeSet: attributeSet)

    searchableItems.append(searchableItem)
}

CSSearchableIndex.default().deleteAllSearchableItems(completionHandler: { (error) -> Void in
    CSSearchableIndex.default().indexSearchableItems(searchableItems) { (error) -> Void in
        if error != nil {
            print(error?.localizedDescription ?? "Error")
        }
    }
})

接下来我要做的事情是使用self._images这个图片数组。这个数组中有两种类型的元素:空字符串("")或者URL字符串("https://mywebsite.com/image.png")。

目前,我可以使用以下代码将UIImageView的图像设置为该URL处的图像,使用AlamofireImage库。

if (self._images[0] != "") {
    myImageView.af_setImage(withURL: URL(string: self._images[0])!)
}

如何将同一张图片添加到CoreSpotlight attributeSet中?
我猜attributeSet.thumbnailData.af_setImage(withURL: imagedownloadURL)不起作用,尤其是因为它是异步的。
最简单的集成方法是什么?
我尝试了一些东西,如for循环等,但最大的问题是它是异步的,而且我无法找到一个解决办法,因为它是异步的,而且我有多个项目。
非常感谢您的帮助!
2个回答

6

最简单的解决方案,但不是最好的选择...

DispatchQueue.global(qos: .userInitiated).async {
    var searchableItems: [CSSearchableItem] = []
    for i in 0 ..< self._ids.count {
        let attributeSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeItem as String)
        attributeSet.title = self._titles[i]
        attributeSet.contentDescription = self._descriptions[i]
        let searchableItem = CSSearchableItem(uniqueIdentifier: self._ids[i], domainIdentifier: "com.domain.appname", attributeSet: attributeSet)

        if let imageUrl = URL(string: self._images[i]) {
            let urlRequest = URLRequest.init(url: imageUrl)
            if let cashedImage = UIImageView.af_sharedImageDownloader.imageCache?.image(for: urlRequest, withIdentifier: nil) {
                if let data = UIImageJPEGRepresentation(cashedImage, 1.0) {
                    attributeSet.thumbnailData = data
                }
            } else {
                if let data = NSData.init(contentsOf: imageUrl) {
                    attributeSet.thumbnailData = data as Data
                    if let image = UIImage.init(data: data as Data) {
                        let urlRequest = URLRequest.init(url: imageUrl)
                        UIImageView.af_sharedImageDownloader.imageCache?.add(image, for: urlRequest, withIdentifier: nil)
                    }
                }
            }
        }
        searchableItems.append(searchableItem)
    }

    CSSearchableIndex.default().deleteAllSearchableItems(completionHandler: { (error) -> Void in
        CSSearchableIndex.default().indexSearchableItems(searchableItems) { (error) -> Void in
            if error != nil {
                print(error?.localizedDescription ?? "Error")
            }
        }
    })
}

编辑

为什么不用更好的解决方案?为了避免异步问题,我只是将所有内容都放在一个异步闭包中,并进行同步图像下载。

更新

添加了默认的Alamofire缓存,在下载之前现在首先查找缓存的图像。


你能否在你的回答中再加入一些细节呢?你的代码示例是如何工作的?为什么它不是最佳解决方案?总体上更多的细节会更有帮助。 - Charlie Fish
那个细节很有帮助。我仍在努力理解Swift中异步与同步的区别。我现在要点赞你的回答。在奖励结束之前,我不会授予奖励或接受答案,以防有更好的答案之类的情况。但是在奖励结束后,我会授予一些问题并接受一些答案。非常感谢你。 - Charlie Fish
经过测试,似乎可以工作,但速度有点慢。或者至少第一次有点慢。一些项目在 Spotlight 中没有立即显示出来。因此,如果您恰好有更好的解决方案来提高此性能,那将是很棒的。因为我正在使用 af_setImage,它似乎不会每次重新加载图像。只有第一次。 - Charlie Fish

5
这里有一个更好的解决方案,使用thumbnailURL或thumbnailData,因为你已经缓存了图片,可以使用Alamofire、SDWebImage等库。

这个方法简单而且性能非常好。

对于thumbnailURL,它只接受本地路径:

  1. 获取缓存图像的文件路径
  2. 从文件路径创建一个URL对象,并在前面加上"file://"前缀

"file://"代表它是本地路径

    if let path = SDImageCache.shared().defaultCachePath(forKey: item.url_thumbnail), let url = URL(string: "file://\(path)") {
        attributeSet.thumbnailURL = url
    }

对于thumbnailData:

只需要分配本地url路径。

attributeSet.thumbnailData = try? Data(contentsOf: url)

调试并了解正在发生的情况,只需

 do {
     attributeSet.thumbnailData = try Data(contentsOf: url)
 }catch (let error as NSError){
      print(error)
 }

请注意,我正在使用SDWebImage获取缓存图像的路径,因为我正在使用它来缓存照片。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接