Archive for August, 2008
Creating Static Libraries for iPhone/iPod Touch
by Philippe Hausler on Aug.29, 2008, under iPhone/iPod Touch
With the popularity of the iPhone rising and the base iPhone SDK lacking in certain commonly used APIs it becomes apparent to me that the need for a good tutorial on home-brew static libraries is needed. This might pose as a daunting task since there is no base project template for this type of target.To create a static lib you must first create a new empty project.
Next you need to add a new target for you project so that the source can compile to a lib.
Next you need to change the Base SDK from Current Mac OS to Device - iPhone OS 2.0
This will now allow you to compile a static library for device target applications. One major caveat: The application will only run on the device and NOT run in the simulator when the static library is used. If it is desired to run the application in the simulator, you must link the application against a static library compiled as a target to Mac OS X.
This target method does need to be refined; currently the library is static and cannot be directly compiled as a framework. Hybrid targets still need to be implemented for being able to run as both simulator and device like the Apple frameworks. When I finish the compile templates for frameworks for iPhone/iPod Touch I will post them here.
UITableViewCell Templates
by Philippe Hausler on Aug.29, 2008, under Objective-C, iPhone/iPod Touch
Interface Builder by far is probably one of the easiest user interface design applications I have used. It is wonderful for rapid application design not only for Mac OS X but also iPhone. Unfortunately it still seems rather limited in some respects for the newly released iPhone SDK. Namely table cells still have to be hard programmed into your application and no layout management is directly available through Interface Builder.
This doesn’t have to be the case. There is a native UI object for UITableViewCells in Interface Builder just no way of directly formatting the table like the way Mac OS X applications are handled for tables.To get around this a subclass of UITableViews has to be made to allow a IBOutlet to a cell template.
@protocol AdvancedTableViewDelegate @optional - (void)tableView:(UITableView *)tableView didDeselectRowsFromTouches:(NSSet *)touches; @end @interface AdvancedTableView : UITableView { IBOutlet UITableViewCell *cellTemplate; } @property (nonatomic, retain) UITableViewCell *cellTemplate; @end
@synthesize cellTemplate; - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { BOOL isCellTouch = NO; for(UITouch *aTouch in touches) { if(aTouch.view != self) { isCellTouch = YES; } } if(!isCellTouch) { if([self.delegate respondsToSelector:@selector(tableView:didDeselectRowsFromTouches:)]) { [self.delegate performSelector:@selector(tableView:didDeselectRowsFromTouches:) withObject:self withObject:touches]; } } [super touchesEnded:touches withEvent:event]; }
Furthermore, the native table view has no notification or delegate protocol to alert the delegate of a UITableView that the selection has changed to nothing. Since events bubble much like the concept of DOM events, the table views can capture the touch events and test to see if they are either to a cell or not. If the touch event is not a cell, most assuredly the event is indented to deselect the current table selection. Also accessor methods will need to be implemented to allow the table view to reference the assigned template from the xib.
@implementation UITableViewCell (Copying) - (id)copyWithZone:(NSZone *)zone { UITableViewCell *copy = [[[self class] allocWithZone:zone] initWithFrame:self.frame reuseIdentifier:self.reuseIdentifier]; copy.textAlignment = self.textAlignment; copy.image = self.image; copy.selectedImage = self.selectedImage; copy.accessoryType = self.accessoryType; copy.accessoryView = self.accessoryView; copy.indentationLevel = self.indentationLevel; copy.indentationWidth = self.indentationWidth; copy.textColor = self.textColor; copy.selectedTextColor = self.selectedTextColor; copy.shouldIndentWhileEditing = self.shouldIndentWhileEditing; copy.showsReorderControl = self.showsReorderControl; [copy addSubview:[self.contentView copy]]; return copy; } @end
@implementation UIView (Copying) - (id)copyWithZone:(NSZone *)zone { return [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:self]]; } - (id)firstSubviewOfClass:(Class)aClass { for(id subView in self.subviews) { if([subView class] == aClass) { return subView; } } return NULL; } - (id)subviewAtIndex:(NSUInteger)index { return [[self subviews] objectAtIndex:index]; } @end
With these two extensions to the base views, table rows can now be rendered on the fly as copies of the original UITableViewCell template assigned to the table view. WARNING: Make sure to set the identifier in the UITableViewCell template object to the identifier specified in the table rendering code! Unfortunately any connections, bindings or actions will be lost in this copy so they will need to be remade programmatically.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSInteger index = [indexPath indexAtPosition:1]; static NSString *MyIdentifier = @"MyIdentifier"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; if (cell == nil) { cell = [[(AdvancedTableView *)tableView cellTemplate] copy]; } [[[cell subviewAtIndex:1] firstSubviewOfClass:[UILabel class]] setText:[testData objectAtIndex:index]]; [[[cell subviewAtIndex:1] firstSubviewOfClass:[UIProgressView class]] setProgress:[[testProgressData objectAtIndex:index] floatValue]]; return cell; }
Since the cell creation and rendering method does not have the table passed as a subclass the object must be typeclassed. When referencing the subviews one must also be warry that the order of render defined in the xib file is going to most likely be the order that is in the actual rendered cell (this may not be the case if the cell has any children that are programmatically made). This method is also interoperable with the standard methods of creating cells, however if the cell is a subclass, any connections are lost.
libmysqlclient for iPhone
by Philippe Hausler on Aug.04, 2008, under MySQL, iPhone/iPod Touch
On release the iPhone and iPod Touch have only one database application available to them; SQLite. This is all fine and dandy if you are looking to locally store data and manipulate records on your device, however this provides no connectivity to an external server. I have taken the liberty to undertake a massive project of porting the base connectivity from libmysqlclient to a build target static library for the iPhone SDK.
Currently my port compiles properly and allows access to the base functions for creating connections, preforming queries and basic concepts of administration. Since Sun’s GNU license conflicts with Apple’s iPhone Developer license in the regards to releasing source code I am awaiting further details from Sun Microsystems for a release of the binary library. As a base test for this API I have started development of a iPhone/iPod native admin application for MySQL, which should near completion soon.