Swift 4 app crashes when open file from icloud - ios

I have a problem that my app crashes when it is opening a file from iCloud. If I open this file from my app with a Document Picker, everything is fine. But if I try to open from outside my app, for example from iCloud or safari download it crashes. If I open it from local storage "my iphone" it is also working. It is interesting because it was good one week ago :)
So in AppDelegate, I've implemented the following method:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {}
According to the logs the crash occurs because the file does not exist.
file:///private/var/mobile/Library/Mobile%20Documents/com~apple~CloudDocs/Desktop/twic1121.pgn
This is the result if I print the URL from the parameter. I think this means that the file is there.
But if i do this: print(fm.fileExists(atPath: url.path)) then this is false.
So it is obvious that after let dataFromFile = fm.contents(atPath: url.path)
this is nil.
I have no idea what could be the problem here. So the real question here is why this is nil?

It appears that the error can be many things, all not related to the class you are applying the code (AppDelegate) nor the methods you are calling.
My guess is that the URL you are calling is not correctly built (not pointing to the correct object you are trying to point to). For many reasons.
See if one of this reasons fix your issue:
(1) The end of the URL you are calling had the suffix "pgn". If you are looking to load a picture, maybe the suffix is wrong. In that case it could have been some known and supported format like "png", "jpeg" or "jpg".
(2) The "%20"symbol at the middle of your code also lifts a flag. Does not seem to be a correct URL object of swift. Maybe the URL you are using is not represented in the correct way.
(3) com~apple~CloudDocs also lifts a flag, since it would unlikely have a "~" symbol in a URL passed. This also strongly suggests that maybe the URL you are using is not represented in the correct way.
I think your URL is not pointing to where you are trying to point to, resulting in the "does exist" method return false and the loading resulting in nil.
If all of this does not fix your issue, post more details of the code. Specially what method you are calling to build/create this URL object you are using, that points to: file:///private/var/mobile/Library/Mobile%20Documents/com~apple~CloudDocs/Desktop/twic1121.pgn

Related

eBuildfire: IOS issue for buildfire.navigation.openWindow parameter encoded

Buildfire suppor team, I'm trying to open up a new link using buildfire.navigation.openWindow and I noticed an issue on IOS with the URL parameters, as the = (equal sign) gets URL encoded. Please see my example below and the attached screenshot.
https://example.com/something?id=1654161096657Felix
is transformed to
https://example.com/something?id%3D1654161096657Felix
app code screenshot
Example URL works fine:
buildfire.navigation.openWindow("https://example.com/something?id=1654161096657Felix", "_system")
And when inspecting the new window on device I'm getting this:
I would check the server (the real URL) you are using and see if it is redirecting the url to something else.

Using reopened standard file descriptors in an iOS app with background capabilities?

I would like to be able to redirect my logging statements to a file so that I can retrieve them when my app runs standalone (i.e. is not attached to Xcode). I have discovered (thank you Stackoverflow) that freopen can be used to accomplish this.
If I create a new Xcode project and add the code to redirect stderr then everything works as expected.
However, when I add the redirection code to my existing, bluetooth project I am having trouble. The file is being created and I can retrieve it using iTunes or Xcode's Devices window, but it is of size 0. If I explicitly close the file then the text that I wrote actually makes it into the file. It is as though iOS is not flushing the file when the app is terminated. I suspect that the trouble stems from the fact that I have enabled background processing. Can anyone help me to understand this?
Here is my code:
let pathes = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true);
let filePath = NSURL(fileURLWithPath: pathes[0]).URLByAppendingPathComponent("Test.log")
freopen(filePath.path!, "a", stderr);
fputs("Hello, Samantha!\r\n", stderr);
struct StderrOutputStream: OutputStreamType {
static let stream = StderrOutputStream()
func write(string: String) {fputs(string, stderr)}
}
var errStream = StderrOutputStream.stream
print("Hello, Robert", toStream: &errStream)
fclose(stderr) // Without this the text does not make it into the file.
I'd leave this as a comment, but have you looked into NSFileHandle? It sounds like you just need a way to append data to the end of a text file, correct?
Once you have a handle with something like NSFileHandle(forWritingToURL:), you can use .seekToEndOfFile() and .writeData(_:). As a side note, you'll need to convert your String to Data before writing it.
Admittedly, this will probably end up being more lines of code, and you'll almost certainly need to take threading into consideration.

NSURL/NSURLRequest is unexpectedly nil

