Date String causing error in NSMutableURLRequest URL using swift language - ios

I am passing date after converting to String but causing error
unexpectedly found nil while unwrapping a value
this is code of Request
let url = SERVICE_URL + "GetHistoryDataByTerminalNo?TerminalNo=\(VehicleList.SelectedTerminal.selectedTerminalId)&fromDate=\(fromDateText)&toDate=\(endDateText)"
let request = NSMutableURLRequest(url: NSURL(string: url)! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 30.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers
UPDATE
I am getting this URL
http://labs2.unitedtracker.com/api/Trackers/GetHistoryDataByTerminalNo?TerminalNo=351535058776063&fromDate=2020-08-23 14:15:52.000&toDate=2020-08-23 16:15:52.000

You cannot just put a string with a space into a URL, you have to URL-encode it first.
First of all, add extension for URL encoding:
extension String {
public var urlEncoded: String {
var allowedCharacters = CharacterSet.urlQueryAllowed
allowedCharacters.remove(charactersIn: "!*'();:#&=+$,/?%#[]")
return addingPercentEncoding(withAllowedCharacters: allowedCharacters) ?? ""
}
}
Second, encode the parameter values:
let url = SERVICE_URL + "GetHistoryDataByTerminalNo?TerminalNo=\(VehicleList.SelectedTerminal.selectedTerminalId.urlEncoded)&fromDate=\(fromDateText.urlEncoded)&toDate=\(endDateText.urlEncoded)"
Or, you could use URLComponents and URLQueryItem to generate your URL.

I would recommend not messing around with URL encoding manually - we have URLComponents for this.
For example:
let SERVICE_URL = "https://example.com/service/"
let url = SERVICE_URL + "GetHistoryDataByTerminalNo"
var components = URLComponents(string: url)!
components.queryItems = [
URLQueryItem(name: "TerminalNo", value: VehicleList.SelectedTerminal.selectedTerminalId),
URLQueryItem(name: "fromDate", value: fromDateText),
URLQueryItem(name: "toDate", value: toDateText)
]
let request = URLRequest(url: components.url!, timeoutInterval: 30)
(you probably want a little more error checking)
Also, as #Joakim mentioned, don't use NS... types if you can avoid them.

Related

URLRequest to Alamofire URLConvertible

I have found the same question but not worked for me. thats why I'm posting this again.
The following code gives me an error.
Could not cast value of type 'Foundation.URLRequest' to 'Alamofire.URLConvertible'
the code sample:
let url = (wURL).replacingOccurrences(of: "(f_id)", with: String(conID))
let _url = URL(string: url)
var urlRequest = URLRequest(url: _url!)
urlRequest.timeoutInterval = TimeInterval(exactly: 30)!
let finalUrl = urlRequest as! URLConvertible
What am I missing?
You can't do it, because for URLRequest there is special protocol URLRequestConvertible.
let realURL: URL = URL(string: "https://google.com")!
let url: Alamofire.URLConvertible = realURL
let urlRequest: Alamofire.URLRequestConvertible = URLRequest(url: realURL)
AF.request(urlRequest).responseJSON {
print($0)
}

Swift - Sending binary file to a server (convert to string request)

Here is my function for building a request to send to a server. This code works perfectly fine when it's a small, plain-text file. However, when I pass it a binary file, it crashes on the line indicated below (when it tries to convert that to a utf string and blows up b/c the conversion does not work, as it creates a nil value):
func buildFilePushRequest(fromUrl url: URL, httpBody: Data? = nil, fileName: String) -> NSMutableURLRequest? {
let cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringLocalCacheData
let request = NSMutableURLRequest(url: url, cachePolicy: cachePolicy, timeoutInterval: 2.0)
request.httpMethod = "POST"
// Set Content-Type in HTTP header.
let boundaryConstant = "Boundary-7MA4YWxkTLLu0UIW"; // This should be auto-generated.
let contentType = "multipart/form-data; boundary=" + boundaryConstant
let fileName = fileName
request.setValue(contentType, forHTTPHeaderField: "Content-Type")
request.setValue("keep-alive", forHTTPHeaderField: "Connection")
var dataString = "--\(boundaryConstant)\r\n"
dataString += "Content-Disposition: form-data; name=file; filename=\"\(fileName)\"\r\n"
dataString += "Content-Type: octet-stream\r\n\r\n"
dataString += String(data: httpBody!, encoding: .utf8)! <-- CRASHES HERE
dataString += "\r\n"
dataString += "--\(boundaryConstant)--\r\n"
print("dataString: \(dataString)")
let requestBodyData = dataString.data(using: .utf8)
request.httpBody = requestBodyData
return request
}
I've read a bit that base64 is a better way to go rather than utf8 for binary type data, but I'm not really sure how best to modify the code above to use that instead, or if there is a better solution? Thanks in advance!
If the httpBody parameter can contain binary data you could compound the entire http body as Data
First of all please use native URLRequest, it's mutable as variable and why is the return value optional?
func buildFilePushRequest(fromUrl url: URL, httpBody: Data? = nil, fileName: String) -> URLRequest {
var request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 2.0)
...
var data = Data("--\(boundaryConstant)\r\n".utf8)
data += Data("Content-Disposition: form-data; name=file; filename=\"\(fileName)\"\r\n".utf8)
data += Data("Content-Type: octet-stream\r\n\r\n".utf8)
if let body = httpBody { data += body }
data += Data("\r\n".utf8)
data += Data("--\(boundaryConstant)--\r\n".utf8)
request.httpBody = data

Add parameters to URL (resource from path, WKWebView)

I am using Swift 4 & WKWebView. The HTML pages are included in the app (not downloaded from server).
For configuration purpose I would like to add parameters to the URL (e.g. ...index.html?debug=true).
Currently I am using the following approach to load the page:
let indexHTMLPath = Bundle.main.path(forResource: "f7Shoma/index", ofType: "html")
let url = URL(fileURLWithPath: indexHTMLPath!)
let request = URLRequest(url: url)
...
appWebView!.load(request)
How can parameters be added/passed to the page?
You can use URLComponents to create a URL with a query component:
var components = URLComponents(string: indexHTMLPath)
components?.queryItems = [URLQueryItem(name: "debug", value: "true")]
if let result = components?.url {
let request = URLRequest(url: url)
appWebView!.load(request)
}

crash uiwebview without http or https in swift [duplicate]

This question already has answers here:
Add http:// to NSURL if it's not there
(5 answers)
Closed 5 years ago.
I want show the URL in Web View
here is my code
let urlString:String = "https://www.apple.com"
let url:URL = URL(string: urlString)!
let urlRequest:URLRequest = URLRequest(url: url)
webView.load(urlRequest)
urlTextField.text = urlString
if user forget to write http or https the app crashed how can I resolve this error
Just use starts(with:) on string to detect if the url string starts with http/https, and if not, add the "http://" yourself (also, use safe if let instead of force unwrap):
var urlString: String = "www.apple.com"
if !urlString.starts(with: "http://") && !urlString.starts(with: "https://") {
urlString = "http://\(urlString)"
}
if let url: URL = URL(string: urlString) {
let urlRequest: URLRequest = URLRequest(url: url)
webView.load(urlRequest)
urlTextField.text = urlString
}

How to send Json as parameter in url using swift

I am new in swift language. I looked at some questions for parsing Json in swift in here but my issue is alittle different from others.
when i write /cmd=login&params{'user':'username','password':'pass'} it returns correct data. how to resolve this in swift
I send username and password to url as json but
it retrieve error which means "invalid format "
Please help me.
Here is what i have tried:
var url:NSURL = NSURL(string: "http://<host>?cmd=login")!
//var session = NSURLSession.sharedSession()
var responseError: NSError?
var request = NSMutableURLRequest(URL: url!, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: 5)
// var request:NSMutableURLRequest = NSMutableURLRequest(URL: url)
var response: NSURLResponse?
request.HTTPMethod = "POST"
let jsonString = "params={\"user\":\"username\",\"password\":\"pass\"}"
request.HTTPBody = jsonString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion:true)
request.setValue("application/json; charset=UTF-8", forHTTPHeaderField: "Content-Type")
// send the request
NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &responseError)
// look at the response
if let httpResponse = response as? NSHTTPURLResponse {
println("HTTP response: \(httpResponse.statusCode)")
} else {
println("No HTTP response")
}
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){
data, response, error in
if error != nil {
println("error=\(error)")
return
}
println("****response= \(response)")
let responseString = NSString(data: data, encoding: NSUTF8StringEncoding)
println("**** response =\(responseString)")
var err: NSError?
var json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers , error: &err) as? NSDictionary
}
task.resume()
Assuming based on your question that the format the server is expecting is something like this:
http://<host>?cmd=login&params=<JSON object>
You would need to first URL-encode the JSON object before appending it to the query string to eliminate any illegal characters.
You can do something like this:
let jsonString = "{\"user\":\"username\",\"password\":\"pass\"}"
let urlEncoadedJson = jsonString.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())
let url = NSURL(string:"http://<host>?cmd=login&params=\(urlEncoadedJson)")
Let's say url is
https://example.com/example.php?Name=abc&data={"class":"625","subject":"english"}
in Swift 4
let abc = "abc"
let class = "625"
let subject = "english"
let baseurl = "https://example.com/example.php?"
let myurlwithparams = "Name=\(abc)" + "&data=" +
"{\"class\":\"\(class)\",\"subject\":\"\(subject)\"}"
let encoded =
myurlwithparams.addingPercentEncoding(withAllowedCharacters:
.urlFragmentAllowed)
let encodedurl = URL(string: encoded!)
var request = URLRequest(url: encodedurl!)
request.httpMethod = "GET"
I don't think you need to encode your JSON the way you're doing it. Below should work.
let jsonString = "params={\"user\":\"username\",\"password\":\"pass\"}"
var url:NSURL = NSURL(string: "http://<host>?cmd=login&?\(jsonString)")!
//var session = NSURLSession.sharedSession()
var responseError: NSError?
var request = NSMutableURLRequest(URL: url!, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: 5)
// var request:NSMutableURLRequest = NSMutableURLRequest(URL: url)
var response: NSURLResponse?
request.HTTPMethod = "POST"
You json string is not valid, it should be like:
let jsonString = "{\"user\":\"username\",\"password\":\"pass\"}"
As for the request, I think GET it what you really need:
var urlString = "http://<host>" // Only the host
let payload = "?cmd=login&params=" + jsonString // params goes here
urlString += payload
var url:NSURL = NSURL(string: urlString)!
// ...
request.HTTPMethod = "GET"

Resources