I\'m trying to create a sharing extension using the new iOS 8 app extensions. I tried to get the current URL of a Safari site to show it in a UILabel. Simple enough.
All of those previous answers are really good but I just came accross this issue in Swift and felt it was a little tidious to extract the URL from a given NSExtensionContext especially in the CFString to String conversion process and the fact that the completionHandler in loadItemForTypeIdentifier is not executed in the main thread.
import MobileCoreServices
extension NSExtensionContext {
private var kTypeURL:String {
get {
return kUTTypeURL as NSString as String
}
}
func extractURL(completion: ((url:NSURL?) -> Void)?) -> Void {
var processed:Bool = false
for item in self.inputItems ?? [] {
if let item = item as? NSExtensionItem,
let attachments = item.attachments,
let provider = attachments.first as? NSItemProvider
where provider.hasItemConformingToTypeIdentifier(kTypeURL) == true {
provider.loadItemForTypeIdentifier(kTypeURL, options: nil, completionHandler: { (output, error) -> Void in
dispatch_async(dispatch_get_main_queue(), { () -> Void in
processed = true
if let url = output as? NSURL {
completion?(url: url)
}
else {
completion?(url: nil)
}
})
})
}
}
// make sure the completion block is called even if no url could be extracted
if (processed == false) {
completion?(url: nil)
}
}
}
That way you can now simply use it like this in your UIViewController subclass:
self.extensionContext?.extractURL({ (url) -> Void in
self.urlLabel.text = url?.absoluteString
println(url?.absoluteString)
})