How do I load a URL using NSItemProvider's new Async loadItem method?
I had to cast to Data
and then construct the URL
from that:
if let data = try await urlProvider
.loadItem(forTypeIdentifier: UTType.fileURL.identifier) as? Data {
url = URL(dataRepresentation: data, relativeTo: nil) }
Accessing Website URL and Title in ShareExtension
Change your "loadItem" to "loadItemAsync" and run it that way. I ran into literally the EXACT same problem of the completion block not running, but when I call "loadItemAsync" instead of just "loadItem," it runs fine and I get all the output from my JS file.
Code outside loop being executed during loop
For this kind of async work you need something like DispatchGroup
.
Edited your example to take use of it
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true)
itemProviders = results.map(\.itemProvider)
iterator = itemProviders.makeIterator()
let dispatchGroup = DispatchGroup()
while let itemProvider = iterator?.next(), itemProvider.canLoadObject(ofClass: UIImage.self) {
dispatchGroup.enter()
print("\n Entered while")
itemProvider.loadObject(ofClass: UIImage.self) { image, error in
DispatchQueue.main.async {
guard let image = image as? UIImage else { return }
self.images.append(image)
print("Image: \(image)")
print("Images: \(self.images)")
dispatchGroup.leave()
}
}
}
dispatchGroup.notify(queue: DispatchQueue.main) {
self.displayAndStoreImages()
}
}
func displayAndStoreImages(){
print("\n Entered displayAndStoreImages()")
print("Images: \(images) \n")
}
iOS YouTube Share Extension Not Providing URL
My first recommendation is to find out what types are actually provided by theitemProvider
:
if let item = extensionContext?.inputItems.first as? NSExtensionItem {
for (index, _) in (item.attachments?.enumerated())! {
if let itemProvider = item.attachments?[index] as? NSItemProvider {
// print out the registered type identifiers so we can see what's there
itemProvider.registeredTypeIdentifiers.forEach { print String(describing: $0) }
In this case, according to your comments, you are able to get plain text or kUTTypePlainText
and that text contains a URL so:
if let item = extensionContext?.inputItems.first as? NSExtensionItem {
for (index, _) in (item.attachments?.enumerated())! {
if let itemProvider = item.attachments?[index] as? NSItemProvider {
if itemProvider.hasItemConformingToTypeIdentifier(kUTTypePlainText) {
itemProvider.loadItem(forTypeIdentifier: kUTTypePlainText, options: nil, completionHandler: { (string, error) -> Void in
if let string = (string as? String), let shareURL = URL(string) {
// send url to server to share the link
print (shareURL.absoluteString!)
My second recommendation is to always use the kUTType constants instead of raw strings :-)
Swift - Using Async Method to Load PHPickerResult
I don't know why your code doesn't work. (It doesn't work for me either, for what it's worth.) However, I did determine code that does work, although you might not consider it to be an improvement over just using loadObject with a callback:
Task {
do {
let url = try await item.loadItem(forTypeIdentifier: "public.image") as! URL
let data = try Data(contentsOf: url)
if let image = UIImage(data: data) {
print("Image loaded: \(image)")
} else {
print("Error loading image!");
}
} catch let error {
print("async loadItem failed: \(error)")
}
}
Note: I tried to use UIImage(contentsOfFile: url.absoluteString)
instead of loading the URL into a Data object and then loading the UIImage from that. That didn't work, and I don't know why. All I know is that UIImage(contentsOfFile:)
returned nil.
Related Topics
How Does Swift Disambiguate Type Arguments in Expression Contexts
Covert Realm List to Realm Result
Problem with Frameworks in Command Line Tool
Swift Set UIbutton Setbordercolor in Storyboard
Implementing Undo and Redo in a UItextview with Attributedtext
Shortest Code to Create an Array of Random Numbers in Swift
How to Use This Fetchrequest() in Swift
Occasional Blank Frames After Exporting Asset - Avexportsession
Uibutton Background Color Overlaps Text on Highlight
How to Refer to a Global Type from Within a Class That Has a Nested Type with The Same Name
Arkit/Scenekit on iOS 14 Throws New Warning (Metal)
Why Swift Disallows Weak Reference for Non-Optional Type
#If Canimport(Coreimage) Not Working in Swift Package Manager
I Opened My App in Xcode 10 and Now I Have Errors in 9.4.1: Sdkapplicationdelegate (Facebookcore)
Weird Toolbar with Nested Conditionals Behavior
Proper Way of Editing a Cocoapod Library