How can I get variable to text from php to swift app - swift

I use this code and work perfect. I use swift. PHP is work fine.
I also try some other examples at this
I have 2 problems
first my responseString values turns in Optional("Success"). Why?
second is How can assign it on my button?
func makePostCall() {
var request = URLRequest(url: URL(string: "MyURL/page.php")!)
request.httpMethod = "POST"
let postString = "id=login"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(responseString)")
self.lbl.text = responseString
}
task.resume()
//return responseString
}

You need to use DispatchQueue.main.async to work with UI from URLRequests. Also you need to use [weak self] to prevent reference cycle problem. At last, btn.setTitle(responseString, for: .normal) to set title for button state .normal. Here is correct answer!
func makePostCall() {
var request = URLRequest(url: URL(string: "MyURL/page.php")!)
request.httpMethod = "POST"
let postString = "id=login"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) {[weak self] data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
guard let responseString = String(data: data, encoding: .utf8) else {
return
}
print("responseString = \(responseString)")
DispatchQueue.main.async {
self?.lbl.text = responseString
self?.btn.setTitle(responseString, for: .normal) // your button
}
}
task.resume()
//return responseString
}

Related

How can I translate the following code from Swift 2 to Swift 5?

I believe the following code below is written in Swift 2. How can the syntax be converted to the latest Swift (5)?
When using Xcode for conversion, it leaves me with errors like:
Extra argument 'usingEncoding' in call
and
Cannot call value of non-function type 'URLSession'
Original (Need Help Converting):
let request = NSMutableURLRequest(URL: NSURL(string: "http://www.sample.com/sample.php")!)
request.HTTPMethod = "POST"
let postString = "a=\(customerLabel!)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
print("error=\(error)")
return
}
print("response = \(response)")
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("responseString = \(responseString)")
}
task.resume()
}
This was my attempt but it has errors:
let request = NSMutableURLRequest(url: URL(string: "http://www.sample.com/sample.php")!)
request.httpMethod = "POST"
let postString = "a=\(customerLabel!)"
request.HTTPBody = postString.data(usingEncoding: NSUTF8StringEncoding)
let task = URLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
print("error=\(error)")
return
}
print("response = \(response)")
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("responseString = \(responseString)")
}
task.resume()
Don't use NSMutableURLRequest. Use URLRequest.
Don't use NSString, use String.
Look at the URLSession documentation and see that you need shared, not sharedInstance().
data(using .utf8).
Lots of other fixes.
Here's your fixed code with better handling of optionals in the completion handler:
var request = URLRequest(url: URL(string: "http://www.sample.com/sample.php")!)
request.httpMethod = "POST"
let postString = "a=\(customerLabel!)"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("error=\(error)")
return
}
print("response = \(response)")
if let data = data, let responseString = String(data: data, encoding: .utf8) {
print("responseString = \(responseString)")
}
}
task.resume()

How to wait for a download task to finish in swift 3

