Extract substring from URL string - swift
I have the following URL string:
eventid=VSl4WcedBNbjqgXe7bzQCw×tamp=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×tamp=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×tamp=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")
}
Related
I am doing a post request where I want to type in a question and with the post request get the most common answer
I have done my Post-request but I am unsure about how to make it possible to send a full question and to get the most common answers back to my app. I am in such a big need of this code in my program so would love to get some examples on how to make it work Have tried to right the question into the parameters with a "+" instead of space which resulted into nothing. #IBAction func GetAnswer(_ sender: Any) { let myUrl = URL(string: "http://www.google.com/search?q="); var request = URLRequest(url:myUrl!) request.httpMethod = "POST" let postString = questionAsked; request.httpBody = postString.data(using: String.Encoding.utf8); let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in if error != nil { print("error=\(String(describing: error))") return } print("response = \(String(describing: response))") do { let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary if let parseJSON = json { let answer = parseJSON[" Answer "] as? String self.AnswerView.text = ("Anwer: \(String(describing: answer))") } } catch { print(error) } } task.resume() }
You do not use google.com/search, please check the api documentation Paste following in Playground, should give a good start struct Constants { static let apiKey = "YOUR_API_KEY" static let bundleId = "YOUR_IOS_APP_BUNDLE_ID" static let searchEngineId = "YOUR_SEARCH_ENGINE_ID" } func googleSearch(term: String, callback:#escaping ([(title: String, url: String)]?) -> Void) { let urlString = String(format: "https://www.googleapis.com/customsearch/v1?q=%#&cx=%#&key=%#", term, Constants.searchEngineId, Constants.apiKey) let encodedUrl = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) guard let url = URL(string: encodedUrl ?? urlString) else { print("invalid url \(urlString)") return } let request = NSMutableURLRequest(url: url, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10) request.httpMethod = "GET" request.setValue(Constants.bundleId, forHTTPHeaderField: "X-Ios-Bundle-Identifier") let session = URLSession.shared let datatask = session.dataTask(with: request as URLRequest) { (data, response, error) in guard error == nil, let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String : Any] else { // error handing here callback(nil) return } guard let items = json["items"] as? [[String : Any]], items.count > 0 else { print("no results") return } callback(items.map { ($0["title"] as! String, $0["formattedUrl"] as! String) }) } datatask.resume() } Usage googleSearch(term: "George Bush") { results in print(results ?? []) } Create a new search engine using following url https://cse.google.com/cse/create/new If you would like search entire web, use following steps edit your engine using https://cse.google.com/cse/setup/basic?cx=SEARCH_ENGINE_ID remove any pages listed under Sites to search turn on Search the entire web
How did swift make web requests
I`m a new swifter ,so can take me some help to use swift to make web requests,thanks. Why can't it be reviewed and submitted。 //创建请求体 let param = ["moblie":"18392387159"] let data = try! JSONSerialization.data(withJSONObject: param, options: JSONSerialization.WritingOptions.prettyPrinted) var string = "json=" let Str = String(data: data, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue)) //拼接 string = string + Str! let Url = URL.init(string: "http://huixin.smartdot.com:9901/GoComWebService/restful/GoComeRestful/getResetCode") let request = NSMutableURLRequest.init(url: Url!) request.timeoutInterval = 30 //请求方式,跟OC一样的 request.httpMethod = "POST" request.httpBody = string.data(using: String.Encoding.utf8) let session = URLSession.shared let dataTask = session.dataTask(with: request as URLRequest) { (data, response, error) -> Void in if (error != nil) { return } else { //此处是具体的解析,具体请移步下面 let json: Any = try! JSONSerialization.jsonObject(with: data!, options: []) if let value = JSON(json)["status"].string { print("状态是:\(value)") } print(json) } } dataTask.resume() i write like this , why it did not work !
I suggest you modify the following code data is not recommended mandatory unpack ,I am here only to help you find the problem quickly to deal with this problem do { let dic = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments) print(dic) } catch { print(error) } Error returned here is Error Domain = NSCocoaErrorDomain Code = 3840 "No value." UserInfo = {NSDebugDescription = No value.} You may ask the parameters of the problem, check their own
Why does post request work much faster from the second call?
I launch the app. Press the button which call this function, wait 2-3 seconds and than get the JSON. Then I press it again, wait 0-1 and then I get the JSON. Can you explain me the reason why it's happening and how can I avoid it? public func serverUserRegister(userPhone: String?, userEmail: String?, completionHandler: #escaping ((String) -> ())) { if let phone = userPhone { if let email = userEmail { let url = URL(string: "https://example.com/service.php")! let session = URLSession.shared let request = NSMutableURLRequest(url: url) request.httpMethod = "POST" request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData let paramString = "phone=\(phone)&email=\(email)" request.httpBody = paramString.data(using: .utf8) let task = session.dataTask(with: request as URLRequest) { (data, response, error) in guard let _: Data = data, let _: URLResponse = response, error == nil else { return } if let json = try? JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary { if let jsonStatus = json?["status"] as? String { completionHandler(jsonStatus) } } } task.resume() } } }
Is it possible to return result set from POST call
I have this code: private func data_request(url : String) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { let url:NSURL = NSURL(string: self.self.newUrl.createUrl(url))! let session = NSURLSession.sharedSession() let request = NSMutableURLRequest(URL: url) request.HTTPMethod = "POST" request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData let paramString = "data=Hello" request.HTTPBody = paramString.dataUsingEncoding(NSUTF8StringEncoding) let task = session.dataTaskWithRequest(request) { ( let data, let response, let error) in guard let _:NSData = data, let _:NSURLResponse = response where error == nil else { print("error") return } let dataString = NSString(data: data!, encoding: NSUTF8StringEncoding) } task.resume() } } I call it like this: var result = data_request("localhost/test"); That is working fine, but is it possible to return the results from the request function? My plan is to put the result in the result variable.
You should use closures to get the data since the NSURLSession API is asynchronous, meaning that you don't know when the data will arrive. It may be instantly or in 10 seconds, you never know. You will return from the function immediately, but you'll get the value from the closure. private func data_request(url : String, completion: (String) -> ()) { //... //... let dataString = NSString(data: data!, encoding: NSUTF8StringEncoding) // Now call completion to pass the value completion(dataString) } And when you need to call the function you will use: data_request("http://someapi.com/api") { dataString in print(dataString) // This is the string you passed to the completion }
URL request using Swift
I have access the "dictionary" moviedb for example : https://www.themoviedb.org/search/remote/multi?query=exterminador%20do%20futuro&language=en How can i catch only the film's name and poster from this page to my project in Swift ?
It's answer :) import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() reload() } private func reload() { let requestUrl = "https://www.themoviedb.org/search/remote/multi?query=exterminador%20do%20futuro&language=en" let config = NSURLSessionConfiguration.defaultSessionConfiguration() let session = NSURLSession(configuration: config) let request = NSURLRequest(URL: NSURL(string: requestUrl)!) let task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in if let error = error { println("###### error ######") } else { if let JSON = NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments, error: nil) as? [NSDictionary] { for movie in JSON { let name = movie["name"] as! String let posterPath = movie["poster_path"] as! String println(name) // "Terminator Genisys" println(posterPath) // "/5JU9ytZJyR3zmClGmVm9q4Geqbd.jpg" } } } }) task.resume() } }
You need to include your api key along with the request. I'd just try something like this to see if it works or not. If it does, then you can go about using the api key in a different way to make it more secure. I wouldn't bother as it's not an api with much sensitive functionality. let query = "Terminator+second" let url = NSURL(string: "http://api.themoviedb.org/3/search/keyword?api_key=YOURAPIKEY&query=\(query)&language=en")! let request = NSMutableURLRequest(URL: url) request.addValue("application/json", forHTTPHeaderField: "Accept") let session = NSURLSession.sharedSession() let task = session.dataTaskWithRequest(request) { data, response, error in if let response = response, data = data { print(response) //DO THIS print(String(data: data, encoding: NSUTF8StringEncoding)) //OR THIS if let o = NSJSONSerialization.JSONObjectWithData(data, options: nil, error:nil) as? NSDictionary { println(dict) } else { println("Could not read JSON dictionary") } } else { print(error) } } task.resume() The response you'll get will have the full list of properties. You need the poster_path and title (or original_title) property of the returned item.