Git Product home page Git Product logo

appirater's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

appirater's Issues

multitasking and Appirater

There are a few issues in + (void)appLaunched:(BOOL)canPromptForRating.

  1. [device respondsToSelector:@selector(multitaskingSupported)] always returns false. This is because the getter is called isMultitaskingSupported,
    [device respondsToSelector:@selector(isMultitaskingSupported)] works fine.
  2. On at least iOS 4.0.1 I do not get a call on applicationWillEnterForeground: on my delegate on first launch. (But I do get it on switching to the application if it is running.) This means that if the first issue is fixed, the initial launch on multitasking environments may not be recorded.

P.S. This is a great piece of code, keep up the good work!

Is Storekit functionality beneficial to Appirater?

If running on iOS 6, then Appirater uses Storekit's ability to present a product page on the app store in a modal view.

However I'd question whether this actually does more harm than good in getting users to leave ratings or reviews since it involves one more user action than the URL method.

Storekit (iOS 6)
Designed for handling in app purchases rather than reviews, so the reviews tab cannot be selected automatically and the user must:

  1. Select "Reviews" tab
  2. Touch the "Write a Review" button

URL method to App Store app (pre-iOS 6)
This takes the user directly to the "Reviews" tab, so they only need to:

  1. Touch the "Write a Review" button

Yes it's only one more action, but every action counts when it comes to getting feedback from users! Personally I don't think leaving the host app is a problem since the user doesn't know what is about to happen until they press the button!

Use SKStoreProductViewController for in-app rating (feature request)

Hi,

Starting from iOS 6, it's possible to show an iTunes controller within the app with the SKITunesProductViewController class.

I believe this could be used to rate the app. This means the user wouldn't need to abandon the app being rated in order to rate it.

Implementing this wouldn't be trivial, since we need to push the view controller. I believe we would need to make some changes to the delegate protocol:

  1. We need to get the view controller that will be used to push and dismiss the modal controller. If the user doesn't implement this delegate method, we may fall back to jumping to the iTunes URL.

  2. We need to let the delegate know when we're pushing a view controller (e.g. so a game can pause) and when we're dismissing it (e.g. so a game can unpause).

  3. We may need to ask the delegate if we should push with animations enabled or not, as pushing with animations can be troublesome in some (rare) cases.

Thoughts?

Regards,

EXC_BAD_ACCESS when running on iOS 5.0 simulator (but not on iOS 6 device/simulator)

I am receiving a crash immediately upon app launch when running the latest version of Appirater on the iOS 5.0 simulator.

The debugger is pointing to the dispatch_async line of code on line 345 of Appirator.m. Any ideas why this would happen?

+ (void)appLaunched:(BOOL)canPromptForRating {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0),
                   ^{
                       [[Appirater sharedInstance] incrementAndRate:canPromptForRating];
                   });
}

The settings I am using:

    [Appirater setAppId:@"1234567890"];
    [Appirater setDaysUntilPrompt:1];
    [Appirater setUsesUntilPrompt:10];
    [Appirater setSignificantEventsUntilPrompt:-1];
    [Appirater setTimeBeforeReminding:5];
    [Appirater setDebug:NO];
    [Appirater appLaunched:YES];

Leaks

Hi,

