Swift Google search with more than two variables - swift

I'm trying to add a google search to my textfield. I've got it so I can look up one or two variables, but after three it crashes. What do I need to change or add to make it work? Here's my code...
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
var urlString: String = textField.text
var url = NSURL(string: urlString)
if (url != nil) {
url = NSURL(string: "http://www.google.com/search?q=\(urlString)")
var request = NSURLRequest(URL: url!)
self.webView.loadRequest(request)
}
if url?.scheme == nil {
var spaces = urlString.rangeOfString(" ")
var urlStrings = urlString.stringByReplacingCharactersInRange(spaces!, withString: "+")
var url = NSURL(string: "http://www.google.com/search?q=\(urlStrings)")
var request = NSURLRequest(URL: url!)
self.webView.loadRequest(request)
}
return false
}

Your spaces = urlString.rangeOfString(" ") is only finding the first space in the string, and so with a string that has more it will only replace the first space with + and none of the others. You need to use something more along the lines of:
urlString = urlString.replacingOccurrences(of: " ", with: "+")
Here we replace every occurence of the " " character with "+". So to summarise:
var urlString: String = textField.text!
urlString = urlString.replacingOccurrences(of: " ", with: "+")
let url = URL(string: "http://www.google.com/search?q=\(urlString)")
let request = URLRequest(url: url!)
webView.load(request)
n.b. I've force unwrapped some things just for example purposes.
You'll also want to make sure that you trim urlString first in order to remove any excess whitespace (e.g double spaces, or spaces at the beginning and end). See here for how to do that!

Update for Swift 5:
var keyword = "Rhinoceros Beetles"
keyword = keyword.replacingOccurrences(of: " ", with: "+")
This should allow you to open the url properly.

Related

let myUrl = URL(string: returns nil in swift

let adr = "http://www.dummy.com/mobil.aspx?id=\(uyeNo)&kaynak=ios\(ulke)&req=DB2021&list=\(liste)"
let encAdr = adr.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) ?? ""
let myUrl = URL(string: encAdr)
myUrl is always nil. I couldn't find the reason.
I see String Interpolations in your URL string:
\(uyeNo) \(ulke) \(liste)
Have you assigned values on those three? If not, maybe that's the reason why your myURL value returns fatally nil.
Anyways, if above isn't necessarily your case, you may try the following code that may suit your need:
func myCompleteURL(uyeNo: String,ulke:String,liste: String) -> URL {
let adr = "http://www.dummy.com/mobil.aspx?id=\(uyeNo)&kaynak=ios\(ulke)&req=DB2021&list=\(liste)"
let encAdr = adr.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) ?? ""
let myUrl = URL(string: encAdr)
return myUrl!
}
func sampleCallFunction(){
let url = myCompleteURL(uyeNo: "i",ulke: "love",liste: "cats")
print(url)
// Prints: http://www.dummy.com/mobil.aspx?id=i&kaynak=ioslove&req=DB2021&list=cats
}
try! this Updated Answer
let urlString = "http://www.dummy.com/mobil.aspx?id=\(uyeNo)&kaynak=ios\(ulke)&req=DB2021&list=\(liste)"
let urlStringEncoding = urlString.addingPercentEncoding(withAllowedCharacters: .alphanumerics) ?? ""
guard let url = URL(string: urlStringEncoding) else {
return
}
print(url)

Master Detail app in Swift - how to convert string into URL

I'm new here, so please bear with me. I have a Master-Detail app, and in the DetailViewController.swift file, here's the configureView func where it calls a web view to open a web page.
It's complaining on the let request = URLRequest(url:url) line because url variable is defined as a string. I've tried everything but it won't work.
By the way, MasterViewController.MyVariables.urlString is an array of strings.
func configureView() {
// Update the user interface for the detail item.
if let detail: AnyObject = detailItem {
if let myWebview = webView {
let url = MasterViewController.MyVariables.urlString
let request = URLRequest(url: url)
myWebview.scalesPageToFit = true
myWebview.loadRequest(request)
}
}
}
You can either pass an URL object or create an URL object from the string that you´re passing. Anyhow you need to convert your string into an URL.
if let url = URL(string: MasterViewController.MyVariables.urlString) {
// use url in here
}
Update:
Use this for your example:
if let url = URL(string: MasterViewController.MyVariables.urlString) {
// use url in here
let request = URLRequest(url: url)
}
Update 2:
You have your Struct which is an array of strings. Then you need to do this to get the value you want:
struct MyVariables {
static var urlString: [String]? = ["something"]
}
if let str = MyVariables.urlString?.first, let url = URL(string: str) {
// use url in here
let request = URLRequest(url: url)
print(url)
}
Right now I´m using MyVariables.urlString?.first, in the future if you want another index then you need to get that instead.
This is what I did to make it work:
let stringRepresentation = MasterViewController.MyVariables.urlString?.joined(separator:"")
print ("urlString", MasterViewController.MyVariables.urlString)
print ("sR",stringRepresentation)
let url = NSURL(string: stringRepresentation as! String)
let request = URLRequest(url: url! as URL)
myWebview.scalesPageToFit = true
myWebview.loadRequest(request)

