eval(art);

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.

newproject.png

Next you need to add a new target for you project so that the source can compile to a lib.

addtarget.png

Next you need to change the Base SDK from Current Mac OS to Device - iPhone OS 2.0

basesdk.png

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.

Comments Off more...

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.

Comments Off more...

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.

Leave a Comment more...

XSLT Transformations via mod_rewrite and PHP

by Philippe Hausler on Sep.23, 2007, under PHP, Web

Latently Apache does not have any methodology to transform XML via XSL templates. However there are a few features that can easily accomplish this feat. In most installations of Apache mod_rewrite is enabled by default. This allows any sent url to be dynamically behind the scenes redirected to another file. With some handy rules we can ensure that any XML file is first processed by a PHP script at a set location. Here is an example of an addition to a base website root .htaccess file.

RewriteEngine On
RewriteRule ^(.*\.xml)$ /xml.php [QSA]

This will redirect any file accessed that ends in a tag of .xml to our XML processing script but also send any query variables.When the XML processing script is executed, the script has basic parameters that are still attached to the original XML file being viewed. $_SERVER['REQUEST_URI']will still point to the original request: NOTE this is radically different than our uri of the script being redirected to. Of course we have both a path and a query parameter in this URI. The original file can then be represented as an expression $_SERVER['DOCUMENT_ROOT'].$url['path'].Once we have our XML file loaded, we need to determine what XSL stylesheets are included within the document.

$xml = new DOMDocument;
$xml->load($file);
$proc = new XSLTProcessor;
foreach($xml->childNodes
as $childNode){
   if(get_class($childNode)=="DOMProcessingInstruction"){
      if(strtolower($childNode->target) == "xml-stylesheet"){
         //match the type and href of the stylesheet
         preg_match("/type(?:\s*)=(?:\s*)\"(.*)\"/U",$childNode->data, $matches);
         $type = $matches[1];
         preg_match("/href(?:\s*)=(?:\s*)\"(.*)\"/U",$childNode->data, $matches);
         $href = $matches[1];
         //load the stylesheet into memory
         $xsl = new DOMDocument;
         $xsl->load(dirname($file)."/".$href); //<—- this is WRONG! but it works >.>
         $proc->importStyleSheet($xsl);
      }
   }
}

Since the variables passed to our XML “preprocessor” include some extra junk, we need to ensure that the passed variables are not haphazardly assigned (this limits this script to GET only)

parse_str($url['query'], $query);
foreach($query as $key=>$value){
   $proc->setParameter(,
$key, $value);
}

Next we need to apply our transform and then clean up.

$transformed = $proc->transformToDoc($xml);

Remove any, no longer needed, stylesheet references since the document is now fully formatted.

foreach($transformed->childNodes as $childNode){
   if(get_class($childNode)=="DOMProcessingInstruction"){
      if($childNode->target == "xml-stylesheet"){
         $transformed->removeChild($childNode);
      }
   }
}

After the clean-up, all we have left to do is actually output our newly stylized XML file. This same process could also apply to XHTML and also include modifications to the DOM tree.

header("Content-type: text/xml");
echo $transformed->saveXML();

Comments Off more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Visit our friends!

A few highly recommended friends...