Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS CoreSpotlight Thumbnail Image from URL

I'm trying to build a test app that uses CoreSpotlight to make content searchable in iOS Spotlight. Currently I have it setup to whenever the user taps a refresh button it makes a server request then deleteAllSearchableItems then indexSearchableItems (probably not the best way but easiest for right now, since I'm still in the beginning phases of figuring this out).

Below is my code that does that.

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")
        }
    }
})

My next thing I'm trying to do is I have an array of images called self._images. Inside of that array is either an empty string ("") or a string of a URL ("https://mywebsite.com/image.png").

Currently I can use the code below to set the image of a UIImageView to the image at that URL, using AlamofireImage.

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

How can I get that same image into the CoreSpotlight attributeSet?

I'm assuming attributeSet.thumbnailData.af_setImage(withURL: imagedownloadURL) won't work. Especially since it's async.

What would be the easiest way to integrate this?

I've tried a few things such as for loops and such but the biggest problem is the async and I can't seem to figure out a solution to do this since it's async and I have multiple items.

Thank you so much in advance!

like image 845
Charlie Fish Avatar asked May 22 '17 00:05

Charlie Fish


1 Answers

Easiest solution but not the best one...

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")
            }
        }
    })
}

Edited

Why not the good solution? To avoid async issue, I have just put everything in one async closure and doing the sync image downloading.

UPDATE

Added default Alamofire cashing, before downloading it first look's for the cashed image now.

like image 107
Bilal Avatar answered Oct 09 '22 03:10

Bilal