'Callback' is a missing argument in call? - ios

I have a Seperated Swift file for the call. this looks like this:
var DEVICEBUNDLE_API_ROOT = "https://apps-dev.profects.nl/profects-apps/current/web/app.php/api/v2/device"
var session = NSURLSession.sharedSession()
init(action: NSString, data: NSString, callback: (success: Bool, data: NSDictionary) -> Void) {
var body = "{\"action\":\"" + action + "\",\"data\":" + data + "}";
var request = NSMutableURLRequest(URL: NSURL(string: DEVICEBUNDLE_API_ROOT)!)
request.HTTPMethod = "POST"
request.HTTPBody = body.dataUsingEncoding(NSUTF8StringEncoding) // Use UTF-8
var task = session.dataTaskWithRequest(request, completionHandler: {
data, response, error -> Void in
var strData = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Response: \(strData)")
var json = NSJSONSerialization.JSONObjectWithData(data, options : .MutableLeaves, error: nil) as? NSDictionary
if let parsedJSON = json
{
if let status = parsedJSON["status"] as? NSDictionary
{
if let statusCode = status["code"] as? NSString
{
if let responseData = parsedJSON["data"] as? NSDictionary
{
callback(success: statusCode == "201", data: responseData)
}
else
{
callback(success: false, data: NSDictionary())
}
}
}
}
})
task.resume()
}
The call for the login looks like this:
var request = JSONRequest("registerDeviceId", "{\"email\":\"" + usernameField.text + "\",\"password\":\"" + passwordField.text + "\", \"UUID\":\"Tset124235346456457567\", \"OS\":\"Android\"}")
Now an error shows up saying 'Missing Argument for parameter 'callback' in call'
How can I fix this? I already tried adding an value "" at the end of the call.

You are missing the callback. This is the closure that will be called when the request has finished running.
let action = "registerDeviceId"
let data = ...whatever...
var request = JSONRequest(action: action, data: data, callback: { (success: Bool, data: NSDictionary) in
// Do something here with the success and data info that you got from the request
return
})
More information about closures

Related

How to parse Json and Normal Parmeters with URLSession swift 3

I am passing parameters in parameters And Using below code.
this is ok for this parametere: module = mymoduleName and userId = userId
func callWebServices(url: String, methodName: String, parameters: String,istoken: Bool, tokenval: String, completion: #escaping CompletionHandler){
var url_param = url
if(methodName == "GET" && parameters != "")
{
url_param = url_param + "?" + parameters
}
var request = URLRequest(url: URL(string: url_param)!)
request.httpMethod = methodName
if(methodName == "POST" && parameters != "")
{
let postString = parameters
request.httpBody = postString.data(using: .utf8)
}
if(istoken)
{
request.setValue("Bearer " + tokenval , forHTTPHeaderField: "Authorization")
}
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data, error == nil else {
print("error=\(String(describing: error))")
return
}
if let httpsStatus = response as? HTTPURLResponse, httpsStatus.statusCode != 200 {
print("Status Code should be 200, but it is \(httpsStatus.statusCode)")
print("response = \(String(describing: response))")
}
do {
let dictData = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! NSDictionary
completion(dictData)
} catch {
print("error is : \(error)")
}
}
task.resume()
}
But i have to parse parameters and json together like
module = mymoduleName
userId = userId and data = [{
"dmode_id": 1,
"user_id": 1,
"schedule_course_id": 1,
"course_id": 1}]
when i am calling this method getting error. help me to fix this issue. I am calling method like this.
callWebServices(url: URLS.Base_URL, methodName: "POST", parameters: param, istoken: false, tokenval: "", completion: { (jsonResult) in
print(jsonResult)
})

Expression resolves to an unused function (Swift)

