Links for 2011-7-14 through 2011-7-31

Links for 2011-7-14 through 2011-7-31:

  • Cocos2D Tutorial – Dynamically Coloring Sprites [Brandon Trebitowski, brandontreb.com] Have you ever seen a game (such as Tiny Tower) that contains similar sprites that only vary by certain attributes (coloring, shading, accessories, etc…)? I would often wonder how long it would take the artists to create each permutation of these sprites. After discovering that you can call a method on a CCSprite called setColor, I realized how most of this customization is done in code.
  • Muddying the Budget Waters With Social Security Many people misunderstand how the program operates. Payroll taxes stream into the trust fund that is used to pay current retirees’ benefits. When there is a surplus, that money is invested in a special type of Treasury bond that pays interest to the trust fund. At the end of last year, the trust fund had about $2.6 trillion. And though last year was the first year since 1983 that the fund paid out more than it received in tax revenue, it still continued to grow because of the interest accrued — and it is estimated to continue to grow through 2022.

    Since the money in the trust fund is held in Treasury securities, taxes collected are essentially being lent to the federal government to pay for whatever it wants (and this allows the government to borrow less from the public).

  • The Cult of Centricism We have a crisis in which the right is making insane demands, while the president and Democrats in Congress are bending over backward to be accommodating — offering plans that are all spending cuts and no taxes, plans that are far to the right of public opinion.

    So what do most news reports say? They portray it as a situation in which both sides are equally partisan, equally intransigent — because news reports always do that. And we have influential pundits calling out for a new centrist party, a new centrist president, to get us away from the evils of partisanship.

    The reality, of course, is that we already have a centrist president — actually a moderate conservative president.

  • Revamp of a game [Yuchen Wang, ClingMarks]
  • Cocos2D and ARC [Jerrod Putman, Tiny Tim Games]
  • How To Use Custom Classes With Core Data Without Fear [Doug Sjoquist , Sunetos]
  • User Testing in the Wild: Joe’s First Computer Encounter « Boriss’ Blog
  • Make a backup copy of the MacBook Air USB Software Reinstall Drive | TUAW – The Unofficial Apple Weblog Since it doesn't come with an optical drive, giving MacBook Air buyers a DVD of the operating system wouldn't be very helpful. That's why Apple's lightest laptop comes with the USB Software Reinstall Drive — a very small white USB drive. Sometimes USB flash drives are referred to as "Thumb Drives," but this one is more like the size of a baby's finger.

Posted by Postilicious

Links for 2011-6-6 through 2011-7-13

Links for 2011-6-6 through 2011-7-13:

Posted by Postilicious

Links for 2011-5-21 through 2011-6-1

Links for 2011-5-21 through 2011-6-1:

  • Structured Procrastination the procrastinator can be motivated to do difficult, timely and important tasks, as long as these tasks are a way of not doing something more important. Structured procrastination means shaping the structure of the tasks one has to do in a way that exploits this fact.
  • 18 Signs That Life In U.S. Public Schools Is Now Essentially Equivalent To Life In U.S. Prisons In the United States today, our public schools are not very good at educating our students, but they sure are great training grounds for learning how to live in a Big Brother police state control grid. Sadly, life in many U.S. public schools is now essentially equivalent to life in U.S. prisons. Most parents don't realize this, but our students have very few rights when they are in school. Our public school students are being watched, tracked, recorded, searched and controlled like never before.
  • Accessorizer Made Simple
  • Appsterdam Immigration | mur.mu.rs Now for the entry you’ve all been waiting for: a quick guide on how to emigrate to Appsterdam.
  • TextEditors Wiki: HomePage

Posted by Postilicious

Links for 2011-03-10 through 2011-03-16

Links for 2011-03-10 through 2011-03-16:

Posted by Postilicious

Links for 2011-02-22 through 2011-02-26

