Change the display name of your iOS apps

Decided on a long name for your application when you created it, but are now fed up of seeing it display like this on the home screen?

You can quickly and easily change the display name of your application but amending InfoPlist.strings to the following

/* Localized versions of Info.plist keys */

CFBundleDisplayName = "My App";

Easy as that, since the plist file is localised, we can use this for multiplate languages/locales.

Sending Tweets from your iOS5 app, easy!

Sending a tweet from your iOS application could not be any easier, Apple and Twitter really were looking out for their developers.

With iOS 5, the twitter account is authenticated under the settings menu of the device, which means that any application can request this account to use for tweet, and that is all you need to do; sign in, then request these details in your application.

Follow these easy steps

Sign into twitter on your phone

Go to Settings > Twitter > Sign in, as displayed below

Enabling tweets from your application

Then from your application, make sure that you add the twitter framework in as a linked framework. You can do this by clicking the application target, select summary page, scroll down to “Linked Frameworks and Libraries”, then add a new one, searching for “Twitter”, this all comes bundled with the Xcode development environment.

One the framework is linked, you can now import the following header into your application, such as in any one of your ViewControllers:

#import <Twitter/Twitter.h>

Now, we just have to display the view for allowing the user to create a tweet. I usually append this onto a button click, but you could invoke it from any other event, such as the view appearing, a slider being altered, or even after a segue. This is my example for creating a tweet on a button click :

- (IBAction)postToTwitterClicked:(id)sender 
{
    if ([TWTweetComposeViewController canSendTweet])
    {
        TWTweetComposeViewController *tweetSheet = [[TWTweetComposeViewController alloc]init];
        
        [tweetSheet setInitialText:@"This is a sample tweet!"];
        [tweetSheet addURL:[NSURL URLWithString:@"http://www.Twitter.com"]];
        
        [self presentModalViewController:tweetSheet animated:YES];
    }
    else 
    {
        UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Unable to tweet"
                                                     message:@"Please ensure that you have at least one twitter account setup and have internet connectivity. You can setup a twitter account in the iOS Settings > Twitter > login."
                                                    delegate:self 
                                           cancelButtonTitle:@"OK" 
                                           otherButtonTitles:nil];
        [av show]; 
    }
}

A little explanation of the above. First, we want to check if we have the capability of sending a tweet, this just checks to see that you have at least one account signed in. If you can’t send a tweet, do something to notify the user what is wrong, such as displaying an alert prompting them to sign in, otherwise the user will wonder why they can’t make a tweet.

Next, alloc/init a TWTweetComposeViewController, this is the controller that handles composing a tweet. You can set the initial message (the tweet contents). You can also set URLs, locations, and images, refer to the documentation for info on those.

Finally, present the view controller modally (sits on top of anything else). It should look a little like this :

Once you’ve sent a tweet, it will sound a bird chirp to let the user know it is successful.

Easy, its a little shame that the same cannot be said for Facebook…hopefully iOS6 may ease integration.

Improving Tesseract OCR results on the iOS platform

If you’ve found yourself using Tesseract on the iOS platform, and you’re scratching your head as to why the OCR results are so terribly incorrect, you might be interested in the following. Most of the tesseract iOS tutorials talk about compiling the libraries, but don’t really cover how to use it.

Theres always an app for that, but how do you understand how it works?

Are you using something like this to interface with the tesseract API?

char* text = tess->TesseractRect(imageData,(int)bytes_per_pixel,(int)bytes_per_line, 0, 0,(int) imageSize.height,(int) imageSize.width);

NSLog(@"Converted text: %@",[NSStringstringWithCString:text encoding:NSUTF8StringEncoding]);

I was using this to start with, and the results were terrible, if it was able to read anything it was mostly returning special characters or just utter nonsense.

Looking closer at the API documentation, you can see this :

/**
   * Recognize a rectangle from an image and return the result as a string.
   * May be called many times for a single Init.
   * Currently has no error checking.
   * Greyscale of 8 and color of 24 or 32 bits per pixel may be given.
   * Palette color images will not work properly and must be converted to
   * 24 bit.
   * Binary images of 1 bit per pixel may also be given but they must be
   * byte packed with the MSB of the first byte being the first pixel, and a
   * 1 represents WHITE. For binary images set bytes_per_pixel=0.
   * The recognized text is returned as a char* which is coded
   * as UTF8 and must be freed with the delete [] operator.
   *
   * Note that TesseractRect is the simplified convenience interface.
   * For advanced uses, use SetImage, (optionally) SetRectangle, Recognize,
   * and one or more of the Get*Text functions below.
   */
  char* TesseractRect(const unsigned char* imagedata,
                      int bytes_per_pixel, int bytes_per_line,
                      int left, int top, int width, int height);

Therefore, swap over and use this implementation:

    tess->SetImage(imageData,(int) imageSize.width, imageSize.height, (int)bytes_per_pixel,(int)bytes_per_line);
    char* someChars = tess->GetUTF8Text();
    NSString * someString = [NSString stringWithCString:someChars encoding:NSUTF8StringEncoding];
    NSLog(@"Better results this way %@", someString);

Nothing groundbreaking here, just pointing it out!

Don’t forget to use blacklisting and whitelisting for character sets, that helps improve results tremendously.

Thanks