How do I trap a bad URL in openURL swift - ios

If my url has a space at the end it crashes with EXC_BAD_INSTRUCTION.
I thought canOpenURL would trap for a bad URL but it doesn't.
if let strurl = cell.url{
if (UIApplication.sharedApplication().canOpenURL(NSURL(string:strurl)!)) {
UIApplication.sharedApplication().openURL(NSURL(string:strurl)!);
}
}
In my case a URL with an extra space at the end crashes it. I can trim white space, but what about anything else? Is there a proper way to trap for this error?

You are force unwrapping NSURL which causes the app to crash if it happens to be nil. To check the validity of the URL you should be using if let on the URL itself as well.
if let strurl = cell.url,
let url = NSURL(string: strurl) {
if (UIApplication.sharedApplication().canOpenURL(url) {
UIApplication.sharedApplication().openURL(url)
}
}

Related

Why can't I convert this String to a URL?

I have x 2 questions about urls and webViews.
Question 1:
I have a string which I am getting from an API that is supposed to be a url. The string is https://godochurch.blob.core.windows.net/sermons/1031/30-1-2017-Vision Sunday-Devotion.mp3
When trying to convert to a url I'm getting nil.
Here is the code:
if let sermonUrl = sermonUrl {
if let url = URL(string: sermonUrl) {
let requestObj = URLRequest(url: url)
webView.loadRequest(requestObj)
}
}
I have worked out that the space between 'Vision' and 'Sunday' is the problem.
Should I be encoding the string in some way before trying to convert it to a URL? What's confusing is that if I paste the string into my browser it works just fine, but I notice the browser is percent encoding the space.
If I am supposed to be encoding the string, how do I do that?
Question 2:
I see that URL(string: "urlStringHere") is only available from iOS 10. My app needs to work for iOS 9. How can I convert the above code so it works on iOS 9 and 10.
Thanks in advance for your time.
1: escape that space with %20 or +:
if let url = URL(string: "https://godochurch.blob.core.windows.net/sermons/1031/30-1-2017-Vision%20Sunday-Devotion.mp3") {
// ...
}
2: URL was introduced with Swift 3, which is compatible with iOS 8 and later. See this question on how to make it work with older versions of iOS.
Edit: the easiest way to percent-escape a URL is to use URLComponents:
var components = URLComponents(string: "https://godochurch.blob.core.windows.net")!
components.path = "/sermons/1031/30-1-2017-Vision Sunday-Devotion.mp3"
if let url = components.url {
// ...
}
If you happen to get you URL strings from a webservice and it contains a space, that service is bad. Space is not allowed in an URL. Web browsers relax that rule because they know there are bad URLs out there. Swift won't take it.

Swift: string url encoding not working as expected

So I have a url like this:
let remoetURL = "http://xxx-test.img-cn-hangzhou.aliyuncs.com/materials/talk_-XXXXX-XXXXXXX/STEM RULE.pdf"
As you can see, at then end of the url, there is a white space, so I need to get rid of it to have a valid encoded url.
After doing some research, I realized I might use
let escapedString = remoteURL.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLPathAllowedCharacterSet())
But this does not returned the expected working url, because it encodes the ":" after "http" too
http%3A//xiaobandeng-staging.img-cn-hangzhou.aliyuncs.com/talk_materials/talk_-K4yjX4-238Ku74WVIJk/STEM%20RULE.pdf
I have also tried URLHostAllowedCharacterSet, but no luck. So I wonder if it is because I don't have www here, so it does not recognise which part is the host correctly. If so, what might be the elegant solution? I know I could replace white spaces with %20 by calling stringByReplacingOccurrencesOfString, but that seems just a bit fragile.
Thank you in advance.
Try this used by SwiftyJSON
let urlString = remoteURL.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
Swift 3:
let urlString = remoteURL.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
Have you try this
let urlPath = NSString(format: remoetURL).stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
For iOS 9
let encodedHost = NSString(format: remoetURL).stringByAddingPercentEncodingWithAllowedCharacters(.URLQueryAllowedCharacterSet())
Hope this will help you

Escape Character in URL - iOS Swift

I'm pulling a URL from a string and turning that into a button to a WebView of the link.
This is the error I'm getting...
2015-11-10 18:58:05.159 MPSTApp[520:169178] -canOpenURL: failed for URL: "https:/www.facebook.com/prontosantateresa -- file:///" - error: "This app is not allowed to query for scheme file"
For this instance the string is https://www.facebook.com/prontosantateresa but I believe it's using the double // as an escape character.
The code calling the url link is such -
var anchorLink: String?
func loadWebPage(){
let requestURL = NSURL(string: anchorLink!)
let request = NSURLRequest(URL: requestURL!)
webView.loadRequest(request)
}
It's exactly what the error message says: It tries to open a file:// url. So, your algorithm for retrieving the https:// url seems to do something wrong and turn "//" into "/". It could also come handy to add the NSAllowArbitaryLoads key to your Info.plist.
I investigated issue. Since I was using an app browser, it didn't need to use UIApplication.canOpenUrl().
So, to resolve this I replaced the event method with below code in
#IBAction func website1ButtonPressed(sender: UIButton) {
if self.anchorLink != nil{
self.performSegueWithIdentifier("categoryDetailToWebSegue", sender: nil)
}
}

