URLSession datatask accessing older version of website? - ios

I am using URLSession to scrape JSON data from my website. My code was throwing various errors relating to casting types, so I added some print statements to my code and found that this function is for some reason accessing an older version of my site. I have since updated the website's data, and verified that the new data is displaying properly both through visiting the website myself and using Rested. However, the print statements in the code below yield old data. The code does not read data from the disk so I am not sure why this is happening.
I have removed the website's link from my code for privacy purposes, but otherwise the function can be found below.
func websiteToDisk() {
let config = URLSessionConfiguration.default
config.waitsForConnectivity = true
let defaultSession = URLSession(configuration: config)
let url = URL(string: someURL)
let task = defaultSession.dataTask(with: url!) { data, response, error in
do {
print("Getting information from website")
if let error = error {
print(error.localizedDescription)
} else if let data = data,
let response = response as? HTTPURLResponse,
response.statusCode == 200 {
//do {
let jsonDecoder = JSONDecoder()
print("about to dcode")
let decodedData = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]//try jsonDecoder.decode([String: [String]].self, from: data)
print(decodedData)
print("accessing dictionary")
print(decodedData!["busLoops"])
let toWrite = decodedData!["busLoops"] as! [String]
let documentDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let busLoopsURL = documentDirectoryURL.appendingPathComponent("busLoops").appendingPathExtension("json")
let jsonEncoder = JSONEncoder()
let jsonData = try jsonEncoder.encode(toWrite)
try jsonData.write(to: busLoopsURL)
//} catch { print(error)}
}
}
catch { print(error)}
}
task.resume()
}

Try ignore local cache data
guard let url = URL(string: "http://....") else{
return
}
let request = NSMutableURLRequest(url: url)
request.cachePolicy = .reloadIgnoringCacheData
let task = URLSession.shared.dataTask(with: request as URLRequest) { (data, resp, error) in
}
task.resume()

Related

URLRequest in Swift5

I'm using the OpenWeather Current Weather Data Api, and trying to make a url request to get json data from the api in Swift5. I need to print the json data. Here is some code I found on the internet that I have been trying to use, but has not been working.
Note: I do NOT want to use any external libraries. like alamofire.
let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?lat=35&lon=139&appid={APIKEY}")!
var request = URLRequest(url: url)
let session = URLSession.shared
let task = session.dataTask(with: request) { (data, response, error) in
if let error = error {
print(error)
} else if let data = data {
print(data)
} else {
print("nope")
}
}
task.resume()
The Openweathermap API documentation is a bit misleading, the expression {API key} indicates the API key without the braces.
Insert the key with String Interpolation
let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?lat=35&lon=139&appid=\(APIKEY)")!
The URLRequest is not needed and dataTask returns either valid data or an error
let task = URLSession.shared.dataTask(with: url) { (data, _, error) in
if let error = error { print(error); return }
print(String(data: data!, encoding: .utf8)!)
}
task.resume()
To display the data create an appropriate model and decode the data with JSONDecoder
So, at first you should be aware that you are registered and already have your own API Key. The main reason that can occur here for not opening link is that You are using a Free subscription and try requesting data available in other subscriptions . And for future if you want to do just get request you don't need to do session.dataTask(with: request), the session.dataTask(with: url) will be OK.)
Here is simpler way of your code.
guard let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?lat=35&lon=139&appid={APIKEY}") else {return}
let session = URLSession.shared
let task = session.dataTask(with: url) { (data, response, error) in
if let error = error {
print(error)
} else if let data = data {
print(data)
} else {
print("nope")
}
}
task.resume()
Not all APIs work with just URL
So if the API has a header in request, try this code.
Note: The header are dependent on your API.
let semaphore = DispatchSemaphore (value: 0)
let param = [
"language": "english",
"serviceRequestId": 1,
"location": ["latitude": "12.34","longitude": "12.34"]
] as [String : Any]
var request = URLRequest(url: URL(string: "UrlHere")!,timeoutInterval: Double.infinity)
request.addValue("tokenHere", forHTTPHeaderField: "Authorization")
do{
let i = try JSONSerialization.data(withJSONObject: param, options: .prettyPrinted)
// print("\(type(of: i))")
print(String(data: i,
encoding: .ascii) ?? "nil")
request.httpMethod = "POST"
request.httpBody = i
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print(String(describing: error))
semaphore.signal()
return
}
semaphore.signal()
do{
let postData = try JSONDecoder().decode(ModelRootClassHere.self, from: data)
print(postData)
MyData = postData
completion()
}
catch{
print(error)
print("error............")
}
}
task.resume()
semaphore.wait()
}catch{
print(error)
}

Why not getting response from one URL?

I am using URLSession. I am not receiving any error or response.
It works with one url. However it does not work with one another.
I have also tried percentencoding. But it doesn't work too.
The code is below
let urlString = "https://stark-spire-93433.herokuapp.com/json"//This is not working
//let urlString = "https://jsonplaceholder.typicode.com/todos"//This is working
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)//URLSession.shared
var request = URLRequest(url: URL(string:urlString)!)
request.httpMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try? JSONSerialization.data(withJSONObject: [], options: [])
let task = session.dataTask(with: request, completionHandler: { data, response, error -> Void in
print("response---",response)
print("error--",error)
if data != nil {
let json = try? JSONSerialization.jsonObject(with: data!)
print("JSOn",json)
} else {
print("error data is nil")
}
})
task.resume()
Too cumbersome code.
This is sufficient
let url = URL(string:"https://stark-spire-93433.herokuapp.com/json")!
let task = URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data else { print(error!); return }
do {
let json = try JSONSerialization.jsonObject(with: data)
print("JSOn",json)
} catch {
print(error)
}
}
task.resume()

