Archive for July, 2009

31
Jul

Keypad codes

Here’s an article with a bunch of keypad codes you can enter into your iPhone to get all sorts of interesting network and settings statuses. Apparently most of them aren’t actually iPhone-specific, with the exception of this one,

*3001#12345#*- Opens up the “Field Test” settings on your iPhone, which allows you to see many, many advanced network settings on your phone including cell site information and more.

… but hey, for those of us who aren’t hardcore cellphone geeks, this is news!

[EDIT: And here's a list of standard GSM codes for call forwarding and the like which the iPhone ought to support; also check wikipedia!]

h/t: MobileOrchard!

30
Jul

UI Design Patterns

If you’ve got anything to do with designing iPhone interfaces — on paper or not — do not miss this post over at the new to us but worthwhile looking Flyosity blog about the advantages and disadvantages of different types of conventional iPhone application view organization

These three main interaction concepts correspond to three different types of View Controllers: Navigation Controllers, Tab Bar Controllers, Modal View Controllers and Table View Controllers respectfully. These are the building blocks for crafting iPhone applications.

and designing custom interfaces as well, with several paradigms of each type. Nothing overly surprising, but a nicely crafted overview, and the custom examples chosen are particularly interesting.

h/t: Daring Fireball!

29
Jul

App Store keywords

Just in case you missed the news so far, now you’re allowed to put up to 100 comma-separated characters of keywords (although the instructions claim 255) in your App Store listings — sign into iTunes Connect and you’ll see a new field in your application information screen:

keywords.png

You read our bit a couple days ago about seeding your description with keywords, yes? Well, time to start applying all your SEO-fu to a direct keyword selection now!

28
Jul

iPhone Stencil Kit

Now here’s something that we bet you didn’t see coming as an aid to your iPhone UI design: a stainless steel stencil. Yes, the kind that works with paper.

iphonestencil.jpg

Personally, we figure Interface Builder live design is the way to go when trying out interface ideas … but hey, there is a body of opinion out there that believes in paper prototyping, and if you’re one of them, this is for you, indeed. Besides, it just looks cool, doesn’t it now?

h/t: LinkedIn!

27
Jul

GUI Elements with Keynote

Now here’s a clever-sounding workflow for whipping together some reasonably attractive non-standard GUI elements for your iPhone project in short order; particularly useful for trolls, who as artists are really good programmers, if you get our drift.

Turns out that Keynote, which chances are fairly good you probably have on your machine even if you didn’t realize it as part of iWork, is very good at creating custom buttons and the like.

Then he recommends you just shimmy the shapes Keynote produces through the Acorn image editor, which apparently handles them quite gracefully — we wouldn’t know, so far we’ve found GraphicConverter the heartwarmingly geekiest of bitmap editors for us, but when we give this plan a whirl next time we want a funky button we’ll try out Acorn if GraphicConverter happens to not handle Keynote creations gracefully — et voilà, you have Xcode/IB-ready graphic files!

Easier to watch than describe, check out the video to see a demonstration.

We also note from the comments that OmniGraffle is suggested for this kind of designer-challenged design as well, so there’s another option.

h/t: iPhoneFlow!

26
Jul

Sales reporting update

So you may recall that up until now we’ve been quite pleased with the daily email reports from AppFigures.com — but OH NOES! they’ve decided they actually want to make us pay for it now: $5 + $1.50 per app over two … per month.

Hmmm. While we suppose it wouldn’t actually bankrupt us, that is going to mount up, especially if you want to track various free, promotional, etc. versions as well as apps people are actually paying for. In addition, as well as reporting to people that we’re publishing on behalf of, there’s also the situation of being paid through royalties for things published by other people, in which we’d like to specify a daily reporting method … but insisting on a paid service is likely to cause unnecessary friction there. Very likely, in fact.

So we had a little wander around the web, and although we found a few new little tidbits to update our exhaustive sales tool list with, there still does not seem to be any tool other than AppFigures that will let you schedule daily email reports.

Sooooo, since we much prefer to keep our financial information and iTunes Connect passwords on our machine and out of the cloud anyways — it’s time to roll our own! And looks like the only two fairly full-featured (by which we mean, ‘scrapes iTunes Connect on its own’) starting points we see are both iPhone applications:

1. AppSales Mobileon Google Code, moving to github — New BSD License

2. My App Sales — $15 for source — no commercial use

Not that we have any current plans to actually make any kind of commercial offering to compete with the existing solutions, but just in case the desire ever arises, we’ll start by checking out the AppSales Mobile code and see about scarfing what it does for a desktop daemon. If it turns out that everything we need isn’t there — although it looks like it is — then we’ll check out this other product.

Any other options to suggest, Dear Readers?

25
Jul

Snippet: NaturalDates

Snippet time again: here’s an NSDate category for you to easily provide “Today”, “Yesterday” etc. in Mail.app style, which is a friendly kind of thing to do when you have a date denoted kind of list:

@implementation NSDate (NaturalDates) 

- (BOOL)isSameDay:(NSDate*)anotherDate
{
   NSCalendar* calendar = [NSCalendar currentCalendar];
   NSDateComponents* components1 = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:self];
   NSDateComponents* components2 = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:anotherDate];
   return ([components1 year] == [components2 year] && [components1 month] == [components2 month] && [components1 day] == [components2 day]);
} 

