LinkedIn SDK ios swift - ios

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

Related

Stuck with Api response Ktor

I am trying to build a KMM application using Ktor for our ApiServices. I have created a BaseApiClass where I have all of the api related code.
Code for BaseApiClass :-
class BaseAPIClass {
//Create Http Client
private val httpClient by lazy {
HttpClient {
defaultRequest {
host = ApiEndPoints.Base.url
contentType(ContentType.Application.Json)
header(CONNECTION, CLOSE)
}
install(Logging) {
logger = Logger.DEFAULT
level = LogLevel.ALL
}
install(HttpTimeout) {
requestTimeoutMillis = NETWORK_REQUEST_TIMEOUT
}
expectSuccess = false
// JSON Deserializer
install(JsonFeature) {
val json = Json {
ignoreUnknownKeys = true
coerceInputValues = true
}
serializer = KotlinxSerializer(json)
}
}
}
// Api Calling Functions I have few more similar to this but issue is random and comes in any of the api
#Throws(Exception::class)
suspend fun sampleApi(requestBody: RequestBody?) : Either<CustomException, BaseResponse<EmptyResponseModel>> {
return try {
val response = httpClient.post<BaseResponse<EmptyResponseModel>> {
url(ApiEndPoints.sample.url)
if (requestBody != null) {
body = requestBody
}
}
Success(response)
}
catch (e: Exception) {
Failure(e as CustomException)
}
}
Here's how I call the api from iOS app :-
val apiClass = BaseApiClass()
func callApi() {
apiClass.sampleApi(requestBody: .init(string: "value here")) { (result, error) in
result?.fold(failed: { (error) -> Any? in
// Error here
}, succeeded: { (result) -> Any? in
// Success here
})
}
}
Now here if I try to call similar few more api's with the same object i.e apiClass then after few calls it get stuck inside my function callApi it don't send even api request (Because I can't see Request Logs printed in my console) and because of that I cannot do any other operations as I don't get anything from api.
As soon as I change my screen or close the app and try to call the same api then it works good.
But instead of creating a object only at one time like this apiClass = BaseApiClass() if I try to do with BaseApiClass().sampleApi(request params here) {// completion handler here} it works fine I don't get any issues with this.
I am not sure what causes this to happen everything works good in Android this is faced only with iOS.
Try to set LogLevel.NONE in the install(Logging) block.
At the moment I resolved in this way because it seems a bug of Ktor.
See: https://youtrack.jetbrains.com/issue/KTOR-2711
It should be fixed in the version 1.6.0.
Are you using the multithreaded variant of the Coroutines library? The official docs state that you should use this variant when working with Ktor. See here
After all the efforts and trying a lot of debugging skills I got to understand that my completion handler in the shared module is never called even if I receive the response the response from api.
The only solution I have achieved is creating the different HTTP Client using expect and actual mechanism. By making separate clients I have not encountered the issue yet.
If you have any other answers or solutions I would be happy to have a look at it.

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

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});
});

How do I convert this line of code to swift 2.0?

I am a new programmer. I started learning swift 2.0 without objective c, which I guess was a mistake.
I am trying to integrate quickblox into my swift app, however this line of code is really confusing me. I was wondering if someone could give me a hand
- (void (^)(QBResponse *response, QBUUser *user))successBlock
{
return ^(QBResponse *response, QBUUser *user) {
// Login succeeded
};
}
The function returns a block function, which gets two parameters: the response and the user. Its return type is void.
So in swift, it should basically look like this:
func successBlock() -> (QBResponse, QBUUser) -> Void {
return { (response, user) in
//Login succeeded.
}
}
It could also be converted to a computed property as it does not have side effects and does not rely on any parameters:
var successBlock: (QBResponse, QBUUser) -> Void {
return { (response, user) in
//Login succeeded.
}
}

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 :)

How one tests http requests in iOS 8?

In ruby I used to test http requests with vcr gem which recorded the request so the tests didn't send request to real host. Is there anything like this in iOS8 world?
The requests I want to test really need to be recorded since those requests may be outdated in some time and will return some other response
P.S. It would be great if it was some default Apple/iOS approach/library like XCTest for testing in general
What you want is something like OHHTTPStubs or Nocilla or AMY server. All of them essentially use NSURLProtocol to intercept your request and allow you to designate a response. We used OHHTTPStubs but pick the one with the feature set closest to your use case.
Here's an example of an OHHTTPStubs implementation in a unit test for a service that talks to a single REST endpoint:
NSString *loadRoomJSON = #{ #"key" : #"value" }; /* some JSON */
NSNumber identifier = #1;
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) {
NSString *url = [NSString stringWithFormat:#"v1/user/%#/room", identifier];
XCTAssert([request.URL.relativePath containsString:url], #"Expected certain URL");
return YES;
} andRespond:^OHHTTPStubsResponse *(NSURLRequest *request) {
return [OHHTTPStubsResponse responseWithJSONObject:loadRoomJSON statusCode:200 headers:nil];
}];
XCTestExpectation *loadPromise = [self expectation:#"Room loaded"];
[service loadRoomOnSucceed:^(Room *room) {
// Do your asserts here. For us, the JSON is mapped to an object
// so for example you could assert that the object is mapped correctly
[loadPromise fulfill];
} onFail:^(NSError *error) {
expect(error).to.beNil();
}];
[self waitForExpectationsWithTimeout:1.0 handler:^(NSError *error) {
expect(error).to.beNil();
}];
In reality our tests are shorter since we write wrapper/helpers to make it read better so this is an exploded-out version. Should give you the general idea. OHHTTPStubs (if you use it) has helper functions to load responses directly from files as well.
Im not sure if I understood you correct. But if I understand you right, you should be able to use XCTest to test your request and response.
class Tests:XCTestCase{
func testing(){
var expectation = self.expectationWithDescription("Your request")
var url = NSURL(string: "http://yourUrl.com")
let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in
if let httpRes = response as? NSHTTPURLResponse {
println("status code=",httpRes.statusCode)
//200 means OK
if httpRes.statusCode == 200 {
println(NSString(data: data, encoding: NSUTF8StringEncoding))
}
}else{
println("error \(error)")
}
}
}
}

Resources