Extract substring from URL string

I have the following URL string:
eventid=VSl4WcedBNbjqgXe7bzQCw&timestamp=1501047125&status=ok&ldpj=-23&author=Al+Jazeera+Arabic+قناة+الجزيرة&ptchn=fiwzLy-8yKzIbsmZTzxDgw&live_chunk_readahead=3&video_id=fN2sEo7hq-E&allow_ratings=0&allow_embed=1&token=vThp8hY3AuC-jibt_jf7TEzWnuqUY7oImICFXKxkWbM=&plid=AAVVMcSvP1Tr6SGM&partnerid=27&of=sjG7v9N-R2P9uySMx2Af7Q&live_default_broadcast=1&watermark=,https://s.ytimg.com/yts/img/watermark/youtube_watermark-vflHX6b6E.png,https://s.ytimg.com/yts/img/watermark/youtube_hd_watermark-vflAzLcD6.png&streaminglib_module=1&live_storyboard_spec=https://i.ytimg.com/sb/fN2sEo7hq-E/storyboard_live_60_3x3_b0/M$M.jpg?rs=AOn4CLBoEYL8Dt3Yf1HhjHlpNUAc4jqmSg#106#60#3#3&video_verticals=[881,+397]&csn=VSl4WcedBNbjqgXe7bzQCw&muted=0&length_seconds=1800&hlsdvr=1&videostats_playback_base_url=https://s.youtube.com&title=Al+Jazeera+Arabic+Live+Stream+HD-+البث+الحي+لقناة+الجزيرة+الإخبارية+بجودة+عالية&ptk=aljazeera&iurl=https://i.ytimg.com/vi/fN2sEo7hq-E/hqdefault_live.jpg&vm=CAEQARgE&hlsvp=https://manifest.googlevideo.com/api/manifest/hls_variant/gcr/us/signature/26ADA228BD5549EC76852E925945A6EDBD8A78A9.268E76E7A0831E0DB3C36670FCA24805B0F9AD94/requiressl/yes/source/yt_live_broadcast/key/yt6/ip/72.239.175.191/ipbits/0/maudio/1/playlist_type/DVR/itag/0/expire/1501068725/sparams/gcr,go,id,ip,ipbits,itag,maudio,playlist_type,requiressl,source,expire/go/1/id/fN2sEo7hq-E.0/file/index.m3u8&pltype=contentlive&cl=162900125&iurlmq=https://i.ytimg.com/vi/fN2sEo7hq-E/mqdefault_live.jpg&enable_cardio_before_playback=1&no_get_video_log=1&short_view_count_text=3M+views&avg_rating=4.24240619416&fexp=9422596,9431012,9434289,9441392,9446364,9449243,9457141,9460072,9461821,9463594,9464546,9465833,9466793,9466795,9466797,9466851,9467217,9468797,9468799,9468805,9471755,9475953,9477113,9477691,9478524,9478670,9480034,9480475,9480535,9480795,9481684,9482647,9483080,9484209,9484514,9484643,9484706,9485999&keywords=al+jazeera+tv,al+jazeera+Arabic,الجزيره,اخبار,خبر,free+tv+channels,aljazira,اخبار+الجزيرة,الاسكندرية,الجزيرة+مصر+مباشر,al+jazeera+english+live,aljazeera+tv+live,داعش,العراق,اخبار+العراق,اخبار+سوريا,دمشق,اخبار+مصر,سوريا,بشار+الاسد,عاجل+ليبيا,عاجل,الحصاد,النشرة,نشرة,الاخبار,الاهرام,الوفد,الجزيرة+مباشر,الجمهورية,syria+news,البث+الحي,البث+الحي+لقناة+الجزيرة,جودة+عالية,hd&idpj=-4&c=WEB&innertube_client_version=1.20170718&account_playback_token=QUFFLUhqa3NJenBCUUNnZnBtMHdOb3FLSWE0cG9qQkZBZ3xBQ3Jtc0ttYkdZeEI0TExmQWo1RldLQlFZSGtLTE1wcEJGamNNZnE4UlhDaUpfRGtvSG5WbG1KUHNvbk44T2dtM2NRb0NwWmNZaU9sdGc2MTY3QUg3SldKTmtxOWNzMjVfZ0R5VDYwM1E3RDVQQnNHTU12OVphSQ==&iv3_module=1&iurlhq=https://i.ytimg.com/vi/fN2sEo7hq-E/hqdefault_live.jpg&dashmpd=https://manifest.googlevideo.com/api/manifest/dash/hfr/1/as/fmp4_audio_clear,fmp4_sd_hd_clear/source/yt_live_broadcast/key/yt6/ip/72.239.175.191/expire/1501068725/ipbits/0/signature/D9AC8668BF9CF6B884B618938C9823515B17D8F2.1FDA7E07B2B55FBCCF80C654BA9E0A1F9A48F589/playlist_type/DVR/itag/0/requiressl/yes/sparams/as,gcr,hfr,id,ip,ipbits,itag,playlist_type,requiressl,source,expire/gcr/us/id/fN2sEo7hq-E.0&ypc_ad_indicator=4&ucid=UCfiwzLy-8yKzIbsmZTzxDgw&iv_load_policy=1&iurlmaxres=https://i.ytimg.com/vi/fN2sEo7hq-E/maxresdefault_live.jpg&oid=o0grDQo8XcVLrPz5jByaaQ&iv_invideo_url=https://www.youtube.com/annotations_invideo?cap_hist=1&video_id=fN2sEo7hq-E&ei=VSl4WcedBNbjqgXe7bzQCw&cver=1.20170724&live_playback=1&fmt_list=&auth_timeout=21600000&thumbnail_url=https://i.ytimg.com/vi/fN2sEo7hq-E/default.jpg&root_ve_type=&has_cc=False&is_listed=1&url_encoded_fmt_stream_map=&fresca_module=1&enable_cardio=1&fresca_preroll=1&ypc_license_checker_module=1&iurlsd=https://i.ytimg.com/vi/fN2sEo7hq-E/sddefault_live.jpg&remarketing_url=https://googleads.g.doubleclick.net/pagead/viewthroughconversion/962985656/?backend=player_vars&cname=1&cver=AS3&data=backend%3Dplayer_vars%3Bcname%3D1%3Bcver%3DAS3%3Bptype%3Dview%3Btype%3Dview%3Butuid%3DfiwzLy-8yKzIbsmZTzxDgw%3Butvid%3DfN2sEo7hq-E&foc_id=fiwzLy-8yKzIbsmZTzxDgw&label=followon_view&ptype=view&delay=5&tmi=1&view_count=3025044&use_cipher_signature=False
How do I go about extracting the m3u8 url from the above string? I want it to look like this once done:
hlsvp=https://manifest.googlevideo.com/api/manifest/hls_variant/gcr/us/signature/26ADA228BD5549EC76852E925945A6EDBD8A78A9.268E76E7A0831E0DB3C36670FCA24805B0F9AD94/requiressl/yes/source/yt_live_broadcast/key/yt6/ip/72.239.175.191/ipbits/0/maudio/1/playlist_type/DVR/itag/0/expire/1501068725/sparams/gcr,go,id,ip,ipbits,itag,maudio,playlist_type,requiressl,source,expire/go/1/id/fN2sEo7hq-E.0/file/index.m3u8
I have the following code that stops at this point, as below:
extension ViewController {
/*https://stackoverflow.com/questions/35608686/how-can-i-get-the-actual-video-url-of-a-youtube-live-stream*/
func get_youtube_link(videoID: String) {
let url: URL = URL(string: "https://www.youtube.com/get_video_info?&video_id=fN2sEo7hq-E&el=info&ps=default&eurl=&gl=US&hl=en")!
let session = URLSession.shared
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
let task = session.dataTask(with: request as URLRequest, completionHandler: {(data, response, error) in
// grab the URL returned by YouTube, which is a URL with many parameters
let feedback = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
// convert NSString to String
var newString = String(feedback!)
//https://www.uraimo.com/swiftbites/swift-url-encoding/
newString = newString.removingPercentEncoding!
newString = newString.replacingOccurrences(of: "%2C", with: ",")
print(newString)
})
task.resume()
}
}
This is YouTube's web query data received in RAW format:
partnerid=27&root_ve_type=&c=WEB&iurl=https%3A%2F%2Fi.ytimg.com%2Fvi%2FVmxIA8L3Xz8%2Fhqdefault_live.jpg&of=GC6OCn1lTVgpgJyrp2hYjw&hlsdvr=1&eventid=FEx5We_CJMut4QSH_5OYCw&ypc_license_checker_module=1&auth_timeout=21600000&videostats_playback_base_url=https%3A%2F%2Fs.youtube.com&token=WIs368zOOjdA6jb7Wo5HIeCUIjDqF6aTm40Qf9Lm8xY%3D&csn=FEx5We_CJMut4QSH_5OYCw&plid=AAVVQxkmPLDdDSm-&allow_ratings=1&live_playback=1&live_default_broadcast=1&fexp=9422596%2C9431012%2C9434289%2C9441386%2C9446364%2C9449243%2C9457141%2C9460072%2C9461821%2C9463594%2C9464546%2C9465833%2C9466793%2C9466795%2C9466797%2C9466851%2C9467217%2C9468797%2C9468799%2C9468805%2C9471755%2C9475953%2C9477113%2C9477691%2C9478524%2C9478670%2C9480034%2C9480475%2C9480535%2C9480795%2C9481684%2C9482647%2C9483080%2C9483701%2C9484209%2C9484514%2C9484643%2C9484706%2C9485999&fresca_module=1&idpj=-7&delay=5&iurlmq=https%3A%2F%2Fi.ytimg.com%2Fvi%2FVmxIA8L3Xz8%2Fmqdefault_live.jpg&avg_rating=4.53108348135&ypc_ad_indicator=4&remarketing_url=https%3A%2F%2Fgoogleads.g.doubleclick.net%2Fpagead%2Fviewthroughconversion%2F962985656%2F%3Fbackend%3Dplayer_vars%26cname%3D1%26cver%3DAS3%26foc_id%3DSrZ3UV4jOidv8ppoVuvW9Q%26label%3Dfollowon_view%26ptype%3Dno_rmkt&innertube_client_version=1.20170718&video_verticals=%5B16%2C+396%5D&ldpj=-27&title=euronews+LIVE&tmi=1&watermark=%2Chttps%3A%2F%2Fs.ytimg.com%2Fyts%2Fimg%2Fwatermark%2Fyoutube_watermark-vflHX6b6E.png%2Chttps%3A%2F%2Fs.ytimg.com%2Fyts%2Fimg%2Fwatermark%2Fyoutube_hd_watermark-vflAzLcD6.png&cver=1.20170725&iv3_module=1&no_get_video_log=1&has_cc=False&thumbnail_url=https%3A%2F%2Fi.ytimg.com%2Fvi%2FVmxIA8L3Xz8%2Fdefault.jpg&iv_invideo_url=https%3A%2F%2Fwww.youtube.com%2Fannotations_invideo%3Fcap_hist%3D1%26video_id%3DVmxIA8L3Xz8%26ei%3DFEx5We_CJMut4QSH_5OYCw&author=euronews+%28in+English%29&status=ok&ptk=youtube_none&fresca_preroll=1&iurlsd=https%3A%2F%2Fi.ytimg.com%2Fvi%2FVmxIA8L3Xz8%2Fsddefault_live.jpg&length_seconds=1800&view_count=159557&is_listed=1&vm=CAEQABgE&enable_cardio_before_playback=1&dashmpd=https%3A%2F%2Fmanifest.googlevideo.com%2Fapi%2Fmanifest%2Fdash%2Fas%2Ffmp4_audio_clear%252Cfmp4_sd_hd_clear%2Fgcr%2Fus%2Fexpire%2F1501143156%2Fsignature%2F7779193FA964EC075A94C62E6720B2380AEE39A0.B546BFA286574BA5D7BE116159ACC45130650938%2Fkey%2Fyt6%2Fip%2F72.239.175.191%2Fplaylist_type%2FDVR%2Fitag%2F0%2Fipbits%2F0%2Fsource%2Fyt_live_broadcast%2Frequiressl%2Fyes%2Fhfr%2F1%2Fsparams%2Fas%252Cgcr%252Chfr%252Cid%252Cip%252Cipbits%252Citag%252Cplaylist_type%252Crequiressl%252Csource%252Cexpire%2Fid%2FVmxIA8L3Xz8.0&hlsvp=https%3A%2F%2Fmanifest.googlevideo.com%2Fapi%2Fmanifest%2Fhls_variant%2Fgcr%2Fus%2Fkey%2Fyt6%2Fip%2F72.239.175.191%2Fplaylist_type%2FDVR%2Fexpire%2F1501143156%2Fitag%2F0%2Fsource%2Fyt_live_broadcast%2Fmaudio%2F1%2Fid%2FVmxIA8L3Xz8.0%2Fsparams%2Fgcr%252Cgo%252Cid%252Cip%252Cipbits%252Citag%252Cmaudio%252Cplaylist_type%252Crequiressl%252Csource%252Cexpire%2Fipbits%2F0%2Fgo%2F1%2Frequiressl%2Fyes%2Fsignature%2FB225396C754E6783728F71F0C1AD4CFE9AFC3839.B2C6E2FFCB07B136D4AECFA5A8F001DFEC084543%2Ffile%2Findex.m3u8&timestamp=1501121556&iurlmaxres=https%3A%2F%2Fi.ytimg.com%2Fvi%2FVmxIA8L3Xz8%2Fmaxresdefault_live.jpg&use_cipher_signature=False&live_chunk_readahead=3&iv_load_policy=1&live_storyboard_spec=https%3A%2F%2Fi.ytimg.com%2Fsb%2FVmxIA8L3Xz8%2Fstoryboard_live_60_3x3_b0%2FM%24M.jpg%3Frs%3DAOn4CLBjUwFPDoNQCv904oDJpmFEM5xg7g%23106%2360%233%233&ucid=UCSrZ3UV4jOidv8ppoVuvW9Q&allow_embed=1&pltype=contentugclive&short_view_count_text=159K+views&fmt_list=&keywords=&enable_cardio=1&video_id=VmxIA8L3Xz8&streaminglib_module=1&url_encoded_fmt_stream_map=&cl=162900125&account_playback_token=QUFFLUhqbl9LME8tdzdIT1VJaG1qRk1VZ3U1OFNnMW1PZ3xBQ3Jtc0ttY0dMZWZJdGtkUVNqTjlFWHpubjE2Rjg5OGxlU21fUndLa3Y0THoyMWpGa3ZXWDN2R3JkR1JHS2tEcm51OXhTbTFqYlNGTHVKY1hrOWllcFlHRU9NNHFZTjZNNGRZQjZ1eFc2VGxjMHpScWFDWnUxdw%3D%3D&muted=0&iurlhq=https%3A%2F%2Fi.ytimg.com%2Fvi%2FVmxIA8L3Xz8%2Fhqdefault_live.jpg
So, I found the answer. I'll post it just incase someone needs it.
Here you go: Extract the M3U8 video link from a YouTube live channel in Swift 3
I'd like to point out that Code Different's answer is more elequent than mine. Give them both a try and see what fits your project needs :)
//
// EXT_youtube_JSON.swift
// YoutubeStreamURL
//
// Created by Haitham Alkibsi on 7/25/17.
// Copyright © 2017 Haitham Al-Kibsi. All rights reserved.
//
import Foundation
extension ViewController {
/* https://stackoverflow.com/questions/35608686/how-can-i-get-the-actual-video-url-of-a-youtube-live-stream */
func downloadJSON_youtube(videoID: String) {
let url: URL = URL(string: "https://www.youtube.com/get_video_info?&video_id=\(videoID)&el=info&ps=default&eurl=&gl=US&hl=en")!
let session = URLSession.shared
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
let task = session.dataTask(with: request as URLRequest, completionHandler: {(data, response, error) in
// grab the URL returned by YouTube, which has many parameters
var youtubeReply = String(data: data!, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue))!
// remove percent encoding
//https://www.uraimo.com/swiftbites/swift-url-encoding/
youtubeReply = youtubeReply.removingPercentEncoding!
youtubeReply = youtubeReply.replacingOccurrences(of: "%2C", with: ",")
//https://www.dotnetperls.com/find-swift
let firstResult = youtubeReply.range(of: "hlsvp=", options: NSString.CompareOptions.literal, range: youtubeReply.startIndex..<youtubeReply.endIndex, locale: nil)
if let range = firstResult {
// Start of range of found string.
let start = range.lowerBound
// Display string starting at first index.
var firstExtraction = youtubeReply[start..<youtubeReply.endIndex]
firstExtraction = firstExtraction.chopPrefix(6)
let secondResult = firstExtraction.range(of: ".m3u8", options: NSString.CompareOptions.literal, range: firstExtraction.startIndex..<firstExtraction.endIndex, locale: nil)
if let range2 = secondResult {
let start = range2.lowerBound
let secondExtraction = firstExtraction[firstExtraction.startIndex..<start]
let m3u8_URL = secondExtraction + ".m3u8"
print(m3u8_URL)
}
}
})
task.resume()
}
}
//https://stackoverflow.com/questions/28445917/what-is-the-most-succinct-way-to-remove-the-first-character-from-a-string-in-swi
extension String {
func chopPrefix(_ count: Int = 1) -> String {
return substring(from: index(startIndex, offsetBy: count))
}
func chopSuffix(_ count: Int = 1) -> String {
return substring(to: index(endIndex, offsetBy: -count))
}
}
Your sample data is tortuously long but did not help clarify your question in any way. It's better to come up with Minimum, Complete and Verifiable example.
Now to your question, use URLComponents to extract data from the URL:
// Assuming feedback is what you get back from YouTube
let feedback = "partnerid=27&root_ve_type=&c=WEB&iurl=https%3A%2F%2Fi.ytimg.com%2Fvi%2FVmxIA8L3Xz8%2Fhqdefault_live.jpg&of=GC6OCn1lTVgpgJyrp2hYjw&hlsdvr=1&eventid=FEx5We_CJMut4QSH_5OYCw&ypc_license_checker_module=1&auth_timeout=21600000&videostats_playback_base_url=https%3A%2F%2Fs.youtube.com&token=WIs368zOOjdA6jb7Wo5HIeCUIjDqF6aTm40Qf9Lm8xY%3D&csn=FEx5We_CJMut4QSH_5OYCw&plid=AAVVQxkmPLDdDSm-&allow_ratings=1&live_playback=1&live_default_broadcast=1&fexp=9422596%2C9431012%2C9434289%2C9441386%2C9446364%2C9449243%2C9457141%2C9460072%2C9461821%2C9463594%2C9464546%2C9465833%2C9466793%2C9466795%2C9466797%2C9466851%2C9467217%2C9468797%2C9468799%2C9468805%2C9471755%2C9475953%2C9477113%2C9477691%2C9478524%2C9478670%2C9480034%2C9480475%2C9480535%2C9480795%2C9481684%2C9482647%2C9483080%2C9483701%2C9484209%2C9484514%2C9484643%2C9484706%2C9485999&fresca_module=1&idpj=-7&delay=5&iurlmq=https%3A%2F%2Fi.ytimg.com%2Fvi%2FVmxIA8L3Xz8%2Fmqdefault_live.jpg&avg_rating=4.53108348135&ypc_ad_indicator=4&remarketing_url=https%3A%2F%2Fgoogleads.g.doubleclick.net%2Fpagead%2Fviewthroughconversion%2F962985656%2F%3Fbackend%3Dplayer_vars%26cname%3D1%26cver%3DAS3%26foc_id%3DSrZ3UV4jOidv8ppoVuvW9Q%26label%3Dfollowon_view%26ptype%3Dno_rmkt&innertube_client_version=1.20170718&video_verticals=%5B16%2C+396%5D&ldpj=-27&title=euronews+LIVE&tmi=1&watermark=%2Chttps%3A%2F%2Fs.ytimg.com%2Fyts%2Fimg%2Fwatermark%2Fyoutube_watermark-vflHX6b6E.png%2Chttps%3A%2F%2Fs.ytimg.com%2Fyts%2Fimg%2Fwatermark%2Fyoutube_hd_watermark-vflAzLcD6.png&cver=1.20170725&iv3_module=1&no_get_video_log=1&has_cc=False&thumbnail_url=https%3A%2F%2Fi.ytimg.com%2Fvi%2FVmxIA8L3Xz8%2Fdefault.jpg&iv_invideo_url=https%3A%2F%2Fwww.youtube.com%2Fannotations_invideo%3Fcap_hist%3D1%26video_id%3DVmxIA8L3Xz8%26ei%3DFEx5We_CJMut4QSH_5OYCw&author=euronews+%28in+English%29&status=ok&ptk=youtube_none&fresca_preroll=1&iurlsd=https%3A%2F%2Fi.ytimg.com%2Fvi%2FVmxIA8L3Xz8%2Fsddefault_live.jpg&length_seconds=1800&view_count=159557&is_listed=1&vm=CAEQABgE&enable_cardio_before_playback=1&dashmpd=https%3A%2F%2Fmanifest.googlevideo.com%2Fapi%2Fmanifest%2Fdash%2Fas%2Ffmp4_audio_clear%252Cfmp4_sd_hd_clear%2Fgcr%2Fus%2Fexpire%2F1501143156%2Fsignature%2F7779193FA964EC075A94C62E6720B2380AEE39A0.B546BFA286574BA5D7BE116159ACC45130650938%2Fkey%2Fyt6%2Fip%2F72.239.175.191%2Fplaylist_type%2FDVR%2Fitag%2F0%2Fipbits%2F0%2Fsource%2Fyt_live_broadcast%2Frequiressl%2Fyes%2Fhfr%2F1%2Fsparams%2Fas%252Cgcr%252Chfr%252Cid%252Cip%252Cipbits%252Citag%252Cplaylist_type%252Crequiressl%252Csource%252Cexpire%2Fid%2FVmxIA8L3Xz8.0&hlsvp=https%3A%2F%2Fmanifest.googlevideo.com%2Fapi%2Fmanifest%2Fhls_variant%2Fgcr%2Fus%2Fkey%2Fyt6%2Fip%2F72.239.175.191%2Fplaylist_type%2FDVR%2Fexpire%2F1501143156%2Fitag%2F0%2Fsource%2Fyt_live_broadcast%2Fmaudio%2F1%2Fid%2FVmxIA8L3Xz8.0%2Fsparams%2Fgcr%252Cgo%252Cid%252Cip%252Cipbits%252Citag%252Cmaudio%252Cplaylist_type%252Crequiressl%252Csource%252Cexpire%2Fipbits%2F0%2Fgo%2F1%2Frequiressl%2Fyes%2Fsignature%2FB225396C754E6783728F71F0C1AD4CFE9AFC3839.B2C6E2FFCB07B136D4AECFA5A8F001DFEC084543%2Ffile%2Findex.m3u8&timestamp=1501121556&iurlmaxres=https%3A%2F%2Fi.ytimg.com%2Fvi%2FVmxIA8L3Xz8%2Fmaxresdefault_live.jpg&use_cipher_signature=False&live_chunk_readahead=3&iv_load_policy=1&live_storyboard_spec=https%3A%2F%2Fi.ytimg.com%2Fsb%2FVmxIA8L3Xz8%2Fstoryboard_live_60_3x3_b0%2FM%24M.jpg%3Frs%3DAOn4CLBjUwFPDoNQCv904oDJpmFEM5xg7g%23106%2360%233%233&ucid=UCSrZ3UV4jOidv8ppoVuvW9Q&allow_embed=1&pltype=contentugclive&short_view_count_text=159K+views&fmt_list=&keywords=&enable_cardio=1&video_id=VmxIA8L3Xz8&streaminglib_module=1&url_encoded_fmt_stream_map=&cl=162900125&account_playback_token=QUFFLUhqbl9LME8tdzdIT1VJaG1qRk1VZ3U1OFNnMW1PZ3xBQ3Jtc0ttY0dMZWZJdGtkUVNqTjlFWHpubjE2Rjg5OGxlU21fUndLa3Y0THoyMWpGa3ZXWDN2R3JkR1JHS2tEcm51OXhTbTFqYlNGTHVKY1hrOWllcFlHRU9NNHFZTjZNNGRZQjZ1eFc2VGxjMHpScWFDWnUxdw%3D%3D&muted=0&iurlhq=https%3A%2F%2Fi.ytimg.com%2Fvi%2FVmxIA8L3Xz8%2Fhqdefault_live.jpg"
let urlString = "https://www.youtube.com?" + feedback
let components = URLComponents(string: urlString)!
if let queryItems = components.queryItems,
let hlsvp = queryItems.first(where: { $0.name == "hlsvp" })
{
print(hlsvp.value!)
} else {
print("hlsvp not found")
}