Links for 2011-02-22 through 2011-02-26:

  • OS X Lion Walkthrough: Versions and Auto Save – Two new features that have found their way in the first Lion developer preview but might seem too complicated or “hidden” as only Apple applications support them right now are Versions and Auto Save. With auto-saving capabilities for documents and a proper versioning system in place, Apple is aiming at simplifying the workflows of many users that have to deal with dozens of documents on a daily basis but often forget to save changes and are inevitably forced to start over. To put it simply, Lion will let you work on your documents without having to worry about saving anything. If you do want to save a specific version of a document, however, you can do so in order to access it later from a Time Machine-esque interface that will let you revert to a previous version of a document at any time. Let’s see how it works.
  • Tiny Wings – Huge Success [Stefan Sorin Nicolin, Spielhaus] – With all these AAA titles coming out for the iOS platform (and elsewhere) there are still some games who pop out of nowhere and climb the charts in no time as if there is nothing easier in the world to accomplish.
  • [devel] OpenGL ES 2.0 support « cocos2d for iPhone – The idea is to use this thread to discuss how to implement OpenGL ES 2.0 support without the need to write a shader for each CCNode.
    The idea is that if the CCNode contains a shader, then it should use it, otherwise it should continue rendering itself using the GL ES 1.0 code.
  • Django Reinhardt: A Look Behind the Namesake of WordPress 3.1 | Blogging, WordPress, Social Media, Web Publishing – WordCast – With the release of WordPress 3.1 and announcement that this version was named Django Reinhardt, WordPress fans around the world are now learning about Django Reinhardt, the legendary and often overlooked jazz guitarist and composer.
  • Cocoa Samurai: Practical Design Patterns with Blocks and Grand Central Dispatch – When Mac OS X 10.6 was introduced, the Mac got a very powerful duo of developer tools that made development on a lot easier. With iOS 4.0 developers finally got access to these tools as well. These tools are known as Blocks & Grand Central Dispatch.
  • Does the world *really* need yet another Twitter client, RSS reader, ToDo list or backup application? « Successful Software – My heart sinks every time I hear a would-be-entrepreneur announcing they have written yet another Twitter client, RSS reader, ToDo list or backup application. Haven’t we got enough of those already? There are more than 1,900 Twitter apps already (possibly a lot more). Somebody probably released another one while I was writing this post. We have passed the Twitter app event horizon, where it is probably quicker to write your own custom app than it is to try and work out if any of the existing apps fulfils your requirements.

Posted by Postilicious

Links for 2011-02-15 through 2011-02-22

Links for 2011-02-15 through 2011-02-22:

Posted by Postilicious

Links for 2011-01-17 through 2011-02-02

Links for 2011-01-17 through 2011-02-02:

Posted by Postilicious

Links for 2011-01-01

Links for 2011-01-01:

Posted by Postilicious

Why I chose SQLite instead of Core Data

A lot has been written about the relative benefits of Core Data or SQLite in an iPhone app. In most cases, Core Data is easier and has some performance benefits, but the data store is difficult to create & modify from outside of your application. SQLite, on the other hand, has some excellent tools like SQLiteManager for creating & editing data. Therefore, if you have a large amount of pre-loaded data that you want to be able to edit easily, SQLite makes more sense.

This is exactly the case with Removr. Game levels are defined by an object that specifies the background image and a bitmap of the layout of pieces on the screen. Although Core Data could easily fetch the object as needed in Removr, it would be very difficult for an external level editor to create those objects and update the persistent store.

My level object happens to be very simple and can easily be mapped to a database structure.

// Level.h
@interface Level : NSObject {
    NSData * _map;
    NSString * _background;
    NSNumber * _index;
}

@property (nonatomic, retain) NSData * map;
@property (nonatomic, retain) NSString * background;
@property (nonatomic, retain) NSNumber * index;

@end

// Level.m
#import "Level.h"

@implementation Level
@synthesize map = _map, background = _background, index = _index;

- (void)dealloc
{
    self.map = nil;
    self.background = nil;
    self.index = nil;
    [super dealloc];
}
@end

The corresponding database structure looks like this:

CREATE TABLE levels (
	ix integer NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
	background text,
	map blob NOT NULL
);

Fetching the objects from sqlite takes more code than using Core Data but isn’t too difficult. I need to deal with two different SQLite3 objects for the database connection and the prepared query. Rather than interpreting the SQL query every time you execute it, you will prepare the query once and execute it as many times as you want.

A good introduction to the SQLite3 C interface is available here.

Here is my level manager. My init method opens the database connection and prepares the query that will be used later. Note that the query includes a ‘?’ for variable substitution.