I am trying to build a user regeistration form, which should check if the user already exists. So I am sending a php request to my my mysql server. If the return value is empty, the user does not exists yet.
Unfortunatley I am really stuck with waiting for this check to finish. I tried several solutions I found googleing but none of them worked. My current code uses semaphores and will crash with "fatal error: unexpectedly found nil while unwrapping an Optional value", so the semaphore is not waiting until the task is finished as I would expect it.
Any hints, would be greatly appreciated. Thanks guys.
private func isUniqueEmail(email: String) -> Bool {
var result: Bool?
let semaphore = DispatchSemaphore(value: 1)
let requestURL = URL(string: "http://localhost/firstpostget/functions/get.php")
var request = URLRequest(url: requestURL!)
request.httpMethod = "POST"
let postParameters = "email=" + email
request.httpBody = postParameters.data(using: .utf8)
let configuration = URLSessionConfiguration.default
let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: OperationQueue.main)
let task = session.dataTask(with: request) {(data, response, error) in
var myJson: AnyObject
do{
myJson = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
if myJson.count == 0{
result = true
semaphore.signal()
} else{
result = false
semaphore.signal()
}
} catch{
//TODO
print(error)
}
}
task.resume()
semaphore.wait(timeout: .distantFuture)
return result!
}
Your task is async and you are force unwrapping nil value so this is the reason it crashes.
You have to change your function implementation to also be async, for example using closures:
private func isUniqueEmail(email: String, completion: ((Bool) -> (Void))?) {
let requestURL = URL(string: "http://localhost/firstpostget/functions/get.php")
var request = URLRequest(url: requestURL!)
request.httpMethod = "POST"
let postParameters = "email=" + email
request.httpBody = postParameters.data(using: .utf8)
let configuration = URLSessionConfiguration.default
let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: OperationQueue.main)
let task = session.dataTask(with: request) {(data, response, error) in
var myJson: AnyObject
do{
myJson = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
if myJson.count == 0 {
completion?(true)
} else{
completion?(false)
}
} catch{
//TODO
print(error)
}
}
task.resume()
}
Now you can use this function in this way:
isUniqueEmail(email: "aaa#bbbb.com") { result in
if result {
print("email unique")
} else {
print("email not unique")
}
}
I think you should rethink the pattern you're using to get the data out of your request, you should consider using a custom handler/callback method that you pass along with the email you're trying to check. See below for an example:
private func isUniqueEmail(email: String, handler: ((_ result: Bool) -> Void)?) -> Void {
let requestURL = URL(string: "http://localhost/firstpostget/functions/get.php")
var request = URLRequest(url: requestURL!)
request.httpMethod = "POST"
let postParameters = "email=" + email
request.httpBody = postParameters.data(using: .utf8)
let configuration = URLSessionConfiguration.default
let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: OperationQueue.main)
let task = session.dataTask(with: request) {(data, response, error) in
var myJson: AnyObject
var result: Bool = false
do{
myJson = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
if myJson.count == 0 {
result = true
}
guard handler != nil else {
return
}
handler!(result)
} catch{
//TODO
print(error)
}
}
task.resume()
}
Run:
isUniqueEmail(email: "test#test.com", handler: { result in
print(result) // true || false
})
If you really want to go down the "wait" route then take a took at DispatchGroup's
https://developer.apple.com/documentation/dispatch/dispatchgroup
try using this:
ApihelperClass
static let sharedInstance = ApihelperClass()
typealias CompletionHandler = (_ success:Bool, _ error:Bool, _ result:NSDictionary) -> Void
typealias ErrorHandler = (_ success: Bool, _ error:Bool) -> Void
func callPostRequest(_ urlPath: String, params:[String: AnyObject], completionHandler: #escaping CompletionHandler, errorHandler:#escaping ErrorHandler ){
print("urlPath:==> \(urlPath) ")
let session = Foundation.URLSession.shared
let url = URL(string: urlPath)
var request = URLRequest(url : url!)
request.httpMethod = "POST"
do {
let jsonData = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData
session.dataTask(with: request, completionHandler: { data, response, error in
OperationQueue.main.addOperation {
guard error == nil && data != nil else { // check for fundamental networking error
print("error=\(error)")
errorHandler(false, true)
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
// print("response = \(response)")
}
let responseString = String(data: data!, encoding: String.Encoding.utf8)
print("responseString = \(responseString!)")
if let responsedata = responseString!.data(using: String.Encoding.utf8)! as? Data{
do {
let jsonResult:NSDictionary = try JSONSerialization.jsonObject(with: responsedata, options: []) as! NSDictionary
print("Get The Result \(jsonResult)")
//parse your jsonResult as per your requirements
if error != nil {
print("error=\(error)")
completionHandler(false, true, jsonResult)//
}
if let str = jsonResult["success"] as? NSNull {
print("error=\(str)")
completionHandler(false, true, jsonResult)
}
else {
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
// print("Response string : \(responseString)")
completionHandler(true, false, jsonResult)
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
}
}) .resume()
}catch {
print("Error ->Catch")
}
}
Add to your viewcontroller
func isUniqueEmail(email: String){
ApihelperClass.sharedInstance.callPostRequest("http://localhost/firstpostget/functions/get.php", params: ["email":email as AnyObject], completionHandler: { (success, error, result) in
//success 200
}) { (success, error) in
//error
}
}
you can use URlSession like :
func isUniqueEmail(email: String,completion: #escaping (Bool) -> ()) {
var request = URLRequest(url: URL(string: "http://localhost/firstpostget/functions/get.php")!)
request.httpMethod = "POST"
let postString = "email=\(email)"
request.httpBody = postString.data(using: .utf8)
// loading to wait request
UIApplication.shared.isNetworkActivityIndicatorVisible = true
let task = URLSession.shared.dataTask(with: request) { data, response, error in
// we get request request
UIApplication.shared.isNetworkActivityIndicatorVisible = false
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(String(describing: error))")
completion(false)
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
completion(false)
}else{
completion(true)
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(String(describing: responseString))")
}
task.resume()
}
and used in code Like
self.isUniqueEmail(email: "your Email") { (isExit) in
if isExit {
}else{
}
}
Ok, I just found a solution. My semaphore approach actually worked as well as dispatchgroups. The task just needed to be URLSession.shared.dataTask
Still thank's a lot for all the answers.

How to use special characters \n in URL

I have POST request:
init (url: String,arg: String) {
self.responseString = nil
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = "POST"
let postString = arg
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) {
data, response, error in
guard let data = data, error == nil else {
print("error=\(error)")
self.responseString = nil
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { //
self.responseString = nil
} else {
self.responseString = String(data: data, encoding: .utf8)
}
}
task.resume()
}
When arg have a character \n, half arg text is lost. How fix this problem?
strUrl = strUrl.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!
let url = URL.init(string: strUrl)
let requestURL = URLRequest(url: url!)
You need to add addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) method to allow URL Query.

swift http request crash nil value

I am using the following code to retrieve a response from a php page. Its works fine except every once in a while it crashes with an error after recieveing a nil value on the following line:
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
is there a way I can catch this?
let myUrl = NSURL(string: "https://*****backend/newmessage.php")
let request = NSMutableURLRequest(url: myUrl! as URL)
request.httpMethod = "POST"
let postString = "userid=\(userid!)"
print(postString)
request.httpBody = postString.data(using: String.Encoding.utf8)
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async {
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
if error != nil {
print("Error: \(error)")
}
DispatchQueue.main.async() {
print(responseString!)
if (responseString! == "NEW"){
self.messageIcon.setImage(UIImage(named: "newmessage.png"), for: UIControlState.normal)
}else{
self.messageIcon.setImage(UIImage(named: "envelope.png"), for: UIControlState.normal)
}
}
}
}
task.resume()
Why not address a potential nil w/ an if-else statement? Alternatively, you could use a guard statement.
if responseString != nil { // do stuff } else { // do other stuff}

http post method passing multiple json parameters with alamofire in swift 2.0

strong text this is my code to pass two parameters(jsonData and device_Secret) to httpBody for that i should get following son in response
{"success":false,"msg":"Key not created plz try again."}
but i m getting this
responseString = Optional({"success":false,"msg":"Invalid Method"})
there is a problem in parameters format, what i am doing wrong?
my code is following /////////////
let JsonData = ["method":"device_token","params":["key":"1234jhg","device_id":"eb7e630a9637b0b83557e5a62121be8cb9210afb9aa5b878f819b775cb7d42a6"]]
let device_secret = ["params":["token":"-1","device_id":"9de47fb53c67eca4","key":"-1"]]
let params = ["data":JsonData, "device_secret":device_secret] as Dictionary<String, AnyObject>
let request = NSMutableURLRequest(URL: NSURL(string: "http://dev.jobsmarket.pk/api/v1")!)
print(request)
request.HTTPMethod = "POST"
let data : NSData = NSKeyedArchiver.archivedDataWithRootObject(params)
print("NSdata of params is")
print(data)
NSJSONSerialization.isValidJSONObject(params)
print( NSJSONSerialization.isValidJSONObject(params))
// request.HTTPBody = params
request.HTTPBody = NSKeyedArchiver.archivedDataWithRootObject(params)
print("httpBody is ")
print(request.HTTPBody)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
guard error == nil && data != nil else { // check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("responseString = \(responseString)")
}
task.resume()
/////////////////////////