SKStoreProductViewControllerDelegate method not being called - ios

I'm simply trying to implement the iTunes store screen in my application, and it displays correctly. However, when the user is finished with the screen (makes a purchase or clicks 'cancel') all I get is a white screen, and I have to completely close my app and reopen it.
It turns out my productViewControllerDidFinish method isn't being called.
I have a table view controller that has the SKStoreProductViewControllerDelegate and I'm presenting and dismissing the store view in the same class, so why isn't the delegate method being called?
- (void)toStore:(Button*)sender {
SKStoreProductViewController *storeProductViewController = [[SKStoreProductViewController alloc] init];
[storeProductViewController loadProductWithParameters:#{SKStoreProductParameterITunesItemIdentifier : #"stuff"} completionBlock:^(BOOL result, NSError *error) {
if (error) {
NSLog(#"Error %# with User Info %#.", error, [error userInfo]);
} else {
[self presentViewController:storeProductViewController animated:YES completion:nil];
}
}];
}
- (void)productViewControllerDidFinish:(SKStoreProductViewController*)viewController {
[self dismissViewControllerAnimated:YES completion:nil];
}
Both in a UITableViewController. Thanks in advance!

Set delegate of SKStoreProductViewController controller.. You missed to do that..
Set it just below object allocation..
storeProductViewController.delegate = self;

Related

Open app from App Store not the same as in board

