application openURL giving invalid urls - ios

The function
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
is still called like normal, but when I do:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
do {
let contentsOfFile = try NSString(contentsOfFile: url.path, encoding: String.Encoding.utf8.rawValue)
Swift.print("COF \(contentsOfFile)")
} catch let error {
Swift.print("error \(error)")
}
...
}
I get the error "The file “____” couldn’t be opened because there is no such file."
This used to work in iOS 12. I'm not doing anything with SceneDelegate or anything, so I'm not sure why it's giving me invalid URLs now.
Update: if I drag a file from my Dropbox onto the iOS Simulator, it works. If I drag a file from anywhere else on my computer, it doesn't work.

The function open url can be used to read the files like below ,
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let stringPath = Bundle.main.path(forResource: "bbc", ofType: "json") // File name
let fileUrl = URL(fileURLWithPath: stringPath!)
let canOpenBool = application(UIApplication.shared, open: fileUrl)
print(canOpenBool)
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
do {
let contentsOfFile = try NSString(contentsOfFile: url.path, encoding: String.Encoding.utf8.rawValue)
Swift.print("COF \(contentsOfFile)")
return true
} catch let error {
Swift.print("error \(error)")
return false
}
}
}

Well, I guess it's just something to do with the simulator. If I drag a file from my Dropbox onto the iOS Simulator, it works. If I drag a file from anywhere else on my computer onto the simulator, it doesn't work. But it still works fine on a real device, as far as I can tell.

Related

IOS Swift 4 AppDelegate application to handle receiving a custom URL AirDrop file not being hit

My iPhone app sends a custom URL file via AirDrop to my iPad app. The URL has an extension of .fdre. When sent the iPad app opens. However, Application function to handle receiving the custom file in AppDelegate never seems to get hit. Any help would be greatly appreciated.
I have this in my "sending" app:
func exportToURL (data : String) -> URL {
var input : String = ""
let url = self.getDocumentsDirectory().appendingPathComponent("FUNduroResult.fdre")
do {
try data.write(to: url, atomically: true, encoding: .utf8)
input = try String(contentsOf: url)
print(input)
print(url)
} catch {
print(error.localizedDescription)
}
return url
}
#IBAction func airdropButton(_ sender: Any) {
let text = formatDataAsCSV()
let url = exportToURL(data: text)
let activity = UIActivityViewController(
activityItems: ["Check out this result for the FUNduro.", url],
applicationActivities: nil
)
activity.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
present(activity, animated: true, completion: nil)
}
I have this in the AppDelegate of my receiving app:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
if url.pathExtension == "fdre" {
print("got result")
}
return true
}
I have this in my receiving app for the document types:
Document Types
cheers kbjb

iOS 12 - AppAuth redirect URL not trigger AppDelegate

