From 6c5e09550ff10dac1a35d58043f4b58a5df4c50e Mon Sep 17 00:00:00 2001 From: Jeff Arena Date: Tue, 14 May 2013 12:33:13 -0400 Subject: [PATCH] Fix bug in modal dismissal of SKStoreProductViewController Per the iOS View Controller Programming Guide, a modal view should be dismissed by the controller that presented it originally. Currently, the modally presented SKStoreProductViewController is dismissing itself, which is incorrect. We fix this issue by storing a weak reference to the presenting view controller and using it to dismiss the modal view. --- Appirater.m | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Appirater.m b/Appirater.m index 5c1ad5c1..6b39b124 100644 --- a/Appirater.m +++ b/Appirater.m @@ -37,6 +37,7 @@ #import "Appirater.h" #import #include +#import #if ! __has_feature(objc_arc) #warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). @@ -64,6 +65,8 @@ static UIStatusBarStyle _statusBarStyle; static BOOL _modalOpen = false; +static char SKStoreProductViewControllerPresentingController; + @interface Appirater () - (BOOL)connectedToNetwork; + (Appirater*)sharedInstance; @@ -449,7 +452,9 @@ + (void)rateApp { if ([self.sharedInstance.delegate respondsToSelector:@selector(appiraterWillPresentModalView:animated:)]) { [self.sharedInstance.delegate appiraterWillPresentModalView:self.sharedInstance animated:_usesAnimation]; } - [[self getRootViewController] presentViewController:storeViewController animated:_usesAnimation completion:^{ + id rootViewController = [self getRootViewController]; + objc_setAssociatedObject(self, &SKStoreProductViewControllerPresentingController, rootViewController, OBJC_ASSOCIATION_ASSIGN); + [rootViewController presentViewController:storeViewController animated:_usesAnimation completion:^{ [self setModalOpen:YES]; //Temporarily use a black status bar to match the StoreKit view. [self setStatusBarStyle:[UIApplication sharedApplication].statusBarStyle]; @@ -516,9 +521,8 @@ + (void)closeModal { BOOL usedAnimation = _usesAnimation; [self setModalOpen:NO]; - // get the top most controller (= the StoreKit Controller) and dismiss it - UIViewController *presentingController = [UIApplication sharedApplication].keyWindow.rootViewController; - presentingController = [self topMostViewController: presentingController]; + // Retrieve a reference to the UIViewController used to present the StoreKit view controller + UIViewController *presentingController = objc_getAssociatedObject(self, &SKStoreProductViewControllerPresentingController); [presentingController dismissViewControllerAnimated:_usesAnimation completion:^{ if ([self.sharedInstance.delegate respondsToSelector:@selector(appiraterDidDismissModalView:animated:)]) { [self.sharedInstance.delegate appiraterDidDismissModalView:(Appirater *)self animated:usedAnimation];