PayPal - IOS SDK - Live production env communications error - ios

We have implemented the IOS SDK (https://github.com/paypal/PayPal-iOS-SDK) into a Native IOS app that we are building - All was working fine during initial tests (both Sandbox and production) - a payment for 10p in GBP worked without issue in the live production environment on Nov 5th.
Checked a production environment transaction again today as part of the apps final tests and although we can log in with a live PayPal account - the payment fails with an error stating -
'Were sorry There was a problem communicating with the paypal servers. Please try again.'
No Log errors that seem to be relevant, just these -
2013-11-27 15:51:32.528 GetPTFit[2181:60b] nested push animation can result in corrupted navigation bar
2013-11-27 15:51:32.893 GetPTFit[2181:60b] Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
bizarre - has anyone experienced anything similar and know how to resolve!?
This is my pay method if any help -
- (IBAction)pay {
// Remove our last completed payment, just for demo purposes.
self.completedPayment = nil;
PayPalPayment *payment = [[PayPalPayment alloc] init];
payment.amount = [[NSDecimalNumber alloc] initWithString:self.shopObject.shopIPrice];
payment.currencyCode = #"GBP";
payment.shortDescription = self.shopObject.shopITitle;
if (!payment.processable) {
// This particular payment will always be processable. If, for
// example, the amount was negative or the shortDescription was
// empty, this payment wouldn't be processable, and you'd want
// to handle that here.
}
// Any customer identifier that you have will work here. Do NOT use a device- or
// hardware-based identifier.
NSString *customerId = #"GetPTFit";
// Set the environment:
// - For live charges, use PayPalEnvironmentProduction (default).
// - To use the PayPal sandbox, use PayPalEnvironmentSandbox.
// - For testing, use PayPalEnvironmentNoNetwork.
[PayPalPaymentViewController setEnvironment:PayPalEnvironmentProduction];
PayPalPaymentViewController *paymentViewController = [[PayPalPaymentViewController alloc] initWithClientId:kPayPalClientId
receiverEmail:kPayPalReceiverEmail
payerId:customerId
payment:payment
delegate:self];
paymentViewController.hideCreditCardButton = !self.acceptCreditCards;
// Setting the languageOrLocale property is optional.
//
// If you do not set languageOrLocale, then the PayPalPaymentViewController will present
// its user interface according to the device's current language setting.
//
// Setting languageOrLocale to a particular language (e.g., #"es" for Spanish) or
// locale (e.g., #"es_MX" for Mexican Spanish) forces the PayPalPaymentViewController
// to use that language/locale.
//
// For full details, including a list of available languages and locales, see PayPalPaymentViewController.h.
paymentViewController.languageOrLocale = #"en";
[self presentViewController:paymentViewController animated:YES completion:nil];
}
Cheers

Dave from PayPal here.
Please see my response in the issue that you raised at our github repo. Feel free to respond in turn over there, or else here on StackOverflow if you prefer.

Related

Admob bannerView Request Error: No ad to show

I'm having this issue on one of my ads for an ios game
Here is my code, the odd thing is that if I add the device on the request.testDevices list it displays the demo banner, if I remove from testDevices, it does not show a real banner, but if I change my bundleIdentifier on XCODE, it shows a real banner,so I believe its something with my admob account, does anyone ever got something like it?
Its always failing with this error:
AdView didFailToReceiveAdWithError --------------------------- : Error Domain=com.google.ads Code=1 "Request Error: No ad to show." UserInfo={NSLocalizedDescription=Request Error: No ad to show., NSLocalizedFailureReason=Request Error: No ad to show.}
On my AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Use Firebase library to configure APIs
[FIRApp configure];
[[FIRAnalyticsConfiguration sharedInstance] setAnalyticsCollectionEnabled:YES];
// Initialize Google Mobile Ads SDK
[GADMobileAds configureWithApplicationID:#"ca-app-pub-xx~xx"];
/* other stuff here... */
}
on my rootViewController.m
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
bannerViewAdded = NO;
interstitialViewAdded = NO;
[self addBanner];
// ..... more stuff here;
}
- (void)addBanner{
NSLog(#"CALL ADD BANNER ROOTVIEWCONTROLLER");
if(!bannerViewAdded && ![MKStoreManager isFeaturePurchased:kFeatureAId]){
NSLog(#"ADD BANNER ROOTVIEWCONTROLLER");
CGSize size = [[CCDirector sharedDirector] winSize];
// Create adMob ad View (note the use of various macros to detect device)
if (IS_IPAD || IS_IPADHD) {
bannerView = [[GADBannerView alloc] initWithAdSize:kGADAdSizeLeaderboard];
bannerView.center = CGPointMake(size.width/2, (size.height-CGRectGetHeight(bannerView.frame)/2)-2);
}
else if (IS_IPHONE6) {
bannerView = [[GADBannerView alloc] initWithAdSize:kGADAdSizeBanner];
bannerView.center = CGPointMake(size.width/2, (size.height-CGRectGetHeight(bannerView.frame)/2)-2);
}
else if (IS_IPHONE6P) {
bannerView = [[GADBannerView alloc] initWithAdSize:kGADAdSizeBanner];
bannerView.center = CGPointMake(size.width/2, (size.height-CGRectGetHeight(bannerView.frame)/2)-2);
}
else {
// boring old iPhones and iPod touches
bannerView = [[GADBannerView alloc] initWithAdSize:kGADAdSizeBanner];
bannerView.center = CGPointMake(size.width/2, (size.height-CGRectGetHeight(bannerView.frame)/2)-2);
}
//[bannerView setBackgroundColor:[UIColor blueColor]];
// Need to set this to no since we're creating this custom view.
//bannerView.translatesAutoresizingMaskIntoConstraints = NO;
// Note: Edit SampleConstants.h to provide a definition for kSampleAdUnitID
// before compiling.
// Replace this ad unit ID with your own ad unit ID.
bannerView.adUnitID = #"ca-app-pub-xx/xx";
bannerView.rootViewController = self;
bannerView.delegate = self;
[self.view addSubview:bannerView];
GADRequest *request = [GADRequest request];
//request.testDevices = #[ kGADSimulatorID ];
//request.testDevices = #[ #"xx", #"xx" , kGADSimulatorID ];
[bannerView loadRequest:request];
bannerViewAdded = YES;
}
}
- (void)removeBanner {
//admob
if(bannerViewAdded){
bannerViewAdded = NO;
[bannerView removeFromSuperview];
[bannerView release];
bannerView = nil;
}
//No AdMOB
if(localBannerAdded){
localBannerAdded = NO;
[localBannerButton removeFromSuperview];
[localBannerButton release];
localBannerButton = nil;
}
}
- (void)addInterstitial{
if(!interstitialViewAdded && ![MKStoreManager isFeaturePurchased:kFeatureAId]){
NSLog(#"INIT INTERSTITIAL ROOTVIEWCONTROLLER");
interstitialView = [[GADInterstitial alloc] initWithAdUnitID:#"ca-app-pub-xx/xx"];
GADRequest *request = [GADRequest request];
// Requests test ads on devices you specify. Your test device ID is printed to the console when
// an ad request is made. GADBannerView automatically returns test ads when running on a
// simulator.
//request.testDevices = #[ kGADSimulatorID, #"xxx", #"xxx" ];
[interstitialView loadRequest:request];
[interstitialView setDelegate:self];
}
}
- (void)adView:(GADBannerView *)gadBannerView didFailToReceiveAdWithError:(GADRequestError *)error{
NSLog(#"AdView didFailToReceiveAdWithError --------------------------- : %#", error);
[self removeBanner];
if(!localBannerAdded){
CGSize size = [[CCDirector sharedDirector] winSize];
localBannerButton = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain];
localBannerButton.frame = CGRectMake(0.0, 0.0, 320.0, 50.0);
[localBannerButton setTitle:#"DOWNLOAD MORE FREE GAMES" forState:UIControlStateNormal];
localBannerButton.backgroundColor = [UIColor whiteColor];//[UIColor clearColor];
[localBannerButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal ];
[self.view addSubview:localBannerButton];
[localBannerButton setCenter:CGPointMake(self.view.center.x,(size.height-CGRectGetHeight(localBannerButton.frame)/2)-2)];
// Add Target-Action Pair
[localBannerButton addTarget:self action:#selector(openAppStore:) forControlEvents:UIControlEventTouchUpInside];
localBannerAdded = YES;
}
}
I just had this error today, the problem for me was simple, it was because the adUnitID is basically still new. I had to wait more than 2 hours after creating the adUnitID in order for the ads to be served.
If you have this error, and some of your adUnitIDs serve ads and some don't. You're highly likely having the same issue, and the only way to fix it is to wait.
The ad server will return this message mainly because of the following:
There are no ads for your ad unit id.
Check whether your ad unit id is proper or not.
You will get the same error if either your banner width/height is 0.
Make sure that your adUnitID is perfect.
or
check following links its may help you
https://groups.google.com/forum/#!topic/google-admob-ads-sdk/ioXU2nX9W28
AdMob Legacy Publisher ID not showing ads
I had just created a new account and seen that problem. When checking my account there was a message shown on the top of admob page: "Your ad units are not displaying ads because you haven't provided your account payments information yet.". Click on the button Fix it, fill the form and the ads will be shown within few hours
I met this error too. Both my banner and interstitial ads failed with this error. I found that it is my mistake to change UserAgent globally, after I change UserAgent to default it works well.
Make sure you are using the test ad IDs when in a debug session.
https://developers.google.com/admob/ios/banner?hl=en-US
The easiest way to load test ads is to use our dedicated test ad unit ID for iOS banners: ca-app-pub-3940256099942544/2934735716
This error could happen if you have not setup your payment and billing information in your AdMob account.
As per Admob after you setup the payment details, it can take up to 2 hours before it would be completely functional
Billing and Payments
This solved my problem
changing banner id to example id.
run the app then .
changing id back to production id.
For me, the reason why it started showing this is that I didn't have any payment methods set up on my AdMob account.
Once I have set this up, the error has disappeared and ads started showing instantly.
Hope this helps someone!
One possible reason is a Constraint bug.
you should guarantee your bannerView's constraint to other views is
right
I had the same issue when testing the sample application on my phone. I fixed with the following steps:
Reset Advertising identifier on iPhone 6, Go to:
Settings -> Privacy -> Advertising -> Reset Ad identifier
After create adUnitID, Wait for 1-2 hours and then try it out.
Because I had the same issue and it gets solved just after 1-2 hours.
Enjoy coding :)
If you are using your app in debug or testing mode make sure you are using test AppID and BannerID provided by google admob which would be as:-
Google Test AdMobID:
ca-app-pub-3940256099942544~1458002511
Google Test BannerID
ca-app-pub-3940256099942544/2934735716
In my case, ads are working fine but suddenly it stop showing ad with error: No ad to show.
I noticed console is throwing error about test device identifier. Somehow the test device identifier get changed. I don't know how it happen, may be due to Xcode upgrade. I am not sure. But once I changed the test device identifier, it start working again.
Do not make any modifications in code if this error pops, just wait about 3-4 days. Google takes time to send adds for new accounts
Make sure not to make an other variable of GADBannerView. Use one variable in every controller by making it global and just change unit id.
e.g this line should be out of any controller (global)
var bannerView: GADBannerView!
then use it wherever you want and just change id accordingly
bannerView.adUnitID = "ca-app-exampleid-abcabc938-4e8"
I was used to init the banner like this:
adBannerView = GADBannerView()
and it was working.
I can't say precisely from which AdMob library version, but suddently the banner wasn't show anymore.
Init the banner with the size as parameter, fixed the problem:
adBannerView = GADBannerView(adSize: kGADAdSizeBanner)
I solve this by adding request.testDevice = #[#"xxxxxxxxxxxx"] before load request.(I get this tip and test device number from console)
The best way I think should be used the test ad Ids from the integration guide from Google, after that change to your Ad Ids when it goes live.
I faced with this issue even with google test ad units.
In my scenario, problem was, I modified the WkWebView UserAgent directly without concatenating with the real one.
I had to change from;
static func arrangeUserAgent() {
let webView = WKWebView()
webView.evaluateJavaScript("navigator.userAgent") { (result, error) in
webView.customUserAgent = "Some Awesome User Agent"
let dictionary = Dictionary(dictionaryLiteral: ("UserAgent", webView.customUserAgent!))
UserDefaults.standard.register(defaults: dictionary)
}
}
to;
static func arrangeUserAgent() {
let webView = WKWebView()
webView.evaluateJavaScript("navigator.userAgent") { (result, error) in
let mergedUserAgent = "\(result ?? "") Some Awesome UserAgent"
webView.customUserAgent = mergedUserAgent
let dictionary = Dictionary(dictionaryLiteral: ("UserAgent", mergedUserAgent))
UserDefaults.standard.register(defaults: dictionary)
}
}
Had rough times to find the problem.
Be careful with the UserAgent you change.
Happy coding.
In the Settings of your iOS device: Settings > Privacy > Advertising: Turn on and then turn off "Limit Ad Tracking" ("Reset of Ad Identifier" doesn't always help. Try "Reset of Ad Identifier" first and comment if this action doesn't help you).
But! It will help only get ads on your own device and will not solve the problem that matching rate of your ad is low.

Apple pay PKPaymentauthorizationViewController always returning nil when loaded with Payment request

I am getting the PK Payment auth view controller instance returned as nil. What is wrong with this code?
if([PKPaymentAuthorizationViewController canMakePayments])
{
if ([PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:#[PKPaymentNetworkAmex, PKPaymentNetworkMasterCard, PKPaymentNetworkVisa]])
{
PKPaymentRequest *request = [[PKPaymentRequest alloc] init];
request.currencyCode = #"USD";
request.countryCode = #"US";
request.merchantCapabilities = 0;
request.requiredBillingAddressFields=PKAddressFieldAll;
request.merchantIdentifier = #"merchant.com.domain.mine";
PKPaymentSummaryItem *item = [[PKPaymentSummaryItem alloc] init];
item.label=#"Merchant";
item.amount=[NSDecimalNumber decimalNumberWithString:#"10"];
request.paymentSummaryItems=#[item];
PKPaymentAuthorizationViewController *viewController = [[PKPaymentAuthorizationViewController alloc] initWithPaymentRequest:request];
viewController.delegate = self;
[self presentViewController:viewController animated:YES completion:nil];
}
}
Before accessing the PKPaymentAuthorizationViewController, you should configure Apple Pay properly on your iPhone device. If you have not configured Apple Pay on your device you'll get nil value for PKPaymentAuthorizationViewController. You can even find an exception on the console stating "This device cannot make payment."
To configure Apple Pay on your device follow the below steps:
Go to Settings.
Select Passbook and Apple Pay option (if this option is not visible in settings, go to General -> Language & Region, change your region to US or UK, after this you'll be able to see the Passbook & Apple Pay option in Settings)
Open Passbook application from your home screen and configure a valid credit/debit card (US/UK based card only).
After verifying the added card, run your application you'll get a valid PKPaymentAuthorizationViewController instance.
Hope this will help.
I had a similar issue. It looks like you included it, but for anyone else struggling with this, my problem was not initially supplying merchantCapabilities to the request.
Swift:
request.merchantCapabilities = PKMerchantCapability.capability3DS
https://developer.apple.com/documentation/passkit/pkmerchantcapability?language=objc
If you are instantiating the supporting networks with raw value, make sure they are done so with the proper capitalization.
// Summarized for posting purposes
let networks = ["AmEx", "Visa", "MasterCard", "Discover"].reduce(into: [PKPaymentNetwork]()) { $0.append(PKPaymentNetwork($1)) }
if PKPaymentAuthorizationViewController.canMakePayments(usingNetworks: networks, capabilities: .capability3DS) {
// Hooray
}

Facebook iOS SDK 4.1.0 Share Callback

Using the FBSDK mentioned in the title of this question, I present a simple share dialog in a view controller:
// Setup the content for the share
FBSDKShareLinkContent *content = [[FBSDKShareLinkContent alloc] init];
content.contentURL = linkUrl;
content.contentDescription = description;
content.contentTitle = title;
content.imageURL = imageUrl;
// Show the share dialog
[FBSDKShareDialog showFromViewController:controller
withContent:content
delegate:someDelegate];
And implement the delegate method...
- (void)sharer:(id<FBSDKSharing>)sharer didCompleteWithResults:(NSDictionary *)results
{
NSLog(#"Sweet, they shared.");
}
So far so good, as long as the user has the Facebook application installed on their device. The issue arises when the user does not have Facebook installed. If this is the case, Safari opens up to a web version of Facebook's login flow (this is fine), but if you then switch back to the original application without logging into Facebook / performing any additional tasks, the completion delegate method shown above is called.
Does anyone have any experience with a workaround for this? It seems like there should be a reliable way for determining whether or not the post did indeed occur.
Note: The above code is pretty pseudo-ish. In the actual implementation I have indeed implemented all of the delegate call backs (didComplete, didCancel, and didFail).
Edit: It turns out, the results dictionary is empty when the completion method is called if the Facebook app is installed on the device. To overcome this, a check needs to be done to see if Facebook is installed first.
Of course after posting I stumbled upon the answer. The results dictionary returned in the didCompleteWithResults method contains a postId key if the share actually occurred. So the logic is as simple as:
- (void)sharer:(id<FBSDKSharing>)sharer didCompleteWithResults:(NSDictionary *)results
{
NSURL *fbURL = [NSURL URLWithString:#"fb://"];
if (![[UIApplication sharedApplication] canOpenURL:fbURL])
if (results[#"postId"]) {
NSLog(#"Sweet, they shared, and Facebook isn't installed.");
} else {
NSLog(#"The post didn't complete, they probably switched back to the app");
}
} else {
NSLog(#"Sweet, they shared, and Facebook is installed.");
}
}
Although this works, it doesn't seem to be a very safe way of going about things (what if Facebook changes the key from "postId" to something else in the future? Unlikely but you get my point).

GameKit matchmaking fails for 3G connections

I am making a multiplayer game for iOS and I read the material in Apple Developer Center, specifically this one. Here is my code for custom matchmaking, which is pretty straightforward:
- (void)findProgrammaticMatch {
GKMatchRequest *request = [[GKMatchRequest alloc] init];
request.minPlayers = 2;
request.maxPlayers = 2;
request.defaultNumberOfPlayers = 2;
request.playersToInvite = nil;
request.playerAttributes = 0;
request.playerGroup = 0;
UILabel *loading = (UILabel *)[aiw viewWithTag:792];
[[GKMatchmaker sharedMatchmaker] findMatchForRequest:request withCompletionHandler:^(GKMatch *match, NSError *error) {
if (error){
//error handling
[loaderLayer stopAnimating];
UIButton *cancelButton = (UIButton *)[loaderLayer viewWithTag:442];
[cancelButton setTitle:#"Go Back" forState:UIControlStateNormal];
loading.text = #"Cannot find any players. Please try again later.";
} else if (match != nil) {
//save match
self.match = match;
self.match.delegate = self;
loading.text = #"Found a player. Preparing session...";
if (!self.matchStarted && match.expectedPlayerCount == 0) {
self.matchStarted = YES;
//begin game logic
[self.scene setState:1];
self.myTicket = 1000+arc4random_uniform(999);
[self.scene send:self.myTicket];
[self stopLoading];
}
}
}];
}
However, matchmaking fails when one or more devices are connected to the internet via cellular networks. When I investigated the underlying error I found out that even if it is a wifi to wifi case, the completion handler does not work as intended. That is, match.expectedPlayerCount is never 0. Instead, the game starts when - (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state handler is invoked after the completion handler as following:
...
- (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state {
switch (state) {
case GKPlayerStateConnected:
self.matchStarted = YES;
//begin game logic
[self.scene setState:1];
self.myTicket = 1000+arc4random_uniform(999);
[self.scene send:self.myTicket];
[self stopLoading];
break;
...
The problem now is if a device with 3g is connected (and matched-sort of) didChangeState is never invoked. I checked for several other related questions on the internet and this site, although they are far from being satisfactory. I also read that sandbox servers of Game Center are not reliable and for some people production version worked perfectly(it just works!) despite the errors in sandbox mode, but I don't want to take that risk. Has anybody have experienced similar problem with their multiplayer game?
Hgeg,
There is nothing wrong with your code.
You have to allow cellular data usage to your app which needs users permission.
The following paragraph is selected from Apple's support website :
At the Foundation layer, you can use the setAllowsCellularAccess:
method on NSMutableURLRequest to specify whether a request can be sent
over a cellular connection. You can also use the allowsCellularAccess
to check the current value.
At the Core Foundation layer, you can achieve the same thing by
setting the kCFStreamPropertyNoCellular property before opening a
stream obtained from the CFSocketStream or CFHTTPStream APIs.
In older versions of iOS, you can continue to use the
kSCNetworkReachabilityFlagsIsWWAN as a best-effort way of determining
whether traffic will be sent over a cellular connection, but you
should be aware of its limitations.
Good luck
Iman
According to the latest apple news, from iOS 9, the sand box mode will no longer exist, instead of the sandbox you'll have one unified environment.
So you'll have just one unified environments where you can share the same accounts, this should solve all the usual problems from the SandBox mode.
The new Unified System it's also compatible with TestFlight so you'll be able to test you code across multiple device and accounts.
All of these changes will be made directly by apple, so the only think that you can do it's to wait until they update to the new system, so far it's the only way to be sure that it's not a Sand Box problem.
For more info please have a loot at the WWDC video
Based on the code that you have shown us, there should'nt be any issue regardless of the connection type, 3G or otherwise; however, if you previously interspersed code for exception handling that was tied back to connection status, or for graphics which represent a loading state, something could be tied up elsewhere logically and produce this error at this point in the game logic. Even a corrupt spinner graphic can become an issue.
Did you have any other exception handlers in the code that called the following:
request.playersToInvite
or
request.playerGroup
or
that changed a loader layer characteristic?

PayPal iOS SDK nil View Controller

I am using the most recent PayPal iOS sdk in my app. For some unknown reason, when I try to init the PayPalPaymentViewContoller then present it, it is crashing. I have determined that the viewController is nil, but I have no idea why.
Here are the two lines of code to do with this.
The first line is the init, and the second is present
PayPalPaymentViewController *paymentViewController = [[PayPalPaymentViewController alloc] initWithPayment:payment configuration:self.payPalConfig delegate:self];
[self presentViewController:paymentViewController animated:YES completion:nil];
Any ideas? Let me what more information you need. I am not really sure what else to provide.
Dave from PayPal here.
#linuxer have you followed our sample code? In particular, from step 5:
// Check whether payment is processable.
if (!payment.processable) {
// If, for example, the amount was negative or the shortDescription was empty, then
// this payment would not be processable. You would want to handle that here.
}
If the payment is not "processable", but you go ahead anyway to create the PayPalPaymentViewController, then you would indeed get back nil.
You should also see a message to that effect in your console log. Have you taken a look there?
When you create object for PayPalItem at here in withPrice param, amount always be in two value after decimal. See below example:
PayPalItem *item1 = [PayPalItem itemWithName:#"T Shirt" withQuantity:1 withPrice:[NSDecimalNumber decimalNumberWithString:**
[NSString stringWithFormat:#"%0.2f",overAllTotalAmt]
**] withCurrency:#"USD" withSku:#"Hip-00037"];

Resources