Archive

Archive for the ‘Open Source’ Category

Introducing APTokenField

April 1st, 2012 Comments off

Working on Line2, I wanted to emulate the message composition screen Apple uses in iMessage and in the MFMailComposeViewController class. Specifically, I wanted to emulate the ‘To:’ field so I could use it in the SMS message composition screen in Line2. At the time, the only option that met the need was TTPickerTextField (part of Three20). I finally bit the bullet and integrated it into Line2, but it had some drawbacks, the biggest being that you have to integrate all of Three20 to use it.

After awhile, I got an itch to remove my dependency on Three20, so I wrote APTokenField. A lightweight, stand-alone implementation of the TTPickerTextField functionality. First some pictures to show what it’s capable of:

APTokenField screen shot 1

APTokenField as used in its sample app

APTokenField screen shot 2

APTokenField as used in Line2

Let’s take a look at the available features:

  • You can specify a text label to be displayed on the left side of the token field.
  • You can specify a custom rightView, that does whatever you want it to do. Just set the rightView‘s bounds and assign it to the APTokenField’s rightView property
  • Support for multiple lines of tokens. Even when the number of tokens is large, the view scrolls up to let the user see the result set.
  • Easy to use in your parent view’s layout. No need to mess around with UIScrollViews. Just add it to your view hierarchy and set it’s frame to whatever size you want. The table of results will automatically hide when there are no results, and it will take up whatever area is available in the frame.
  • Everything is contained in two source files. No images required.

If you wanna jump right into it, head over to the APTokenField github page and clone away. Otherwise, here’s a brief tutorial to start using it.

  1. Add APTokenField.h and APTokenField.m to your project
  2. Add the QuartzCore and CoreGraphics frameworks to your project

Let’s take a look at the project in the APTokenField repo. It contains a controller (APTokenFieldController) and a data source (AmericanStatesDataSource).

The data source conforms to the APTokenFieldDataSource protocol, which lets the user search the 50 American states and add them to the field by tapping a result. The meat of this class happens in the four required methods, which search and return values from the array of American states. As the user types characters into text field, the -(void)tokenField:searchQuery method will be called with the current text. It’s up to you to decide how to implement your search, but for this simple example we just check if the search text exists in the name of any of the states, and if it does, the matching state gets placed into the results array. The table of results gets updated automatically in the UI, and you don’t have to make any complicated callbacks when you’re done (I’m looking at you Three20).

If you want to get feedback on when the user adds and removes tokens, you can implement the APTokenFieldDelegate protocol. If you wanna use a custom UITableViewCell for the results, take a look at the optional methods in the APTokenFieldDataSource protocol.

You should follow me on Google+.

Share
Categories: iPhone, Open Source Tags:

Presenting, Appirater

September 7th, 2009 16 comments

Like most developers, I’m not thrilled with the way the App Store presents my apps. There are several problems, but in particular, I really don’t like the user review system. It’s biased towards bad reviews, and that ends up hurting sales (there are odd exceptions to this). The only time a user is reminded or asked to rate an app is when you delete it, and you probably don’t care for the app if you’re deleting it. In comparison to the unhappy user, the satisfied user rarely takes the time to review your app. Which leaves you with crummy reviews from uninformed users hurting sales of your app.

If Apple would allow developers to respond to reviews, or more easily challenge the validity of a review, this would be no big deal. But I don’t have any hopes of Apple wising up and fixing anything, so I’m left trying to get more positive reviews of my apps to drown out the negatives ones.

Appirater
The goal of Appirater is to encourage your satisfied user’s to rate your app. To use it, place the Appirater code into your project, and add the following code in your app’s delegate class.

// import the Appirater class
#import “Appirater.h”

@implementationMyAppDelegate- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// all your app’s startup code
    // …

// call the Appirater class
    [Appirater appLaunched];return YES;
}

@end

Finally, open up Appirater.h and change the APPIRATER_APP_ID to your apps software id. You can also change the other #defines, for a more customized reminder message and buttons, but the default should suffice for most apps.

Now every time the user launches your app, Appirater will see if they’ve used the app for 30 days and launched it at least 15 times. If they have, they’ll be asked to rate the app, and then be taken to your app’s review page in the App Store. If you release a new version of your app, Appirater will again wait until the new version has been used 15 times for 30 days and then prompt the user again for another review. Optionally, you can adjust the days to wait and the launch number by changing DAYS_UNTIL_PROMPT and LAUNCHES_UNTIL_PROMPT in Appirater.h.

Appirater as used in Prayer Book app

Code: http://github.com/arashpayan/appirater/

BTW, if you like Appirater, please consider checking out my game, Jabeh or the lite version of it.

UPDATE: Ivan Nikitin has made a MonoTouch port of Appirater.

Share

APXML: NSXMLDocument ‘substitute’ for iPhone/iPod Touch

January 14th, 2009 3 comments

After spending some time working on Jabeh, my latest creation for iPhone/iPod Touch, I’m taking some time to dump a little learned knowledge into my blog.

In my first app, my XML needs weren’t that great, so putting up with the lack of NSXMLDocument in the iPhone SDK was not a big deal. However, in Jabeh I was changing the XML format so often and using so much of it for my network communication creating delegates for NSXMLParser quickly became a huge time sink. After a little hacking, I came up with APXML to solve my DOM problem. It’s not a perfect implementation of the W3C XML 1.0 standard, but it’s close enough for a lot of usage. One particular shortcoming is its lack of support for namespaces but maybe somebody else can add that support. If you just want to jump in and start using it (LGPL license), you can get the code from github:

http://github.com/arashpayan/apxml/

Most of my XML manipulation experience has been with various Java libraries (org.w3c.dom interface, JDOM and XOM), and the only one that I enjoyed using was XOM, because of its simplicity and licensing. Almost all of my design decisions were based on how XOM does things.

Let’s say we want to represent the following XML document in memory using APXML:

<books>
    <book id="1" author="Michael Pollan">The Omnivore’s Dilemma</book>
    <book id="2" author="Foley, van Dam, Feiner, Hughes">Computer Graphics: Principles and Practices</book>
</books>

In code, we do the following:

#import "APXML.h"

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    // create the document with it’s root element
    APDocument *doc = [[APDocument alloc] initWithRootElement:[APElement elementWithName:@"books"]];
    APElement *rootElement = [doc rootElement]; // retrieves same element we created the line above
    
    // create the first book entry (The Omnivore’s Dilemma)
    APElement *book1 = [APElement elementWithName:@"book"];
    [book1 addAttributeNamed:@"id" withValue:@"1"];
    [book1 addAttributeNamed:@"author" withValue:@"Michael Pollan"];
    [book1 appendValue:@"The Omnivore's Dilemma"];
    [rootElement addChild:book1];
    
    // create the second book entry (Computer Graphics)
    APElement *book2 = [APElement elementWithName:@"book"];
    [book2 addAttributeNamed:@"id" withValue:@"2"];
    [book2 addAttributeNamed:@"author" withValue:@"Foley, van Dam, Feiner, Hughes"];
    [rootElement addChild:book2];
}

@end

And if we want to convert the document to an NSString*, we use one of the two methods in APDocument:

    // converts the xml to a compact string with no newlines or tabs (good for production)
    NSString *xml = [doc xml];

or

    // converts the xml to an easy to read string with newlines and tabs (good for debugging)
    NSString *prettyXML = [doc prettyXML];

Often times when I’m working with XML, I like to see what the current element contains, so for added convenience, you can obtain an XML string containing the element you’re working with, its attributes and all its children directly from the APElement by calling one of two methods:

- (NSString*)prettyXML:(int)tabs;
- (NSString*)xml;

Now for the best part of the library, which is the ability to read in XML and represent it in APXML. All you have to execute is one simple line:

    APDocument *doc = [APDocument documentWithXMLString:xmlString];

Hopefully this will be helpful to other developers out there. I may post another article soon if anybody has some questions.

UPDATE Sep 5, 2009: Here’s an example that demonstrates traversing the XML document.

    APElement *rootElement = [doc rootElement];
    NSLog(@"Root Element Name: %@", rootElement.name);
    
    // get all the child elements (each book)
    NSArray *childElements = [rootElement childElements];
    
    for (APElement *child in childElements)
    {
        // returns the tag name
        NSLog(@"Child Name: %@", child.name);
        
        // reads the attribute named ‘author’
        NSLog(@"Author: %@", [child valueForAttributeNamed:@"author"]);
        
        // returns the text content of the element
        NSLog(@"Title: %@", [child value]);
    }

In the console you’ll see (I’ve removed the NSLog markup):

Root Element Name: books
Child Name: book
Author: Michael Pollan
Title: The Omnivore’s Dilemma
Child Name: book
Author: Foley, van Dam, Feiner, Hughes
Title: Computer Graphics: Principles and Practices
Share

FileTree update (v1.1)

June 4th, 2008 Comments off

I recently received an email from Ryan McFall that he is using FileTree, and he noticed that the FileTree doesn’t actually display everything accurately on Windows. The shortcoming was in the fact that Windows explorer displays all directories first before displaying files in a tree. He fixed the problem, and kindly sent the changes back to me for posting on the website github.

I hope this makes FileTree useful for many more people.

Share
Categories: Open Source Tags: , ,

FileTree version 1.0

September 23rd, 2007 1 comment

I was coding at work, and I needed a tree view of the file system so user’s could select a directory in a utlitiy I was writing. There’s nothing in the Java libraries that does that (as of JDK 1.6), so I figured this would be a cool little swing object to develop and make available for others. I finished it about a month ago, but I didn’t have time to thoroughly document it and make a page for it on my website until now.

I call it FileTree and it extends the Java JTree class. It has the native system icons next to all the files and directories for OS X and Windows. On Linux, because neither the File class or the FileSystemView class return specific icons, some generic icons are used for the folder and file nodes.

I hope this library comes in handy for any Java developers out there, and if you find any bugs, make any improvements or have any interesting feature requests, please let me know about them.

Features

  • Enable/disable deleting of files and folders in the view
  • Enable/disable showing of hidden files
  • Enable/disable navigating into OS X application bundles
  • Ability to not show files so you can force the user to select a directory
FileTree on OS X

FileTree on OS X

Share
Categories: Open Source Tags: , ,