Thanks for your code. Great idea!
It contains a bunch of leaks though. Maybe you should put on the Static Analyser (check your build settings). These are the leaks that the static analyser detects:
• unreleased UIAlertview (line 185) -- after show, it should be released
• testConnection (line 83) -- should be released
• Appirater unreleased (line 93) -- after detaching a new thread, it can be auto-released (it's retained by the thread)

M

Allow for more buttons like an email us button

One of the biggest complaints I have with apple's app store is that as a developer I can't respond to user's reviews. It would be nice if appirater would give users an option to email the developer if they have complaints or suggestions. I've does something similar in some of my apps with good success. No bad reviews and useful feedback.

NSLocalizedString

Hi,

this is a great project. I really like it. Thanks for creating it.

There is one thing missing, though its not difficult to add it myself, but just wanted to note that it would be great to add NSLocalizedString to the master Branch for multilingual support if someone needs it like myself.

Buju77

Appirater comes up on first use

Following the instructions, and not using any "significant events" appirater comes up the first time the app launches. Any ideas? It also comes up any time the app enters the foreground. Tried reinstalling with no luck.

iOS 5.1
Xcode 4.4

AppName not displayed

Hi,

Appirater is really cool, but I am not able to show my Apps Name on the UIAlertView. Instead of the Name (Winzis Pairs) I see only "null"...

Another question: How can Appirater be tested? Currently I have to wait 1 day until I see the UIAlertView, which is not really practicable. How do you handle this?

Thanks and BR,

Stefan

Using NSNotificationCenter without unsubscribing from it.

In line 202 Appirater is adding itself as an observer to NSNotificationCenter without unregistering from NSNotificationCenter again. Documentation says:

"Be sure to invoke removeObserver: (or removeObserver:name:object:) before notificationObserver or any object specified in addObserver:selector:name:object: is deallocated."

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/nsnotificationcenter_Class/Reference/Reference.html#//apple_ref/occ/instm/NSNotificationCenter/removeObserver:

Fix could be to call removeObserver:self in an overridden dealloc-method.

Please add semantic version tags

Somebody have recently added appirater to the CocoaPods package manager repo.

CocoaPods is a tool for managing dependencies for OS X and iOS Xcode projects and provides a central repository for iOS/OS X libraries. This makes adding libraries to a project and updating them extremely easy and it will help users to resolve dependencies of the libraries they use.

However, appirater doesn't have any version tags. Now we use current HEAD as version 0.0.3, but a version tag will make dependency resolution much easier.

Semantic version tags (instead of plain commit hashes/revisions) allow for resolution of cross-dependencies.

In case you didn’t know this yet; you can tag the current HEAD as, for instance, version 1.0.0, like so:

$ git tag -a 1.0.0 -m "Tag release 1.0.0"
$ git push --tags

Ask for rating in a different position in an app

I'd like to move where the rating dialog is show, instead of when the app starts, to after a certain feature has been used. However I still want to preserve all of the app uses, as normal.

From reading the comments in the h file, it sounds like all I need to do is call [Appirater appLaunched:NO]; in app delegate then call [Appirater appLaunched:YES]; at the certain desired point in my app ?

However, it does say that calling appLaunched will increment uses, so I'm concerned that the second call will increment the uses as well as the first?

Obviously I can't just call [Appirater appLaunched:YES]; at the certain point, as this doesn't occur every time the app runs.

Thanks in advance.

Changelog / release notes? (1.0.5 > 2.0.x)

Hello there,

Can someone point me to release notes or a changelog for Appirater? We have been using 1.0.5 from CocoaPods, and I noticed that it has recently been bumped to 2.0.1. I want to know what requirements and behaviour have changed between these versions before updating, but I can find no trace of such documentation.

thanks,

b

ratingConditionsHaveBeenMet - micro optimizations

It is better to move at least to checks: "// has the user already rated the app?" and "// has the user previously declined to rate this version of the app?" to method head. They are cheaper than time interval checks so after application is rated (or rating was declined by user) the check won't waste the processor time that much as creating NSDate and NSTimeInterval objects.

Review Page blank on iOS [Redacted]

Though the link still works on iOS 6, iOS [REDACTED] redirects to a blank page. Do you think this is temporary, or is Apple removing the direct link to the review page?

Suggestion : check for #ifdef DEBUG before checking for APPIRATER_DEBUG

In ratingConditionsHaveBeenMet I would suggest to place an additional check if the app is in debug mode before checking the APPIRATER_DEBUG flag. This will ensure that developers don't accidentally submit an app to the app store that displays the rating dialog on every launch.

 - (BOOL)ratingConditionsHaveBeenMet {
#ifdef DEBUG 
    if (APPIRATER_DEBUG)
        return YES;
#endif

I'm assuming here that most devs have a DEBUG flag defined on the debug builds (if not, they should).

Launching an app never calls incrementAndRate on multitaskng devices

If you launch an app on a multi-tasking iOS, incrementAndRate is never called. When the dev calls
[Appirater appLaunched:YES];

That method checks for multi-tasking:
if ([device respondsToSelector:@selector(isMultitaskingSupported)] &&
[device isMultitaskingSupported])
{
return;
}

Since multi-tasking is available, the method immediately returns without incrementing counts or checking if the rating dialog should be shown. It will not be until the user exits the app and relaunches it (assuming that it was still running in the background) that Appiraters appEnteredForeground will be called and the increments and checks performed. Note that applicationWillEnterForeground will not be called when an app is launched initially, only when it is being launched from the background.

In addition, for developers this means that setting APPIRATER_DEBUG to YES will have no effect unless you background the app and bring it to the foreground.

There is no guarantee that any app will remain in the background. Backgrounded apps can be killed by the OS at any time or the user can kill backgrounded apps.

To resolve the problem, appLaunched still needs to call incrementAndRate regardless if multi-tasking is supported.

SKStoreProductParameterITunesItemIdentifier:appId, appId must be NSString

SKStoreProductViewController *storeViewController = [[SKStoreProductViewController alloc] init];
NSNumber *appId = [NSNumber numberWithInteger:_appId.integerValue];
[storeViewController loadProductWithParameters:@{SKStoreProductParameterITunesItemIdentifier:appId} completionBlock:nil];
storeViewController.delegate = self.sharedInstance;

"SKStoreProductParameterITunesItemIdentifier:appId" the appId must be string, simply change it to SKStoreProductParameterITunesItemIdentifier:_appId will work.

Mistake

Sorry, this issue is a mistake. Please delete it.

+ (void)closeModal won't work when AppDelegate is using navigationController

Hi,
My app uses Navigation Controller, and closeModal couldn't close the AppStore view because it couldn't find the topMostViewController .

I fixed this issue by not using closeModal, but instead doing the following, at Appirater.m -

-(void)productViewControllerDidFinish:(SKStoreProductViewController *)viewController {
MyDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate.navigationController.topViewController dismissModalViewControllerAnimated:_usesAnimation];
}

This is not a good way to solve this issue, as this is a very specific way to deal with it. Unfortunately, I'm running out of time to release my app and will leave the code in this way, but I'm aware that this issue should be solved inside topMostViewController .

Thanks!

iOS 6 Language code produces invalid link

In iOS 6, a new URL has been added, which replaces LANGUAGE for the 2 character country code. However, in the UK, the value that replaces LANGUAGE comes back as en-GB (which doesn't work and yields a broken url).

deprecation of UIStatusBarStyleBlackOpaque in .m of code

here is where the code throws the error

  • (id)getRootViewController {
    UIWindow *window = [[UIApplication sharedApplication] keyWindow];
    if (window.windowLevel != UIWindowLevelNormal) {
    NSArray *windows = [[UIApplication sharedApplication] windows];
    for(window in windows) {
    if (window.windowLevel == UIWindowLevelNormal) {
    break;
    }
    }
    }

for (UIView *subView in [window subviews])
{
UIResponder *responder = [subView nextResponder];
if([responder isKindOfClass:[UIViewController class]]) {
return [self topMostViewController: (UIViewController *) responder];
}
}

return nil; <----------flag is thrown here
}

Compile error in iOS 3.2

While trying to add appirater to my iPad app I ran into a problem when trying to make the app compile under both iOS 3.2 and 4.2. The error resulted from the call to device.multitaskingSupported.

I was able to fix this by making it a method call instead of accessing the property. I also switched the if statement to a slightly more robust version. I also had to use isMultitaskingSupported, or the method call wouldn't work.

Here is the code I changed from line 296 of Appirater.m:

    UIDevice *device = [UIDevice currentDevice];
    if ([device respondsToSelector:@selector(isMultitaskingSupported)]) {
        if([device isMultitaskingSupported]) {
            return;
        }
    }

iPad-only URL being selected even on iPhone...

I've just integrated Appirater into our app (awesome work, btw!) and noticed that the iPad-only app store URL is being targeted by Appirater every time, no matter that our app is Universal. It even goes to the wrong URL when running on the iPhone. As a workaround, I am hardcoding the iPad URL to match the iPhone / Universal URL.

README.md bug?

In the README.md file, it says "If you wanted to show the request after 5 days only you can set the following."
However, the code seems to be doing "5 times" instead of "5 days".

Armenian translation for Appirater

Hello,

Here are Armenian translation.

"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Եթե Դուք հաճույքով եք օգտագործում %@-ը, դեմ չե՞ք լինի տրամադրել մեկ րոպե այն գնահատելու համար: Այն չի պահանջի ձեզանից ավելի քան մեկ րոպե: Շնորհակալություն աջակցության համար:";
"Rate %@" = "Գնահատել %@-ը";
"No, Thanks" = "Ոչ, շնորհակալություն";
"Remind me later" = "Հիշեցնել ավելի ուշ";

Best regards,
Vardan Gevorgyan

Problem when app moves to background

If the UIAlertView is present and the user moves the app to the background, Appirater gets stuck in a vicious circle of briefly presenting the alert and then dismissing it.

As a brute force measure, I am simply cycling through subviews from applicationDidEnterBackground: and calling dismissWithClickedButtonIndex: on the UIAlertView. This works for my particular implementation, but is obviously not safe for everyone.

Alerts will not show on iPad

Added all code to an universal iOS app. The alert shows no problem on the iPhone/iPod Touch, but will not show on iPad. Any ideas?

please rename Localizable.strings

Renaming Localizable.strings would avoid issues when you have multiple localization files in your bundle.

This has been implemented by

ypelud@2afc7aa

where Appirater.strings is used instead of Localizable.strings

appirater causes defaults changed notfication from multiple threads

Appirater uses dispatch_async to schedule work in the low priority global queue, this causes defaults changed events to be posted from multiple threads and assorted race conditions in naive apps. I would believe that this should be mentioned in the readme as it surprised me and causes some head scratching to find out where that crash came from.

no longer compiles for iOS 4.x

The recent addition of the delegate notion includes a property annotated "weak", which won't compile for iOS4.x targets. We need to change this to unsafe_unretained for platforms before iOS5.

i.e. change

@Property(nonatomic, weak) NSObject *delegate;

to

@Property(nonatomic, unsafe_unretained) NSObject *delegate;

How to test Appirator

I want to know what settings to add so that Appirator will show up immediately when opening the app, for testing purposes. I'm building the app in Xcode of course and closing and re-launching it multiple times from my device to test. I have tried all combinations of adding the methods or changing the static values to 0s or 1s, but I can't get it to pop up. I suspect that I may have something else wrong with my setup that is preventing it from working, but can anyone confirm what would make it show up at each launch?

I currently have the messages below at the beginning in my AppDelegate.m didFinishLaunchingWithOptions method.

[Appirater setDaysUntilPrompt:0];
[Appirater setUsesUntilPrompt:0];
[Appirater setSignificantEventsUntilPrompt:-1];
[Appirater setTimeBeforeReminding:0];

Thanks for reading.

Help on setup AppiRater

How do i use setSignificantEventsUntilPrompt and setTimeBeforeReminding properties? Thanks

iTunes URL protocol (itms-apps://) won't work in simulator. Provide developer log message.

The iTunes URL protocol to open the app store (itms-apps://) won't work in simulator. Most devs understand this, but it would probably be a good idea to put some checking around the code to provide a reminder. I've modified the alertView:clickedButtonAtIndex as follows:

#if (TARGET_IPHONE_SIMULATOR)
    NSLog(@"iTunes URL protocol (itms-apps://) doesn't work in the simulator.");
#else

MESSAGE_TITLE and RATE_BUTTON refer to the same localized string.

Since APPIRATER_LOCALIZED_MESSAGE_TITLE and APPIRATER_LOCALIZED_RATE_BUTTON both refer to the same key ("Rate %@") in the strings file, you can't set separate text for these without editing the class. There may be some cases where you prefer to have the title and rate button differ.

NSAlertWarnUnsafeBackgroundThreadUsage

I've got this warn message running appirater with MacOS X Lion.

"NSAlert is being used from a background thread, which is not safe. This is probably going to crash sometimes. Break on _NSAlertWarnUnsafeBackgroundThreadUsage to debug. This will be logged only once. This may break in the future."

iOS6 review link works again

Apple fixed the review link issue on iOS6 app store, and it works again.
But, it doesn't go to the review page where you can start writing right away as you did on iOS5.

I'm not sure if there is better way, but I am doing like this at the moment.

  • (void)rateApp {

    if TARGET_IPHONE_SIMULATOR

    NSLog(@"APPIRATER NOTE: iTunes App Store is not supported on the iOS simulator. Unable to open App Store page.");

    else

    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    NSString *reviewURL = [templateReviewURL stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%@", _appId]];

    [userDefaults setBool:YES forKey:kAppiraterRatedCurrentVersion];
    [userDefaults synchronize];
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:reviewURL]];

    endif

    }

iOS 6 support

Does anyone know if this works with iOS 6, as I believe the links to review have changed.

SCNetworkReachabilityGetFlags compiling error

Hi, I'm trying to use Appirater but when compiling I get the following error:

"_SCNetworkReachabilityGetFlags", referenced from:
-[Appirater(hidden) connectedToNetwork] in Appirater.o
"_SCNetworkReachabilityCreateWithAddress", referenced from:
-[Appirater(hidden) connectedToNetwork] in Appirater.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

Alert not displaying Message.

When the alert is displayed in my app it doesn't show the message:

define APPIRATER_MESSAGE [NSString stringWithFormat:@"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!", APPIRATER_APP_NAME]

It only says Rate Ice Cold

(Ice Cold is the name of my app)

Any ideas about how I can solve this?

memory leak

diff --git a/Appirater.m b/Appirater.m
index 0d2bb62..bbcd13e 100644
--- a/Appirater.m
+++ b/Appirater.m
@@ -85,7 +85,7 @@ NSString *templateReviewURL = @"itms-apps://ax.itunes.apple.com/WebObjects/MZSto

        NSURL *testURL = [NSURL URLWithString:@"http://www.apple.com/"];
        NSURLRequest *testRequest = [NSURLRequest requestWithURL:testURL  cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0];
-       NSURLConnection *testConnection = [[NSURLConnection alloc] initWithRequest:testRequest delegate:self];
+       NSURLConnection *testConnection = [[[NSURLConnection alloc] initWithRequest:testRequest delegate:self] autorelease];

     return ((isReachable && !needsConnection) || nonWiFi) ? (testConnection ? YES : NO) : NO;
 }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.