I am new to swift programming and need bit of your help forgive me if i am asking something stupid. I am trying call a function from my UIViewController for a POST request to API. Calling function is like this
#IBAction func actionStartSignIn(sender: AnyObject) {
let email: String = txtEmail.text!
let password: String = txtPassword.text!
if !email.isEmpty && !password.isEmpty && General.isValidEmail(email) && password.characters.count>6{
var request = RequestResponse()
request.email = email
request.password = password
let isValid = NSJSONSerialization.isValidJSONObject(request)
print(isValid)
var requestBody: String = ""
// Facing issue in following line
RequestManager.sharedInstance.postRequest(Constants.BASE_URL + Constants.LOGIN, body: requestBody, onCompletion: {(json: JSON) in{
let result = json["response"]
print(result)
}
}
)
}
}
And Called Function is like this
func postRequest(route: String, body: String, onCompletion: (JSON) -> Void) {
makeHTTPPostRequest(route, requestBody: body, onCompletion: { json, err in
onCompletion(json as JSON)
})
}
Further,
// MARK: Perform a POST Request
private func makeHTTPPostRequest(path: String, requestBody: String, onCompletion: ServiceResponse) {
let request = NSMutableURLRequest(URL: NSURL(string: path)!)
// Set the method to POST
request.HTTPMethod = "POST"
do {
// Set the POST body for the request
// let jsonBody = try NSJSONSerialization.dataWithJSONObject(body, options: .PrettyPrinted)
// request.HTTPBody = jsonBody
request.HTTPBody = requestBody.dataUsingEncoding(NSUTF8StringEncoding);
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
if let jsonData = data {
let json:JSON = JSON(data: jsonData)
onCompletion(json, nil)
} else {
onCompletion(nil, error)
}
})
task.resume()
}/* catch {
// error
onCompletion(nil, nil)
}*/
}
and
typealias ServiceResponse = (JSON, NSError?) -> Void
I am facing "Expression resolves to an unused function" while calling
RequestManager.sharedInstance.postRequest(Constants.BA‌​SE_URL + Constants.LOGIN, body: requestBody, onCompletion: {(json: JSON) in{ let result = json["response"] print(result) } } )
May be i am missing some basic syntax. Any help will be really appreciated.
Thank You.
Remove the { } phase after the in will solve the problem.
It should look like this:
RequestManager.sharedInstance.postRequest(Constants.BASE_URL + Constants.LOGIN, body: requestBody, onCompletion: {(json: JSON) in
let result = json["response"]
print(result)
}
)
For the closure param, you should not type it by yourself to prevent typo. Use tab key to select that param, then press enter, xCode will auto generate the code for you.
If use the way I just said, the trailing closure will look like this:
RequestManager.sharedInstance.postRequest(Constants.BASE_URL + Constants.LOGIN, body: requestBody) { (json) in
let result = json["response"]
print(result)
}

NSData to [String : AnyObject]

I have some legacy code I am porting to Swift 2.0 which is producing an error, where previously it had worked ok.
The error is : Cast from 'NSData?' to unrelated type '[String : AnyObject]' always fails
Prior to moving the code to a new project I did not receive the error and the code had worked just fine.
Code:
func RestApiRequest(RestPath RestPath:String, Method:Alamofire.Method, Headers:NSDictionary?, Body:AnyObject?,ContentType:String,
OnCompletion:(StatusCode:Int, ResponseData:NSData, inout ResponseError:NSError?) -> (Void))
{
//Set REST url to be called
let mutableURLRequest = NSMutableURLRequest(URL: NSURL(string: "\(self.baseUrl!)\(RestPath)")!)
//Store body data if it exists
var data: NSData?
//Check if body value is set
if(Body != nil) {
//Check if body is a dictionary
if(Body is NSDictionary){
//Convert to JSON
let jsonBody = JSON(Body!)
data = try! jsonBody.rawData()
}
//Check if body is an array
else if(Body is NSArray) {
//convert to json
let jsonBody = JSON(Body!)
data = try! jsonBody.rawData()
}
else {
let bodyData = Body?.dataUsingEncoding(NSUTF8StringEncoding)
data = bodyData
}
}
let manager = Alamofire.Manager.sharedInstance
manager.session.configuration.HTTPAdditionalHeaders = Headers as? [NSObject : AnyObject]
manager.request(Method,mutableURLRequest, parameters: data as? [String : AnyObject], encoding: .Custom({ (convertible, params) in
let mutableRequest = convertible.URLRequest.copy() as! NSMutableURLRequest
if(data != nil) {
mutableRequest.HTTPBody = data
}
return (mutableRequest, nil)
})).response { (request, response, data, error) in
var _error = error
print(request)
print(NSString(data: data!, encoding:NSUTF8StringEncoding))
OnCompletion(StatusCode: (response?.statusCode)!, ResponseData: data!, ResponseError: &_error)
}
}
}
Is there a way to successfully make this conversion without producing an error?

How to make rest api call with HTTP PUT method in swift