The GetLevel method is where the interesting stuff happens. The function sqlite3_bind_int() tells it which level number we’re looking for and sqlite3_step() actually executes the query. In this case, I’m only interested in a single row, but in many cases it will be called repeatedly as long as it returns SQLITE_ROW. I then use the sqlite3_column functions to extract data from the result row and populate my Level object. Finally, calling sqlite3_reset() will allow the prepared statement to be reused.

// LevelManager.h
@interface LevelManager : NSObject {

    NSString *_dbpath;

    sqlite3 * db;
    sqlite3_stmt * query;
}

@property (retain,nonatomic) NSString *dbpath;

@end

// LevelManager.m
#import "LevelManager.h"
#import "Level.m"

@implementation LevelManager

@synthesize dbpath = _dbpath;

- (id) init
{
    if ((self = [super init])) {
        self.dbpath = [[NSBundle mainBundle] pathForResource:@"levels" ofType:@"sqlite3"];
        sqlite3_open([self.dbpath UTF8String] , &db);

		// this query will be used to obtain a level from the database.
		// The '?' will be replaced with the level number when we perform the query
        sqlite3_prepare_v2(db, "SELECT * FROM levels WHERE ix=?", -1, &query, NULL);

    }
    return self;
}

- (void)dealloc
{
    sqlite3_finalize(query);
    sqlite3_close(db);

    self.dbpath = nil;

    [super dealloc];
}

- (Level*)GetLevel: (int)number
{
    Level *lvl = nil;

	// specify the level number we want for the query
    sqlite3_bind_int(query, 1, number);

	// request a row from the query result
    if (sqlite3_step(query) == SQLITE_ROW) {
        void *blob;
        int nbytes;

		// first, create a new level object
        lvl = [[Level alloc] init];

		// integer columns are easy
        lvl.index = [NSNumber numberWithInt: sqlite3_column_int(query, 0)];

		// string columns are a bit more complex since we need to convert a C string to a NSString
        lvl.background = [NSString stringWithCString:(char*)sqlite3_column_text(query, 1)
                                                                 encoding:NSUTF8StringEncoding];

		// BLOB columns require two calls to obtain the actual data and the length
        blob = (void*)sqlite3_column_blob(query,2);
        nbytes = sqlite3_column_bytes(query,2);

		// we use the bytes & length to create a NSData
        if (blob && (nbytes > 0)) {
            lvl.map = [NSData dataWithBytes:blob length:nbytes];
        }
    }

	// get ready to reuse the query
    sqlite3_reset(query);

	// we should return an autoreleased object
    return [lvl autorelease];
}

@end

Quick and easy image caching for UITableViews

PicSlide uses a table that lets you choose a picture to play with. For each picture it shows a thumbnail. When the thumbnails are loaded from the application’s resources, you don’t have to be too concerned with image loading time.However, when I load those thumbnails from the web, as I do now with the Magic Panda, scrolling the table can become extremely slow.

Previously, I was loading the thumbnail directly from my table data source’s cellForRowAtIndexPath: method.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"tvCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        [[NSBundle mainBundle] loadNibNamed:@"tvCell" owner:self options:nil];
        cell = tvCell;
        self.tvCell = nil;
    }
    NSString *url = [picUrls objectAtIndex: indexPath.row];
    UIImageView *img = (UIImageView*)[cell viewWithTag: 2];
    img.image = [UIImage imageWithData: [NSData dataWithContentsOfURL:[NSURL URLWithString: url]]];
}

If you don’t have too many rows, a NSMutableDictionary makes a quick & easy image cache. I simply added one method to implement image caching:

NSMutableDictonary *imageCache;

- (UIImage *)getCachedImage: (NSString*)url
{
    UIImage* theImage = [imageCache objectForKey:url];
    if ((nil != theImage) && [theImage isKindOfClass:[UIImage class]]) {
        return theImage;
    }
    else {
        theImage = [UIImage imageWithData: [NSData dataWithContentsOfURL:[NSURL URLWithString: url]]];
        [imageCache setObject:theImage forKey:url];
        return theImage;
    }
}

When I load my table, I now call getCachedImage rather than fetching the image directly.

    img.image = [self getCachedImage: url];

The result can be seen below: