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];
Related
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];
Apple says:
Use the passes method of the PKPassLibrary class to get all passes that your app is entitled to access. Passes are returned in an arbitrary order.
PKPassLibrary *passLib = [[PKPassLibrary alloc] init];
NSArray *passArray = [passLib passes];
if ([passArray count] > 0)
{
PKPass *lastPassAdded = [passArray objectAtIndex:0];
NSLog(#"Pass Localized Name: %#",[lastPassAdded localizedName]);
NSLog(#"Pass Organization Name: %#", [lastPassAdded organizationName]);
NSLog(#"passTypeIdentifier = %#", [lastPassAdded passTypeIdentifier]);
NSLog(#"passSerial Number = %#",[lastPassAdded serialNumber]);
[[UIApplication sharedApplication] openURL:[[passLib passWithPassTypeIdentifier:[lastPassAdded passTypeIdentifier] serialNumber:[lastPassAdded serialNumber]] passURL]];
}
In my code I can get all the coupons, but dont know if there is a form to sort by inclusion date of passbook
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.
My app uses EventKit to read and write new reminders to and from the Reminders app, which works well. However, I've only found a way to write reminders to the default list that the user selects in the Settings app... My question is, does anyone know if there's a way to create a whole new list, rather than use the default list.
Nope.
Apple doesn't allow apps to write to lists other than the default list - looking through the docs yields no way to do so.
YES!!!
Looking through some more literature, I found this!
It seems that the EKReminder objects can be added to any list - based on my limited understanding, this should work at least to write to a different list:
NSArray *calendars = [_eventStore
calendarsForEntityType:EKEntityTypeReminder];
for (EKCalendar *calendar in calendars)
{
NSLog(#"Calendar = %#", calendar.title);
}
EKCalendar *calendar = ... //pick one.
EKReminder *reminder = [EKReminder reminderWithEventStore:self.eventStore];
reminder.title = #"Go to the store and buy milk";
reminder.calendar = calendar;
NSError *error = nil;
[_eventStore saveReminder:reminder commit:YES error:&error];
I want my App to be used from few iTunes stores. I read NSLocale Class Reference and they are talking about "current user". So, who is "current user"? Is it user which has downloaded app?
1) is it possible to get NSLocale depending on current appleID country or iTunes store country from which my App was downloaded?
2) is it possible to simulate NSLocale to test my App?
In iOS, there is no such thing as a "current user". The reference to "current user" in the NSLocale docs is probably a hold over from the OS X docs.
In iOS, run the Settings app and go to General, then International. The "Region Format" and the "Language" settings define what you get back in iOS for [NSLocale currentLocale].
There is no way, in iOS, for a third party app to obtain any sort of appleID or information about a specific iTunes store.
To directly answer your two questions:
1) No, you have no access to this information
2) Yes, run the Settings app and change the Language and/or Region Format settings. This will affect the NSLocale you obtain in your app.
Mates, i found a solution to get user's (Apple ID, iTunes store) locale! You can get locale from SKProduct.
if([SKPaymentQueue canMakePayments])
{
[self requestProductData];
}
#pragma mark -
#pragma mark In-App Purchase Delegate Methods
- (void)requestProductData
{
NSLog(#"IN-APP:requestProductData");
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:<your in-app identifier>]];
request.delegate = self;
[request start];
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
NSArray *myProduct = [[NSArray alloc]initWithArray:response.products];
if ([myProduct count]>0)
{
SKProduct *product = [myProduct objectAtIndex:0];
NSLog(#"Price: %.2f",product.price.floatValue);
NSLog(#"Price Locale: %#",product.priceLocale.localeIdentifier);
NSLog(#"Product Identifier: %#",product.productIdentifier);
NSLog(#"IN-APP:array count: %i", [myProduct count]);
[request autorelease];
}
[myProduct release];
myProduct = nil;
}