I have tried the below REST Api with PUT method.
Here is my code,
let url = NSURL(string: "http://sampleurl")
let request = NSMutableURLRequest(URL: url!)
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "PUT"
let session = NSURLSession(configuration:NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: nil, delegateQueue: nil)
let params:[String: AnyObject] = ["deviceId" : "device_1","mobileDeviceId" : "abcd","deviceType":"ios"]
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions(), error: nil)
let dataTask = session.dataTaskWithRequest(request) { (data, response, error) -> Void in
if error != nil {
//handle error
print("Parsed error: '\(error)'")
}
else {
let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Parsed JSON: '\(jsonStr)'")
}
}
dataTask.resume()
It is not working. Please help me to find out where it is wrong.
This is a working code, I send your dictionary as a JSON formatted string to the server, and in the server, I parse the request and build another JSON object that contains the same values as the request, and send them back to the app. In the app, I parse the response and print the results:
let session = NSURLSession.sharedSession()
let url = "http://localhost:8080/yourServerGoesHere/putMethodTest"
let request = NSMutableURLRequest(URL: NSURL(string: url)!)
request.HTTPMethod = "PUT"
let params:[String: AnyObject] = ["deviceId" : "device_1","mobileDeviceId" : "abcd","deviceType":"ios"]
do{
request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions())
let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
if let response = response {
let nsHTTPResponse = response as! NSHTTPURLResponse
let statusCode = nsHTTPResponse.statusCode
print ("status code = \(statusCode)")
}
if let error = error {
print ("\(error)")
}
if let data = data {
do{
let jsonData = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions())
let deviceId = jsonData["deviceId"] as! String
let mobileDeviceId = jsonData["mobileDeviceId"] as! String
let deviceType = jsonData["deviceType"] as! String
print (" deviceId= \(deviceId), mobileDeviceId= \(mobileDeviceId), deviceType= \(deviceType)")
}catch _ {
print ("the response is not well JSON formatted")
}
}
})
task.resume()
}catch _ {
print ("Oops something happened buddy")
}
If you want to try, this is the Java web service code:
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
#Path("/putMethodTest")
#PUT
#Consumes(MediaType.TEXT_PLAIN)
public Response putMethodTest(String requestString) {
JSONObject requestJSON = new JSONObject(requestString);
String deviceId = requestJSON.getString("deviceId");
String mobileDeviceId = requestJSON.getString("mobileDeviceId");
String deviceType = requestJSON.getString("deviceType");
JSONObject response = new JSONObject();
response.put("deviceId", deviceId);
response.put("mobileDeviceId", mobileDeviceId);
response.put("deviceType", deviceType);
return Response.ok().entity(response.toString()).build();
}
Define the put function like this :
//
// Put request
//
static func put(path: String, accessToken: Bool, data: Dictionary<String, AnyObject>, finish: (accessTokenX:String, data: JSON) -> ()) {
apiRequest("PUT", path: path, accessToken: accessToken, contentType: nil, data: data) { (accessTokenX:String, data: AnyObject) in
dispatch_async(dispatch_get_main_queue(), {
finish(accessTokenX:accessTokenX, data: JSON(data))
})
}
}
An example of use :
//
// Update informations of the profile
//
static func accountUpdate(profile: [String: AnyObject], finish: (accessTokenX:String, data: JSON) -> ()) {
let dataProfile = ["profile": profile]
API.put("/users/profile", accessToken: true, data: dataProfile) { accessTokenX, data in finish(accessTokenX:accessTokenX, data: data)
}
}
Try this!!!
http://jamesonquave.com/blog/making-a-post-request-in-swift/
func data_request()
{
let url:NSURL = NSURL(string: url_to_request)!
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData
let paramString = "data=Hello"
request.HTTPBody = paramString.dataUsingEncoding(NSUTF8StringEncoding)
let task = session.dataTaskWithRequest(request) {
(
let data, let response, let error) in
guard let _:NSData = data, let _:NSURLResponse = response where error == nil else {
print("error")
return
}
let dataString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print(dataString)
}
task.resume()
}

AFNetworking and Swift