Why is the URL error occurring?

I am using the iTunes search API, and for testing I am searching for "Angry Birds" and printing the results. But when I convert the urlPath into NSURL I get a nil value. How do I fix this? The urlPath has the link, but it is nil in the url variable. This is the exact error:
fatal error: unexpectedly found nil while unwrapping an Optional value.
var searchTerm: String = "Angry Birds"
var itunesSearchTerm = searchTerm.stringByReplacingOccurrencesOfString(" ", withString: "+", options: NSStringCompareOptions.CaseInsensitiveSearch, range: nil)
var escapedSearchTerm = itunesSearchTerm.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
var urlPath = "https://itunes.apple.com/search?term=\(escapedSearchTerm)&media=software"
var url: NSURL = NSURL(string: urlPath)!
var request: NSURLRequest = NSURLRequest(URL: url)
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)!
print("Search iTunes API at URL \(url)")
connection.start()
stringByAddingPercentEscapesUsingEncoding returns an Optional String, so what you get is actually this:
https://itunes.apple.com/search?term=Optional("Angry+Birds")&media=software
The solution is to safely unwrap the Optional:
if let escapedSearchTerm = itunesSearchTerm.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding) {
let urlPath = "https://itunes.apple.com/search?term=\(escapedSearchTerm)&media=software"
let url = NSURL(string: urlPath)
// ...
}
Result:
https://itunes.apple.com/search?term=Angry+Birds&media=software
NSURL returns nil when URL contain illegal characters like space. Verify that your URlString is correct one.

