Google Places API Autocomplete on iOS - ios

Over the last few days I've been struggling to get Google Places autocomplete to work on my app, and no matter what I do, I always get the REQUEST_DENIED error.
I followed Google's "tutorial" for the implementation, Places API is enabled, API key has the correct bundle ID, I also tested with a Browser ID, with no success.
I am pretty sure it has something to do with the key, though. Curiously, on the Android version of the app, the service will work with the Browser Key. And on the browser, obviously, it works with that key too.
These are the two keys I experimented with:
And this is my implementation code, using AFNetworking:
NSURL *url = [NSURL URLWithString:#"https://maps.googleapis.com/maps/api/place/autocomplete/"];
NSDictionary *params = #{#"input" : [input stringByReplacingOccurrencesOfString:#" " withString:#"+"],
#"location" : [NSString stringWithFormat:#"%f,%f", searchCoordinate.latitude, searchCoordinate.longitude],
#"sensor" : #(true),
// #"language" : #"pt_BR",
// #"types" : #"(regions)",
// #"components" : #"components=country:br",
#"key" : GOOGLE_API_KEY};
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
[httpClient setParameterEncoding:AFFormURLParameterEncoding];
[httpClient getPath:#"json"
parameters:params
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSDictionary *JSON = [[NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:nil] dictionaryWithoutNulls];
if (completion) {
completion(JSON[#"predictions"]);
}
}
failure:^(AFHTTPRequestOperation *operation, NSError *errorResponse) {
NSLog(#"[HTTPClient Error]: %# for URL %#", [errorResponse localizedDescription], [[[operation request] URL] path]);
}];
I know there are some questions like this one here, but some are old, and say that Places API does not work on Android or iOS, which clearly is not the case anymore, since Google itself publishes examples on both platforms, as seen on Places API page: https://developers.google.com/places/documentation/autocomplete
A workaround I'm currently using is Apple's GeoCoding system, which works good when you type the full address, but is terrible with half-typed phrases. This is not good at all, I'd really like to use Google's API.

I got it!
The paramenter sensor should receive either #"true"or #"false", and not #(true)or #(false).
For the record, the API key used is indeed the Browser Key, and not an iOS key.

You should init httpClient with base URL #"https://maps.googleapis.com/" and get path /maps/api/place/autocomplete/json. Base URL - host only, it does not take other parts of path, so in your case you get request to URL "https://maps.googleapis.com/json".

https://maps.googleapis.com/maps/api/geocode/json?address="%#","%#"&sensor=false,yourAddress,your c

Related

Is it possible using Foursquare API search places containing string?

I want search result like Google search.
Here if I search for 'tokyo' then it gives me four results containing place 'tokyo'.
Same functionality I want to do using Foursquare API. Currently I am able to find near places from current position or given position.
You need to use the https://api.foursquare.com/v2/venues/search endpoint and use the query parameter so that it will return matches based on your keyword. Since you're on iOS you can use UITableView to show the results as search suggestions or other libraries that fit your requirement. Since it will be like an autocomplete/autosuggest search, I suggest that you try to call the endpoint on the change event of the text field with a delay.
Example using AFNetworking Library for iOS:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
[params setObject:FOURSQUARE_CLIENTID forKey:#"client_id"];
[params setObject:FOURSQUARE_CLIENTSECRET forKey:#"client_secret"];
[params setObject:searchTextField.text forKey:#"query"];
[params setObject:LatLong forKey:#"ll"];
[params setObject:FOURSQUARE_VERSION forKey:#"v"];
[manager GET:#"https://api.foursquare.com/v2/venues/search" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
//Process the JSON response here and output each venue name as search suggestion
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
I suggest you read more on the FourSquare documentation and how to process JSON results and show them to a UITableView if you don't know how to yet.
Also notice that you still have to provide your "ll" as parameter since you can only query for nearby places using the endpoint.
For global search and not using "ll" or "nearby" parameter. You can try to use the global intent which according to the documentation:
Finds the most globally relevant venues for the search, independent of
location. Ignores all other parameters other than query and limit.

FB Graph Subscription IOS send access_token

There is something to the Facebook Graph SDK (and its iOS implementation) that really makes my life miserable. And it seems I'm on my own, because I don't seem to be able to find anyone on the 'net with a similar problem/lack of understanding like me.
Without further ado:
I have this code in my iOS app, that is supposed to subscribe my app to user updates:
-(void)subscribeToFacebook{
(FBSession.activeSession.isOpen) ? NSLog(#"is open") : NSLog(#"is closed");
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
#"page", #"object",
#"http://www.example.com/fbcallback.php", #"callback_url",
#"about, picture", #"fields",
#"ItsMeAlright", #"verify_token",
nil
];
/* make the API call */
[FBRequestConnection startWithGraphPath:#"/app/subscriptions"
parameters:params
HTTPMethod:#"POST"
completionHandler:^(
FBRequestConnection *connection,
id result,
NSError *error
) {
/* handle the result */
NSLog(#"error= %#",error);
}];
}
When I run this code, an error is logged, stating:
"(#15) This method must be called with an app access_token."
Now, I (think) I know how to get the access_token
NSString *fbAccessToken = [[[FBSession activeSession] accessTokenData] accessToken];
but I have't got a clue on where and when to send it to Facebook.
I tried to append it to the #"/app/subscriptions" part like this
NSString *urlString = [NSString
stringWithFormat:#"/app/subscriptions?access_token=%#",
[fbAccessToken stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
but that didn't work.
Your input is extremely welcome!
The way to do this will be to create a FBSession with the application token. Because the current session isn't what you want.
https://developers.facebook.com/docs/reference/ios/current/class/FBSessionTokenCachingStrategy
https://developers.facebook.com/docs/facebook-login/ios#sessions
But, security wise, you shouldn't be doing this at all. It's very insecure to embed your application token in a production application. I believe that the iOS sample generated for you is incorrect.
You should be sending any request that requires the application token with a server call (e.g. PHP)

why AFNetworking get unsupported url when putting '|' pipe sign in the url

I've been using AFNetworking for a while and ran into a bizarre issue today.
I'm do a GET request using AFNetworking with Google Places API
https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=21.283974,-157.836222&radius=1600&types=food|bar|cafe&key=myownapikeyhere
the places nearby search api uses type restriction to constrain the result you can get from the api. see document
the way you do it is to have parameter types=type1|type2|type3|etc, the type1, type2, type3 are the types of places you want fetch with the url.
I managed to get results when I paste the url into browser and request it. but whenever I use it with AFNetworking, the '|' sign seems to break it. It throws an unsupported url error.
Is there a reason with this issue? Any suggestion would be helpful.
Thanks!
Are you building this URL yourself? If you used the parameters of a AFNetworking GET request, I believe it would percent escape it properly. But if you build the URL yourself, you're not letting AFNetworking do the necessary percent escaping.
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *params = #{#"location" : #"21.283974,-157.836222",
#"radius" : #1600,
#"types" : #"food|bar|cafe",
#"key" : #"myownapikeyhere"};
[manager GET:#"https://maps.googleapis.com/maps/api/place/nearbysearch/json" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"responseObject = %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error = %#", error);
}];
It is too simple. Just replace the | with %7C
NSString *string = #"https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=21.283974,-157.836222&radius=1600&types=food|bar|cafe&key=myownapikeyhere";
NSString *newString = [string stringByReplacingOccurrencesOfString:#"|" withString:#"%7C"];

Facebook iOS SDK Graph Api Public Page Feed

Can anyone point me in the direction of a thorough tutorial on how to get a public page's post feed? I'd like to really understand what's going on rather than copying and pasting. Even still I haven't found anything I could copy and paste that works. I've managed to make some headway with the following code but the resulting json is not pretty and making extracting image urls virtually impossible (it doesn't require an appId, which I do actually have entered into the plist anyway). I'd rather be using FBRequestConnection. It doesn't seem like it'd be too challenging but I'm unfamiliar with the sdk and the documentation on this seems a bit wanting.
NSString *pageId = #"##################";
NSString *urlString = [NSString stringWithFormat:#"https://www.facebook.com/feeds/page.php?format=json&id=%#", pageId];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
self.tags = [[NSArray alloc] initWithObjects:#"#meditation", nil];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response,
NSData *data, NSError *connectionError)
{
QuoteItem *menuItem = [[QuoteItem alloc] init];
if (data.length > 0 && connectionError == nil)
{
NSDictionary *fbFeed = [NSJSONSerialization JSONObjectWithData:data
options:0
error:NULL];
NSMutableArray *entries = [fbFeed objectForKey:#"entries"];
I was trying to keep it brief, but to further clarify I've tried using the instruction given by facebook here (https://developers.facebook.com/docs/graph-api/reference/v2.2/page/feed#read) by doing the following:
[FBRequestConnection startWithGraphPath:#"/###########9055/feed"
parameters:nil
HTTPMethod:#"GET"
completionHandler:^(
FBRequestConnection *connection,
id result,
NSError *error
) {
/* handle the result
}];
And I get this runtime error: "FBSDKLog: Error for request to endpoint '/164313873599055/feed': An open FBSession must be specified for calls to this endpoint." So I looked up FBSession (which is not mentioned at the destination of the aforementioned link) and tried to remedy the situation but I'm not sure how to set permissions. What I have a tried led to a prompt for the user to allow access to their feed, which is not wanted. I just want the user to see this darn public page feed without having to log in, without seeing anything facebook related in the app.
Which is why I was looking for a thorough tutorial to step a person through the above in one place. These tutorials, I know, do exist for other aspects of iOS development and I was wondering if there was something similar for this case WITHOUT having to write an essay.
I doubt that you had a look in the Facebook docs, because there it's all outlined:
https://developers.facebook.com/docs/graph-api/reference/v2.2/page/feed/#read
The call is
/{page_id}/feed
where {page_id} is the id of the Page you're looking for. You'll need to add an Access Token to the call.

To understand the AFNetworking ios library AFXMLRequestOperation

Hi I am new to AFNetworking library and am integrating it for first time in my iPAD app. However I am having hard time finding a working example for reference.
I found the following solution by rckoenes here AFNetworking POST and get Data back. However I am hard time implementing it. Since that answer is already marked as correct. I am assuming the library as changed since that time and the example might not be relevant.
Any help with a working example reference is highly appreciated.
NSURLRequest *request = [wsu generateURLRequest:getFavAPI method : #"GET" arguments:nil eventName:USER_FAVS_SUCCESS_NOTIF contentType:nil];
NSLog(#"Request %#", request.description);
AFXMLRequestOperation *favOpertion = [[AFXMLRequestOperation alloc] initWithRequest:request];
//favOpertion.responseXMLParser = [NSXMLParser initialize]; // error: setting the readOnly property.
[favOpertion setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *favOpertion, id responseObject) {
NSLog(#"Response: %#",[favOpertion responseString]); // Never reached here
} failure:^(AFHTTPRequestOperation *favOpertion, NSError *error) {
NSLog(#"Error: %#",[favOpertion error]); // never reached here
}];
The code prints the request desc as valid: http://[server name]/favorites/folders/user/[uid]>
Here is an example of the default SAX style parsing. There are some other XML request operations people have made that give you an actual XML document:
AFKissXMLRequestOperation
AFGXMLRequestOperation

Resources