Rune's Blog

A blog about code, graphics, UI, marketing and whatever else interests me. Follow me on Twitter: @runmad

Linking *directly* into your app’s reviews in the App Store [UPDATED]

Posted by Rune Madsen on January 21, 2010
Posted in: App Store, Code, iPhone. Tagged: App Store, ratings, reviews, uialertview. 3 comments

UPDATED 10/3:

I have received some feedback regarding this post that I thought I would share:

One developer implemented this feature in a UIAlertView pop-up, asking users nicely if they’re enjoying the app and whether they would like to be taken to the App Store to review the app. This UIAlertView happens after the 10th app launch, so you’re already dealing with people who have used your app enough that they must be liking it. It’s a $0.99 app by the way.

In just two short hours after implementing this, he had received 6 new app store reviews, all with positive feedback along with 4 or 5 stars, nothing less!

What can we learn from this?

1. People are, by nature, lazy. Consider the steps required to actually reviews an app that you like: You have to actively find it again in the App Store, scroll down and go to the review page. Then tap the button to submit your own review, login, etc. Unless someone’s super excited or very pissed off about your app, you will only see a small percentage of people taking their time to go through all those steps to review and rate your app. By asking users, who’ve been using your app more than just a few times nicely for a review, then linking *directly* to the App Store, they’re already skipping many of the above steps and rating and reviewing your app becomes a quick activity related to an app they’re enjoying.

2. Reviews are generally positive. Ratings on the other hand tend to be more black and white. Either people hate your app, delete it and quickly give it 1 star. I doubt a lot of people give apps 4-5 stars when they delete an app. They’re deleting it for a reason; either they didn’t like it, or it just wasn’t what they needed/expected. If they like the app, chances are they’d never delete it, and you wouldn’t be getting those great 4-5 star ratings (refer to #1). I have seen reviews that have pointed out several wrongs about apps, but they’re still adding a 4-5 star rating with the review. It may seem there’s a difference in people’s mind about a review and a rating. I think a lot of users think of reviews as a way of communicating to the developer that there’s an issue with the app, or they want this or that added, but they still use and love the app regardless (giving it a high rating).

3. You’re asking the right users. When deleting an app, Apple has implemented a horrible UIAlertView asking the same people who just got rid of your app to rate it. I think we all agree this is ridiculous (refer to #2). With a UIAlertView inside your app for 10+ launches linking into the reviews of your app in the App Store, you can pretty much assume these people are enjoying the app, especially if they agree to review it. If they’re don’t like it that much or don’t have time, it’s just a simple tap to dismiss the UIAlertView.

ORIGINAL:

Today @coffeeandiphone we briefly discussed ratings/reviews for apps, and one person mentioned he’d like to show some of the users who have used his app more than X amount of times an alert where he’d ask them to review his app in the app store.

So here’s a link that will take people directly to the review section of your app in the App Store. Note, though, they won’t be able to go “Back” to the actual page for your app in the App Store (when on a device), so they can’t really see that they’re on the review page for your app. Therefore, you probably want to make it veryclear where your linking to and before sending them out of your app, into the App Store.

http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?id=341136260&pageNumber=0&sortOrdering=1&type=Purple+Software&mt=8

See where is says “?id=341136260″ ? That’s the only thing you need to change. Just insert your own app ID there and you’re good to go. Don’t get confused by “type=Purple+Software&mt=8″, because if you change that, it won’t work for some reason. I am not quite sure why it has to say Purple Software, but I don’t really care as long as it works :)

Combine it with something like this (“Fighting Back Against The App Store’s Negative Rating Bias”) and you’re good to go!

Edit: I can’t remember where I got this info from, but credit goes to whoever/wherever, of course.

Colouring fun with moreNavigationController

Posted by Rune Madsen on January 9, 2010
Posted in: Code, iPhone, Objective-C, Xcode. Tagged: barStyle, color, iPhone, morenavigationcontroller, tintColor, uitabbarcontroller. 8 comments

When adding more than 5 view controllers to your UITabBarController, a “More” tab is automatically setup for you, which includes a view controller and even a modal view for letting the user edit the app’s tabs in the order they want.

By default, the navigation bars for both the moreNavigationController and the modal view (edit) are the Default blue, but changing these colours isn’t exactly straightforward.

Here’s an example of what we want to achieve:

I use an orange colour in one of my apps for the navigation bars and it just looks wrong when the more tab’s navigation bars are blue.

Changing the colour of the moreNavigationController is quite easy. After you alloc the UITabBarController, set the colour of the moreNavigationController:

tabBarController.moreNavigationController.navigationBar.tintColor = [UIColor orangeColor];

You can also use the barStyle property if you like:

tabBarController.moreNavigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;

That wasn’t so hard. But the navigation bar for the modal view that pops up when the user taps “Edit” is still the default blue. So let’s change that as well:

First, if you haven’t already, make sure your AppDelegate implements the UITabBarControllerDelegate. Then add the optional delegate method willBeginCustomizingViewControllers: in your AppDelegate’s implementation file, and add the following lines of code:

- (void)tabBarController:(UITabBarController *)controller willBeginCustomizingViewControllers:(NSArray *)viewControllers {
    UIView *editView = [controller.view.subviews objectAtIndex:1];
    UINavigationBar *modalNavBar = [editView.subviews objectAtIndex:0];
    modalNavBar.tintColor = [UIColor orangeColor];
}

Again, it’s possible to set the barStyle property instead of the tintColor, but barStyle won’t give you all the colour options, of course.

Now that you have gained control of the modal view, you change more properties. By default, the navigation bar title says “Configure”, but you can change that as well, or how about the background colour? Here’s how:

- (void)tabBarController:(UITabBarController *)controller willBeginCustomizingViewControllers:(NSArray *)viewControllers {
    UIView *editView = [controller.view.subviews objectAtIndex:1];
    editView.backgroundColor = [UIColor grayColor];
    UINavigationBar *modalNavBar = [editView.subviews objectAtIndex:0];
    modalNavBar.tintColor = [UIColor orangeColor];
    modalNavBar.topItem.title = @"Edit Tabs";
}

Regarding the HIG… I am not sure if all this is allowed. I will be submitting an update with an orange coloured navigation bar for both those views, and I believe other apps have it (NY Times) so I don’t think it goes against the HIG.

However, I don’t think it’s a good idea to change the backgroundColor property of the “editView”. I tried with a grey colour and it doesn’t look right. It might also get your app rejected, because it’s such a big change. That your navigation bars are the same colour throughout your app only makes it look better in my opinion, rather than having a blue navigation bar clash with the rest of your beautifully designed app :)

