Retrieving game center achievement by identifier - iphone

I have a question related to Game center achievements. Is it possible to retrieve the name/description of an achievement by its identifier? I am trying to avoid hardcoding every identifier with its corresponding name, so is there a solution that can get the name?
thanks,
Sami

Of course, that's exactly why you have localization support for achievements (as well as leaderboards) inside iTunes Connect.
However, there is no way to ask Game Center about localized info for just one achievement based on it's ID. Instead, you ask for info about all achievements which gives you an array of GKAchievementDescription objects which would be best to put into a dictionary where keys are achievement IDs and then you select a proper GKAchievementDescription object from that dictionary.
NSMutableDictionary *achievementDescriptions = [[NSMutableDictionary alloc] init];
[GKAchievementDescription loadAchievementDescriptionsWithCompletionHandler:^(NSArray *descriptions, NSError *error) {
if (error != nil) {
NSLog(#"Error getting achievement descriptions: %#", error);
}
for (GKAchievementDescription *achievementDescription in descriptions) {
[achievementDescriptions setObject:achievementDescription forKey:achievementDescription.identifier];
}
}];
And then when you want to display info for some achievement:
GKAchievementDescription *achievementDescription = [achievementDescriptions objectForKey:currentAchievement.identifier];
This object gives you a localized title, description for when it is achieved and unachieved, as well as number of points it awards and an image you specified in iTunes Connect.

Related

Saving and retrieving data from parse using swift

I was successfully able to save data (integer) to parse using swift.
var gameScore = PFObject(className:"GameScore")
gameScore["score"] = highscore
I have successfully stored in data in an objectId named "EN34LdmbSB" I found this objectId by logging into parse.com and looking it up. I have later unsuccessfully tried to use same objectId to retrieve data and it did not work. I have to 2 questions:
1) How to I retrieve this data from parse.
2) If this app is downloaded, say for example by 1000 users, then 1000 unique objectIds will be created when users save their score. How do I then look up their score using their unique objectIds?
I am new to database and Parse so please pardon my naivety. I am currently using NSUserDefaults to store my game score. I am trying to get a more secure way of storing the score data, hence using parse. Tried using KeyChain but did not get very far.
Thank you
You can easily retrieve the data using one of their method in iOS SDK:
PFQuery *query = [PFQuery queryWithClassName:#"GameScore"];
[query whereKey:#"playerName" equalTo: highscore];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// The find succeeded.
NSLog(#"Successfully retrieved %d scores.", objects.count);
// Do something with the found objects
for (PFObject *object in objects) {
NSLog(#"%#", object.objectId);
}
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
You can look it up in the tutorial they provided and it's really helpful and saving time:https://parse.com/docs/ios_guide#queries/iOS
For you second question, I don't quite get what you want to ask. Parse built the backend for you so that you don't have to create database to manage your data. I suggested you to go check what Parse truly does or you can modify it so that I can understand better.

Parse.com: PFQuery querying data from PFUser currentUser

In my iOS app, I am using the Parse.com framework. When the app is launched for the first time or the user isn't signed in, the PFLogInViewController and the PFSignUpViewController will show up on the view. When the user creates his/her account, the application will automatically create the user, like always, but it will also create another variable under the user which is called isPrivate, which calls for a boolean. My question is how do I use the PFQuery to get the value of isPrivate for the currentUser?
Querying helps you find many objects matching a criteria. This doesn't really apply when you already know the object you want (the current user). You can decide whether the currentUser is private with
[PFUser.currentUser[#"isPrivate"] boolValue];
Though in this particular case, you don't actually need to keep a separate field to determine whether the user is an anonymous user (the type created by automatic users). Try:
[PFAnonymousUtils isLinkedWithUser:PFUser.currentUser];
This works for all authentication utils (PFFacebookUtils, PFTwitterUtils, and PFAnonymousUtils). isLinkedWithUser determines whether those auth systems have credentials for a particular user.
After playing around with PFObject, PFUser, and PFQuery, I found the answer to my question.
You have to create a PFQuery the queries the PFUser class, then you have to narrow the query down to only the currentUser username, then you request the value of isPrivate.
PFQuery *query= [PFUser query];
[query whereKey:#"username" equalTo:[[PFUser currentUser]username]];
[query getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error){
BOOL isPrivate = [[object objectForKey:#"isPrivate"]boolValue];
}];

Get place names using CLGeocoder (not street names)

I want to develop my own maps app. I have been successful in getting a street address at the point of touch on my iPhone using CLGeocoder. Now my question is the following:
I know that you can get information about a place by using a URL like https://maps.google.com/?q=37.324599,-122.031844
If you click on the above URL, it will take you near a church in Cupertino. Now CLGeocoder will only give me its street address i.e. 10110 N De Anza Blvd Cupertino, CA 95014 (I get this). But how to get the actual name i.e. St Joseph of Cupertino Church and Parish?
We can see it on Google Maps that means they must have it stored somewhere right?
Is there any way to access those place names (Not just by CLGeoCoder, any way is fine).
The GeoCoding API in general is for converting between street addresses and coordinates. If you want place names you can probably use the Places API.
(I know this is more of a comment than an answer, but I think I don't have enough reputation points to comment on questions yet)
YOu need t odo like this way after getting lat long use this code by CLLocation manager class
{
CLGeocoder *reverseGeo = [[CLGeocoder alloc] init];
[reverseGeo reverseGeocodeLocation: loc completionHandler:
^(NSArray *placemarks, NSError *error) {
NSLog(#"%#",[placemarks objectAtIndex:0]);
for (CLPlacemark *placemark in placemarks) {
NSLog(#"~~~~~~~~%#",placemark.locality);
}
}];
}

Use CurrentLocation for Continent iPhone

Is there a way to find out the users location Continent? I need to set an AWS entry point based on if they open the app in the US, or Europe. etc.
Is there a way to do this without taking GPS coordinates and making ranges out of them?
If you are in iOS5, you can use GLGeocoder to retrieve the information abotu a current location:
[self.CLGeocoder reverseGeocodeLocation: locationManager.location completionHandler:
^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
//placemark contains the address
}];
CLPlacemark reference:
https://developer.apple.com/library/ios/#DOCUMENTATION/CoreLocation/Reference/CLPlacemark_class/Reference/Reference.html
GLGeocoder reference:
https://developer.apple.com/library/ios/#DOCUMENTATION/CoreLocation/Reference/CLGeocoder_class/Reference/Reference.html
you can reverse geocode a location and get details of where the user is located in text. You use the reverseGeocodeLocation:completionHandler: method on the CLGeocoder class to do this
The completion handler in this method gets passed in an array of CLPlacemark objects, which contain the country code, which you can use to determine the users continent
Although a CLPlacemark object contains lots of useful information, its corresponding continent is not present on it.
I wrote a small category to add a -continent method that returns the corresponding string of the continent based on the -ISOCountryCode of a CLPlacemark.
https://github.com/Hecktorzr/Transcontinental

Is there any way to get the "Me" card from iPhone Address Book API?

So I'm stumped on this one.
In Mac OS X there is an easy way to get the "Me" card (the owner of the Mac/account) from the built-in address book API.
Has anyone found a way to find out which contact (if it exists) belongs to the owner of the iPhone?
You could use the undocumented user default:
[[NSUserDefaults standardUserDefaults] objectForKey:#"SBFormattedPhoneNumber"];
and then search the address book for the card with that phone number.
Keep in mind that since the User Default is undocumented, Apple could change at any time and you may have trouble getting into the App Store.
Another approach you could take, although it is much more fragile, is to look at the device name. If the user hasn't changed it from the default "User Name's iPhone" AND they are using their real name as an iPhone, you could grab the user name from that. Again, not the best solution by any means, but it does give you something else to try.
The generally accepted answer to this question is to file a Radar with Apple for this feature and to prompt users to choose their card.
Contacts container have a me identifier property on iOS that can be accessed using container.value(forKey: "meIdentifier")
if let containers = try? CNContactStore().containers(matching: nil) {
containers.forEach { container in
if let meIdentifier = container.value(forKey: "meIdentifier") as? String {
print("Contacts:", "meIdentifier", meIdentifier)
}
}
The identifier is a legacy identifier used in the old AddressBook framework. You can still access it in CNContact:
let iOSLegacyIdentifier = contact.value(forKey: "iOSLegacyIdentifier")
There is no such API in the iPhone SDK 2.2.1 and earlier. Please file a request for it at: http://bugreport.apple.com
Edit: [Obsolete answer]
There's no API for getting the "me" card because there is no "me" card. The iPhone's contacts app has no way of marking a card as being "me", and the API reflects this.
I came up with a partial solution to this
you can get the device name as follows
NSString *ownerName = [[UIDevice currentDevice] name];
in English a device is originally called, for example, 'Joe Blogg's iPhone'
the break out the name
NSRange t = [ownerName rangeOfString:#"’s"];
if (t.location != NSNotFound) {
ownerName = [ownerName substringToIndex:t.location];
}
you can then take that name and search the contacts
CNContactStore *contactStore = [CNContactStore new];
NSPredicate *usersNamePredicate = [CNContact predicateForContactsMatchingName:usersName];
NSArray * keysToFetch = #[[CNContactFormatter descriptorForRequiredKeysForStyle:CNContactFormatterStyleFullName],CNContactPhoneNumbersKey,CNContactEmailAddressesKey,CNContactSocialProfilesKey, ];
NSArray * matchingContacts = [contactStore unifiedContactsMatchingPredicate:usersNamePredicate keysToFetch:keysToFetch error:nil];
Of course other languages differ in the device name string e.g. 'iPhone Von Johann Schmidt' so more parsing needs to be done for other languages and it only works if the user hasn't changed the name of the device in iTunes to something like "Joes phone' but it gives you a starting point
well... it gives you an array of matching items :) So if there is more than one contact with that array you just have to use pot luck and go with the first one or work thru multiple cards and take what you need from each.
I did say its a partial solution and even though it won't work for all user cases you might find it works for many of your users and reduces a little friction