I'm trying to load a PDF into a UIWebView, but when using loadRequest, I'm getting the error unexpectedly found nil while unwrapping an Optional. My relevant code is below:
let url = NSURL(string: "http://www.urartuuniversity.com/content_images/pdf-sample.pdf")!
println(url.fileURL)
println("The URL is \(url.absoluteURL!)")
let request = NSURLRequest(URL: url)
webView.loadRequest(request)
The second line of code outputs false (unsurprisingly), but the third outputs the correct URL. webView is a connected UIWebView.
I've looked at a few examples of similar errors yet none seemed applicable, especially because the NSURL appears to be working due to the URL.absoluteURL! correctly outputting, as did numerous other similar commands.
I've also seen references to RFC 2396, but when looking at W3's documentation, my URL appears to be following these guidelines, but if it doesn't, then please tell me what the format is and how to change the URL (because I will have to literally change thousands more, and this PDF is merely an example PDF I found online).
When looking in the debug section, url is a NSURL and the place holding its value says the URL of the PDF, rather than a memory address, which could contribute partly to some of my problems.
Edit: To make my situation even weirder, because I'm using a universal app with a split-view and a table view, when I load an iPad, the PDF loads correctly, but the moment I go back to the master view and click on something, reloading the detail view, the fatal exception is found. If this made no sense, please tell me and I'll try to make it more comprehensible.
The problem is that you do not know what is nil. Add more logging, like this:
let url = NSURL(string: "http://www.urartuuniversity.com/content_images/pdf-sample.pdf")!
let request = NSURLRequest(URL: url)
println(url)
println(request)
println(webView)
webView.loadRequest(request)
In this way, by putting your app through its paces and trying to reproduce the crash, you will discover, just before the crash, exactly what is nil. I'm guessing it's the webView, but guessing is not programming — and the problem is that, so far, you are just guessing. Don't guess. You have a debugger! Debug!!!

Configure deep links in swift?

So I have an app written in swift that I would like to use deep links for. A user would click on one that in the route of the URL had different pieces of information such as the id of the post or the number of likes it has or something like that. I understand that you put this in the AppDelegate:
func application(application: UIApplication,openURL url: NSURL,sourceApplication sourceApplication: String?,annotation annotation: AnyObject?) -> Bool {
println(url.host as String!)
return true
}
And that prints everything after appname://. But how can I get url.host to my view controller to be parsed into the information I need. If the declaration of URL was outside of that function then I could use this:
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let InfoFromDeepLink = appDelegate.url.host
but since it's inside of that bulky Objective-C function, I'm helpless. How do you do this? I'm completely baffled. I can't even set the function to return url.host because it doesn't allow that. That's what I would do in Javascript. If you also know Javascript maybe put it in terms that a web developer would understand because I'm pretty new to this. This has to be so simple for a Swift developer right? I feel so stupid.
I would recommend using this cocoapods package called DeepLinkKit HERE IS THE SOURCE CODE
pod "DeepLinkKit"
You can simple route and have an error handling:
// Matches the URL.
router[#"timeline"] = ^{ … }
// Does not match the URL.
router[#"/timeline"] = ^{ … }
Here is a good tutorial that shows you in depth how it works.
Apple no longer supports Deep Links. It is now called Universal Links and works a bit differently.
Source
Now that Apple no longer supports URI schemes for deep linking, developers must implement Universal Links in order to deep link properly on iOS. If you are already using URI schemes, check out our blog on transitioning to Universal Links.
From: HERE
And HERE is another article on Universal Links and what they are.

For plug in running on iOS

What I want to implement is as follow:
A-app (calling app) : request the return value of a-string sent as parameter : request(a-string) -> b-string.
B-app (plug-in installed separately by me or others, it plays the role of dictionary or database ) : search a-string from database and return the result (b-string).
With successful experiences of plug-in on android and with Apple's confident rhetoric of plug-in, I thought plug-in, of course, run on iOS. After a lot of hard work, however, I finally found out:
* Note : The creation and use of loadable bundles is not supported in iOS.*
Nonetheless, not giving up, I finally made it with custom URl and pasteboard:
A-app : write a-string and false state to pasteboard & call B-app via custom URL.
B-app : viewDidLoad runs following func and thereafter exit program ; func { read pasteboard and search from database & write the result(b-string) and true state to pasteboard }
A-app : while-loop detects whether state is false or true. if true, catch b-string from pasteboard.
Anyway it works but it's too long thus almost useless. Do you have any idea for better solutions? Why doesn't Apple allow plug-in for iOS? Any responses are welcome. Thank you.
I can't answer why Apple doesn't allow plug-ins, but I can offer some advice on what you're trying to achieve.
The common pattern for sending data back to your application is to implement a callback url, so the A-app would also implement a custom URI and add that to the uri sent to B-app.
B-app would then process the uri as you have already implemented, but then instead of exiting, it simply sends the data you requested in the uri passed to it.
See http://x-callback-url.com for more details and example implementations.

Resources