Background: I used same code for iOS 8.2,8.3 it was working fine.
PKPaymentAuthorizationViewController *paymentPane = [[PKPaymentAuthorizationViewController alloc] initWithPaymentRequest:request];
paymentPane.delegate = self;
[self presentViewController:paymentPane animated:TRUE completion:nil];
PaymentRequest Code:
PKPaymentRequest *request = [[PKPaymentRequest alloc] init];
NSString *chargeApplePay=[NSString stringWithFormat:#"%.02f",pay];
PKPaymentSummaryItem *total = [PKPaymentSummaryItem summaryItemWithLabel:#"Grand Total"
amount:[NSDecimalNumber decimalNumberWithString:chargeApplePay]];
request.paymentSummaryItems = #[total];
request.countryCode = #"US";
request.currencyCode = #"USD";
request.supportedNetworks = #[PKPaymentNetworkAmex, PKPaymentNetworkMasterCard, PKPaymentNetworkVisa];
request.merchantIdentifier = #"valid.com.myIdentifier";
request.merchantCapabilities = PKMerchantCapability3DS;
Question: Now on iOS 8.4 when I try to present my paymentPane its value is nil somehow.
Fatal Exception: NSInvalidArgumentException Application tried to
present a nil modal view controller on target .
What I have already tried by googling and using answers from stackoverflow.
Used Checks like
[PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:#[PKPaymentNetworkAmex, PKPaymentNetworkMasterCard, PKPaymentNetworkVisa]]
and
[PKPaymentAuthorizationViewController canMakePayments]
Checking my merchant id is valid or not.
Checking All the code I used for request is valid or not.
Check whether you've added Credit card information in your device Passbook or not.
Check whether you can make payment using your device.
Objective C :
if ([PKPaymentAuthorizationViewController canMakePayments]) {
NSLog(#"Can Make Payments");
}
else {
NSLog(#"Can't Make payments");
}
Swift :
if PKPaymentAuthorizationViewController.canMakePayments() {
NSLog(#"Can Make Payments");
}
else {
NSLog(#"Can't Make Payments");
}
Check whether you can make payment using the allowed payment networks.
Objective C :
NSArray *paymentNetworks = [NSArray arrayWithObjects:PKPaymentNetworkMasterCard, PKPaymentNetworkVisa, PKPaymentNetworkAmex, nil];
if ([PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:paymentNetworks]) {
NSLog(#"Can Make payment with your card");
}
else {
NSLog(#"Card is not supporting");
}
Swift :
let paymentNetworks = [PKPaymentNetworkAmex, PKPaymentNetworkMasterCard, PKPaymentNetworkVisa]
if PKPaymentAuthorizationViewController.canMakePaymentsUsingNetworks(paymentNetworks) {
NSLog(#"Can Make payment with your card");
}
else {
NSLog(#"Card is not supporting");
}
I have also had similar problems when running inside the Xcode debugger. As a workaround I stop the app in Xcode and then manually start the app on the iPhone or iPad.
One drawback with this is obviously that you can't debug any issues. I've had to resort to NSLog and reading the console log.
Related
I am using the the iOS client quick start project hosted on https://github.com/twilio/voice-callkit-quickstart-objc
on server I am using python (as recommended on github project)
When I clicked on "Place outgoing call" it worked fine and I got "Welcome to Twilio" voice. Great!
Then I changed the code a bit and tried to make an outgoing call to specific number. Here's the modified code
Button click event
- (IBAction)placeCall:(id)sender {
NSUUID *uuid = [NSUUID UUID];
NSString *handle = #"Real Number";
[self performStartCallActionWithUUID:uuid handle:handle];
}
Here's the CallKit handle
- (void)performStartCallActionWithUUID:(NSUUID *)uuid handle:(NSString *)handle {
if (uuid == nil || handle == nil) {
return;
}
CXHandle *callHandle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:handle];
CXStartCallAction *startCallAction = [[CXStartCallAction alloc] initWithCallUUID:uuid handle:callHandle];
CXTransaction *transaction = [[CXTransaction alloc] initWithAction:startCallAction];
[self.callKitCallController requestTransaction:transaction completion:^(NSError *error) {
if (error) {
NSLog(#"StartCallAction transaction request failed: %#", [error localizedDescription]);
} else {
NSLog(#"StartCallAction transaction request successful");
CXCallUpdate *callUpdate = [[CXCallUpdate alloc] init];
callUpdate.remoteHandle = callHandle;
callUpdate.supportsDTMF = YES;
callUpdate.supportsHolding = NO;
callUpdate.supportsGrouping = NO;
callUpdate.supportsUngrouping = NO;
callUpdate.hasVideo = NO;
[self.callKitProvider reportCallWithUUID:uuid updated:callUpdate];
}
}];
}
And the number to call
- (void)provider:(CXProvider *)provider performStartCallAction:(CXStartCallAction *)action {
NSLog(#"provider:performStartCallAction:");
[[VoiceClient sharedInstance] configureAudioSession];
NSDictionary *toParam = #{#"To": #"+14805058877"};
//THIS IS WHERE WE NEED TO INSERT CALLING NUMBER
self.outgoingCall = [[VoiceClient sharedInstance] call:[self fetchAccessToken]
params:toParam
delegate:self];
if (!self.outgoingCall) {
[action fail];
} else {
self.outgoingCall.uuid = action.callUUID;
[self toggleUIState:NO];
[self startSpin];
[action fulfillWithDateStarted:[NSDate date]];
}
}
No matter what I enter in the parameter value I always get "Welcome to Twilio" msg. I need to know if I need change anything on the Python server or in the iOS client code. Please help!
Twilio developer evangelist here.
Have you set your TwiML application up correctly? The Voice Request URL should be pointing to your python server. I only ask as the message from the Python server, which comes from this line in the code, should be "Congratulations! You have made your first oubound call! Good bye." and you said it was "Welcome to Twilio"
Once you are definitely set up pointing at your Python app, once you have made your first outbound call you will get that message. Now you need to update your Python app as well as the iOS app.
You're sending a parameter To with the number you're trying to call. You need to change the Python so that it reads that number and outputs the TwiML that will dial that number.
That should look a bit like this:
#app.route('/outgoing', methods=['GET', 'POST'])
def outgoing():
resp = twilio.twiml.Response()
resp.dial(request.form['To'])
return str(resp)
Let me know if that helps at all.
During researching of the PrivateFrameworks that are available at iOS 9 i found interesting library that could give access to the call history of the jailbreak iPhone. The question is how to use this framework?
Brief example of my :
NSBundle *b = [NSBundle bundleWithPath:#"/System/Library/PrivateFrameworks/CallHistory.framework"];
BOOL success = [b load];
if (success) {
Class CallHistoryDBHandle = NSClassFromString(#"CallHistoryDBClientHandle");
SEL theSelector = NSSelectorFromString(#"fetchAllNoLimit");
id si = [CallHistoryDBHandle valueForKey:#"createForClient"];
NSLog(#"-- %#", [si performSelector:theSelector]);
} else {
NSLog(#"NO");
}
I am trying to integrate apple pay with stripe in my iOS app.
Using ApplePayStub provide by stripe to check apple pay in DEBUG Mode
I am using the latest stripe and ApplePayStub code from git
Trying to run on iPhone 6 simulator and the code that i am using is:
paymentController = [[STPTestPaymentAuthorizationViewController alloc] initWithPaymentRequest:request];
((STPTestPaymentAuthorizationViewController*) paymentController).delegate = self;
Getting error:
Error Domain=com.stripe.lib Code=50 "Your payment information is formatted improperly. Please make sure you're correctly using the latest version of our iOS library. For more information see https://stripe.com/docs/mobile/ios ." UserInfo=0xxxxxxxxxxx {com.stripe.lib:ErrorMessageKey=Your payment information is formatted improperly. Please make sure you're correctly using the latest version of our iOS library. For more information see https://stripe.com/docs/mobile/ios ., NSLocalizedDescription=Your payment information is formatted improperly. Please make sure you're correctly using the latest version of our iOS library. For more information see https://stripe.com/docs/mobile/ios .},
Any help is greatly appreciated.
#Wizyashas, Your setup of the STPTestPaymentAuthorizationViewController is perfectly fine. The problem happens when you try to generate the token via STPAPIClient. There's where it all gets messy.
This little bit of RnD helped me. Digging into the CustomSampleProject provided by Stripe themselves, ApplePayStubs works pretty well when the STPCard is recognized when the delegate
- (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller
didAuthorizePayment:(PKPayment *)payment
completion:(void (^)(PKPaymentAuthorizationStatus))completion
of PKPaymentAuthorizationViewControllerDelegate is called. The sample code here checked if the code was run in debug that is for ApplePayStubs, the (PKPayment *)payment in the delegate is converted to a STPCard and is launched to the STPAPIClient for STPToken generation. Following is the body of the above mentioned delegate:
#if DEBUG // This is to handle a test result from ApplePayStubs
if (payment.stp_testCardNumber)
{
STPCard *card = [STPCard new];
card.number = payment.stp_testCardNumber;
card.expMonth = 12;
card.expYear = 2020;
card.cvc = #"123";
[[STPAPIClient sharedClient] createTokenWithCard:card
completion:^(STPToken *token, NSError *error)
{
if (error)
{
completion(PKPaymentAuthorizationStatusFailure);
[[[UIAlertView alloc] initWithTitle:#"Error"
message:#"Payment Unsuccessful! \n Please Try Again"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil] show];
return;
}
/*
Handle Token here
*/
}];
}
#else
[[STPAPIClient sharedClient] createTokenWithPayment:payment
completion:^(STPToken *token, NSError *error)
{
if (error)
{
completion(PKPaymentAuthorizationStatusFailure);
[[[UIAlertView alloc] initWithTitle:#"Error"
message:#"Payment Unsuccessful!"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil] show];
return;
}
/*
Handle Token here
*/
}];
#endif
This worked for me. With ApplePayStubs (on Simulator) and without them (on Device).
Hope this Helps :)
Try making request using PaymentKit
#IBAction func payTapped(AnyObject) {
// Valiate that this device can take payments
if (PKPaymentAuthorizationViewController.canMakePayments()) {
// Construct the basic payment request
var paymentRequest = PKPaymentRequest()
paymentRequest.merchantIdentifier = "merchant.com.example";
paymentRequest.supportedNetworks = [PKPaymentNetworkVisa, PKPaymentNetworkMasterCard, PKPaymentNetworkAmex]
paymentRequest.merchantCapabilities = PKMerchantCapability.Capability3DS | PKMerchantCapability.CapabilityEMV
paymentRequest.countryCode = "US"
paymentRequest.currencyCode = "USD"
paymentRequest.requiredShippingAddressFields = PKAddressField.All;
// Add a line item
var totalItem = PKPaymentSummaryItem(label:"Foo", amount:NSDecimalNumber(string:"0.05"))
paymentRequest.paymentSummaryItems = [totalItem];
// Show the Apple Pay controller
var payAuth = PKPaymentAuthorizationViewController(paymentRequest: paymentRequest)
payAuth.delegate = self
self.presentViewController(payAuth, animated:true, completion: nil)
}
}
I've sent scores to the leaderboard with different test accounts but when I try to see the leaderboard I can only see the score from the account that I'm logged in.
I used this code to send the scores :
- (void)reportScore:(int64_t)score forLeaderboardID:(NSString*)identifier
{
GKScore *scoreReporter = [[GKScore alloc] initWithLeaderboardIdentifier: #"GHS"];
scoreReporter.value = score;
scoreReporter.context = 0;
[GKScore reportScores:#[scoreReporter] withCompletionHandler:^(NSError *error) {
if (error == nil) {
NSLog(#"Score reported successfully!");
} else {
NSLog(#"Unable to report score!");
}
}];
}
This is the code I'm using to show the leaderboard:
- (void)showLeaderboardOnViewController:(UIViewController*)viewController
{
GKGameCenterViewController *gameCenterController = [[GKGameCenterViewController alloc] init];
if (gameCenterController != nil) {
gameCenterController.gameCenterDelegate = self;
gameCenterController.viewState = GKGameCenterViewControllerStateLeaderboards;
gameCenterController.leaderboardIdentifier = _leaderboardIdentifier;
[viewController presentViewController: gameCenterController animated: YES completion:nil];
}
}
Maybe it's because it is sandboxed and stuff? is this normal maybe?
Thanks
I've had this issue before and after much searching it seems to be an error with sandbox accounts. I split my table into highest of all time, highest today and highest friend and in each case other higher scores from my other sandbox accounts were ignored. When I added another one of my accounts as a friend, they started sharing scores just fine.
I used code more or less identical to your own and submitted to the App Store where it was accepted, now it works fine with live accounts.
Using the sandboxed Gamecenter.
No matter what I do the scores never appear in a leaderboard.
I am using the following code:
- (void)scoreReported: (NSError*) error {
NSLog(#"%#",[error localizedDescription]);
}
- (void)submitScore{
if(self.currentScore > 0)
{
NSLog(#"Score: %lli submitted to leaderboard %#", self.currentScore, self.currentLeaderBoard);
[gameCenterManager reportScore: self.currentScore forCategory: self.currentLeaderBoard];
}
}
And scoreReported doesnt produce an error, yet the score doesnt appear in the leaderboard. I know the category is correct as I use currentLeaderBoard in:
- (void)showLeaderboard {
NSLog(#"leaderboard = %#", self.currentLeaderBoard);
GKLeaderboardViewController *leaderboardController = [[GKLeaderboardViewController alloc] init];
if (leaderboardController != NULL)
{
leaderboardController.category = self.currentLeaderBoard;
//leaderboardController.category = nil;
leaderboardController.timeScope = GKLeaderboardTimeScopeWeek;
leaderboardController.leaderboardDelegate = self;
[self presentModalViewController: leaderboardController animated: YES];
}
}
I have tried the usual
2 different sandbox GC accounts to get the leaderboard working
Even tried 4 different GC accounts each logging in on both the simulator (iOS 6.1) and device (iOS 6.0.1)
Yet still no joy
any suggestions - or is it just that the sandboxed gamecenter is far too buggy!!! (I would raise a bug about sandbox but the apple bug reporting form has a bug in it so that doesnt work either)
Score reporting to Game Center works almost immediately for me, even in sandbox mode.
Here are the few things you can try
Make sure the the Leaderboard identifiers are correct when reporting scores (Should exactly match with "Leaderboard ID"s in iTunesConnect)
Try Deleting the test data under "Manage Game Center" section of iTunesConnect
Delete the application, launch "Game Center" application in your device and goto "Games" tab and remove your app. Reinstall the app and try reporting the score again.
Make sure [gkScore reportScoreWithCompletionHandler:^(NSError *error) doesn't return any error
For those who want to know this what I changed my submitScore method to:
- (void)submitScore {
GKScore * GCscore = [[GKScore alloc] initWithCategory:self.currentLeaderBoard];
GCscore.value = [[NSUserDefaults standardUserDefaults] integerForKey:#"NEWSCORE"];
[GCscore reportScoreWithCompletionHandler:^(NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^(void) {
if (error == NULL) {
NSLog(#"Score Sent");
} else {
NSLog(#"Score Failed, %#",[error localizedDescription]);
}
});
}];
}
and it worked