Dedicated Static Analyzer Debug Configuration in Xcode

Posted by Rune Madsen on December 4, 2009
Posted in: Code, iPhone, Objective-C, Xcode. Tagged: analyze, clang, tech talk, Xcode. Leave a Comment

I went to iPhone Tech Talk in Toronto yesterday, and among the many sessions, I attended Michael Jurewitz’ (@jurewitz) session, “Testing and Debugging Your iPhone Application.” He covered a lot of the basics for using Instruments (very similar to last year’s session on that), how to setup provisioning, etc. for Ad-Hoc Beta testing, etc.

He also covered Xcode’s new built in Static Analyzer (Clang), which is incredibly useful and powerful now that it’s a part of Xcode. However, I haven’t been using it that much (he said to use it at least once a week), but he briefly showed that there’s actually a setting in the project’s build settings called “Run Static Analyzer,” which is a checkbox and checking this will run the Static Analyzer every time you build your project. Jurewitz mentioned you could make a duplicate Debug build configuration that is dedicated to running the Static Analyzer.

He went over this very fast, so I think a lot of people missed the benefit of this great tip!

So here’s how you do it:

Open your project settings and go to the Configurations pane. Pick your Debug configuration (or whichever build configuration you want to dedicate to running the Static Analyzer) and hit Duplicate in the bottom of the window. I called mine “Debug with Clang,” so I know it’s my Debug build configuration.

Next, hop into the Build pane and find “Build Options”. Within those options you’ll find the “Run Static Analyzer” option. Check the checkbox and you’re good to go!

Now, every time you build your project using your new “Debug with Clang” it’ll automatically analyze your project. Personally it’ll probably help me remember to run the Static Analyzer way more often on my project, instead of just once in a while.

Keep in mind that running the Static Analyzer increases the time it takes to build your project, so don’t choose that build setting if you’re just testing new code, etc. Also, I find it’s a good idea to “Clean All Targets” once in while, as it seems to ‘reset’ the Static Analyzer, because otherwise I am finding that it tends to miss certain errors on the second, third, fourth, etc. time you build with the “Run Static Analyzer” option on.

Shadow offset in custom UITableViewCells (for the inner OCD in you)

Posted by Rune Madsen on November 16, 2009
Posted in: Code, iPhone, Objective-C. Tagged: iPhone, shadowOffset, uitableview, uitableviewcell. 1 comment

Apple has a great example code for drawing fast UITableView using custom, complex UITableViewCells called AdvancedTableViewCells. In the example code, you get three versions and I prefer the one named CompositeSubviewBasedApplicationCell, because it draws your cell as one view, just like Loren Brichter’s Fast Scrolling example.

However, Apple’s example code goes a bit further than Loren’s code and adds example for drawing images, different coloured backgrounds and also has better code for handling highlighted cells in my opinion.

As great as the code is, they left out one small detail that really adds a bit extra to the look of your UITableView, plus I find it makes the text less blurry and easier to read. It only requires a few lines of code for each piece of text you’re drawing. The example code provided is actually from the App Store, which, if you look on your device has the nice white shadow y offset.

Here are the before and after pictures:

BEFORE

AFTER

Original code:

_highlighted ? [[UIColor whiteColor] set] : [[UIColor blackColor] set];
[_cell.name drawAtPoint:CGPointMake(81.0, 22.0) withFont:[UIFont boldSystemFontOfSize:17.0]];

Drawing the shadow:

CGPoint point = CGPointMake(81.0, 23.0);
_highlighted ? [[UIColor clearColor] set] : [[UIColor colorWithWhite:1.0 alpha:0.3] set];
[_cell.name drawAtPoint:point withFont:[UIFont boldSystemFontOfSize:17.0]];
point.y -= 1;
_highlighted ? [[UIColor whiteColor] set] : [[UIColor blackColor] set];
[_cell.name drawAtPoint:point withFont:[UIFont boldSystemFontOfSize:17.0]];

There are a couple of things to note in the above code. Firstly, I made a CGPoint from the original code and made the Y location one pixel lower. This is because we’re drawing the shadow first, underneath the original text. After the shadow has been drawn, we just tell the point to move up one pixel and the text will be drawn in the original location from the original code.

Second, you’ll need to set the text colours twice. Note that for the shadow, we need to use [UIColor clearColor] so it doesn’t look weird when highlighted. Also, set the alpha low (you need to check with your cell’s background colour), but make sure it’s not too white. It’ll be really subtle, yet noticeable to anyone who appreciate nice UI design.

Of course it doesn’t work with white cells, but if you’re doing any kind of custom UITableViewCell drawing it’s a nice touch. Here’s how I use it in my app:

Translucent UINavigationBar

Posted by Rune Madsen on September 17, 2009
Posted in: Code, iPhone, Objective-C. Tagged: iPhone, tintColor, uinavigationbar. Leave a Comment

Apparently, making your UINavigationBar requires a (tiny) bit more code than just:

self.navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;

After trying hard to change my UINavigationBar colour, and mostly giving up, I found out you have to set its tintColor to nil.

self.navigationController.navigationBar.tintColor = nil;
self.navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;

Getting visual with UITableViews [UPDATED]

Posted by Rune Madsen on August 23, 2009
Posted in: Code, iPhone, Objective-C. Tagged: iPhone, uiimageview, uitableview, uitableviewcell. 1 comment
UPDATED 27/8:

I’ve updated the code and pushed it to bitbucket. All the drawing takes place in a separate class and only one subview is added to the cell(s). Again, if you need to add images for every single cell in a large UITableView, you should probably update the code a bit to suit your needs :)

