I am trying to download webcontent for a weather app that I am making. When I run the app the source code on the website does not appear on my Xcode. I also updated my info.plist to accept web content.
Do you have an idea on what the problem is and how I can solve it?
I have a copied my code below:
override func viewDidLoad() {
super.viewDidLoad()
let url = NSURL(string: "http://weather.weatherbug.com/weather-forecast/now/abuja")!
let request = NSMutableURLRequest(url:url as URL)
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
if error != nil{
print(error.debugDescription)
}
else {
if let unwrappedData = data{
let dataString = NSString(data: unwrappedData, encoding: String.Encoding.utf8.rawValue)
print(dataString as Any)
}
}
}
task.resume()
}
Change your url to use https and it should work.
let url = NSURL(string: "https://weather.weatherbug.com/weather-forecast/now/abuja")!
Here's an example in Swift 4 for downloading a document and parsing as JSON:
// If you're doing this in an Xcode Playground, uncomment these lines:
// import XCPlayground
// XCPSetExecutionShouldContinueIndefinitely()
let url = URL(string: "http://json-schema.org/example/geo.json")!
let task = URLSession.shared.dataTask(with: url) {
data, response, error in
guard error == nil else { return }
guard data != nil else { return }
guard (response as? HTTPURLResponse)?.statusCode == 200 else { return }
do {
if let json = try JSONSerialization.jsonObject(with: data!, options: []) as? [String: Any] {
print(json)
}
} catch { return }
}
task.resume()
Use "if let" instead of only "let" and it should work.
if let url = URL(string:"http://weather.weatherbug.com/weather-forecast/now/abuja"){
let request = NSMutableURLRequest(url: url)
let task = URLSession.shared.dataTask(with: request as URLRequest){
data, responds, error in
if error != nil{
print(error!)
} else {
if let unwrappedData = data {
let dataString = NSString(data: unwrappedData, encoding: String.Encoding.utf8.rawValue)
print(dataString!)
DispatchQueue.main.sync(execute: {
})
}
}
}
task.resume()
}
Use
let myURLString = "http://weather.weatherbug.com/weather-forecast/now/abuja"
guard let myURL = URL(string: myURLString) else {
print("Error: \(myURLString) doesn't seem to be a valid URL")
return
}
do {
let myHTMLString = try String(contentsOf: myURL, encoding: .ascii)
print("HTML : \(myHTMLString)")
} catch let error {
print("Error: \(error)")
}
From Link
Related
I'm trying to get results from an API, and I'm having trouble running the request itself.
Here is the code I currently have:
let url = URL(string: "https://httpbin.org/get")!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if let error = error {
print("error: \(error)")
} else {
if let response = response as? HTTPURLResponse {
print("statusCode: \(response.statusCode)")
}
if let data = data, let dataString = String(data: data, encoding: .utf8) {
print("data: \(dataString)")
}
}
}
task.resume()
However, it doesn't seem to run anything inside the code block in dataTask.
Thanks for your help :)
Your code works well. It seems like you're just calling the function incorrectly...try it this way:
1:
func request() {
let url = URL(string: "https://httpbin.org/get")!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if let error = error {
print("error: \(error)")
} else {
if let response = response as? HTTPURLResponse {
print("statusCode: \(response.statusCode)")
}
if let data = data, let dataString = String(data: data, encoding: .utf8) {
print("data: \(dataString)")
}
}
}
task.resume()
}
2:
override func viewDidLoad() {
super.viewDidLoad()
request()
}
This is the Url I am requesting for :
https://api.rss2json.com/v1/api.json?rss_url=https%3A%2F%2Fwww.theverge.com%2Frss%2Findex.xml&api_key=u3vl3sxdva2cch7jjyrnynvwlhjycjrizhcsgmmq
If you run this on browser, it works fine and gives a JSON response. However I get this error in the catch block on running the following code : URLSession parameters must be valid :
let callURL = URL.init(string: urlString) // urlString is the above url
var request = URLRequest.init(url: callURL!)
request.addValue(ContentType_ApplicationJson, forHTTPHeaderField: HTTPHeaderField_ContentType)
request.httpMethod = HTTPMethod_Get
let dataTask = urlSession.dataTask(with: request) { (data,response,error) in
if error != nil{
completion(nil)
return
}
do {
if let resultJson = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary{
print("Result",resultJson)
if let news = resultJson.value(forKeyPath: "articles") as? [NSDictionary]{
print("News",news)
completion(news)
return
}
}
} catch {
print("Error -> \(error)")
}
}
dataTask.resume()
I am not sure what is wrong in your code but I have tested your above code in playground I am getting news below is the code
import Foundation
import UIKit
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
let urlString = "https://api.rss2json.com/v1/api.json?rss_url=https%3A%2F%2Fwww.theverge.com%2Frss%2Findex.xml&api_key=u3vl3sxdva2cch7jjyrnynvwlhjycjrizhcsgmmq"
let callURL = URL.init(string: urlString) // urlString is the above url
var request = URLRequest.init(url: callURL!)
request.addValue("Content-Type", forHTTPHeaderField: "application/json")
request.httpMethod = "GET"
let dataTask = URLSession.shared.dataTask(with: request) { (data,response,error) in
let res = response as! HTTPURLResponse
print(res)
if error != nil{
print(error!)
return
}
do {
if let resultJson = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary{
print("Result",resultJson)
if let news = resultJson.value(forKeyPath: "articles") as? [NSDictionary]{
print("News",news)
return
}
}
} catch {
print("Error -> \(error)")
}
}
dataTask.resume()
This worked with me
let callURL = URL.init(string: "https://api.rss2json.com/v1/api.json?rss_url=https%3A%2F%2Fwww.theverge.com%2Frss%2Findex.xml&api_key=u3vl3sxdva2cch7jjyrnynvwlhjycjrizhcsgmmq") // urlString is the above url
var request = URLRequest.init(url: callURL!)
request.httpMethod = HTTPMethod.get.rawValue
let dataTask = URLSession.shared.dataTask(with: request) { (data,response,error) in
if error != nil{
print(error)
}
do {
if let resultJson = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary{
print("Result",resultJson)
if let news = resultJson.value(forKeyPath: "articles") as? [NSDictionary]{
print("News",news)
return
}
}
} catch {
print("Error -> \(error)")
}
}
dataTask.resume()
You don't need an URLRequest for a GET request, it's the default, just pass the URL
This works, however there is no value for key articles
let urlString = "https://api.rss2json.com/v1/api.json?rss_url=https%3A%2F%2Fwww.theverge.com%2Frss%2Findex.xml&api_key=u3vl3sxdva2cch7jjyrnynvwlhjycjrizhcsgmmq"
let callURL = URL(string: urlString)!
let dataTask = URLSession.shared.dataTask(with: callURL) { (data,response,error) in
if error != nil { return }
do {
if let resultJson = try JSONSerialization.jsonObject(with: data!) as? [String:Any] {
print("Result",resultJson)
// if let news = resultJson["articles"] as? [[String:Any]] {
// print("News",news.count)
// return
// }
}
} catch {
print("Error -> \(error)")
}
}
dataTask.resume()
And – as always – do not use NSDictionary and valueForKey in Swift and .allowFragments is pointless if the root object is a collection type.
Iam getting an error while i try to send the POST request in swift 3. Any one please suggest me the correct syntax for URLSession.shared method in swift 3. this is what i tried. iam new here.
let task = URLSession.shared.dataTask(with: request, completionHandler: {
(data, response, error) in
if error != nil{
print("error");
return
}
do{
let myjson = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parsejson = myjson{
var msg: String!
msg = parsejson["message"] as! String?
print(msg)
}catch error {
print ("")
}
}
})
task.resume().
Here's working URLSession.shared code. I don't have your URL so I used one that is online, free, and produces JSON:
let someURL = URL(string:"https://jsonplaceholder.typicode.com/posts/2")!
let request = URLRequest(url: someURL)
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if error != nil {
print("error")
return
}
guard let data = data else {
print("No data")
return
}
do {
if let myjson = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? Dictionary<String,Any> {
if let title = myjson["title"] {
print("Title was \"\(title)\"")
}
}
} catch {
print("Error parsing JSON: \(error)")
}
}
task.resume()
This outputs Title was "qui est esse" for me.
I need to parse JSON from 2 different URL's
let jsonUrlStr1 = "https://123"
let jsonUrlStr2 = "https://325"
guard let url1 = URL(string: jsonUrlStr1) else { return }
guard let url2 = URL(string: jsonUrlStr2) else { return }
Here I'm running session for 1st url:
URLSession.shared.dataTask(with: url1) { (data, response, err) in
if err != nil {
print("Error:\(String(describing: err))")
}
guard let data = data else { return }
do {
let myData1 = try JSONDecoder().decode(SomeJsonModel1.self, from: data)
//Some code
} catch let jsonErr {
print("Error:\(jsonErr)")
}
}.resume()//URLSession
And then again, I'm running another session for 2nd url, using the same way:
URLSession.shared.dataTask(with: url2) { (data, response, err) in
if err != nil {
print("Error:\(String(describing: err))")
}
guard let data = data else { return }
do {
let myData2 = try JSONDecoder().decode(SomeJsonModel2.self, from: data)
//Some code
} catch let jsonErr {
print("Error:\(jsonErr)")
}
}.resume()//URLSession
This code works and I get the result.
But I think there should be a more correct way to parse 2 URLs.
Please advise how to do it correctly. Thanks.
You can try using completion block like this :
func getDataFromJson(url: String, completion: #escaping (_ success: [String : Any]) -> Void) {
let request = URLRequest(url: URL(string: url)!)
let task = URLSession.shared.dataTask(with: request) { Data, response, error in
guard let data = Data, error == nil else { // check for fundamental networking error
print("error=\(String(describing: error))")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print(response!)
return
}
let responseJSON = try! JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String : Any]
completion(responseJSON)
}
task.resume()
}
and call method like this :
let jsonUrlStr1 = "https://123"
let jsonUrlStr2 = "https://325"
getDataFromJson(url: jsonUrlStr1, completion: { response in
print("JSON response for url1 :: ",response) // once jsonUrlStr1 get it's response call next API
getDataFromJson(url: jsonUrlStr2, completion: { response in
print("JSON response for url2 :: ",response)
})
})
I have JSON looking like this:
{"posts":
[
{
"id":"1","title":"title 1"
},
{
"id":"2","title":"title 2"
},
{
"id":"3","title":"title 3"
},
{
"id":"4","title":"title 4"
},
{
"id":"5","title":"title 5"
}
],
"text":"Some text",
"result":1
}
How can I parse that JSON with Swift 3?
I have this:
let url = URL(string: "http://domain.com/file.php")!
let request = URLRequest(url: url)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print("request failed \(error)")
return
}
do {
if let json = try JSONSerialization.jsonObject(with: data) as? [String: String], let result = json["result"] {
// Parse JSON
}
} catch let parseError {
print("parsing error: \(parseError)")
let responseString = String(data: data, encoding: .utf8)
print("raw response: \(responseString)")
}
}
task.resume()
}
Use this to parse your data:
let url = URL(string: "http://example.com/file.php")
URLSession.shared.dataTask(with:url!, completionHandler: {(data, response, error) in
guard let data = data, error == nil else { return }
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String:Any]
let posts = json["posts"] as? [[String: Any]] ?? []
print(posts)
} catch let error as NSError {
print(error)
}
}).resume()
Use guard to check if you have data and that error is empty.
Swift 5.x version
let url = URL(string: "http://example.com/file.php")
URLSession.shared.dataTask(with:url!, completionHandler: {(data, response, error) in
guard let data = data, error == nil else { return }
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String:Any]
let posts = json?["posts"] as? [[String: Any]] ?? []
print(posts)
} catch {
print(error)
}
}).resume()
In swift 3.0 for GET method:
var request = URLRequest(url: URL(string: "Your URL")!)
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(String(describing: error))")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(String(describing: responseString))")
}
task.resume()
In swift 3.0 for POST method:
var request = URLRequest(url: URL(string: "Your URL")!)
request.httpMethod = "POST"
let postString = "user_name=ABC" // Your parameter
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(String(describing: error))")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(String(describing: responseString))")
}
task.resume()
Because your data structure of test json should be "[String: AnyObject]". The json key "posts" value is Array type.
DISTANCE--DIFFICULT API
========================>
class ViewController: UIViewController {
var get_data = NSMutableData()
var get_dest = NSArray()
var org_add = NSArray()
var row_arr = NSArray()
var ele_arr = NSArray()
var ele_dic = NSDictionary()
var dist_dic = NSDictionary()
var dur_dic = NSDictionary()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
getmethod()
}
func getmethod()
{
let url_str = URL(string: "https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&departure_time=1408046331&origins=37.407585,-122.145287&destinations=37.482890,-122.150235")
let url_req = URLRequest(url: url_str!)
let task = URLSession.shared.dataTask(with: url_req) { (data, response, error) in
if let my_data = data
{
print("my data is----->",my_data)
do
{
self.get_data.append(my_data)
let jsondata = try JSONSerialization.jsonObject(with: self.get_data as Data, options: [])as! NSDictionary
print("json data is--->",jsondata)
self.get_dest = jsondata.object(forKey: "destination_addresses")as! NSArray
let get_dest1:String = self.get_dest.object(at: 0) as! String
print("destination is--->",get_dest1)
self.org_add = jsondata.object(forKey: "origin_addresses")as! NSArray
let get_org:String = self.org_add.object(at: 0)as! String
print("original address is--->",get_org)
self.row_arr = jsondata.object(forKey: "rows")as! NSArray
let row_dic = self.row_arr.object(at: 0)as! NSDictionary
self.ele_arr = row_dic.object(forKey: "elements")as! NSArray
self.ele_dic = self.ele_arr.object(at: 0)as! NSDictionary
self.dist_dic = self.ele_dic.value(forKey: "distance")as! NSDictionary
print("distance text is--->",self.dist_dic.object(forKey: "text")as! String)
print("distance value is--->",self.dist_dic.object(forKey: "value")as! Int)
// self.ele_dic = self.ele_arr.object(at: 1)as! NSDictionary
self.dur_dic = self.ele_dic.value(forKey: "duration")as! NSDictionary
print("duration text--->",self.dur_dic.value(forKey: "text")as! String)
print("duration value--->",self.dur_dic.value(forKey: "value")as! Int)
print("status---->",self.ele_dic.object(forKey: "status")as! String)
}
catch
{
print("error is--->",error.localizedDescription)
}
}
};task.resume()
}