Parsing response Facebook iOS sdk - ios

Could you help me to parse response correctly:
Parser in - (void)request:(FBRequest *) request didLoad:(id)result:
case education:{
NSArray *arrayRsult = [[result objectForKey:#"education"] objectForKey:#"school"];
for (NSDictionary *placeForResults in arrayRsult){
NSString *output = [placeForResults objectForKey:#"name"];
NSLog(#"%#", output);
}
}
break;
My request:
- (IBAction)eduacation:(id)sender {
currentApiCall = education;
FacebookInfoGetterAppDelegate *delegate = (FacebookInfoGetterAppDelegate *) [[UIApplication sharedApplication] delegate];
[[delegate facebook] requestWithGraphPath:#"me?fields=education" andDelegate:self];
}
But it returns array with nulls. Whats wrong?

first of all you need to set up rights for this - "user_education_history"
I corrected code for your parsing part because your receive dictionary with key education that consists array of your schools.
NSArray *arrayRsult = [result objectForKey:#"education"];
for (NSDictionary *placeForResults in arrayRsult){
NSString *output = [[placeForResults objectForKey:#"school"] objectForKey:#"name"];
NSLog(#"%#", output);
}
it works for me.

Related

Corruption of NSString or encoding issue in Objective C

Please see code below:
+ (void)splashDataFromJSON:(NSData *)objectNotation error:(NSError **)error
{
NSError *localError = nil;
NSDictionary *parsedObject = [NSJSONSerialization JSONObjectWithData:objectNotation options:0 error:&localError];
if (localError != nil) {
*error = localError;
}
NSMutableArray* btms = [[NSMutableArray alloc] init];
NSMutableDictionary* btmManufacturerResolutionDictionary = [[BTMCache sharedManager] btmManufacturerResolutionDictionary];
NSArray *results = [parsedObject valueForKey:#"results"];
NSLog(#"Count %d", parsedObject.count);
NSString* imageBaseUrl = [[parsedObject valueForKey:#"general"] valueForKey:#"image_base_url"];
imageBaseUrl = [imageBaseUrl stringByAppendingString:#"hdpi/"];
NSString* splashImageName = [[[parsedObject valueForKey:#"general"] valueForKey:#"splash"] valueForKey:#"img"];
NSString* splashAdvertiserURL = [[[[parsedObject valueForKey:#"general"] valueForKey:#"splash"] valueForKey:#"url"] copy];
NSMutableString* appendedString = [[NSMutableString alloc] init];
for(int i =0 ;i<[splashAdvertiserURL length]; i++) {
char character = [splashAdvertiserURL characterAtIndex:i];
printf(&character);
sleep(0.1);
if (character != "!")
{
[appendedString appendFormat:#"%c", character];
}
}
[[SplashData sharedManager] setSplashAdvertiserURL:appendedString];
[[SplashData sharedManager] setSplashImageName:splashImageName];
splashAdvertiserURL = [[SplashData sharedManager] splashAdvertiserURL];
}
The point of interest is in splashAdvertiserURL. When I receive this data and print it out using po, it comes out as "https://radar.com/ref/go/84/". This is fine and what was expected. When I look at the incoming data in JSONLint it looks like this:
"general": {
"image_base_url": "https:\/\/radar.com\/img\/manufacturers\/",
"splash": {
"img": "image1.png",
"url": "https:\/\/radar.com\/ref\/go\/84\/"
}
},
As you can see, further on I put the NSString into a singleton with an NSString property. Nothing abnormal here. I then proceed to retrieve it to see that all is ok. Further to this the program continues. In another class I wish to retrieve this information, and when I try and do that, it throws EXC_BAD_ACCESS. There appears to be garbage in there.
I then put in a loop in the code as you can see to print out the characters one at a time. Very curiously, when I print that out using po I get:
https://
r
a
d
ar.com/ref/go/8 4!/"
Exactly in that format. If I then proceed to hardcode the string https://radar.com/ref/go/84/ - including escape characters and everything, then all works fine. No issues. If I handle a normal string incoming without escape characters it stores fine in the singleton as well, no issue. enter code here
I am pretty stumped here as to what is going on. Can someone assist?
Thank you
For URL you received as string you need to encode before use it to in your app. Have a look at below code:
NSString *sampleUrl = #"https:\/\/radar.com\/ref\/go\/84\/";
NSString *encodedUrl = [sampleUrl stringByAddingPercentEscapesUsingEncoding:
NSUTF8StringEncoding];

How to get Mobile Number from vCard String Objective C

I am working on Action Extension Objective C. I have successfully created Extension for share recent contact in my Extension. In that I am getting v Card String. How can I get Mobile Number from v Card String. Any help would be appreciated.
Using contactsWithData:error: class method of CNContactVCardSerialization, you can retrieve info from a vCard.
It's from Contacts.framework, available since iOS9.
For earlier version, you can use AddressBook.framework. You can read info here.
NSError *errorVCF;
NSArray *allContacts = [CNContactVCardSerialization contactsWithData:[contactStr dataUsingEncoding:NSUTF8StringEncoding] error:&errorVCF];
if (!errorVCF)
{
NSMutableString *results = [[NSMutableString alloc] init];
//NSLog(#"AllContacts: %#", allContacts);
for (CNContact *aContact in allContacts)
{
NSArray *phonesNumbers = [aContact phoneNumbers];
for (CNLabeledValue *aValue in phonesNumbers)
{
CNPhoneNumber *phoneNumber = [aValue value];
[results appendFormat:#"%# %#\n", [aValue label], [phoneNumber stringValue]];
}
}
NSLog(#"Final: %#", results);
}

How to search local business by name, location in iOS?

I am working on project in which we are displaying local business search. I am using YELP to search local business. As per YELP Documentation i have created query. But it gives result based on location only.
I am trying with Google Place API but not getting desired result.
My YELP request - http://api.yelp.com/v2/search/?term=restaurant&location=nyc&limit=20&offset=1
My Google Place API request - https://maps.googleapis.com/maps/api/place/textsearch/json?query=hotels+in+nyc&sensor=true&key=AIzaSyCHwd5OgRXdeuTWV46SHdMLq2lXL20t22U
How can i get result by business name & location as well using any YELP or Google Place API?
Which one is better to use YELP or Google Place API?
1) I used Yelp API. Url for special business - http://api.yelp.com/v2/business/
For global search - http://api.yelp.com/v2/search
After search you must correctly pass data in api search url. Notice of url signature in NSStringWithFormat. And don't forget OAuth keys! My request:
-(void)searchBy:(NSString *)categoryFilter inLocationCity:(NSString *)aLocationCity {
NSString *urlString = [NSString stringWithFormat:#"%#?term=%#&location=%#",
YELP_SEARCH_URL,
categoryFilter,
aLocationCity];
NSURL *URL = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
OAConsumer *consumer = [[OAConsumer alloc] initWithKey:OAUTH_CONSUMER_KEY
secret:OAUTH_CONSUMER_SECRET];
OAToken *token = [[OAToken alloc] initWithKey:OAUTH_TOKEN
secret:OAUTH_TOKEN_SECRET];
id<OASignatureProviding, NSObject> provider = [[OAHMAC_SHA1SignatureProvider alloc] init];
NSString *realm = nil;
OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:URL
consumer:consumer
token:token
realm:realm
signatureProvider:provider];
[request prepare];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (conn) {
self.urlRespondData = [NSMutableData data];
}
}
Also add methods NSURLConnectionDelegate:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[self.urlRespondData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)d {
[self.urlRespondData appendData:d];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSError *e = nil;
NSDictionary *resultResponseDict = [NSJSONSerialization JSONObjectWithData:self.urlRespondData
options:NSJSONReadingMutableContainers
error:&e];
if (self.resultArray && [self.resultArray count] > 0){
[self.resultArray removeAllObjects];
}
if (!self.resultArray) {
self.resultArray = [[NSMutableArray alloc] init];
}
DLog(#"YELP response %#", resultResponseDict);
if (resultResponseDict && [resultResponseDict count] > 0) {
if ([resultResponseDict objectForKey:#"businesses"] &&
[[resultResponseDict objectForKey:#"businesses"] count] > 0) {
for (NSDictionary *venueDict in [resultResponseDict objectForKey:#"businesses"]) {
Venue *venueObj = [[Venue alloc] initWithDict:venueDict];
[self.resultArray addObject:venueObj];
}
}
}
[self.delegate loadResultWithDataArray:self.resultArray];
}
-(instancetype)initWithDict:(NSDictionary *)dict {
self = [super init];
if (self) {
self.name = [dict objectForKey:#"name"];
self.venueId = [dict objectForKey:#"id"];
self.thumbURL = [dict objectForKey:#"image_url"];
self.ratingURL = [dict objectForKey:#"rating_img_url"];
self.yelpURL = [dict objectForKey:#"url"];
self.venueId = [dict objectForKey:#"id"];
self.reviewsCount =[[dict objectForKey:#"review_count"] stringValue];
self.categories = [dict objectForKey:#"categories"][0][0];
self.distance = [dict objectForKey:#"distance"];
self.price = [dict objectForKey:#"deals.options.formatted_price"];
self.address = [[[dict objectForKey:#"location"] objectForKey:#"address"] componentsJoinedByString:#", "];
NSArray *adr = [[dict objectForKey:#"location"] objectForKey:#"display_address"];
self.displayAddress = [adr componentsJoinedByString:#","];
}
return self;
}
Method with yelp response values...You need just id. Coordinates need for you location...When you get some venues see theirs id with Log or print.
I solve my problem using Google Places API -
Thanks to This Answer.
We get JSON/XML response
Search hotels near City:
https://maps.googleapis.com/maps/api/place/textsearch/json?query=hotels+in+Pune&sensor=true&key=AddYourOwnKeyHere
Search specific place in city:
https://maps.googleapis.com/maps/api/place/textsearch/json?query=[SearchPlaceName]+in+[CityName]&sensor=true&key=AddYourOwnKeyHere
Search specific place in city by given type:
https://maps.googleapis.com/maps/api/place/textsearch/json?query=[SearchPlaceName]+in+[CityName]&type=[PlaceType]&sensor=true&key=AddYourOwnKeyHere
To retrieve image/icons for restaurant/place -
As per Documentation.
We can use photo_reference & request like -
https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=CoQBegAAAFg5U0y-iQEtUVMfqw4KpXYe60QwJC-wl59NZlcaxSQZNgAhGrjmUKD2NkXatfQF1QRap-PQCx3kMfsKQCcxtkZqQ&key=AddYourOwnKeyHere

empty json reponse in Foursquare2 venue Explore ios api

I'm working on iOS application with foursquare iOS api , I want to get the recommended near venues. I have used following code & it giving me an empty result .. Where have I done the mistake ? ? ?
NSArray* venues;
//get the foursquare locations
- (void)getTipsForLocation:(CLLocation *)location {
//NSLog(#"lat %f",location.coordinate.latitude);
[Foursquare2 venueExploreRecommendedNearByLatitude:#(location.coordinate.latitude)
longitude:#(location.coordinate.longitude)
near:nil
accuracyLL:nil
altitude:nil
accuracyAlt:nil
query:nil
limit:nil
offset:nil
radius:#(1500)
section:nil
novelty:nil
sortByDistance:1
openNow:0
venuePhotos:0
price:nil
callback:^(BOOL success, id result){
if (success) {
NSDictionary *dic = result;
venues = [dic valueForKeyPath:#"response.venues"];
FSConverter *converter = [[FSConverter alloc]init];
self.nearbyVenues = [converter convertToObjects:venues];
//NSLog(#"venues %#",venues);
//NSLog(#"near by places %#",self.nearbyVenues);
}
else{
NSLog(#" foursquare connecting error");
}
}];
NSLog(#"recommended place array %#",venues);
}
You Can Not pass Nil,In NSNumber & NSString.
NSNumber *emptynumber=[[NSNumber alloc] init];
[Foursquare2 venueExploreRecommendedNearByLatitude:lan longitude:lon near:#"" accuracyLL:emptynumber altitude:emptynumber accuracyAlt:emptynumber query:#"" limit:emptynumber offset:emptynumber radius:#(1500) section:#"" novelty:#"" sortByDistance:YES openNow:YES venuePhotos:YES price:#"" callback:^(BOOL success, id result) {
if (success) {
NSLog(#"secondResult: %#",result);
NSDictionary *dic = result;
NSArray *venues = [dic valueForKeyPath:#"response.venues"];
FSConverter *converter = [[FSConverter alloc] init];
self.venues = [converter convertToObjects:venues];
[self.tableView reloadData];
NSLog(#"Data: %#",venues);
}
}];
It Works For me.

Implementing OAuth 1.0 in an iOS app

I've been breaking my head over this the whole day.
I wish to integrate my iOS app with Withings api. It uses OAuth 1.0 and I can't seem to understand fully how to implement it.
I've been downloading multiple OAuth framworks (MPOAuth,gtm-oauth,ssoauthkit) but couldn't figure out completely what exactly I should do.
I searched a lot, also in stack overflow for good references on how to go about implementing OAuth 1.0 in general & integrating with Withings in particular with no success.
Kindly explain the flow of integrating an iOS app with an api that requires OAuth 1.0. Code examples would be very helpful. Suggested 3rd party frameworks would be nice too.
Just to clarify, I fully understand the OAuth 1.0 principles, I just have problems in actually implementing it in my app.
I think that a thorough answer with code examples and good references would be very helpful for lots of people as I couldn't find one. If anyone has good experience with implementing it, please take the time to share it.
TDOAuth in my opinion was the best solution. it is clean and simple, only one .h and .m file to work with, and no complicated example projects..
This is the OAuth 1.0 flow:
step 1 - get request token
//withings additional params
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:CALL_BACK_URL forKey:#"oauth_callback"];
//init request
NSURLRequest *rq = [TDOAuth URLRequestForPath:#"/request_token" GETParameters:dict scheme:#"https" host:#"oauth.withings.com/account" consumerKey:WITHINGS_OAUTH_KEY consumerSecret:WITHINGS_OAUTH_SECRET accessToken:nil tokenSecret:nil];
//fire request
NSURLResponse* response;
NSError* error = nil;
NSData* result = [NSURLConnection sendSynchronousRequest:rq returningResponse:&response error:&error];
NSString *s = [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
//parse result
NSMutableDictionary *params = [NSMutableDictionary dictionary];
NSArray *split = [s componentsSeparatedByString:#"&"];
for (NSString *str in split){
NSArray *split2 = [str componentsSeparatedByString:#"="];
[params setObject:split2[1] forKey:split2[0]];
}
token = params[#"oauth_token"];
tokenSecret = params[#"oauth_token_secret"];
step 2 - get authorize token (by loading the request in a UIWebView, the webViewDidFinishLoad delegate method will handle the call back..)
//withings additional params
NSMutableDictionary *dict2 = [NSMutableDictionary dictionary];
[dict setObject:CALL_BACK_URL forKey:#"oauth_callback"];
//init request
NSURLRequest *rq2 = [TDOAuth URLRequestForPath:#"/authorize" GETParameters:dict2 scheme:#"https" host:#"oauth.withings.com/account" consumerKey:WITHINGS_OAUTH_KEY consumerSecret:WITHINGS_OAUTH_SECRET accessToken:token tokenSecret:tokenSecret];
webView.delegate = self;
[DBLoaderHUD showDBLoaderInView:webView];
[webView loadRequest:rq2];
handle the webView as follow to initiate step 3 (I know the isAuthorizeCallBack smells a lot, but it does the job, should refactor it..)
- (void)webViewDidFinishLoad:(UIWebView *)aWebView
{
[DBLoaderHUD hideDBLoaderInView:webView];
NSString *userId = [self isAuthorizeCallBack];
if (userId) {
//step 3 - get access token
[DBLoaderHUD showDBLoaderInView:self.view];
[self getAccessTokenForUserId:userId];
}
//ugly patchup to fix an invalid token bug
if ([webView.request.URL.absoluteString isEqualToString:#"http://oauth.withings.com/account/authorize?"])
[self startOAuthFlow];
}
- (NSString *)isAuthorizeCallBack
{
NSString *fullUrlString = webView.request.URL.absoluteString;
if (!fullUrlString)
return nil;
NSArray *arr = [fullUrlString componentsSeparatedByString:#"?"];
if (!arr || arr.count!=2)
return nil;
if (![arr[0] isEqualToString:CALL_BACK_URL])
return nil;
NSString *resultString = arr[1];
NSArray *arr2 = [resultString componentsSeparatedByString:#"&"];
if (!arr2 || arr2.count!=3)
return nil;
NSString *userCred = arr2[0];
NSArray *arr3 = [userCred componentsSeparatedByString:#"="];
if (!arr3 || arr3.count!=2)
return nil;
if (![arr3[0] isEqualToString:#"userid"])
return nil;
return arr3[1];
}
- (void)startOAuthFlow
{
[self step1];
[self step2];
}
and finally - step 3 - get access token
- (void)getAccessTokenForUserId:(NSString *)userId
{
//step 3 - get access token
//withings additional params
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:CALL_BACK_URL forKey:#"oauth_callback"];
[dict setObject:userId forKey:#"userid"];
//init request
NSURLRequest *rq = [TDOAuth URLRequestForPath:#"/access_token" GETParameters:dict scheme:#"https" host:#"oauth.withings.com/account" consumerKey:WITHINGS_OAUTH_KEY consumerSecret:WITHINGS_OAUTH_SECRET accessToken:token tokenSecret:tokenSecret];
//fire request
NSURLResponse* response;
NSError* error = nil;
NSData* result = [NSURLConnection sendSynchronousRequest:rq returningResponse:&response error:&error];
NSString *s = [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
//parse result
NSMutableDictionary *params = [NSMutableDictionary dictionary];
NSArray *split = [s componentsSeparatedByString:#"&"];
for (NSString *str in split){
NSArray *split2 = [str componentsSeparatedByString:#"="];
[params setObject:split2[1] forKey:split2[0]];
}
[self finishedAthourizationProcessWithUserId:userId AccessToken:params[#"oauth_token"] AccessTokenSecret:params[#"oauth_token_secret"]];
}
I additionaly save request headers here
NSMutableDictionary *dict2 = [NSMutableDictionary dictionary];
[dict2 setObject:CALL_BACK_URL forKey:#"oauth_callback"];
NSURLRequest *rq2 = [TDOAuth URLRequestForPath:#"/authorize"
GETParameters:dict2
scheme:#"https"
host:#"oauth.withings.com/account"
consumerKey:WITHINGS_OAUTH_KEY
consumerSecret:WITHINGS_OAUTH_SECRET
accessToken:self.token
tokenSecret:self.tokenSecret];
headers = rq2.allHTTPHeaderFields;
And in callback method i will add missing parameters to the request. By doing it this way, i avoid "ugly patchup fix".
- (BOOL)webView:(UIWebView *)wV shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
if (![request.allHTTPHeaderFields objectForKey:#"Authorization"] &&
[request.URL.absoluteString rangeOfString:#"acceptDelegation=true"].location == NSNotFound){
NSMutableURLRequest *mutableCp = [request mutableCopy];
NSLog(#"request :::%#", request);
[mutableCp setAllHTTPHeaderFields:headers];
dispatch_async(dispatch_get_main_queue(), ^{
[webView loadRequest:mutableCp];
});
return NO;
}
return YES;
}
I hope it will help somebody
I would suggest you to check this project both as a reference and as a really working OAuth class. It inherits from another great project, so you you will need to add both in yours.Check if the license will suits your requirements.
https://github.com/rsieiro/RSOAuthEngine

Resources