- (BOOL)isToday
{
   return [self isSameDay:[NSDate date]];
} 

- (BOOL)isYesterday
{
   NSCalendar* calendar = [NSCalendar currentCalendar];
   NSDateComponents *comps = [[NSDateComponents alloc] init];
   [comps setDay:-1];
   NSDate *yesterday = [calendar dateByAddingComponents:comps toDate:[NSDate date]  options:0];
   [comps release];
   return [self isSameDay:yesterday];
} 

- (BOOL)isLastWeek
{
   NSCalendar* calendar = [NSCalendar currentCalendar];
   NSDateComponents *comps = [calendar components:NSWeekCalendarUnit|NSDayCalendarUnit fromDate:[NSDate date] toDate:self options:0];
   NSInteger week = [comps week];
   NSInteger days = [comps day];
   return (0==week && days<=0);
} 

- (NSString *)stringFromDateCapitalized:(BOOL)capitalize;
{
   NSString *label = nil;
   NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
   NSString *dateFormatPrefix = nil;
   [dateFormatter setDateStyle:NSDateFormatterNoStyle]; // Will display hour only, we are building the day ourselves
   [dateFormatter setTimeStyle:NSDateFormatterShortStyle];
   if([self isToday])
   {
      if(capitalize) dateFormatPrefix = NSLocalizedString(@"Today at", @"");
      else dateFormatPrefix = NSLocalizedString(@"today at", @"");
   }
   else if([self isYesterday])
   {
      if(capitalize) dateFormatPrefix = NSLocalizedString(@"Yesterday at", @"");
      else dateFormatPrefix = NSLocalizedString(@"yesterday at", @"");
   }
   else if([self isLastWeek])
   {
      NSDateFormatter *weekDayFormatter = [[NSDateFormatter alloc] init];
      // We will set the locale to US to have the weekday in english.
      // The NSLocalizedString(weekDayString, @"") below will make it
      localized.
      NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
      [weekDayFormatter setLocale:locale];
      [locale release];
      [weekDayFormatter setDateFormat:@"EEEE"];
      NSString *weekDayString = [NSString stringWithFormat:@"%@ at", [weekDayFormatter stringFromDate:self]];
      dateFormatPrefix = NSLocalizedString(weekDayString, @"");
      [weekDayFormatter release];
   }
   else
   {
      [dateFormatter setDateStyle:NSDateFormatterShortStyle]; // Display the date as well
   }
   if(dateFormatPrefix != nil)
   { // We have a day string, add hour only
      label = [NSString stringWithFormat:@"%@ %@", dateFormatPrefix, [dateFormatter stringFromDate:self]];
   }
   else
   { // Use the full date
      label = [dateFormatter stringFromDate:self];
   }
   [dateFormatter release];
   return label;
} 

@end

… yes, we know, it’s just about impossible to actually read the code, we really must get around to finding the time to sort out a theme with a light background and none of this dumb wrapping. One of these days…

h/t: iPhoneSDK!

24
Jul

App Store SEO

A couple posts today about performing SEO for your App Store listing; since that’s pretty much the only thing you can do to market your app to casual App Store browsers — well, unless you buy your way on to the charts I suppose — it does behoove the struggling developer to keep abreast of evolving thoughts on the subject.

Over at How To Make iPhone Apps there’s a discussion of leveraging your app description

Seeding your app description with keywords is one technique that I have not heard discussed often. People who run marketing oriented websites know that they can find out what search terms that users type into browsers to find what they want. You can do the same thing with the App Store’s search engine.

