After this code is ran I get some pretty strange messange on the command line. (However it happens in every application where I write URLSession datatask. (This is the simplest one that reproduce the problem)
Facts:{
iOS: 13.6 (though version does not matter, happened to me in every version.
Xcode: 11.6 (also does not matter at all)
}
func getTemperatureWarning(){
let url = URL(string: "https://urlhere:2222/getTemperatureWarning") // checking settings on server
var request = URLRequest(url: url!)
request.httpMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
_ = URLSession.shared.dataTask(with: request){data, response, error in
if error != nil || data == nil {
print("Client error!")
return
}
guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
fatalError("failed!")
}
do {
let json = try JSONDecoder().decode(TempWarning.self, from: data!)
print(json.value)
DispatchQueue.main.async {
// not yet implemented
}
} catch let error {
print(error)
}
}.resume()
}
CommandLine:
25
2020-07-23 11:54:28.859871+0200 cameden[36484:2032497] [] tcp_input [C2.1.1:3] flags=[R] seq=3143354417, ack=0, win=0 state=LAST_ACK rcv_nxt=3143354417, snd_una=3725130175 2020-07-23
11:54:28.860170+0200 cameden[36484:2032497] [] tcp_input [C2.1.1:3] flags=[R] seq=3143354417, ack=0, win=0 state=CLOSED rcv_nxt=3143354417, snd_una=3725130175
Anybody has any clue what is it about, or how can I dive more deep into it? Is it an error or something that helps me acknowledge there is no error?
25 at the begining is the answer from my python3 flask server. That is the value I'm looking for. After that number there is a two line message which I dont understand. It also happens when I try to access 3rd party servers like twitter API or whatever.
Related
I'm beginner in SwiftUI and I'm not familiar with variable management.
I'd like to send a very simple post request like this one with SwiftUI:
let full_path : String = "https://www.example.com/get_answer?my_message=current temperature"
I've tried with this piece of code but it didn't work.
if (URL(string: full_path) != nil) {
let url = URL(string: full_path)!
var request = URLRequest(url: url)
request.httpMethod = "POST"
var decodedAnswer = String("")
do {
let task = URLSession.shared.dataTask(with: url) { data, response, error in
print(response)
decodedAnswer = String(decoding: response, as: UTF8.self)
}
}
I have the following error:
Value of optional type 'URLResponse?' must be unwrapped to a value of
type 'URLResponse'
I don't know how to get the response.
How can I get the response from a simple Post request in SwiftUI?
Multiple issues here.
You are trying to decode the URLResponse object, but what you want is the data object in the decoder.
You seem to not know about optionals. I would refer you to the basic Apple tutorials about this topic. You can find it with your favorite search engine.
You are in an async context here. Everything inside the url datasession closure will be execute after your network request returns. The code in your function will be completed by that moment and your var decodedAnswer will be out of scope. So move it out of the function in to the class/struct.
You probably want something like this:
This should be defined in class scope or you won´t be able to use it:
var decodedAnswer: String = ""
This should be in a function:
let full_path: String = "https://www.example.com/get_answer?my_message=current temperature"
if let url = URL(string: full_path) {
var request = URLRequest(url: url)
request.httpMethod = "POST"
do {
let task = URLSession.shared.dataTask(with: url) { data, response, error in
//This converts the optionals in to non optionals that could be used further on
//Be aware this will just return when something goes wrong
guard let data = data, let response = response, error == nil else{
print("Something went wrong: error: \(error?.localizedDescription ?? "unkown error")")
return
}
print(response)
decodedAnswer = String(decoding: data, as: UTF8.self)
}
task.resume()
}
}
I would like to implement a way to check if the network is weak or disconnected during network calls I perform using Alamofire 4.9 - the following is what I am currently attempting to do, but I have noticed that if the network it off it never jumps to this line:
URLError.Code.notConnectedToInternet
why does this occur, is there a better way of attempting this?
//Fetch new data
guard let url = URL(string: "test.com")
else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = "value1=test1&value2=test2".data(using: .utf8)
URLSession.shared.dataTask(with: request) { [self] data, _, error in
guard let data = data else { return }
do {
let decoder = JSONDecoder()
let res = try decoder.decode([Structure].self, from: data)
}
}
catch {
if let err = error as? URLError, err.code == URLError.Code.notConnectedToInternet {
// No internet
} else {
print(error)
}
}
}.resume()
There are a variety of errors that can be produced by poor or entirely broken connectivity. .notConnectedToInternet is simply one of them. There is no single, exhaustive list provided by Apple of which errors may be returned when there are connectivity issues, so you'll want to experiment and see what you can produce. Additionally, there are a variety of errors which you can probably throw into a "network connectivity" bucket, such as .dnsLookupFailed or .cannotConnectToHost. Ultimately it may not be worth it to differentiate different types of URLErrors.
By the way, you should use Alamofire 5 if you can, as Alamofire 4 is no longer supported.
I am trying to perform an HTTP POST request in swift that will send some data to my server using PHP file, but it crashes with the error
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
The token and selectedAreaNames (the error is in the first line) are just regular strings. What could be the problem?
let url = URL(string: "https://xxxxxxx.xxx/register.php/\(token)|\ (selectedAreaNames)")! //error is here...
var request = URLRequest(url: url)
request.httpMethod = "POST"
let task = URLSession.shared.dataTask(with: request) { (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()
Assuming that’s really how your URL must look, you can do:
let url = URL(string: "https://xxxxxxx.xxx/register.php")!
.appendingPathComponent(token + "|" + selectedAreasNames)
That will percent escape those portions of the URL (including the |).
That having been said, this is an exceedingly unusual format for a POST request, which usually has the data being posted inside the body of the request, not just added as another path component of the URL. And if this was a GET request, where the parameters are added to the URL, you’d generally see this after a ? in the URL, separating the path of the request from the query. And this structure of simply TOKEN|VALUES is an unusual query structure, too.
I'm trying to develop a download accelerator in Swift. It should get the file's size and divide it to n parts. Then it should download them at once by running multiple threads, and then merge the parts.
I read C# - Creating a Download Accelerator, unfortunately it doesn't help me.
I can do the multiple thread part easily by
DispatchQueue.main.async {
// The new thread
}
but the other part is harder. I usually download a file like this:
try Data(contentsOf: URL(string: assetsUrl!)!)
or I can do the thing that is explained in this answer
class Downloader {
class func load(url: URL, to localUrl: URL, completion: #escaping () -> ()) {
let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig)
let request = try! URLRequest(url: url, method: .get)
let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
if let tempLocalUrl = tempLocalUrl, error == nil {
// Success
if let statusCode = (response as? HTTPURLResponse)?.statusCode {
print("Success: \(statusCode)")
}
do {
try FileManager.default.copyItem(at: tempLocalUrl, to: localUrl)
completion()
} catch (let writeError) {
print("error writing file \(localUrl) : \(writeError)")
}
} else {
print("Failure: %#", error?.localizedDescription);
}
}
task.resume()
}
}
But this is not C - it's very simplistic and doesn't accept many arguments. How can I make it get "first 200_000 bytes" from the server?
First of all, the server needs to implement HTTP range requests. If it doesn't, and you don't control the server, then you will not be able to do this.
If the server supports HTTP range requests, then you need to specify the range with request headers, as explained here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests
The essentials are that you first send a HEAD request to figure out whether the server supports HTTP range requests. This is determined by whether the response includes the Accept-Ranges header, with a non-zero value.
If the server supports HTTP range requests, then you can make a request for the resource, with the Range header set for example to a value of bytes=0-1023 (depends which format the Accept-Ranges header specified, in this case bytes)
I'm trying to do a PUT request using Swift. In a REST client, when I try to do a REST request the following way:
In Body- x-www-form-urlencoded, I add vote=1 and with id being taken in the param for example: /user/:id, it works!
I try to do the same in Swift code, it does not work and I get responseString = Optional(502 Bad Gateway: Registered endpoint failed to handle the request.
Here is my code:
var baseURL = "http://<domain>/user"
let putURL = baseURL + "/\(id)"
print(putURL)
let request = NSMutableURLRequest(URL: NSURL(string: putURL)!)
request.HTTPMethod = "PUT"
let putString = "vote=1"
request.HTTPBody = putString.dataUsingEncoding(NSUTF8StringEncoding)
request.timeoutInterval = 1500
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
guard error == nil && data != nil else {
print("error=\(error)")
return
}
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("responseString = \(responseString)")
}
task.resume()
You forgot to set the content type, e.g.
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
Without that, the server won't know what to do with the blob of random data that you just sent it.
I'm not saying that this is necessarily the only problem, but it is definitely a problem, and one big enough to cause the error you're seeing.