how to send files with url in device in swift 3?

I have a mini file manager in my app that user can copy files with iTunes - FileSharing into the app and then upload them to the server
I used post Method But Didn't worked for me! I got the files url in the device But I don't know this way that I choose is right or not
here is the file detection codes
// Get the document directory url
let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
do {
// Get the directory contents urls (including subfolders urls)
let directoryContents = try FileManager.default.contentsOfDirectory(at: documentsUrl, includingPropertiesForKeys: nil, options: [])
print(directoryContents)
// if you want to filter the directory contents you can do like this:
let pdfFiles = directoryContents.filter{ $0.pathExtension == "pdf" }
print("pdf urls:",pdfFiles)
filesurl = pdfFiles
print(pdfFiles.count)
filesCount = pdfFiles.count
let pdfFileNames = pdfFiles.map{ $0.deletingPathExtension().lastPathComponent }
print("pdf list:", pdfFileNames)
filestext = pdfFileNames
} catch let error as NSError {
print(error.localizedDescription)
}
and here is the Url of files in the device
var names = String()
let rows = fileTableView.indexPathsForSelectedRows.map{$0.map{$0.row}}
print(rows!)
for i in rows! {
print(filesurl[i])
print(filestext[i])
names.append("\(filestext[i])")
fileManagerViewController.filesForUpload.append(filesurl[i])
}
and here is the post method that I used
let parameters = ["myfile" : "\(fileManagerViewController.filesForUpload)"]
print(parameters)
guard let url = URL(string: "http://example.com/api/file?api_token=\(EmailSignInViewController.api_token)") else {return}
var request = URLRequest(url: url)
request.httpMethod = "POST"
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: []) else {return }
request.httpBody = httpBody
let session = URLSession.shared
session.dataTask(with: request) { (data , response , error) in
if let response = response {
print(response)
}
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
print(json)
} catch {
print(error)
}
}
}.resume()

How to parse Json object in swift 3

Hi my question is related to json object. i have this link "http://ip-api.com/json" and this link gives the details of your IP Address. i only need to print IP Address from this json file in swift 3. i am very new might be my question is basic but i need some help to sort out my project. so for i have done like below.
let requestURL: NSURL = NSURL(string: "http://ip-api.com/json")!
let urlRequest: NSMutableURLRequest = NSMutableURLRequest(url: requestURL as URL)
let session = URLSession.shared
let task = session.dataTask(with: urlRequest as URLRequest) {
(data, response, error) -> Void in
let httpResponse = response as! HTTPURLResponse
let statusCode = httpResponse.statusCode
if (statusCode == 200) {
print("Everyone is fine, file downloaded successfully.")
do{
let json = try JSONSerialization.jsonObject(with: data!, options:.allowFragments) as! [String:AnyObject]
if let stations = json["city"] as? [[String: AnyObject]] {
for station in stations {
if let name = station["regionName"] as? String {
self.names.append(name)
print("this is query\(name)")
}
else{
print ("no ip address is found")
}
}
}
}
catch {
print("Error with Json: \(error)")
}
}
}
task.resume()
many thanks in advance.
The IP address is the value for key query on the top level of the JSON
let json = try JSONSerialization.jsonObject(with: data!, options:.allowFragments) as! [String:Any]
if let query = json["query"] as? String {
print(query)
}
In Swift 3 the type of a JSON dictionary is [String:Any]
PS: You don't need a URL request for this task, pass the URL directly and use the native structs URL (and URLRequest)
let requestURL = URL(string: "http://ip-api.com/json")!
...
let task = session.dataTask(with: requestURL) {

Where do I specify ReloadIgnoringLocalCacheData for NSURLSession in Swift 2

I have an app that makes an API call every 5 seconds using NSURLSession and p2-oauth2. I'm running into an issue of it returning cached data instead of the updated information from the API. I read this post by Matt Thompson where he describes the different cache policies, the one I think I need to use is ReloadIgnoringLocalCacheData. I think it's suppose to be put in the AppDelegate DidFinishLaunchingWithOptions functions. But, the problem I'm having is I don't know where or how to specify it. I haven't found any Swift solutions. Can anyone tell me what my function should say?
If it's helpful, here is my API request:
let urlPath = "https://sandbox-api.uber.com/v1/requests/\(uberRequestId)"
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
guard let endpoint = NSURL(string: urlPath) else { print("Error creating endpoint");return }
let request = appDelegate.oauth.request(forURL: NSURL(string:urlPath)!)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "GET"
//get response from Uber and iterate through to find Uber Product ID.
NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) -> Void in
do {
guard let dat = data else { throw JSONError.NoData }
let result = try NSJSONSerialization.JSONObjectWithData(dat, options: NSJSONReadingOptions.MutableContainers)
print(result)
//set status
status = result["status"] as! String
print("found status...returning it back -> \(status)")
completion(status: "\(status)")
} catch let error as JSONError {
print(error.rawValue)
print("ERROR NEEDS TO BE HANDLED.")
} catch {
print(error)
print("ERROR NEEDS TO BE HANDLED.")
}
}.resume()
Here is the final request that properly sets the cache policy. I added one line with ReloadIgnoringLocalCacheData.
let urlPath = "https://sandbox-api.uber.com/v1/requests/\(uberRequestId)"
let url:NSURL = NSURL(string: urlPath)!
let session = NSURLSession.sharedSession()
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let request = appDelegate.oauth.request(forURL: NSURL(string:urlPath)!)
request.HTTPMethod = "GET"
//added this line to set cache policy
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
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)
print(dataString)
}
task.resume()
Assuming the OAuth API returns a mutable request, you can set its cachePolicy property to NSURLRequestCachePolicy.ReloadIgnoringCacheData.

Resources