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!
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.