$ hg clone http://bitbucket.org/runmad/visual-uitableview/
ORIGINAL:

I am working on an app that lists movie releases and tapping a title will display more details about the selected release in a UITableView. One of the details include number of discs included with the product.

Instead of just writing the number of discs in the detailTextLabel, I thought it would be nice to visualize the number of discs. Where appropriate, it’s always a nice touch to use icons/images to dispay information, instead of just using text:

There’s two things added to the cell: a UIImage and a UILabel with the disc amount and label number updated according to the number of discs in the product.

The example code can of course be used for a lot of things than just display some disc icons and a number. Since they’re subviews, it’s probably not wise to use the code as is for every single cell in a large UITableView. Since I am just displaying the icons in one cell, I do not have any memory issues when using subviews.

You can use any integer for the discCount, in the example project, I just used the row number.

A nice touch is the spacing for the disc and label for every disc. The more discs, the less spacing there is between the images and labels (minus one pixel). You will also notice that when there’s 10 or more discs, I simply write the disc amount in the cell’s detailTextLabel and just add one disc image (without a number label). That makes for easier reading when there’s a large amount of discs.

Let me know if you use the code in your own project! I’d love to hear from you if you make any updates to the code that you’d like to share.

cell.textLabel.text = @"Discs";
UIImage *discIcon = [UIImage imageNamed:@"iconDisc.png"];
int discCount = indexPath.row + 1;
if (discCount < 10) {
    for (int i=0; i) {
        CGRect frame = CGRectMake(83 + (17 – discCount) * i, 11, 24, 27);
        UIImageView *discCellImageView = [[UIImageView alloc] initWithFrame:frame];
        discCellImageView.image = discIcon;
        [cell.contentView addSubview:discCellImageView];
        int discNumber = 1 + i;
        CGRect labelFrame = CGRectMake(86 + (17 – discCount) * i, 8, 24, 27);
        UILabel *discCountLabel = [[UILabel alloc] initWithFrame:labelFrame];
        discCountLabel.textColor = [UIColor darkGrayColor];
        discCountLabel.font = [UIFont systemFontOfSize:8];
        discCountLabel.shadowColor = [UIColor whiteColor];
        discCountLabel.shadowOffset = CGSizeMake(0, 1.0);
        discCountLabel.backgroundColor = [UIColor clearColor];
        discCountLabel.text = [NSString stringWithFormat:@"%d", discNumber];
        [cell.contentView addSubview:discCountLabel];
    }
} else if (discCount >= 10) {
    cell.detailTextLabel.text = [NSString stringWithFormat:@"%d", discCount];
    CGRect frame = CGRectMake(113, 11, 24, 27);
    UIImageView *discCellImageView = [[UIImageView alloc] initWithFrame:frame];
    discCellImageView.image = discIcon;
    [cell addSubview:discCellImageView];
}

You can download the project here: http://bitbucket.org/runmad/visual-uitableview/.

Or in Terminal:

$ hg clone http://bitbucket.org/runmad/visual-uitableview/

Thanks to Blake for his input and help!

Posts navigation

Newer Entries →
  • Recent Posts

    • Making Rounded Rectangles Look Great (with CSS)
    • Final #idevblogaday post for this round
    • Accessibility on iOS: Working with VoiceOver support
    • Core Location presentation at TACOW
    • Next TTC follow-up + TACOW Meet-up tomorrow
    • Next TTC: Behind the scenes
    • WWDC in Pictures
    • Introducing GiftKit – gifting made easy
    • ColorKit: A Color Assessment Utility App
    • Faking depth and textures in your app
  • Recent Comments

    • Rune Madsen on Next TTC: Behind the scenes
    • Merch Visoiu on Next TTC: Behind the scenes
    • EeKay on UITabBarController and UIActionSheet – 65% less hit point!
    • vipul on Accessibility on iOS: Working with VoiceOver support
    • Tung Do on Colouring fun with moreNavigationController
  • Meta

    • Log in
    • Entries RSS
    • Comments RSS
    • WordPress.org
Proudly powered by WordPress Theme: Parament by Automattic.