If you do this you are more likely to reach users who already know what they want and are actually looking to buy something. For example, I have an app that is for wine tasting. So, I made sure that I included search terms that wine drinkers are likely to include like “tasting note”, “wine journal”, “wine’ and so on.

This approach may be better for niche audiences and some of it may occur naturally if you simply write a coherent description. However, take extra care to include words that are likely to resonate with your audience. As time goes on you will want the sales coming from people searching out your terms because it will get increasingly difficult to stay at the top of the release date lists.

Indeed. And then, check out this Clever Twist post organized by 6 tips:

  • Tip #1: Learn the Basics
  • Tip #2: Learn to Love Keywords
  • Tip #3: Don’t Waste Your Time or Money on Google Search
  • Tip #4: Give Your App a Descriptive Name
  • Tip #5: Study the Successes
  • Tip #6: Piggyback on the Successes

Although we will warn you to consider most carefully before you decide to follow tip #6,

… If you have a great game that is somewhat similar to a game in the top 10 of the iTunes store, there’s no shame in writing a description that reads something like, “For fans of [successful app], we present [your app].” This way, anyone searching for the first app will come across yours too.

First off, we’re not so sure we agree there’s no shame in this strategy. But more importantly, this is an SEO keyword strategy that a number of developers have stumbled across as being effective and promptly taken to insane lengths, throwing in the names of top ten apps into their descriptions whether or not they actually had anything to do with the application category, never mind the application specifically. Apple quite rightly figured that was a bit rich, and so there’s been some stories of apps being rejected/disapproved because of mentions of applications not published by you in your descriptions. So be warned that if you do try this strategy, you’re taking at least somewhat of a risk. It depends on how blatantly you’re playing the search engine rather than providing some useful comparative information, most likely…

[EDIT: And just a few days later ... Apple adds a keywords field to your application information on iTunes Connect!]

23
Jul

iPhone Recipes submissions

Got any iPhone code snippets that demonstrate your cleverness? Well, here’s an opportunity to show them off:

We’re looking for bite sized recipes for our “iPhone Recipes” book to be published by the Pragmatic Bookshelf. This is your opportunity to show your chops to the community as a whole. In particular, we’re looking for easily understandable, general purpose recipes that aren’t already well documented. We’re not asking you to share your application’s secret sauce, just a few of the toppings.

To propose a recipe idea, here’s what we need from you:

A paragraph or two describing the problem that the recipe solves.
A sentence or two indicating what the solution will be.
The OS version(s) to which the recipe applies.

Email your idea to us at [email protected] by August 1st (or sooner!)

If your recipe is selected, your name, bio, and a link to your site/blog will appear in the book. You’ll also receive a complimentary copy of the book, of course.

Well, that’s a nice try at getting people to write you a book for free, appeal to their vanity, isn’t it now? Be interesting to see how this works out for them! If we can find some spare time before August 1st it’ll probably work on us, after all…

22
Jul

Snippet: Texture Sizes

Here’s a cute little snippet for automatically transmogrifying your OpenGL textures into iPhone-acceptable dimensions at runtime if you don’t want to go to the trouble of sorting out the source assets, because maybe you’re porting existing assets from another platform, or your artists can’t follow directions, or whatever:

First off, figure out power-of-two dimensions:

  1. //     Adjust the width and height to be a power of two
  2. if( (_width != 1) && (_width & (_width – 1)) )
  3. {
  4. i = 1;
  5. while((sizeToFit ? 2 * i : i) < _width)
  6. i *= 2;
  7. _width = i;
  8. }
  9. if( (_height != 1) && (_height & (_height – 1)) )
  10. {
  11. i = 1;
  12. while((sizeToFit ? 2 * i : i) < _height)
  13. i *= 2;
  14. _height = i;
  15. }

You could figure that out on your own no doubt, but you might miss this; if it turns out that the image is too big, your friend CGAffineTransform can sort that out for you!

  1. //      scale down an image greater than the max texture size
  2. while((_width > kMaxTextureSize) || (_height > kMaxTextureSize))
  3. {
  4. _width /= 2;
  5. _height /= 2;
  6. transform = CGAffineTransformScale(transform, 0.5, 0.5);
  7. imageSize.x *= 0.5;
  8. imageSize.y *= 0.5;
  9. }

That’s quicker than going through and canonizing a large asset base yourself, indeed. Read the rest of the article for further explanation; and this is part of the D’Jinn Engine for the iPhone which can be found on Google Code. Enjoy!

h/t: iPhoneDevelopmentBits!