I had some code that I used a while back that worked perfectly. I now wish to use it in my new project which is swift 3 and although I have fixed most errors I still have two left as follows:
The following line of code: var _: NSData? = NSURLConnection.sendSynchronousRequest(request as URLRequest, returning:&response) as NSData produces the following error: Call can throw, but it is not marked with 'try' and the error is not handled
The following line of code: NSLog("Response code: %ld", res?.statusCode ?? <#default value#>); Produces the following error: Editor placeholder in source file.
Any help is appreciated.
Below is the full code which may help solve the issue:
func webViewDidFinishLoad(_ webView: UIWebView) {
UIApplication.shared.isNetworkActivityIndicatorVisible = false
let post:NSString = "userid=349&devicetoken=walan"
NSLog("PostData: %#",post);
let url:NSURL = NSURL(string: "https://str8red.com/updateAPN")!
let postData:NSData = post.data(using: String.Encoding.ascii.rawValue)! as NSData
let postLength:NSString = String( postData.length ) as NSString
let request:NSMutableURLRequest = NSMutableURLRequest(url: url as URL)
request.httpMethod = "POST"
request.httpBody = postData as Data
request.setValue(postLength as String, forHTTPHeaderField: "Content-Length")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
var _: NSError?
var response: URLResponse?
var _: NSData? = NSURLConnection.sendSynchronousRequest(request as URLRequest, returning:&response) as NSData
let res = response as! HTTPURLResponse!;
NSLog("Response code: %ld", res?.statusCode ?? <#default value#>);
}
You could add try keyword and surround the statement with do {} catch {} as follows:
do {
try NSURLConnection.sendSynchronousRequest(request as URLRequest, returning:&response) as NSData
} catch {
print(error)
}
You will still have a warning about the function has been deprecated since iOS 9.
I will see try to see how the whole function could be re-write in iOS 10, Swift 3.1 syntax, but there's a danger that it might break and will look very different from the rest of your legacy code. Stay tuned, I will update this answer again.
As for the 'placeholder error' you could put some value like '500' for example to default to 'Internal server error'
NSLog("Response code: %ld", res?.statusCode ?? 500);
Update: Here is the function updated to Swift 3, iOS 10.
I only update based on the original intent of the function. Just syntax / API update, no removal / adding any functionality.
func webViewDidFinishLoad(_ webView: UIWebView) {
UIApplication.shared.isNetworkActivityIndicatorVisible = false
let post:String = "userid=349&devicetoken=walan"
NSLog("PostData: %#",post);
let url:URL = URL(string: "https://str8red.com/updateAPN")!
let postData:Data = post.data(using: String.Encoding(rawValue: String.Encoding.ascii.rawValue))!
let postLength: String = String( postData.count )
var request:URLRequest = URLRequest(url: url as URL)
request.httpMethod = "POST"
request.httpBody = postData as Data
request.setValue(postLength, forHTTPHeaderField: "Content-Length")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
var _: NSError?
var response: URLResponse?
URLSession.shared.dataTask(with: request) { (data, res, error) in
guard error == nil else {
print(error!)
return
}
response = res
}
let res = response as! HTTPURLResponse!;
NSLog("Response code: %ld", res?.statusCode ?? 500);
}
Related
I have a request in Swift 5 that is trying to make a call to tinify.com. It is supposed to give me back a URL to a compressed image. I am currently getting this error in the print field:
{"error":"Not found","message":"This endpoint does not exist."}
TinyPNG.com API Reference
Code:
let string = "https://api.tinify.com/shrink"
let url = NSURL(string: string)
let request = NSMutableURLRequest(url: url! as URL)
request.httpMethod = "GET"
request.addValue("fakeAPIKey1234", forHTTPHeaderField: "user api")
request.addValue("/dev/stdout", forHTTPHeaderField: "dump-header")
request.addValue("\(String(describing: self.jpegData(compressionQuality: 0.8)!))", forHTTPHeaderField: "data-binary")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let task = URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) -> Void in
guard error == nil else { print(error!.localizedDescription); return }
guard let data = data else { print("Empty data"); return }
if let str = String(data: data, encoding: .utf8) {
print("Grab Image from this url: \(str)")
}
}
Note: fakeAPIKey1234 is not actually the string I'm using. Also I'm sure there is more wrong with my code than this little issue.
This question already has an answer here:
Fixing NSURLConnection Deprecation from Swift 1.2 to 2.0
(1 answer)
Closed 7 years ago.
Xcode says that sendSynchronousRequest is now deprecated.
How should I replace it?
let postData:NSData = post.dataUsingEncoding(NSASCIIStringEncoding)!
let postLength:NSString = String( postData.length )
let request:NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.HTTPBody = postData
request.setValue(postLength as String, forHTTPHeaderField: "Content-Length")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
var response: NSURLResponse?
var urlData: NSData?
do {
urlData = try NSURLConnection.sendSynchronousRequest(request, returningResponse:&response)
} catch _ as NSError {
urlData = nil
} catch {
fatalError()
}
This is a working example,
You should use NSURLSession, with Request.
func testPost(sender: UIButton) {
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: NSURL(string: "http://localhost:8080/iOSServer/ios/helloworld/swiftCalculator")!)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
let d = "4"
let data = "x=4&y=\(d)"
request.HTTPBody = data.dataUsingEncoding(NSASCIIStringEncoding)
let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
if let error = error {
print(error)
}
if let data = data{
print("data =\(data)")
}
if let response = response {
print("url = \(response.URL!)")
print("response = \(response)")
let httpResponse = response as! NSHTTPURLResponse
print("response code = \(httpResponse.statusCode)")
//if you response is json do the following
do{
let resultJSON = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions())
let arrayJSON = resultJSON as! NSArray
for value in arrayJSON{
let dicValue = value as! NSDictionary
for (key, value) in dicValue {
print("key = \(key)")
print("value = \(value)")
}
}
}catch _{
print("Received not-well-formatted JSON")
}
}
})
task.resume()
}
Notice it is not necessary to use the request. you can have a data task with URL, but I added the request because in your code, you have set some headers in the request.
Notice using the completionHandler which will be called when your server responses by http response.
I want to get error status code when my WebView is loaded.
When I open the connexion I use this code :
let simpler = "http://www.example.com"
let url = NSURL(string: simpler)
let request = NSURLRequest(URL: url!)
webview.loadRequest(request)
I have found this code but I obtain errors so it's not working :
Check URL of Loaded WebView
I want to get the errors in the ViewDidLoad
Try this one :-
var url:NSURL = NSURL(string: "http://www.example.com")!
var postData:NSData = post.dataUsingEncoding(NSASCIIStringEncoding)!
var postLength:NSString = String( postData.length )
var request:NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.HTTPBody = postData
//request.setValue(postLength as String, forHTTPHeaderField: "Content-Length")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("*/*", forHTTPHeaderField: "Accept")
var reponseError: NSError?
var response: NSURLResponse?
var urlData: NSData? = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&reponseError)
let res = response as! NSHTTPURLResponse!;
NSLog("Response code: %ld", res.statusCode);
I'm attempting to make a GET request on a Parse database I created using the built-in REST API. The API call is to be made when a user enters text into a UISearchBar, with the ultimate goal being to display the returned data in a UITableView. The code below only captures my attempt to make a valid HTTP request, where I am trying to see if "Query1" matches the search string ("Query1" is a parameter in my Parse database that essentially serves as an associated search term).
//Mark - UISearchBarDelegate
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
makeRequest(searchBar.text)
}
func makeRequest (searchString : String) {
//REST API call to the sampleObjectData class
var request = NSMutableURLRequest(URL: NSURL(string: "https://api.parse.com/1/classes/sampleObjectData")!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "GET"
//THIS IS MY TROUBLE AREA
var params = urllib.urlencode({"where";:json.dumps({
"Query1": "\(searchString)"
})})
var error: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: &error)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
//The kAppId & kRestAPIKey calls are referencing contstants at the top of the file
request.addValue("X-Parse-Application-Id", forHTTPHeaderField: kAppId)
request.addValue("X-Parse-REST-API-Key", forHTTPHeaderField: kRestAPIKey)
var task = session.dataTaskWithRequest(request, completionHandler: { (data, response, err) -> Void in
var stringData = NSString(data: data, encoding: NSUTF8StringEncoding)
println(stringData)
})
task.resume()
}
The result is code that will not build, as I cannot figure out how to apply parameters to the Parse REST API using Swift. Any help would be appreciated.
I received assistance elsewhere, but wanted to post the answer I was given for anyone that has the same issue. Below is a sample Parse REST API call in Swift that uses the same parameters I laid out above.
func makeParseRequest(searchString: String) {
var request = NSMutableURLRequest()
request.HTTPMethod = "GET"
request.addValue(kAppId, forHTTPHeaderField: "X-Parse-Application-Id")
request.addValue(kRestAPIKey, forHTTPHeaderField: "X-Parse-REST-API-Key")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
var params = ["Query1" : "\(searchString)"]
var error: NSError?
var paramsJSON = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: &error)
var paramsJSONString = NSString(data: paramsJSON!, encoding: NSUTF8StringEncoding)
var whereClause = paramsJSONString?.stringByAddingPercentEscapesUsingEncoding(NSASCIIStringEncoding)
let urlString = "https://api.parse.com/1/classes/sampleObjectData"
var requestURL = NSURL(string: String(format: "%#?%#%#", urlString, "where=", whereClause!))
request.URL = requestURL!
var task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data, response, err) -> Void in
var stringData = NSString(data: data, encoding: NSUTF8StringEncoding)
println(stringData)
})
task.resume()
}
I'm (trying to) learn the Swift's Apple language. I'm at Playground and using Xcode 6 Beta. I'm trying to do a simple JSON Post to a local NodeJS server. I already had googled about it and the major tutorials explain how to do it in a project, not at PLAYGROUND, than don't write stupid thinks like: "google it" or "it's obvious" or "look this link" or never-tested-and-not-functional-code
This is what i'm trying:
var request = NSURLRequest(URL: NSURL(string: "http://localhost:3000"), cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: 5)
var response : NSURLResponse?
var error : NSError?
NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error)
I had tried:
var dataString = "some data"
var request = NSMutableURLRequest(URL: NSURL(string: "http://posttestserver.com/post.php"))
request.HTTPMethod = "POST"
let data = (dataString as NSString).dataUsingEncoding(NSUTF8StringEncoding)
var requestBodyData: NSData = data
request.HTTPBody = requestBodyData
var connection = NSURLConnection(request: request, delegate: nil, startImmediately: false)
println("sending request...")
connection.start()
Thank you! :)
Nate's answer was great but I had to change the request.setvalue for it to work on my server
// create the request & response
var request = NSMutableURLRequest(URL: NSURL(string: "http://requestb.in/1ema2pl1"), cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: 5)
var response: NSURLResponse?
var error: NSError?
// create some JSON data and configure the request
let jsonString = "json=[{\"str\":\"Hello\",\"num\":1},{\"str\":\"Goodbye\",\"num\":99}]"
request.HTTPBody = jsonString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
request.HTTPMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
// send the request
NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error)
// look at the response
if let httpResponse = response as? NSHTTPURLResponse {
println("HTTP response: \(httpResponse.statusCode)")
} else {
println("No HTTP response")
}
It looks like you have all the right pieces, just not in quite the right order:
// create the request & response
var request = NSMutableURLRequest(URL: NSURL(string: "http://requestb.in/1ema2pl1"), cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: 5)
var response: NSURLResponse?
var error: NSError?
// create some JSON data and configure the request
let jsonString = "json=[{\"str\":\"Hello\",\"num\":1},{\"str\":\"Goodbye\",\"num\":99}]"
request.HTTPBody = jsonString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
request.HTTPMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
// send the request
NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error)
// look at the response
if let httpResponse = response as? NSHTTPURLResponse {
println("HTTP response: \(httpResponse.statusCode)")
} else {
println("No HTTP response")
}
Here is a little different approach using asynchronous request. You can use synchronous approach this way too but since everyone above used synchronous request, I thought show asynchronous request instead. Another thing is it seems cleaner and easier this way.
let JSONObject: [String : AnyObject] = [
"name" : name,
"address" : address,
"phone": phoneNumber
]
if NSJSONSerialization.isValidJSONObject(JSONObject) {
var request: NSMutableURLRequest = NSMutableURLRequest()
let url = "http://tendinsights.com/user"
var err: NSError?
request.URL = NSURL(string: url)
request.HTTPMethod = "POST"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(JSONObject, options: NSJSONWritingOptions(rawValue:0), error: &err)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue()) {(response, data, error) -> Void in
if error != nil {
println("error")
} else {
println(response)
}
}
}