This is my NSURL
let url = NSURL(string: "tel://\(phoneCall)")
It is always nil, although the phoneCall is a valid mobile number string, and I am testing on a real iPhone.
I tried
let url = NSURL(string: "tel:\(phoneCall)")
but it's still nil.
let phoneCall = "tel://9000002143";
let url:NSURL = NSURL(string:phoneCall);
//OR
var url:NSURL = NSURL(string: "tel://9000002143")
if phoneCall == nil || phoneCall.isEmpty
{
print("phoneCall is empty or nil.")
}
else
{
UIApplication.sharedApplication().openURL(url);
}
Where this phoneCall is set?
I had a similar issue with a optional type. This code illustrate the problem:
let user = row.value
let phone = user?.phone
let url = NSURL(string: "tel://\(phone)")
UIApplication.sharedApplication().openURL(url!)
In this case, the value of urlString variable is "tel://Optional(\"11XXXXXXXXX\")", because the user variable can be nil.
You have to ensure that the user is not nil first, something like:
guard let user = row.value else {
return
}
let phone = user.phone
let urlString = "tel://\(phone)"
let url = NSURL(string: urlString)
UIApplication.sharedApplication().openURL(url!)
Related
I have a query on a Cloud CKRecord, which checks to see if a documents exists (i.e. has been uploaded as an CKAsset) and if not checks if a URL exists (i.e. has been uploaded as a String). All works well if either exist on their own for a given record, however if both exist when clicking on the link nothing happens.
I feel it is something to do with the if and else if statements -
if filename1 != nil {
let asset1 = record.object(forKey: "courseDocument1") as? CKAsset
let filename = record.object(forKey: "courseDocument1Filename") as! String
let path = (NSTemporaryDirectory() as NSString).appendingPathComponent(filename)
let doc1Data : NSData? = NSData(contentsOf:(asset1?.fileURL)!)
do {
try doc1Data!.write(to: URL(fileURLWithPath: path), options: .atomic)
let url = URL(fileURLWithPath: path)
let urlRequest = URLRequest(url: url)
self.courseDoc1WebView?.loadRequest(urlRequest)
self.venueDocButton1.setTitle(cseDocument1,for: [])
self.venueDocButton1.isHidden = false
self.courseDocumentLabel.isHidden = false
} catch {
print(error)
}
} else if cseDocument1URL != nil && filename1 == nil {
let url1 = URL (string: cseDocument1URL!)
let request1 = URLRequest(url: url1! as URL );
self.courseDoc2WebView.loadRequest(request1 as URLRequest);
self.venueDocButton1.setTitle(cseDocument1,for: [])
self.venueDocButton1.isHidden = false
self.courseDocumentLabel.isHidden = false
} else {
print("No Document Found")
}
Any thoughts?
This turned out to be a simple typo rather than logic -
self.courseDoc2WebView.loadRequest(request1 as URLRequest);
which should actually be -
self.courseDoc1WebView.loadRequest(request1 as URLRequest);
This was solved by printing responses and using the debugger - thanks Phillip Mills
Duncan C, you make a good point too - thank-you.
I use oAuth for the users login.
func getUserInfoResponse(_ response: APIResponse!) {
print("----------------------------------------")
print("用户资料获取成功:")
print(response.jsonResponse)
//print(response.jsonResponse["figureurl_qq_2"])
let accessToken = _tencentOAuth.accessToken
let nickname = response.jsonResponse["nickname"] as! String!
let avatar = response.jsonResponse["figureurl_qq_1"] as! String!
let avatar2 = response.jsonResponse["figureurl_qq_2"] as! String!
let urlString:String = "http://www.xxxxxx.com/cloud/app?openid=\(accessToken!)&nickname=\(nickname!)&avatar=\(avatar!)&avatar2=\(avatar2!)"
self.wk = WKWebView(frame: self.view.frame)
let url = URL(string: urlString)!
self.wk.load(URLRequest(url: url))
self.view.addSubview(self.wk)
}
and print(urlString) is
http://www.example.com/cloud/app?openid=xxxxxxx32D1E05D95E91881A15A8CDC75&nickname=
.&avatar=http://q.qlogo.cn/qqapp/101237639/90012AB5E745A1B10A6F5F4A14F0B48D/40&avatar2=http://q.qlogo.cn/qqapp/101237639/90012AB5E745A1B10A6F5F4A14F0B48D/100
when user login, , all the values have value except the url and get this error:
fatal error: unexpectedly found nil while unwrapping an Optional value
Why the url is nil, it has been assigned with value. Sorry I'm new to ios and swift3.
You should encode the url before use it
if let urlEncoded = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed){
let url = URL(string: urlEncoded)
}
I have the following Swift extension on NSURL
public extension NSURL {
func getQueryItemValueForKey(key: String) -> String? {
guard let components = NSURLComponents(URL: self, resolvingAgainstBaseURL: false) else {
return nil
}
guard let queryItems = components.queryItems else { return nil }
return queryItems.filter {
$0.name == key
}.first?.value
}
}
I am writing unit tests for it but I am unable to get 100% code coverage as I don't seem to be able to get NSURLComponents(URL: self, resolvingAgainstBaseURL: false) to return nil. From what I understand, this requires a malformed URL but I am struggling to create one.
I have tried:
let url = NSURL(string: "")
let url = NSURL(string: "http://www.example")
let url = NSURL(string: "http://www.exam ple.com")
let url = NSURL(string: "http://www.example.com/?param1=äëīòú")
And some others that I lost track of. I know this is probably something blatantly obvious but i'm lost at the moment. So, how do I create a malformed URL in Swift?
As found in my research, you can produce a url that is malformed for NSURLComponents but not for NSURL by using negative port number (probably there are more cases but not sure):
let example = "http://example.com:-80/"
let url = NSURL(string: example)
print("url:\(url)") //prints out url:Optional(http://example.com:-80/)
if let url = url {
let comps = NSURLComponents(URL: url, resolvingAgainstBaseURL: false)
print("comps:\(comps)") //prints out comps:nil
}
let imgURL:NSURL = NSURL(string: "\(ImageName)")!
at the above line,i'm getting fatal error
fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb)
Code :
let ImageName = obj["image"] as! String
let imgURL:NSURL = NSURL(string: "\(ImageName)")!
let request: NSURLRequest = NSURLRequest(URL: imgURL)
let session = NSURLSession.sharedSession()
let Imgtask = session.dataTaskWithRequest(request){
(data, response, error) -> Void in
if (error == nil && data != nil)
{
func display_image()
{
pointAnnoation.DisplayImage = UIImage(data: data!)
}
dispatch_async(dispatch_get_main_queue(), display_image)
}
}
Imgtask.resume()
From the above code im trying to store my image from database in annotation
if i printed the 'ImageName' it returns the name from the database correctly, but unable to retain the image
it resulting in the error while running.
You say that
if i printed the 'ImageName' it returns the name from the database correctly
Then that must mean that the ImageName is not valid for a URL
If you look at the description of NSURL(string:) it says:
The URL string with which to initialize the NSURL object. This URL string must conform to URL format as described in RFC 2396, and must not be nil. This method parses URLString according to RFCs 1738 and 1808.
So the question is...how does ImageName look? And can you create a URL from it?
Apart from that, it is always a good idea to use ? instead of ! as #PhillipMills says
Update: I can see that you have posted an example of your URL now. If I do this in a playground:
let url = NSURL(string: " goo.gl/pBmA0d")
I get nil in return, so it would seem that short URLs and NSURLaren't the best of friends.
Update 2: hmm, guess I spoke to quickly, if you look at the above you can see that I have a space before the goo.gl part, if I change that to:
let url = NSURL(string: "goo.gl/pBmA0d")
it actually works, I get a NSURL object.
But another thing I stumbled upon in your code. You declare ImageName as a String here:
let ImageName = obj["image"] as! String
So you don't have to wrap it in \() later on
let imgURL:NSURL = NSURL(string: "\(ImageName)")!
You could simply say:
let imageURL = NSURL(string: ImageName)
And then...as others has said, it is always a good idea to use ? instead of !
So you could write:
if let imageName = obj["image"] as? String,
let imageURL = NSURL(string: imageName) {
//we're in business :-)
}
and be safe and sound
Try to use guard or if let for helping yourself.
let ImageName = obj["image"] as! String
if let imgURL = NSURL(string: ImageName) {
let request: NSURLRequest = NSURLRequest(URL: imgURL)
let session = NSURLSession.sharedSession()
let Imgtask = session.dataTaskWithRequest(request){ (data, response, error) -> Void in
if (error == nil && data != nil)
{
// What's that func??
func display_image()
{
pointAnnoation.DisplayImage = UIImage(data: data!)
}
dispatch_async(dispatch_get_main_queue(), display_image)
}
}
}
Imgtask.resume()
Don't make force unwrap...use if let to avoid crash ...
if let img = obj["image"] as? String,
imgURL = NSURL(string: img) {
// ... continue with your code ...
}
Please try the following code:
//ImageName is a String type.
guard let ImageName = obj["image"] as? String , let imgURL = NSURL(string: ImageName) else{
return
}
let request: NSURLRequest = NSURLRequest(URL:imgURL)
let session = NSURLSession.sharedSession()
let Imgtask = session.dataTaskWithRequest(request){
(data, response, error) -> Void in
if (error == nil && data != nil)
{
func display_image()
{
pointAnnoation.DisplayImage = UIImage(data: data!)
}
dispatch_async(dispatch_get_main_queue(), display_image)
}
Imgtask.resume()
I'm trying to find a way to load a youtube URL string from parse.com database in my swift application. I have it so when the user clicks on a button that says video it will load the video that is connected to the URL. I can't seem to find out how to make this work though. Any Ideas on how to code this?
In the data base I have the class called Products, than the column name for the video is ProductVideo, and the button in the app is called productVideo.
edit:
// Unwrap the current object object
if let object = currentObject {
productName.text = object["ProductName"] as? String
productDescription.text = object["ProductDescription"] as! String productCategory.text = object["ProductCategory"] as? String
videoStatus.text = object["VideoStatus"] as? String var initialThumbnail = UIImage(named: "question")
ProductImage.image? = initialThumbnail!
if let thumbnail = object["ProductImage"] as? PFFile {
ProductImage.file = thumbnail
ProductImage.loadInBackground() if self.videoStatus.text == "None"{ self.productVideo.hidden = true
self.videoView.hidden = true
}
edit:
// Unwrap the current object object
if let object = currentObject {
productName.text = object["ProductName"] as? String
productDescription.text = object["ProductDescription"] as! String productCategory.text = object["ProductCategory"] as? String
videoStatus.text = object["VideoStatus"] as? String
let youtubeURL = currentObject["ProductVideo"] as! String
let url = NSURL(string: youtubeURL)
if UIApplication.sharedApplication().canOpenURL(url!) {
UIApplication.sharedApplication().openURL(url!)
}
var initialThumbnail = UIImage(named: "question")
ProductImage.image? = initialThumbnail!
if let thumbnail = object["ProductImage"] as? PFFile {
ProductImage.file = thumbnail
ProductImage.loadInBackground()
if self.videoStatus.text == "None"
{
self.productVideo.hidden = true
self.videoView.hidden = true
}
If you have the URL like you say you do, then you can
let youtubeURL = parseObjeect["ProductVideo"] as String
and then
let url = NSURL(string: youtubeURL)
if UIApplication.sharedApplication().canOpenURL(url!) {
UIApplication.sharedApplication().openURL(url!)
}
Note: This will open the Youtube Video in Safari or in YouTube if the user has the App installed.