How to launch an ABPeoplePickerNavigationController of only contacts that have mobile numbers? - ios

Apple provided a sample project called PeoplePicker that launches an ABPeoplePickerNavigationController of only contacts that have email addresses:
ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self;
// The people picker will only display the person's name, image and email properties in ABPersonViewController.
picker.displayedProperties = #[#(kABPersonEmailProperty)];
// The people picker will enable selection of persons that have at least one email address.
picker.predicateForEnablingPerson = [NSPredicate predicateWithFormat:#"emailAddresses.#count > 0"];
How do I display only the contacts that have mobile/telephone numbers? I already dug around the Apple docs to find what key to use for the #count operation (emailAddresses in this example), but I can't find it.

Use ABPersonPhoneNumbersProperty like so:
[NSPredicate predicateWithFormat:#"%K.#count > 0", ABPersonPhoneNumbersProperty];

Related

Game Center Challenges in iOS 10

I've implemented Game Center features like achievements and leaderboards, and now I'm working on the challenges. I was under the impression that I didn't have to add any additional code - if I had achievements or leaderboards, players would be able to send challenges to their friends. But now, in iOS10, you no longer have the ability to add players as friends - the challenges are handled through iMessages. The problem is - I don't see that feature anywhere in the GKViewController screen. If you select an achievement/leaaderboard score, you can tap on 'Challenge Friends', but it only suggests the players you already have in your friends list rather than in your contact list. Apple has also deprecated GKChallengesViewController, so I'm not sure where to look on how to do this.
Does anyone know how to add the iMessage Challenges feature to Game Center in iOS 10?
Update: I have seen that this feature lives within the GKMatchmakerViewController, but that seems to be for multiplayer type things. I'm still not sure how to use this to just send challenges.
From the Apple Docs:
Issuing a challenge does not display a user interface to the player issuing the challenge; this is code you need to implement yourself.
There are also a few examples on how to issue challenges and how to find players you can invite, such as:
- (void) challengePlayersToCompleteAchievement: (GKAchievement*) achievement
{
[achievement selectChallengeablePlayers:[GKLocalPlayer localPlayer].friends withCompletionHandler:^(NSArray *challengeablePlayerI, NSError *error) {
if (challengeablePlayers)
{
[self presentChallengeWithPreselectedPlayers: challengeablePlayers];
}
}];
}
...or:
- (void) challengeLesserMortalsForScore: (int64_t) playerScore inLeaderboard: (NSString*) leaderboard
{
GKLeaderboard *query = [[GKLeaderboard alloc] init];
query.leaderboardIdentifier = leaderboard;
query.playerScope = GKLeaderboardPlayerScopeFriendsOnly;
query.range = NSMakeRange(1,100);
[query loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error) {
NSPredicate *filter = [NSPredicate predicateWithFormat:#"value < %qi",playerScore];
NSArray *lesserScores = [scores filteredArrayUsingPredicate:filter];
[self presentChallengeWithPreselectedScores: lesserScores];
}];
}
By the looks of it you still can only invite players that are already part of game center, i.e. no arbitrary "contacts" from the contact list (which makes sense), but this is only an assumption.

MKLocalSearch not working like Apple Maps search?

I have created a MapKit and trying to play around with MKLocalSearch. One thing I noticed in comparison to Apple Maps, is that mklocalsearch is restricted to 10 results. So how does Apple Maps display 15 suggestions under the search bar?
Okay, on to an example. Im trying to find "Barcelona." In Apple Maps it will be suggested after writing just "barc" and it will stay on the suggestion list throughout typing barcelona.
Now in my own Map view, I actually have to type in the full Barcelona to get the suggestion: Spain, Barcelona. On my way I get other suggestions, but nothing like Spain, Barcelona and not like Apple maps.
Any insight on how to get it working and to why Apple Maps work differently (spec. the 15 results vs 10 with mklocalseach)
Here is the code called on textField Changes:
- (IBAction)searchFieldChanged:(UITextField *)sender {
if(self.locationTextfield.text.length>0)
self.tableView.hidden = NO;
else
self.tableView.hidden = YES;
NSString *query = self.locationTextfield.text;
// Create and initialize a search request object.
MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = query;
request.region = self.mapsView.region;//we dont want region-specific search results!
//request.region = MKCoordinateRegionMakeWithDistance(self.mapsView.userLocation.location.coordinate,40000000, 15000000);
// Create and initialize a search object.
MKLocalSearch *search = [[MKLocalSearch alloc] initWithRequest:request];
// Start the search and display the results as annotations on the map.
[search startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error)
{
[placeMarks removeAllObjects];
NSLog(#"p-count: %lu", response.mapItems.count);
for (MKMapItem *item in response.mapItems) {
[placeMarks addObject:item.placemark];
self.tempPlacemark = item.placemark;
NSLog(#"placemark: %#", item.placemark);//.location.coordinate.latitude);
}
//if(placemarks.count==0)
// appDelegate.staticPlacemark = nil;
//[self.mapsView removeAnnotations:[self.mapsView annotations]];
//[self.mapsView showAnnotations:placemarks animated:NO];
[self.tableView reloadData];
}];
}
What you do is a MKLocalSearch using a MKLocalSearchRequest. What Apple in its macOS and iOS map apps does is using the newer MKLocalSearchCompleter class to obtain autocompletion suggestions. These suggestions are used for realtime search and displayed in a UITableView. When the user selects one entry that suggestion is used to initialize a MKLocalSearchRequest to obtain detailled information about this location.

Display IAP Price When Device Cannot Retrieve SKProduct Price

I have an in-app purchase for my app that costs £1.99. I display this price using a pop-up, however, when the device is not connected to the internet it cannot retrieve the price of my IAP, so it shows up blank.
The price of my IAP will always be £1.99 GBP. How do I display this IAP tier for other countries when the device is not connected to the internet?
This is how I currently get the price of my IAP:
_products = nil;
[[AppIAPHelper sharedInstance] requestProductsWithCompletionHandler:^(BOOL success, NSArray *products) {
if (success) {
_products = products;
SKProduct * product = _products[0];
[[AppIAPHelper sharedInstance] productPurchased:product.productIdentifier];
NSNumberFormatter *_priceFormatter = [[NSNumberFormatter alloc] init];
[_priceFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[_priceFormatter setLocale:product.priceLocale];
priceString = [_priceFormatter stringFromNumber:product.price];
NSLog(#"Price string: %#",priceString);
}
}];
I tried to test if priceString.count <= 0 (therefore device is not connected to the internet), and then execute:
NSDecimalNumber *amount = [NSDecimalNumber decimalNumberWithString:#"1.99"];
NSNumberFormatter *currencyFormat = [[NSNumberFormatter alloc] init];
NSLocale *locale = [NSLocale currentLocale];
[currencyFormat setNumberStyle:NSNumberFormatterCurrencyStyle];
[currencyFormat setLocale:locale];
NSLog(#"AmountSo with symbol: %#", [currencyFormat stringFromNumber:amount]);//Eg: $50.00
NSLog(#"Current Locale : %#", [locale localeIdentifier]);//Eg: en_US
But this only adds the local currecy symbol to amount.
The problem is, I need to display the correct price tiers. For example, USD 1.99 converted to GBP is 1.27. But the IAP tiers are 1.99 USD and 1.49 GBP.
So basically - how do I show the App Store IAP price tiers for the user's local currecy without requesting the price of the SKProduct (if the user is not connected to the internet)? Thanks.
You could create a property list (plist), static NSDictionary, or some other relational table containing the current price tiers mapped to country codes. If no network connection is available, grab the current locale country and use it to look up the price tier and local currency symbol.
Question though: since you can't make an in-app purchase without a network connection, why exactly do you care? Just throw a notification stating that network connection is unavailable?
One more option you could have, if you want it to be somewhat robust, is set it to cache using a policy that refreshes it if network is available, otherwise uses the cached copy. Something like this using Reachability would work, though admittedly this is for an NSURLRequest not an SKProduct request.
Reachability *reachability = [Reachability reachabilityForInternetConnection];
NetworkStatus netStatus = [reachability currentReachabilityStatus];
if (netStatus == ReachableViaWiFi)
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
else
[request setCachePolicy:NSURLRequestReturnCacheDataElseLoad];

How to detect google calendar in local EventStore

In setting of iPhone, I was login the google calendar.
I program an iPhone app, that can detect the event that is belonged to the logged in google calendar as above.
EKEventStore* eventStore;
eventStore = [[EKEventStore alloc] init];
NSPredicate* predicate = [eventStore predicateForEventsWithStartDate:firstDate endDate:lastDate calendars:eventStore.calendars];
NSArray* fetchedEvents = [eventStore eventsMatchingPredicate:predicate];
for(EKEvent* ecEvent in fetchedEvents)
{
// How to do
}
How can I do that?
I also research but almost have to:
Method 1: program for user choose an calender (include google calendar)
Method 2: program for get default calendar (may be that is google calendar)
Method 3: program a app that login and get google calendar as same as Using Google Calendar Api in iPhone have other method.
Thank you for your help.
Re: question 1, this will tell you if the event belongs to a google calendar:
EKCalendar *calendar = event.calendar;
if ([[calendar source] sourceType] == EKSourceTypeCalDAV &&
[[[calendar source] title] isEqualToString:#"Gmail"])
NSLog(#"found a Gcal event");
Sometimes (if there are multiple google accounts configured) [[calendar source] title] will return the gmail address instead of #"Gmail", so you may want to check for that as well.

I can't connect paypal account with Mobile Payment Libraries

I have a little problem with "Mobile Payment Libraries", I can't use paypal SDK because I'm not US developer.
I downloaded the iOS Mobile Payments Library SDK from PayPal. I created a developer account and try example test. This works.
I change "PayPalPayment recipient" for check if sandbox account received money. I run app, Paypal button is correctly appear but when I encode email and password for an other sandbox account, the connection button is disable. And this button stay in disable all time after that. This app was kill and uninstall from device and I download again "iOS Mobile Payments Library SDK" and run again, the connection button is already disable with no modification on paypal code.
Why the button is already disable?
Sorry for my english.
This is code call buy Button Paypal with my modification. But I don't things that this is the problem
- (void)simplePayment {
[PayPal getPayPalInst].shippingEnabled = TRUE;
[PayPal getPayPalInst].dynamicAmountUpdateEnabled = TRUE;
[PayPal getPayPalInst].feePayer = FEEPAYER_EACHRECEIVER;
PayPalPayment *payment = [[[PayPalPayment alloc] init] autorelease];
payment.recipient = user.paypalAccount; //Sandbox account Email - Type:BUSINESS - Contry:US
payment.paymentCurrency = #"EUR";
payment.description = description;
payment.merchantName = user.name;
payment.subTotal = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:#"%f",(price * nb)]];
payment.invoiceData = [[[PayPalInvoiceData alloc] init] autorelease];
payment.invoiceData.totalShipping = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:#"%.2f€",type * nb]];
payment.invoiceData.invoiceItems = [NSMutableArray array];
PayPalInvoiceItem *item = [[[PayPalInvoiceItem alloc] init] autorelease];
item.totalPrice = payment.subTotal;
item.name = app.currentTicket.title;
[payment.invoiceData.invoiceItems addObject:item];
[[PayPal getPayPalInst] checkoutWithPayment:payment];
}
Check in your log, maybe you have this message:
PayPalPayment not processable: At this time, 'USD' is the only currency code allowed.
At the moment you can't use EUR as currency, I have the same problem.
Have the same issue. It is not active while you are pasting email/password. When you are typing it handly - it works for me.

Resources