Crash on server Socket.io callback, using swift client library - ios

I've this swift code:
[[self.socket emitWithAck:#"setup_request" with:#[]] timingOutAfter:0 callback:^(NSArray* data) {
NSLog(#"%#", data);
}];
paired with this server function:
client.on('setup_request', function(data, callback) {
callback({ success:true});
});
but when executing it, the server crashes with this message:
callback({ success:true});
^
TypeError: callback is not a function
I'm using server version 2.0.4, and the 13.1.0 Swift client library.
I can't see what I'm doing wrong, and how to fix this error. Thanks for your help.

So i guess there exist some kind of bridging in your project as clearly the first block is Objective C code, and your code is in swift.
Also callback:^(NSArray* data), means the callback expects an NSArray to be passed, but in your code you are passing a closure.
Pass an NSArray instead : callback(["success"] as? NSArray)

Found the issue, the server method interface has changed in version 2.0, now it's like:
client.on('setup_request', (callback) => {
callback({success:true});
});

Related

How to read the body of the request in Azure App Service?

I am trying to create an EasyAPI in Azure App Service (migrated from Azure Mobiles Services). The message is sent from an iOS app using the following command in swift:
let query: Dictionary<String, AnyObject> = ["name": theName]
let param: Dictionary<String, AnyObject> = ["collectionName": theCollectionName, "query": query]
AOAppDelegate.client!.invokeAPI("FMDataAPI", body: param, HTTPMethod: "POST", parameters: nil, headers: nil, completion: {(objects, httpResponse, error) in
if error == nil {
//Process response
} else {
print(error!.userInfo)
}
})
In the API I have the following Javascript code within the EasyAPI MyEasyAPI:
module.exports = {
"post": function (req, res, next) {
console.log("---------------------------------------")
console.log(req.body)
},
But body stays undefined.
Any suggestions?
Thanks,
GA
You need to adjust the app before the easy API gets called. By the time you are adding the middleware, it's too late. Fortunately, bodyparser is already implemented for you. Note that generally, you need to be doing something that expects a body - like a POST - to do this.
Since this is a migrated mobile service, you need to follow the instructions for mobile services - things that are documented for App Service are generally only available for upgraded sites (that is, sites running on App Service that have not been migrated).
Good news is that we have some help there if you need it. Check out the node module: https://github.com/Azure/azure-mobile-apps-node-compatibility for more information.
Thanks for your suggestions.
I reported an issue in the github project of the Azure Mobile Apps iOS client and they suggested that the problem could be in the version of the node package azure-mobile-apps and this was the case.
The azure-mobile-apps package was in version 2.0.0. After I updated to 2.1.0 req.body started to receive data.
Here you have the link to the Gihub issue discussion.
Thanks again for your suggestions.
GA
I had a similar use case with my custom API and fetched the parameter data via the query statement - I used a GET call, but that shouldn't make any difference here:
module.exports = {
get: function (req, res, next) {
var param = req.query.completed;
console.log(param);
}
};
The call with the attached parameter dictionary on the iOS side looked as follows:
[self.client invokeAPI:#"resetMyItems"
body:nil
HTTPMethod:#"GET"
parameters:#{#"completed": #(self.completed)}
headers:nil
completion:^(id result, NSHTTPURLResponse * _Nullable response, NSError * _Nullable error) {
if (error == nil) {
NSLog(#"Got answer from my own API: %#", result);
}
else {
NSLog(#"Something went wrong with POST api call: %#", error);
}
}
];
I searched quite a long time to find out, that the parameter you attach on your API call on the iOS side is called EXACTLY the same as on the query statement on your request.
Hope that helps :)

Parse PFCloud.callInBackground completion block never called i.e no response received

I have defined a function in the Parse Cloud Code called "relatedWords". When I try call this function in my iOS app, the completion block/closure is never called i.e no response is received.
I've tested the function in the Parse API Console and it is working fine there, so I know it's not an issue with the cloud code.
Any ideas on what the issue is?
My swift code:
func fetchRelatedKeyWordsForWord(word: String)
{
PFCloud.callFunctionInBackground("relatedWords", withParameters: ["hashtag": word]) { (response, error) -> Void in
//This is never called
print(response)
print(error)
}
}
Snippet of the cloud code:
Parse.Cloud.define("relatedWords", function(request, response) {
Parse.Cloud.useMasterKey();
var hashtag = request.params.hashtag;
...
...
//Run a query
var query = new Parse.Query(parseClassName);
query.find({
success: function(results) {
if (results.length != 0) {
console.log("Found Objects! Returning Objects");
response.success(results);
return;
}
Edit:
I figured out the problem. It was silly mistake by me. The reason the cloud code was not getting called is that I had not setup parse in my ApplicationDidFinishLaunching i.e I did not call Parse.setApplicationId("...", clientKey: "...")
I figured out the problem. It was silly mistake by me. The reason the cloud code was not getting called is that I had not setup parse in my ApplicationDidFinishLaunching i.e I did not call Parse.setApplicationId("...", clientKey: "...")
I figured out the problem.
you can use other server, other vise pay money on parse and solve the problem.

Calling Objective-c function in swift

Im trying to implement CometChat in my swift application. I managed to import the Objective-c framework successfully via a bridging header. But now I'm stuck trying to call Objective-C methods from swift.
This is the method from the interface i want to call:
- (void)loginWithURL:(NSString *)siteURL
username:(NSString *)username
password:(NSString *)password
success:(void(^)(NSDictionary *response))success
failure:(void(^)(NSError *error))failure;
And this is how the method is called from Objective-C:
[cometChat loginWithURL:#"localhost/cometchat/" username:usernameTextField.text password:passwordTextField.text success:^(NSDictionary *response) {
NSLog(#"SDK log : Username/Password Login Success %#",response);
[self handleLogin];
} failure:^(NSError *error) {
NSLog(#"SDK log : Username/Password Login Error%#",error);
[self handleLoginError:#[#0,error]];
}];
So far i have this:
cometChat.loginWithURL("localhost/cometchat/", username: EmailField.text, password: PasswordField.text){
(success: [NSDictionary], failure:NSError) in {
println("did i make it here?")
}
}
The problem is, it says that there is missing argument "success", but its a mystery to me how it can be an argument, when it clearly returns the response. I want to know how to put together this method call. I also used the objectivec2swift converter, but it wasn't any help. Also, i have no clue what the # means before the #[#0,error]
I know its a beginners question, but i already wasted a whole day on this, since i couldn't find any tutorials on how to call such "complex" Obj-C methods from swift.
Try this :-
cometChat.loginWithURL("localhost/cometchat/", username: "abc", password: "123", success: { (response) -> Void in
print("SDK log : Username/Password Login Success \(response)")
}) { ( error) -> Void in
print("SDK log : Username/Password Login Error \(error)")
}
When you look at the Objective-C signature, you see that the method takes two closures: success is a void function that takes a dictionary, and failure is a void function that takes an error.
In your Swift code you have only one closure: a void function that takes a dictionary and an error.
You either need to change the Objective-C method to take just one closure, or change the Swift code to provide two closures.
When you call a function, and the last parameter is a block / closure, then you can write the last parameter after the function call in { }. That applies to the last block only.
Anyway, you are trying to pass a closure with two parameters success and failure. You need to pass two closures, one as the success parameter of your function, with a parameter response, and one either as the failure parameter of your function, or following the function, with a parameter error.

LinkedIn SDK ios swift

I am trying to integrate LinkedIn SDK in iOS using swift
I found the below code in objective-C (https://developer.linkedin.com/docs/signin-with-linkedin)
NSString *url = [NSString initWithString:#"https://api.linkedin.com/v1/people/~"];
if ([LISDKSessionManager hasValidSession]) {
[[LISDKAPIHelper sharedInstance] getRequest:url
success:^(LISDKAPIResponse *response) {
// do something with response
}
error:^(LISDKAPIError *apiError) {
// do something with error
}];
]}
How to convert this to swift.
I am very new to swift
var url = NSString(string:"https://api.linkedin.com/v1/people/~")
if LISDKSessionManager.hasValidSession {
LISDKAPIHelper.sharedInstance().getRequest(url, success: {
response in
//Do something with the response
}, error: {
error in
//Do something with the error
})
}
This (I think its correct) is the translated version. I don't know Objective-C, I just used my knowledge of Swift to try and figure this out.
Have you learned about closures yet? If not, I don't recommend using SDKs like the LinkedIn one because they rely on closures for many networking requests. I'd check out Treehouse Inc., a coding course site which offers great courses on closures in Swift (along with a bunch of other stuff).
var url = "https://api.linkedin.com/v1/people/~"
if LISDKSessionManager.hasValidSession()
{
try? LISDKAPIHelper.sharedInstance().getRequest(url, success: {(_ response: LISDKAPIResponse) -> Void in
// do something with response
})
}
this is in swift 4

Objective-C completion block in Swift

I would like to call a completion block in Swift as I have always done in Objective-C. I took a look at closures, but for some reason, I cannot get it to work...
Obj-C:
- (void)someMethodWithParam1:(NSString *)param completion:(void(^)(NSArray* arr, NSURLResponse *resp))callback
{
callback(arr, resp);
}
Swift:
func someMethodWithParam1(param: NSString, completion:((NSArray?, NSURLResponse?)->())) ->(){
^
|
/* Error: Insert ',' here */
completion(arr, resp)
}
EDIT
Okay, it was not a syntactical error, but an error from my side. The method header I used here is different from the one in my code. So this code that I originally posted should work fine.
Typealias's are your friend here, just to make the code more readable
typealias onComplete = (NSArray?, NSURLResponse?) -> ()
func someMethodWithParam1(param: NSString, completion:onComplete) -> ()
{
completion(arr, resp)
}

Resources