I'm trying to get a JSON response using Swift.
I sniffed the request and response -> everything ok. However the return value is always nil.
let httpClient = AppDelegate.appDelegate().httpRequestOperationManager as AFHTTPRequestOperationManager;
let path = "/daten/wfs";
let query = "?service=WFS&request=GetFeature&version=1.1.0&typeName=ogdwien:AMPELOGD&srsName=EPSG:4326&outputFormat=json".stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding);
func successBlock(operation: AFHTTPRequestOperation!, responseObject: AnyObject!) {
println("JSON: " + "\(responseObject)")
}
func errorBlock(operation: AFHTTPRequestOperation!, error:NSError!) {
println("Error: " + error.localizedDescription)
}
let urlString = "\(path)" + "/" + "\(query)"
println("urlString: " + httpClient.baseURL.absoluteString + urlString)
I also tried it this way:
httpClient.GET(urlString, parameters: nil,
success: { (operation: AFHTTPRequestOperation!, responseObject: AnyObject!) -> Void in
println("Success")
println("JSON: " + "\(responseObject)")
},
failure:{ (operation: AFHTTPRequestOperation!, error:NSError!) -> Void in
println("Failure")
})
... But the responseObject always seems to be nil
EDIT:
Maybe the reason is the possible wrong initialisation in my AppDelegate:
var httpRequestOperationManager: AFHTTPRequestOperationManager? // JAVA SERVER Client
class func appDelegate() -> AppDelegate {
return UIApplication.sharedApplication().delegate as AppDelegate
}
func configureWebservice() {
let requestSerializer = AFJSONRequestSerializer()
requestSerializer.setValue("1234567890", forHTTPHeaderField: "clientId")
requestSerializer.setValue("Test", forHTTPHeaderField: "appName")
requestSerializer.setValue("1.0.0", forHTTPHeaderField: "appVersion")
let responseSerializer = AFJSONResponseSerializer()
AFNetworkActivityIndicatorManager.sharedManager().enabled = true
// ##### HTTP #####
let baseURL = NSURL(string: "http://data.wien.gv.at");
httpRequestOperationManager = AFHTTPRequestOperationManager(baseURL: baseURL))
httpRequestOperationManager!.requestSerializer = requestSerializer
httpRequestOperationManager!.responseSerializer = responseSerializer
}
Any suggestions what I'm doing wrong?
Swift is fully compatible with Objective-C code, so your problem is not connected with Swift itself. In AFNetworking, the responseObject can sometimes be nil. This includes cases, where:
A 204 No Content status code was returned,
If output stream was set to write to file,
If the error during validation wasn't NSURLErrorCannotDecodeContentData (e.g. unacceptable content type)
Check out #740 and #1280 for more information.
You can use Swift's interoperability with Objective-C frameworks but now there is an official library out there, let's check it out:
https://github.com/Alamofire/Alamofire
This library is written in native Swift, from the creator of AFNetworking. You will probably want to look for this kind of thing when moving to Swift. I tried it out and it's awesome, like its predecessor.
HttpManager.sharedInstance.getNewestAppList("\(self.numberofPhoto)", offset: "0", device_type: "ios",search: self.strSearch, filter: self.strFilter, onCompletion: { (responseObject: NSDictionary?, error: NSError?) -> Void in
if error != nil {
SwiftLoader.hide()
self.showAlertWithMessage("\(error!.localizedFailureReason!)\n\(error!.localizedRecoverySuggestion!)")
} else {
SwiftLoader.hide()
if responseObject!.valueForKey("status") as! NSString as String == "0" {
self.showAlertWithMessage(responseObject!.valueForKey("message") as! NSString as String)
} else {
self.itemsArray = responseObject!.valueForKey("data") as! NSArray
print(self.itemsArray.count)
self.tableCategoryDetailRef.reloadData()
}
}
})
import Foundation
typealias getResponse = (NSDictionary?, NSError?) -> Void
class HttpManager: NSObject {
var AFManager: AFURLSessionManager?
var strUrl: NSString = "url"
class var sharedInstance:HttpManager {
struct Singleton {
static let instance = HttpManager()
}
return Singleton.instance
}
// MARK: - Method
func getCount(device_type:String, onCompletion: getResponse) -> Void {
let post: String = "device_type=\(device_type)"
let postData: NSData = post.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: true)!
let postLength:NSString = String(postData.length)
let configuration: NSURLSessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
AFManager = AFURLSessionManager(sessionConfiguration: configuration)
let URL: NSURL = NSURL(string: "\(strUrl)/count" as String)!
let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: URL)
urlRequest.HTTPMethod = "POST"
urlRequest.setValue(postLength as String, forHTTPHeaderField: "Content-Length")
urlRequest.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
urlRequest.HTTPBody = postData
let task = AFManager?.dataTaskWithRequest(urlRequest) { (data, response, error) in
if response == nil {
SwiftLoader.hide()
} else {
let responseDict:NSDictionary = response as! NSDictionary
onCompletion(responseDict,error)
}
}
task!.resume()
}
}

Resources