Closed dongsuo closed 2 weeks ago
Found an article related to this bug, hope useful https://keyboardkit.com/blog/2024/09/11/ios18-breaks-selector-based-url-opening
damn, that's annoying. Thanks for reporting and for sharing the article. Will treat this issue as top priority
I looked into this a bit. Tried modifying the openHostApp method locally, but no luck.
It looks like Apple has intentionally removed the ability to open URLs from app extensions. The deprecated method used previously won't be coming back :(
App extensions are not allowed to open URLs directly. This isn’t accidental, but a deliberate design choice on Apple’s part. Don’t try to bypass such restrictions using Silly Runtime Hacks™. That just opens yourself up to compatibility problems down the pike.
If your app extension needs to get the user’s attention, do that by posting a local notification.
This is working on ios 18.1 (not thoroughly tested).
// in ShareExtensionViewController.swift
private func openHostApp(path: String?) {
guard let scheme = Bundle.main.object(forInfoDictionaryKey: "HostAppScheme") as? String else { return }
var urlComponents = URLComponents()
urlComponents.scheme = scheme
urlComponents.host = ""
if let path = path {
let pathComponents = path.split(separator: "?", maxSplits: 1)
let pathWithoutQuery = String(pathComponents[0])
let queryString = pathComponents.count > 1 ? String(pathComponents[1]) : nil
// Parse and set query items
if let queryString = queryString {
let queryItems = queryString.split(separator: "&").map { queryParam -> URLQueryItem in
let paramComponents = queryParam.split(separator: "=", maxSplits: 1)
let name = String(paramComponents[0])
let value = paramComponents.count > 1 ? String(paramComponents[1]) : nil
return URLQueryItem(name: name, value: value)
}
urlComponents.queryItems = queryItems
}
let pathWithSlashEnsured = pathWithoutQuery.hasPrefix("/") ? pathWithoutQuery : "/\(pathWithoutQuery)"
urlComponents.path = pathWithSlashEnsured
}
guard let url = urlComponents.url else { return }
openURL(url)
self.close()
}
@objc @discardableResult private func openURL(_ url: URL) -> Bool {
var responder: UIResponder? = self
while responder != nil {
if let application = responder as? UIApplication {
if #available(iOS 18.0, *) {
application.open(url, options: [:], completionHandler: nil)
return true
} else {
return application.perform(#selector(UIApplication.open(_:options:completionHandler:)), with: url, with: [:]) != nil
}
}
responder = responder?.next
}
return false
}
yeah, we need this! ❤️
Thank you @AkbarKhamid! Will give this a try and release a patch this week
just released v1.10.5, which includes @AkbarKhamid's fix! Thanks a lot! Sorry it took so long, I've been swamped with work from my day job.
I just found this code doesn't work on iOS 18, but works on iOS 17.5. It even doesn't call
console.log
Any idea?<TouchableOpacity onPress={() => { console.log(111); openHostApp(
/share?url=${url}) }} >