I have a 'Terms and Conditions' controller I represent in the first launch of the app, but when opening the app in the first time from the App Store page the Terms and Conditions' controller not shown- only after I close the app and reopen it from the device itself (not the App Store page) then the controller is shown.
this code is from the launched screen controller:
- (void)viewDidLoad {
[self agreedToServerTerms];
}
- (void)agreedToServerTerms {
[[HttpUtils instance] httpRequest:TERMS_AGREEMENT_URL :params completionHandler:^(NSData *data, NSError *error) {
#try {
bool acceptTerms = false;
if (error) {
[Utils log:[NSString stringWithFormat:#"agreedToServerTerms error=%#", error]];
} else {
NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if (!error) {
acceptTerms = [jsonData.allValues[0] boolValue];
if (!acceptTerms) {
TermsAndConditionController *tac = [[TermsAndConditionController alloc] initWithNibName:#"TermsAndConditionController" bundle:nil];
tac.delegate = self;
[[SlideNavigationController sharedInstance] pushViewController:tac animated:false];
}
else {
[self performSelectorInBackground:#selector(initialApp) withObject:nil];
}
} else {
[Utils log:[NSString stringWithFormat:#"parsing jsonData error = %#" ,error]];
}
}
} #catch (NSException *e) {
[Utils log:[NSString stringWithFormat:#"Exception occurred: %#, %#", e, [e userInfo]]];
}
}];
}
from App delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
LaunchScreenController *bbp = [[LaunchScreenController alloc] initWithNibName:#"LaunchScreenController" bundle:nil];
[[SlideNavigationController sharedInstance] pushViewController:bbp animated:YES];
if (_launchedURL) {
bbp.launchedURL = _launchedURL;
}
[self.window addSubview:bbp.view];
}
herewith how I do almost the exact same thing. I think you need to rework yours, it could be a bit different, but this may help.
In the first VC that my app displays, in its viewWillAppear message, I have the following code
// Terms of use
if ( [NSUserDefaults.standardUserDefaults integerForKey:#"tou"] != 20170614 )
{
[self performSegueWithIdentifier:#"tou" sender:nil];
[NSUserDefaults.standardUserDefaults setInteger:20170614 forKey:#"tou"];
}
This uses user defaults to note if the terms of use have ever been presented and, if so, it marks #"tou" with some arbitrary value. In your case you can set the logic in your controller and only mark it once the user accepts.
This requires a segue in the storyboard called #"tou" that will present your T&C controller and you may need to prevent exit if the user does not agree, but the idea is to segue away from your first VC if the user did not agree yet to present the user with the T&C rather than injecting it into the app delegate as you do at present.

Calling API for GoogleMap objective c

Can anyone guide me how we can use place auto complete in GoogleMap after all the steps completed for installing pod for GoogleMaps into the project?? I have no idea about this please somebody help me!!!
I hope u have integrated google pods successfully
Import google map class
#import GoogleMaps;
Add delegate
<GMSAutocompleteViewControllerDelegate>
I have button in my screen to go for autocomplete screen.
On button IBAction write this code
GMSAutocompleteViewController *acController = [[GMSAutocompleteViewController alloc] init];
acController.delegate = self;
[self presentViewController:acController animated:YES completion:nil];
and implement GMSAutocompleteViewControllerDelegate
- (void)viewController:(GMSAutocompleteViewController *)viewControllerdidAutocompleteWithPlace:(GMSPlace *)place {
[self dismissViewControllerAnimated:YES completion:nil];
// Do something with the selected place.
NSLog(#"Place name %#", place.name);
NSLog(#"Place address %#", place.formattedAddress);
NSLog(#"Place attributions %#", place.attributions.string);
}
- (void)viewController:(GMSAutocompleteViewController *)viewControllerdidFailAutocompleteWithError:(NSError *)error {
[self dismissViewControllerAnimated:YES completion:nil];
// TODO: handle the error.
NSLog(#"Error: %#", [error description]);
}
// User canceled the operation.
- (void)wasCancelled:(GMSAutocompleteViewController *)viewController {
[self dismissViewControllerAnimated:YES completion:nil];
}
// Turn the network activity indicator on and off again.
- (void)didRequestAutocompletePredictions:(GMSAutocompleteViewController*)viewController {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
}
- (void)didUpdateAutocompletePredictions:(GMSAutocompleteViewController*)viewController {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}

Load another View after successful TouchID login

I played around a bit with TouchID and I have the following question:
After successful TouchID login, how do I present a new ViewController?
The code in the viewController.m is:
#import "ViewController.h"
#import LocalAuthentication;
#import "SVProgressHUD.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
LAContext *context = [[LAContext alloc] init];
NSError *error;
// check if the policy can be evaluated
if (![context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error])
{
NSLog(#"error:%#", error);
NSString *msg = [NSString stringWithFormat:#"Can't evaluate policy! %#", error.localizedDescription];
[SVProgressHUD showErrorWithStatus:msg];
return;
}
// evaluate
[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:#"Please login through TouchID"
reply:
^(BOOL success, NSError *authenticationError) {
dispatch_async(dispatch_get_main_queue(), ^{
if (success) {
[SVProgressHUD showSuccessWithStatus:#"Everything Worked!"];
//Code for new viewController should come here!
}
else {
NSLog(#"error:%#", authenticationError);
[SVProgressHUD showErrorWithStatus:[NSString stringWithFormat:#"FAILED! %#", authenticationError.localizedDescription]];
}
});
}];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
viewController.h is standart. Nothing changed in it.
Thanks for support :)
To present a view controller we normally use following methods
If we are using storyboard,then call following method
[self performSegueWithIdentifier:#"indentifierForViewController" sender:self];
If we are not using storyboard then we can use
NextTaskViewControler *add = [[NextTaskViewControler alloc]
initWithNibName:#"NextTaskViewController" bundle:nil];
[self presentViewController:nextTaskVC animated:YES completion:nil];
I suggest you to use UINavigationController, a specialized view controller that manages other view controllers to provide a hierarchical navigation for the user. Present a viewcontroller only for specific purpose such as presenting a photo with few actions in it.It's easy to maintain when view hierarchy becomes complex
Please go-through UINavigationController Refrence

Authenticate player ios app

I am trying to integrate game center into my app, however I keep getting errors. I input the following code into app delegate.m and this is what i get:
- (void)authenticateLocalPlayer {
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error){
if (viewController != nil) {
[self presentViewController:viewController animated:YES completion:nil];
}
else{
if ([GKLocalPlayer localPlayer].authenticated) {
_gameCenterManager = YES;
// Get the default leaderboard identifier.
[[GKLocalPlayer localPlayer] loadDefaultLeaderboardIdentifierWithCompletionHandler:^(NSString *leaderboardIdentifier, NSError *error) {
if (error != nil) {
NSLog(#"%#", [error localizedDescription]);
}
else{
leaderboardIdentifier = leaderboardIdentifier;
}
}];
}
else{
_gameCenterManager = NO;
}
}
};
}
I use this code, but I get an error for this part of the code:
[self presentViewController:viewController animated:YES completion:nil];
Xcode tells me that this instance method is not found. From my understanding this is an instance method from UIView? Is there anyway I could somehow use this method in the app delegate class?
In Addition to #Raptor's answer try following.
[self.window.rootViewController presentViewController:viewController animated:YES completion:nil];
You should not use [self presentViewController:viewController animated:YES completion:nil]; to present a view controller in App Delegate, as App Delegate does not respond to presentViewController:animated:
You can use:
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];

Getting Twitter to display the option of going to my settings page if Twitter is not set up? iOS5+

If I access Twitter, I would prefer to use the automatic alert box asking that the user go to settings, yet can't get it to work and provide my own default dialog, which I really don't want to do.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"indexPath.row %i", indexPath.row);
if (indexPath.row == 0) {
store = [[ACAccountStore alloc] init]; // Long-lived
twitterType = [store accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[store requestAccessToAccountsWithType:twitterType withCompletionHandler:^(BOOL granted, NSError *error) {
if (granted) {
// Access has been granted, now we can access the accounts
twitterAccounts = [store accountsWithAccountType:twitterType];
if (twitterAccounts.count == 1) {
[self getTwitterData:[twitterAccounts objectAtIndex:0]];
} else {
[self selectTwitterAccount];
}
} else {
// Prefer NOT to do this ************************************
[self performSelectorOnMainThread:#selector(showTwitterError) withObject:nil waitUntilDone:NO];
}
}];
}
It is little tricky , i get by the removing the subviews in *TWTWeetComposeViewController*, so it shows only alert when user is not loged in and by the clicking on setting button , we can open the setting page in my app.
+ (void)setAlertForSettingPage :(id)delegate
{
// Set up the built-in twitter composition view controller.
TWTweetComposeViewController *tweetViewController = [[TWTweetComposeViewController alloc] init];
// Create the completion handler block.
[tweetViewController setCompletionHandler:^(TWTweetComposeViewControllerResult result) {
[delegate dismissModalViewControllerAnimated:YES];
}];
// Present the tweet composition view controller modally.
[delegate presentModalViewController:tweetViewController animated:YES];
//tweetViewController.view.hidden = YES;
for (UIView *view in tweetViewController.view.subviews){
[view removeFromSuperview];
}
}
Here, delegate is your viewcontroller, if you are using this method inside your viewcontroller just use self instead of delegate.
I had to face the same problem and found this sollution
To my knowledge this was only possible in iOS versions 5.0 - 5.0.1.
It was then depreciated again in iOS 5.1
So NO solution at the moment...
In case you would like to use the iOS 5 part:
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"prefs://"]];
And some more reading on the same topic

Resources