Converting URL to String and back again

So I have converted an NSURL to a String.
So if I println it looks like file:///Users/... etc.
Later I want this back as an NSURL so I try and convert it back as seen below, but I lose two of the forward slashes that appear in the string version above, that in turn breaks the code as the url is invalid.
Why is my conversion back to NSURL removing two forward slashes from the String I give it, and how can I convert back to the NSURL containing three forward slashes?
var urlstring: String = recordingsDictionaryArray[selectedRow]["path"] as String
println("the url string = \(urlstring)")
// looks like file:///Users/........etc
var url = NSURL.fileURLWithPath(urlstring)
println("the url = \(url!)")
// looks like file:/Users/......etc
In Swift 5, Swift 4 and Swift 3
To convert String to URL:
URL(string: String)
or,
URL.init(string: "yourURLString")
And to convert URL to String:
URL.absoluteString
The one below converts the 'contents' of the url to string
String(contentsOf: URL)
fileURLWithPath() is used to convert a plain file path (e.g. "/path/to/file") to an URL. Your urlString is a full URL string including the scheme, so you should use
let url = NSURL(string: urlstring)
to convert it back to NSURL. Example:
let urlstring = "file:///Users/Me/Desktop/Doc.txt"
let url = NSURL(string: urlstring)
println("the url = \(url!)")
// the url = file:///Users/Me/Desktop/Doc.txt
There is a nicer way of getting the string version of the path from the NSURL in Swift:
let path:String = url.path
2021 | SWIFT 5.1:
FOR LOCAL PATHS
String --> URL :
let url1 = URL(fileURLWithPath: "//Users/Me/Desktop/Doc.txt")
let url2 = URL(fileURLWithPath: "//Users/Me/Desktop", isDirectory: true)
// !!!!!NEVER DO THIS!!!!!!
let url3 = URL(string: "file:///Users/Me/Desktop/Doc.txt")!
// !!!!!NEVER DO THIS!!!!!!
URL --> String :
let a = String(describing: url1) // "file:////Users/Me/Desktop/Doc.txt"
let b = "\(url1)" // "file:////Users/Me/Desktop/Doc.txt"
let c = url1.absoluteString // "file:////Users/Me/Desktop/Doc.txt"
// Best solution in most cases
let d = url1.path // "/Users/Me/Desktop/Doc.txt"
FOR INTERNET URLs
String --> URL :
let url = URL(string: "https://stackoverflow.com/questions/27062454/converting-url-to-string-and-back-again")!
URL --> String :
url.absoluteString // https://stackoverflow.com/questions/27062454/converting-url-to-string-and-back-again
url.path // /questions/27062454/converting-url-to-string-and-back-again
NOTICE: pay attention to the url, it's optional and it can be nil.
You can wrap your url in the quote to convert it to a string. You can test it in the playground.
Update for Swift 5, Xcode 11:
import Foundation
let urlString = "http://ifconfig.me"
// string to url
let url = URL(string: urlString)
//url to string
let string = "\(url)"
// if you want the path without `file` schema
// let string = url.path
let url = URL(string: "URLSTRING HERE")
let anyvar = String(describing: url)
Swift 3 (forget about NSURL).
let fileName = "20-01-2017 22:47"
let folderString = "file:///var/mobile/someLongPath"
To make a URL out of a string:
let folder: URL? = Foundation.URL(string: folderString)
// Optional<URL>
// ▿ some : file:///var/mobile/someLongPath
If we want to add the filename. Note, that appendingPathComponent() adds the percent encoding automatically:
let folderWithFilename: URL? = folder?.appendingPathComponent(fileName)
// Optional<URL>
// ▿ some : file:///var/mobile/someLongPath/20-01-2017%2022:47
When we want to have String but without the root part (pay attention that percent encoding is removed automatically):
let folderWithFilename: String? = folderWithFilename.path
// ▿ Optional<String>
// - some : "/var/mobile/someLongPath/20-01-2017 22:47"
If we want to keep the root part we do this (but mind the percent encoding - it is not removed):
let folderWithFilenameAbsoluteString: String? = folderWithFilenameURL.absoluteString
// ▿ Optional<String>
// - some : "file:///var/mobile/someLongPath/20-01-2017%2022:47"
To manually add the percent encoding for a string:
let folderWithFilenameAndEncoding: String? = folderWithFilename.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
// ▿ Optional<String>
// - some : "/var/mobile/someLongPath/20-01-2017%2022:47"
To remove the percent encoding:
let folderWithFilenameAbsoluteStringNoEncodig: String? = folderWithFilenameAbsoluteString.removingPercentEncoding
// ▿ Optional<String>
// - some : "file:///var/mobile/someLongPath/20-01-2017 22:47"
The percent-encoding is important because URLs for network requests need them, while URLs to file system won't always work - it depends on the actual method that uses them. The caveat here is that they may be removed or added automatically, so better debug these conversions carefully.
Swift 3 version code:
let urlString = "file:///Users/Documents/Book/Note.txt"
let pathURL = URL(string: urlString)!
print("the url = " + pathURL.path)
Swift 5.
To convert a String to a URL:
let stringToURL = URL(string: "your-string")
To convert a URL to a String:
let urlToString = stringToURL?.absoluteString
Swift 3 used with UIWebViewDelegate shouldStartLoadWith
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
let urlPath: String = (request.url?.absoluteString)!
print(urlPath)
if urlPath.characters.last == "#" {
return false
}else{
return true
}
}