exc-bad-instruction code=i386_invop

I'm getting this error in latest version of xcode using swift 2
on line
let s = linkTxt.text
Text in linkTxt appears by button "pasteFromClipBoard"
let s = linkTxt.text
let u = NSURL(string: s!)
let file = u?.lastPathComponent
What is the reason of it and how to fix it?
Update:
the problem appears in function saveData() which calls when file downloading is finished. It calls from NSURLSessionDataTask function. More interesting, that in start-downloading-button there are the same lines where filename is generating and there is no such error on it. I fixed these issues by declaring variables, writing text's values into them and use these variables in saveData() except textObject.text; I had to delete lines with NSUserDefaults from saveData() too because I got the same error. Did understand nothing >_<
Update 2:
It's really a bug. I've deleted this line and wrote again - problem fixed
linkTxt.txt is returning nil and NSURL(string: s!) will try to forcefully unwrap it.
let s = linkTxt.text
if let s = linkTxt.txt {
let u = NSURL(string: s!)
let file = u?.lastPathComponent
}

'NSURLRequest?' does not have a member named 'URL' - Swift

Hi I am really new to coding in Swift, and am trying to follow the codes in this book: http://www.apress.com/9781484202098. Learn iOS 8 App Development 2nd Edition by James Bucanek
In particular, I am working through Chapter 3 - building a URL shortening app, but despite having copied the code exactly, I am getting an error on the code in Page 76:
if let toShorten = webView.request.URL.absoluteString {
which states 'NSURLRequest?' does not have a member named 'URL'.
I have tried googling an answer, but unfortunately have not come across anything. Any response I can find seems to suggest that my code ought to be working (e.g. How to get url which I hit on UIWebView?). This seems to have the closest answer SWIFT: Why I can't get the current URL loaded in UIWebView? but the solution does not appear to work for me. If I add a ? after the request, it will then at least build it, but I then have a nil variable returned.
I am using Xcode v6.1.1. Here is the piece of code that is coming up with the error in ViewController.swift:
let GoDaddyAccountKey = "0123456789abcdef0123456789abcdef" //this is replaced by my actual account key in my own code
var shortenURLConnection: NSURLConnection?
var shortURLData: NSMutableData?
#IBAction func shortenURL( AnyObject ) {
if let toShorten = webView.request?.URL.absoluteString { // ? now added
let encodedURL = toShorten.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
let urlString = "http://api.x.co/Squeeze.svc/text/\(GoDaddyAccountKey)?url=\(encodedURL)"
shortURLData = NSMutableData()
if let firstrequest = NSURL(string: urlString) //added if here and removed !
let request = NSURLRequest(URL:firstrequest)
shortenURLConnection = NSURLConnection(request:request, delegate:self)
shortenButton.enabled = false
}
}
}
If you have any suggestions on how I can fix this, I would really appreciate it!
Update:
Following suggestions from Ashley below, I have amended my code so that it is no longer bringing up the error (see comments above). However, it is now no longer running. This appears to be because the urlString is being created as http://api.x.co/Squeeze.svc/text/d558979bb9b84eddb76d8c8dd9740ce3?url=Optional("http://www.apple.com/"). The problem is therefore the Optional() that is included and thus makes it an invalid URL. Does anyone have a suggestion on how to remove this please?
request is an optional property on UIWebView:
var request: NSURLRequest? { get }
also stringByAddingPercentEscapesUsingEncoding returns an optional:
func stringByAddingPercentEscapesUsingEncoding(_ encoding: UInt) -> String?
What you need is to make user of optional binding in a few places:
if let toShorten = webView.request?.URL.absoluteString {
if let encodedURL = toShorten.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding) {
let urlString = "http://api.x.co/Squeeze.svc/text/\(GoDaddyAccountKey)?url=\(encodedURL)"
shortURLData = NSMutableData()
if let firstrequest = NSURL(string: urlString) { // If a method can return a nil, don't force unwrap it
let request = NSURLRequest(URL:first request)
shortenURLConnection = NSURLConnection(request:request, delegate:self)
shortenButton.enabled = false
}
}
}
See Apple's docs on optional chaining for details
See Apple's docs for NSURL class

Resources