I'm trying too get the html code from a specific URL with this code:
guard let myURL = URL(string: myURLString) else {
print("Error: \(myURLString) doesn't seem to be a valid URL")
return myLinksArray
}
do {
myHTMLString = try String(contentsOf: myURL, encoding: .ascii)
print("HTML : \(myHTMLString)")
} catch let error {
print("Error: \(error)")
}
but in this way I'm unable to set a timeout. Some websites require too much time to get response.
What's the best way to solve the problem?
Thanks in advance
Have you considered creating an URLSession dataTask, I believe it would be a better approach. You can create a custom URLSessionConfiguration and use it to specify the timeoutIntervalForRequest or timeoutIntervalForResource according to your needs like this:
guard let myURL = URL(string: myURLString) else {
print("Error: \(myURLString) doesn't seem to be a valid URL")
fatalError()
}
let sessionConfig = URLSessionConfiguration.default
sessionConfig.timeoutIntervalForRequest = 15 // seconds
sessionConfig.timeoutIntervalForResource = 15 // seconds
let dataTask = URLSession(configuration: sessionConfig).dataTask(with: myURL) { (data, urlResponse, error) in
guard let data = data else { return }
let myHTMLString = String(data: data, encoding: .ascii)
print("HTML : \(myHTMLString ?? "")")
}
dataTask.resume() // start the request
Related
In my application I am working on Alamofire to fetch the data . I think it is taking little bit more time to fetch json data. I am adding my code here. Can anyone suggest me how to reduce the fetching time?
func getUserData(completion: #escaping LcodeResponseCompletion) {
guard let url = URL(string: "\(LCODE_URL)") else{return}
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = HTTPMethod.get.rawValue
Alamofire.request(urlRequest).responseJSON { (response) in
if let error = response.result.error {
debugPrint(error.localizedDescription)
completion(nil)
return
}
guard let data = response.data else { return completion(nil)}
let jsonDecoder = JSONDecoder()
do {
let lcode = try jsonDecoder.decode(Empty.self, from: data)
completion(lcode)
} catch {
debugPrint(error.localizedDescription)
completion(nil)
}
}
}
The JSON data is
[
{"id":0,"temperature":77,"humidity":0.22,"timeCaptured":"2020-09-25T19:33:27.9733333"},
{"id":0,"temperature":77,"humidity":0.22,"timeCaptured":"2020-09-25T20:38:53.3"},
{"id":0,"temperature":85,"humidity":0.25,"timeCaptured":"2020-09-25T20:38:53.3"},
{"id":0,"temperature":88,"humidity":0.22,"timeCaptured":"2020-09-28T15:30:00"},
// ...
]
My structs look like this
struct TemperatureDataModel: Codable{
let id: Int?
let temperature: Double?
let humidty: Double?
let timeCaptured: String?
}
My function looks like this
func getTemperData(){
//Create the URLs
let temperatureDataUrl = URL(string: "https://weatherstationapi.azurewebsites.net/api/TemperatureSensor/GetData")
// let WindDataUrl = URL(string: "https://weatherstationapi.azurewebsites.net/api/WindData/GetAllData")
guard let requestURLTemp = temperatureDataUrl else { fatalError() }
//Create URL request
var request = URLRequest(url: requestURLTemp)
//Specifiy HTTP Method to use
request.httpMethod = "GET"
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiaWxpci50YWlyaUB0dHUuZWR1IiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZWlkZW50aWZpZXIiOiI4MjEzYzhhMy1iODgxLTQ4NmUtOGUyMC1mZmNlMDlmNGY0ZjgiLCJuYmYiOiIxNjAyNTI2NDI1IiwiZXhwIjoiMTYwNTExODQyNSJ9.t1qnYyXLpRRJ3YQfhgLrylBqL_pdKOnKVMgOfG9IuVc", forHTTPHeaderField: "Authorization")
//Send HTTP Request
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data else {return}
print(data)
//Use parseJSON to convert data
let TemperatureData = parseJSON(data: data)
// for singleValue in TemperatureData {
// print(singleValue.temperautre)
// }
//read list
guard let TemperatureDataModel = TemperatureData else {return}
print("Temperature is : \(TemperatureDataModel.temperature)")
// Check if error took place
if let error = error {
print("Error took place \(error)")
return
}
//Read HTTP Response Status Code
// if let data = data, let dataString = String(data: data, encoding: .utf8) {
// print("Response data string:\n \(dataString)")
// }
}
task.resume()
}
and then my JSON decoder function looks like this
func parseJSON(data: Data) -> TemperatureDataModel? {
var returnValue: TemperatureDataModel?
do {
let returnValue = try JSONDecoder().decode([TemperatureDataModel].self, from: data)
} catch {
print("Error took place \(error).")
}
return returnValue
}
I've looked at 6+ stack overflow posts now and still cannot figure It out. Ive tried putting my model in [] for an array, moving where the function is called, changing the jsondecoder function and more and nothing works.
I think you have to give a format to the date before you parse the data
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
Your issue there is that you are creating another returnValue that is not being returned. You need also change the return type to [TemperatureDataModel]
func parseJSON(data: Data) -> [TemperatureDataModel]? {
do {
return try JSONDecoder().decode([TemperatureDataModel].self, from: data)
} catch {
print("Error took place \(error).")
return nil
}
}
Im trying to access the variable pic after the request is made but its in a closure, thats why print(pic) doesn't work.
How would someone go about accessing this?
guard let url = URL(string: "myurl") else{ return }
var pic = ""
let session = URLSession.shared
session.dataTask(with: url) { (data, response, error) in
if let response = response {
print(response)
}
if let data = data {
print(data)
do {
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
pic = parseJSON["picture"] as! String
print(json!)
}
} catch {
print(error)
}
}
}.resume()
print(pic)
}
Assuming pic is an image you'll be loading into a UIImageView:
You can add an Activity Indicator to your ImageView. Then when you call your function to download the pic simply add:
guard let url = URL(string: "myurl") else{ return }
activityIndicator.isHidden = false
activityIndicator.startAnimating()
The user will know a download is occurring. When complete,
DispatchQueue.main.async {
activityIndicator.isHidden = true
activityIndicator.stopAnimating()
myImageView.image = UIImage(named: "pic")
}
}.resume
Dispatching on the main que will update the UI immediately.
I successfully get data from RSS feeds all the time but I am having a problem with this one and for the life of me I can't tell what the issue is.
Below code executes, returns 200 status code and no content
let urlTMC = URL(string: "https://teslamotorsclub.com/tmc/forums/model-s.73/index.rss")!
let urlRequest = NSMutableURLRequest(url: urlTMC as URL)
let session = URLSession.shared
let task = session.dataTask(with: urlRequest as URLRequest, completionHandler: { data, response, error in
print(data)
print(response)
print(error)
if let response = response, let data = data {
do {
let jsonData = JSON(data: data)
print(jsonData)
} catch {
print("JSONSerial error")
}
}
else {
print(error!)
}
DispatchQueue.main.async(execute: {
print("DISPATCH")
})
})
task.resume()
let myURLString = "https://en.wiktionary.org/wiki/see"
if let myURL = NSURL(string: myURLString) {
let myHTMLString = String(contentsOfURL: myURL, encoding: String.Encoding.utf8)
print("HTML : \(myHTMLString)")
}
And I got printed:
HTML : (https://en.wiktionary.org/wiki/see, Unicode (UTF-8))
But instead I need html content.
What I am doing wrong?
Update:
As a source for the code I used: How To Get HTML source from URL with Swift
Please, read my question with more attention, as the result I got text of link, but instead I need text of html page
Try this:
let myURLString = "http://google.com"
guard let myURL = NSURL(string: myURLString) else {
print("Error: \(myURLString) doesn't seem to be a valid URL")
return
}
do {
let myHTMLString = try String(contentsOfURL: myURL)
print("HTML : \(myHTMLString)")
} catch let error as NSError {
print("Error: \(error)")
}
Hope this helps!
To retrieve the HTML of the webpage referenced by a url you just need to
let myURLString = "https://en.wiktionary.org/wiki/see"
if let
url = NSURL(string: myURLString),
html = try? String(contentsOfURL: url) {
print(html)
}
I tested this code in my Playground and it is retrieving the full HTML of the web page.
Solution: instead of String, use NSString
let myURLString = "https://en.wiktionary.org/wiki/see"
if let myURL = NSURL(string: myURLString) {
do {
let myHTMLString = try NSString(contentsOf: myURL as URL, encoding: String.Encoding.utf8.rawValue)
print("html \(myHTMLString)")
} catch {
print(error)
}
}