I am using AppAuth on my code.
I manage to authenticate successful , but when the SFSafariViewController gets dismiss from my Controller , the redirect url does not trigger the AppDelegate func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool
The redirect URL is my Bundle Identifier name : BundleIdentifier://authenticate
I have setup in info.plist url Schemes and url identifier which they have the same name.
When I run my code setting a break point on this func I can see my redirect url correct for standarizedURL and standarizedRedirectURL
- (BOOL)shouldHandleURL:(NSURL *)URL {
NSURL *standardizedURL = [URL standardizedURL];
NSURL *standardizedRedirectURL = [_request.redirectURL standardizedURL];
return OIDIsEqualIncludingNil(standardizedURL.scheme, standardizedRedirectURL.scheme) &&
OIDIsEqualIncludingNil(standardizedURL.user, standardizedRedirectURL.user) &&
OIDIsEqualIncludingNil(standardizedURL.password, standardizedRedirectURL.password) &&
OIDIsEqualIncludingNil(standardizedURL.host, standardizedRedirectURL.host) &&
OIDIsEqualIncludingNil(standardizedURL.port, standardizedRedirectURL.port) &&
OIDIsEqualIncludingNil(standardizedURL.path, standardizedRedirectURL.path);
But when AppAuth finishes the authentication and I have an access token , func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool doesn't get triggered.
Any idea why?
Here is my code
class func signInAuth(discoveryURLstr: String,presenter : UIViewController,completionHandler: #escaping ( (OIDAuthState?,Error?) -> () )){
guard let discoveruURL = URL(string: discoveryURLstr) else{
completionHandler(nil,AuthErrors.InvalidDiscoveryURL)
return
}
appAuthDiscoverConfiguration(discoveryURL: discoveruURL) { (configurationFile, error) in
guard let configurationFile = configurationFile else {
completionHandler(nil,AuthErrors.InvalidConfigurationFile)
return
}
let authRequest = appAuthRequest(configurationFile: configurationFile)
self.appAuthenticationSession = OIDAuthState.authState(byPresenting: authRequest, presenting: presenter, callback: { (state, error) in
if let error = error {
//self.authState = nil
completionHandler(nil,error)
return
}
if let state = state {
self.authState = state
completionHandler(state,nil)
}else{
completionHandler(nil,AuthErrors.InvalideState)
}
})
}
}
class func appAuthDiscoverConfiguration(discoveryURL : URL, completionHandler: #escaping ((OIDServiceConfiguration?,Error?) -> ())) {
OIDAuthorizationService.discoverConfiguration(forDiscoveryURL: discoveryURL) { (configuration, error) in
if let error = error {
completionHandler(nil,error)
return
}else{
guard let configurationFile = configuration else {
completionHandler(nil,AuthErrors.InvalidConfigurationFile)
return
}
completionHandler(configurationFile,nil)
}
}
}
class func appAuthRequest(configurationFile : OIDServiceConfiguration) -> OIDAuthorizationRequest{
return OIDAuthorizationRequest(configuration: configurationFile, clientId: AppAuthConstants.clientId, clientSecret: nil, scope: AppAuthConstants.scope, redirectURL: AppAuthConstants.redirectURL, responseType: AppAuthConstants.responseType, state: nil, nonce: nil, codeVerifier: nil, codeChallenge: nil, codeChallengeMethod: nil, additionalParameters: AppAuthConstants.additionalParameters)
}
On iOS 12, App-Auth uses ASWebAuthenticationSession, and on iOS 11, it uses the now-deprecated SFAuthenticationSession instead of requiring the app to support handling the redirect manually. To support earlier versions of iOS, you still need your code in the func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool method.
For reference, you can see what AppAuth is doing under the covers here. Also, this is a great answer that explains how to generically get an OAuth token on iOS without using AppAuth.

Back link to previous app from containing app progmatically in case of deeplinks

I created a keyboard extension with a scan button to open a barcode scanner in my containing app. When the scan is completed, it should navigate back to the initial app and the barcode data should be set as text to the textfield that initiated the keyboard and we clicked on scan button.
There is this app Scandit Wedge that does it the same way. But I couldn't find a way to achieve the same.
Please refer GIF below.
https://s3.amazonaws.com/id123-dev-ios/scandit.gif
Any help would be much appreciated.
There is no public API to switch to the previous app, here is the answer: https://stackoverflow.com/a/13447282/1433612
But you could do that if you know the app's bundle id and url scheme. You can find unofficial lists on internet. Assuming that you are able to recognize the source app you can do something like this in your AppDelegate:
public func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
guard let applicationBundleId = options[UIApplicationOpenURLOptionsKey.sourceApplication] as? String else {
return true
}
// Save your source application
sourceApplicationBundleId = applicationBundleId
return true
}
var sourceApplicationBundleId: String?
// Attempt to open application from which your app was opened
func openApplication() {
guard let applicationBundleId = sourceApplicationBundleId, let url = url(for: applicationBundleId) else {
return
}
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
func url(for bundleId: String) -> URL? {
guard let scheme = knownUrlSchemes[bundleId] else {
return nil
}
return URL(string: scheme)!
}
// A list of known url schemes
var knownUrlSchemes: Dictionary<String, String> = {
return ["com.google.Maps": "comgooglemaps://",
"com.facebook.Facebook": "fb://"]
}()

Get value of parameters in deep link url iOS

everyone.
My question is: How can I get data from deep link URL?
I have two apps and I want to send data from app1 to app2 using the deep link.
I have a button on app1 to click and open app2 then app 2 will get data from app1 by deep link URL.
Here is my code of button send in app1:
#IBAction func btnSend_Clicked(_ sender: Any) {
let text = self.txtInput.text?.replacingOccurrences(of: " ", with: "%20")
UIApplication.shared.open(URL(string: "myapp://?code=\(text!)")!, options: [:], completionHandler: nil)
}
so, How can i get data from deeplink url (code parameter) in app2?
Really Thanks for your help !!!!
You implement this code in Appdelegate:
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false)
let items = (urlComponents?.queryItems)! as [NSURLQueryItem]
if (url.scheme == "myapp") {
var vcTitle = ""
if let _ = items.first, let propertyName = items.first?.name, let propertyValue = items.first?.value {
vcTitle = url.query!//"propertyName"
}
}
return false
}

URLSession cached data

I'm new in iOS dev and I do not understand one think. So I have gz file and inside gzip there is xml file. I need to download gz file, every time user start the app. First time when I start my app I use this code to get data. Problem is my xml file was offline on server for few day and my app always start without problem and show data with no problem. So all my files was cached on device?. I want my data is retrieved every time while the user start the application. I am not sure do I did something wrong? Thanks
let url = NSURL(string: "http://sitename/xxx.gz")
if url != nil {
let task = URLSession.shared.dataTask(with: url! as URL, completionHandler: { (data, response, error) -> Void in
if error == nil {
let nsdata = data as NSData?
let content = nsdata?.gunzipped()
let dataContent = content as Data?
let urlContent = NSString(data: dataContent!, encoding: String.Encoding.ascii.rawValue) as NSString!
let xml = XMLParser()
xml.getDataforTable(data: urlContent as! String)
NotificationCenter.default.post(Notification(name: Notification.Name(rawValue: "XmlDataLoaded"), object: nil))
} else {
NotificationCenter.default.post(Notification(name: Notification.Name(rawValue: "DataNotLoaded"), object: nil))
}
})
task.resume()
}
enter code here
in AppDelegate.swift
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
call your web services method inside this method
}

Resources