<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>zdima.net</title>
	<atom:link href="http://zdima.net/blog/feed" rel="self" type="application/rss+xml" />
	<link>http://zdima.net/blog</link>
	<description></description>
	<lastBuildDate>Mon, 30 Jan 2012 11:42:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Control of the Week (Cocoa Controls)</title>
		<link>http://zdima.net/blog/archives/16800</link>
		<comments>http://zdima.net/blog/archives/16800#comments</comments>
		<pubDate>Mon, 30 Jan 2012 11:42:38 +0000</pubDate>
		<dc:creator>ReaderShare</dc:creator>
				<category><![CDATA[shared]]></category>
		<category><![CDATA[Cocoa Controls]]></category>

		<guid isPermaLink="false">http://zdima.net/blog/?p=16800</guid>
		<description><![CDATA[Posted by Cocoa Controls at Cocoa Controls We’ve all dealt with the hassle of constructing UITableViewController subclasses specifically to capture a couple pieces of data. Maybe you’ve even created a half-baked generic frameworky sort of thing to make the process easier. I know I have, at least twice. This isn’t any fun, and yet we keep doing it. I now know that there’s a better way to deal with these sorts of things, with this week’s Control of the Week: QuickDialog. QuickDialog, from Eduardo Scoz, is a super-easy way to create HIG-compliant iOS forms for your apps without having to directly deal with UITableViews, delegates and data sources. Check it out on YouTube … or grab a copy of the source code.]]></description>
			<content:encoded><![CDATA[<p>Posted by Cocoa Controls at <a href="http://www.cocoacontrols.com/posts/control-of-the-week--8?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+CocoaControls+%28Cocoa+Controls%29">Cocoa Controls</a></p>
<p>We’ve all dealt with the hassle of constructing UITableViewController subclasses specifically to capture a couple pieces of data. Maybe you’ve even created a half-baked generic frameworky sort of thing to make the process easier. I know I have, at least twice. This isn’t any fun, and yet we keep doing it. I now know that there’s a better way to deal with these sorts of things, with this week’s Control of the Week: <a href="http://cocoacontrols.com/controls/quickdialog">QuickDialog</a>.</p>
<p>QuickDialog, from <a href="http://escoz.com/">Eduardo Scoz</a>, is a super-easy way to create <span>HIG</span>-compliant iOS forms for your apps without having to directly deal with UITableViews, delegates and data sources.</p>
<p>Check it out on <a href="http://www.youtube.com/watch?v=YLXNwY-INbM&amp;feature=player_embedded">YouTube</a></p>
</p>
<p>… <a href="http://cocoacontrols.com/controls/quickdialog">or grab a copy of the source code</a>.</p>
<p><img src="http://s3.amazonaws.com/cocoacontrols_production/ios_screens/584/full.png?1327355011" alt=""></p>
<p><img src="http://feeds.feedburner.com/~r/CocoaControls/~4/IL5boTyyUuM" height="1" width="1"></p>
]]></content:encoded>
			<wfw:commentRss>http://zdima.net/blog/archives/16800/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BSKeyboardControls (Cocoa Controls)</title>
		<link>http://zdima.net/blog/archives/16798</link>
		<comments>http://zdima.net/blog/archives/16798#comments</comments>
		<pubDate>Sun, 29 Jan 2012 19:42:53 +0000</pubDate>
		<dc:creator>ReaderShare</dc:creator>
				<category><![CDATA[shared]]></category>
		<category><![CDATA[Cocoa Controls]]></category>

		<guid isPermaLink="false">http://zdima.net/blog/?p=16798</guid>
		<description><![CDATA[Posted by Cocoa Controls at Cocoa Controls BSKeyboardControls makes it easy to put previous, next and done buttons above the keyboard in your iPhone or iPad app. BSKeyboardControls is optimized for both iPhone and iPad and therefore fits perfectly in your universal app. For usage instructions please follow the source code link.]]></description>
			<content:encoded><![CDATA[<p>Posted by Cocoa Controls at <a href="http://www.cocoacontrols.com/platforms/ios/controls/bskeyboardcontrols?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+CocoaControls+%28Cocoa+Controls%29">Cocoa Controls</a><br />
BSKeyboardControls makes it easy to put previous, next and done buttons above the keyboard in your iPhone or iPad app.</p>
<p>BSKeyboardControls is optimized for both iPhone and iPad and therefore fits perfectly in your universal app.</p>
<p>For usage instructions please follow the source code link.
<p><img alt="image of this control" src="http://s3.amazonaws.com/cocoacontrols_production/ios_screens/597/full.png?1327686115"></p>
<p><img src="http://feeds.feedburner.com/~r/CocoaControls/~4/22Y7yfkIbzg" height="1" width="1"></p>
]]></content:encoded>
			<wfw:commentRss>http://zdima.net/blog/archives/16798/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JWFolders (Cocoa Controls)</title>
		<link>http://zdima.net/blog/archives/16786</link>
		<comments>http://zdima.net/blog/archives/16786#comments</comments>
		<pubDate>Thu, 26 Jan 2012 03:16:09 +0000</pubDate>
		<dc:creator>ReaderShare</dc:creator>
				<category><![CDATA[shared]]></category>
		<category><![CDATA[Cocoa Controls]]></category>

		<guid isPermaLink="false">http://zdima.net/blog/?p=16786</guid>
		<description><![CDATA[JWFolders is a set of classes that attempt to mimic the folder animation present on the iOS SpringBoard. SOURCE LINK from Cocoa Controls]]></description>
			<content:encoded><![CDATA[<p>JWFolders is a set of classes that attempt to mimic the folder animation present on the iOS SpringBoard.
<p><img alt="image of this control" src="http://s3.amazonaws.com/cocoacontrols_production/ios_screens/550/full.png?1326077965"></p>
<p><img src="http://feeds.feedburner.com/~r/CocoaControls/~4/TzBuBLbTIXQ" height="1" width="1"></p>
<p><a href="http://www.cocoacontrols.com/platforms/ios/controls/jwfolders?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+CocoaControls+%28Cocoa+Controls%29">SOURCE LINK</a> from <a href="http://www.cocoacontrols.com">Cocoa Controls</a></p>
]]></content:encoded>
			<wfw:commentRss>http://zdima.net/blog/archives/16786/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Cocos2D in a UIKit project [Ben Williams] (iDevBlogADay)</title>
		<link>http://zdima.net/blog/archives/16784</link>
		<comments>http://zdima.net/blog/archives/16784#comments</comments>
		<pubDate>Wed, 25 Jan 2012 08:57:59 +0000</pubDate>
		<dc:creator>ReaderShare</dc:creator>
				<category><![CDATA[shared]]></category>
		<category><![CDATA[Ben Williams]]></category>
		<category><![CDATA[iDevBlogADay]]></category>

		<guid isPermaLink="false">http://zdima.net/blog/?p=16784</guid>
		<description><![CDATA[I recently needed to add a “water ripple” effect to a project. Although there is a simple water ripple effect built-in to the SDK, it really didn’t fill my needs. It seemed like my only options would be to quickly boost my OpenGL skills (from none to something), or find an alternative. I soon found a really nice water ripple effect built for Cocos2D, which was exactly what I wanted. The only stumbling block was how to integrate Cocos2D into my existing UIKit project. As it turns out, it’s fairly simple. First, download the source for Cocos2D. If your UIKit project is using ARC, you’ll need to download the “bleeding edge” version from GitHub, as this is currently the only version in which the header files are all ARC friendly. If you are not using ARC, the latest stable version should be fine (currently v1.0.1). Once you have the Cocos2D source, locate the file “cocos2d-ios.xcodeproj”. Open up your UIKit project, and drag this file into your file navigator. You should end up with something like this: Next, go to the Build Phases settings for your project, and add the Cocos2D library (libcocos2d.a) as a linked library. You’ll probably also need to add OpenGLES.framework, and libz.dylib, like so: You’ll also need to modify your Build Settings. Set Always Search User Paths to YES, and add the Cocos2D source directory to the User Header Search Paths (as a recursive path): At this point, you should be able to import the “cocos2d.h” header into one of your source files, and compile your project. If you are using ARC and get some build errors, make sure your Cocos2D source is the development (bleeding edge) branch. Even though Cocos2D itself is not ARC enabled, it’s no problem to combine it with an ARC enabled project, provided you are using the correct version. Now that Cocos2D is part of your project, it’s time to write some code. I only needed Cocos2D in one small part of my application, so I decided to limit it to a single UIViewController. This is the code that I used: - (void)viewDidLoad { [super viewDidLoad]; CCScene *introScene = [CCScene node]; self.introLayer = [IntroLayer node]; [introScene addChild:self.introLayer]; if(![CCDirector setDirectorType:kCCDirectorTypeDisplayLink]) { [CCDirector setDirectorType:kCCDirectorTypeDefault]; } CCDirector *director = [CCDirector sharedDirector]; EAGLView *glView = [EAGLView viewWithFrame:CGRectMake(0, 0, 1024, 768) pixelFormat:kEAGLColorFormatRGB565 depthFormat:0]; [director setOpenGLView:glView]; [director setDeviceOrientation:kCCDeviceOrientationPortrait]; [director setAnimationInterval:1.0/60]; [self setView:glView]; [CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGB565]; [[CCDirector sharedDirector] runWithScene:introScene]; [self.introLayer setupScene]; } - (void)runRippleAnimation { [self.introLayer runRippleAnimation]; } - (void)endRippleAnimation { CCDirector* director = [CCDirector sharedDirector]; [director end]; } I won’t go through the details of how to create a CCScene and CCLayer – there’s plenty of Cocos2D tutorials out there. The code that you’ll be most interested in is this: if(![CCDirector setDirectorType:kCCDirectorTypeDisplayLink]) { [CCDirector setDirectorType:kCCDirectorTypeDefault]; } CCDirector *director = [CCDirector sharedDirector]; EAGLView *glView = [EAGLView viewWithFrame:CGRectMake(0, 0, 1024, 768) pixelFormat:kEAGLColorFormatRGB565 depthFormat:0]; [director setOpenGLView:glView]; [director setDeviceOrientation:kCCDeviceOrientationPortrait]; [director setAnimationInterval:1.0/60]; [self setView:glView]; [CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGB565]; [[CCDirector sharedDirector] runWithScene:introScene]; This basically sets up the Cocos2D environment, and starts running your CCScene. And that’s it! I presented this UIViewController modally, but I expect you should be able to use this method within a subview just as easily. Combining UIKit and Cocos2D does suffer a performance hit, but I’m not doing anything overly complex here, so it wasn’t a problem. I’m also not sure if this is entirely the correct way to do things, but again – it works, so I’m happy. Cocos2D has a heap of really nice effects, with a great community behind it. If you need some extra pizazz in your app, it might just be the way to go. SOURCE LINK from iDevBlogADay]]></description>
			<content:encoded><![CDATA[<p>I recently needed to add a “water ripple” effect to a project. Although there is a <a href="http://stackoverflow.com/questions/5973530/iphone-having-a-ripple-effect-on-a-uiimageview">simple water ripple effect built-in to the SDK</a>, it really didn’t fill my needs. It seemed like my only options would be to quickly boost my OpenGL skills (from none to something), or find an alternative. I soon found a <a href="http://www.cocos2d-iphone.org/forum/topic/25090">really nice water ripple effect built for Cocos2D</a>, which was exactly what I wanted. The only stumbling block was how to integrate Cocos2D into my existing UIKit project. As it turns out, it’s fairly simple.</p>
<p>First, download the source for Cocos2D. If your UIKit project is using ARC, you’ll need to download the <a href="https://github.com/cocos2d/cocos2d-iphone">“bleeding edge” version from GitHub</a>, as this is currently the only version in which the header files are all ARC friendly. If you are not using ARC, the latest <a href="http://www.cocos2d-iphone.org/download">stable version</a> should be fine (currently v1.0.1). Once you have the Cocos2D source, locate the file “cocos2d-ios.xcodeproj”. Open up your UIKit project, and drag this file into your file navigator. You should end up with something like this:</p>
<p><img src="http://www.aspyreapps.com/wp/wp-content/uploads/2012/01/file-navigator.jpg" alt="" width="335" height="142"></p>
<p>Next, go to the Build Phases settings for your project, and add the Cocos2D library (libcocos2d.a) as a linked library. You’ll probably also need to add OpenGLES.framework, and libz.dylib, like so:</p>
<p><img src="http://www.aspyreapps.com/wp/wp-content/uploads/2012/01/build-phases1.jpg" alt="" width="760" height="309"></p>
<p>You’ll also need to modify your Build Settings. Set Always Search User Paths to YES, and add the Cocos2D source directory to the User Header Search Paths (as a recursive path):</p>
<p><img src="http://www.aspyreapps.com/wp/wp-content/uploads/2012/01/search-paths1.jpg" alt="" width="689" height="446"></p>
<p>At this point, you should be able to import the “cocos2d.h” header into one of your source files, and compile your project. If you are using ARC and get some build errors, make sure your Cocos2D source is the development (bleeding edge) branch. Even though Cocos2D itself is not ARC enabled, it’s no problem to combine it with an ARC enabled project, provided you are using the correct version.</p>
<p>Now that Cocos2D is part of your project, it’s time to write some code. I only needed Cocos2D in one small part of my application, so I decided to limit it to a single UIViewController. This is the code that I used:</p>
<pre>
- (void)viewDidLoad {
	[super viewDidLoad];

	CCScene *introScene = [CCScene node];
	self.introLayer = [IntroLayer node];
	[introScene addChild:self.introLayer];

	if(![CCDirector setDirectorType:kCCDirectorTypeDisplayLink]) {
		[CCDirector setDirectorType:kCCDirectorTypeDefault];
	}

	CCDirector *director = [CCDirector sharedDirector];
	EAGLView *glView = [EAGLView viewWithFrame:CGRectMake(0, 0, 1024, 768)
			pixelFormat:kEAGLColorFormatRGB565 depthFormat:0];
	[director setOpenGLView:glView];
	[director setDeviceOrientation:kCCDeviceOrientationPortrait];
	[director setAnimationInterval:1.0/60];
	[self setView:glView];
	[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGB565];
	[[CCDirector sharedDirector] runWithScene:introScene];

	[self.introLayer setupScene];
}

- (void)runRippleAnimation {
	[self.introLayer runRippleAnimation];
}

- (void)endRippleAnimation {
	CCDirector* director = [CCDirector sharedDirector];
	[director end];
}
</pre>
<p>I won’t go through the details of how to create a CCScene and CCLayer – there’s plenty of Cocos2D tutorials out there. The code that you’ll be most interested in is this:</p>
<pre>
if(![CCDirector setDirectorType:kCCDirectorTypeDisplayLink]) {
	[CCDirector setDirectorType:kCCDirectorTypeDefault];
}

CCDirector *director = [CCDirector sharedDirector];
EAGLView *glView = [EAGLView viewWithFrame:CGRectMake(0, 0, 1024, 768)
			pixelFormat:kEAGLColorFormatRGB565 depthFormat:0];
[director setOpenGLView:glView];
[director setDeviceOrientation:kCCDeviceOrientationPortrait];
[director setAnimationInterval:1.0/60];
[self setView:glView];
[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGB565];
[[CCDirector sharedDirector] runWithScene:introScene];
</pre>
<p>This basically sets up the Cocos2D environment, and starts running your CCScene. And that’s it! I presented this UIViewController modally, but I expect you should be able to use this method within a subview just as easily.</p>
<p>Combining UIKit and Cocos2D does suffer a performance hit, but I’m not doing anything overly complex here, so it wasn’t a problem. I’m also not sure if this is entirely the correct way to do things, but again – it works, so I’m happy.</p>
<p>Cocos2D has a heap of really nice effects, with a great community behind it. If you need some extra pizazz in your app, it might just be the way to go.</p>
<p><img src="http://feeds.feedburner.com/~r/idevblogaday/~4/KJsuzhtDSC4" height="1" width="1"></p>
<p><a href="http://www.aspyreapps.com/blog/using-cocos2d-in-a-uikit-project/?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+AspyreApps+%28Aspyre+Apps%29">SOURCE LINK</a> from <a href="http://idevblogaday.com">iDevBlogADay</a></p>
]]></content:encoded>
			<wfw:commentRss>http://zdima.net/blog/archives/16784/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>F3Swirly (Cocoa Controls)</title>
		<link>http://zdima.net/blog/archives/16782</link>
		<comments>http://zdima.net/blog/archives/16782#comments</comments>
		<pubDate>Wed, 25 Jan 2012 08:57:55 +0000</pubDate>
		<dc:creator>ReaderShare</dc:creator>
				<category><![CDATA[shared]]></category>
		<category><![CDATA[Cocoa Controls]]></category>

		<guid isPermaLink="false">http://zdima.net/blog/?p=16782</guid>
		<description><![CDATA[I needed a control which had visual aspects of both an activity indicator as well as an annunciator. This control satisfies that need by providing, textual, color, and animated feedback. The control uses Quartz 2D and Core Animation to provide a reasonable level of performance with virtually no CPU overhead required for the animation. The number of segments, segment color, segment thickness, rotation rate, and text can all be customized. I hope you find this useful! SOURCE LINK from Cocoa Controls]]></description>
			<content:encoded><![CDATA[<p>I needed a control which had visual aspects of both an  activity<br />
indicator as well as an annunciator.    This control satisfies that<br />
need by providing, textual, color, and animated feedback.  </p>
<p>The control uses Quartz 2D and Core Animation to provide a reasonable<br />
level of performance with virtually no CPU overhead required for the<br />
animation.    The number of segments, segment color, segment thickness,<br />
rotation rate, and text can all be customized.   </p>
<p>I hope you find this useful!
<p><img alt="image of this control" src="http://s3.amazonaws.com/cocoacontrols_production/ios_screens/575/full.png?1326856707"></p>
<p><img src="http://feeds.feedburner.com/~r/CocoaControls/~4/mvBtTzdt8eI" height="1" width="1"></p>
<p><a href="http://www.cocoacontrols.com/platforms/ios/controls/f3swirly?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+CocoaControls+%28Cocoa+Controls%29">SOURCE LINK</a> from <a href="http://www.cocoacontrols.com">Cocoa Controls</a></p>
]]></content:encoded>
			<wfw:commentRss>http://zdima.net/blog/archives/16782/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>UIStoryboard Power Drill [Jason Lust] (iDevBlogADay)</title>
		<link>http://zdima.net/blog/archives/16780</link>
		<comments>http://zdima.net/blog/archives/16780#comments</comments>
		<pubDate>Tue, 24 Jan 2012 20:00:05 +0000</pubDate>
		<dc:creator>ReaderShare</dc:creator>
				<category><![CDATA[shared]]></category>
		<category><![CDATA[iDevBlogADay]]></category>
		<category><![CDATA[Jason Lust]]></category>

		<guid isPermaLink="false">http://zdima.net/blog/?p=16780</guid>
		<description><![CDATA[I’ve read some good reasons why Storyboards are not ready for prime time. Some of the articles like Jonathan at toxic software.com simply help me find out that I wasn’t doing something wrong, it just wasn’t meant for that. But there are some benefits from using a storyboard that I wanted to keep, so I got adamant about finding workarounds. Here’s one: Drill down UITableViews – Standard 1. Provided you’ve started with a subclassed UITableViewController, or a TableView in a UIViewController that is already the root relationship from a UINavigationController. 2. You link the push outlet from the cell prototype back to the table view controller.This will automatically provide the control to push-in another of the same ViewController when a cell is clicked. 3. Give the loopback segue an identifier string in the attributes inspector. 4. Instead of implementing tableView:didSelectRowAtIndexPath: in the subclassed viewcontroller you will use prepareForSegue:(UIStoryboardSegue *)segue sender:(id)senderThis method will be passed the segue object that is the “tableLoopBack” the sender object for this segue type will be the UITableViewCell. 5. Prepare what data to send to the next instance the the table. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {          NSArray* myObjectArray;     UITableView* myTable;          if ([segue.identifier isEqualToString:@"tableLoopBack"]) {         SubClassedTable* nextSct = segue.destinationViewController;         UITableViewCell* myCell = (UITableViewCell*)sender;         NSIndexPath* idx = [myTable indexPathForCell:myCell];         nextSct.myObject = [self.myObjectArray objectAtIndex:idx.row];     } } 6. In the TableDataSourceDelegate have it decide how to propagate your tables data array based now on the defined and set value of “myObject”. This is very different for everyones data types. An example, using Core Data and have say AMusicLib &#62; Artists &#62; Albums &#62; Songs &#62; Info The myObject would ideally be of type NSManagedObject* so that you could be any of the above. When the dataDelegates are called like tableview:numberOfRowsInSection: you would want to implement something like the following to handle the many layers. - (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {     if ([self.myObject isKindOfClass:[Music class]]) {         Music* myMusicLib = self.myObject;         return [myMusicLib.artists count];     } else if ([self.myObject isKindOfClass:[Artist class]]) {         Artist* myArtist = self.myObject;         return [myArtist.albums count];     } else if ([self.myObject isKindOfClass:[Album class]]) {         Album* myAlbum = self.myObject;         return [myAlbum.songs count];     } } Now in the implementation of the tableview:cellForRowAtIndexPath: use a similar kindOf conditional so that the cells properties can feed from the difference of the objects at each layer. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {     static NSString *cellID = @”musicCell”;     UITableViewCell* newCell = [tableView dequeueReusableCellWithIdentifier:cellID];     if ([self.myObject isKindOfClass:[Music class]]) {         Music* myMusicLib = self.myObject;         Artist* aArtist = [[myMusicLib.artists allObjects] objectAtIndex:indexPath.row];         newCell.textLabel.text = aArtist.name;     } else if ([self.myObject isKindOfClass:[Artist class]]) {         Artist* myArtist = self.myObject;         Album* aAlbum = [[myArtist.albums allObjects] objectAtIndex:indexPath.row];         newCell.textLabel.text = aAlbum.title;         newCell.imageView.image = [UIImage imageNamed:aAlbum.art];     } else if ([self.myObject isKindOfClass:[Album class]]) {         Album* myAlbum = self.myObject;         Song* aSong = [[myAlbum.songs allObjects] objectAtIndex:indexPath.row];         newCell.textLabel.text = aSong.name;         NSDate* aTime = [NSDate dateWithTimeIntervalSince1970:[aSong.length intValue]];         NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];         [dateFormatter setDateFormat:@"m:ss"];         newCell.detailTextLabel.text = [dateFormatter stringFromDate:aTime];     }     return newCell; } And finally because earlier we used a property self.myObjectArray, this property could have been a consistent type simple array, but because I walked you through handing down different managedObjects this myObjectArray getter would also need to return an NSArray from the different managedObject’s intended NSSet. Same as just above, just return [myArtist.albums allObjects] or [myAlbum.songs allSongs] and so on for the prepareForSegue can hand off the right object to the next controller. Drill Down TableViews – Options The above is simple but can be limiting. The segue always pushes down to another of the same table view. Now you want options, lets go this why, or that. 1. Don’t use the push outlet on the cell prototype. This is whats limiting the control of where we go. 2. Do Implement the tableView:didSelectRowAtIndexPath: this is where we will decide what segue we take, Or none. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {     [tableView deselectRowAtIndexPath:indexPath animated:YES];     if (!sec) {         Section* aSect = [[self.sectionFetchedController fetchedObjects] objectAtIndex:indexPath.row];         [self performSegueWithIdentifier:@"tableLoopBack" sender:aSect];     } else {         Clip* aClip = [self.clipFetchedController objectAtIndexPath:indexPath];         [[VideoPlayerController Player] setMoviePlayerForClip:aClip];     } } What we are effectively doing here is getting the option to loop into another table, or stay and do something else like load a video in a modal MPMoviePlayerController. Or even call another segue that goes to detail view. 3. Continue to make use of the prepareForSegue method - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {     if ([segue.identifier isEqualToString:@"tableLoopBack"]) {         VideoListController* vlc = segue.destinationViewController;         Section* mySec = (Section*)sender;         vlc.title = mySec.title;         vlc.sec = mySec;     } } This is so data is still passed to the new instance of this controller for drill down purposes, even if not all cells drill. 4. And now the hack, if in step 1 we do not link the cell to push to the this viewController, we still need to define a segue and name it “tableLoopBack”.Add a UIBarButtonItem to the viewController and set the push outlet on it to loopback, identify that new segue connection as “tableLoopBack” and you have access to it when calling performSegue. 5. Add another UIBarButtonItem, and link it to another ViewController like one that layout details level. Identify that segue as another name like “detailSegue” and performSegue from didSelectRowAtIndexPath: where you can pass down the object full of details right into the sender, which will also be handed through the prepareForSegue, so make sure you hand it down again to the desired property of the new destinationViewController. Helpful? Vote me up: Stackoverflow.com SOURCE LINK from iDevBlogADay]]></description>
			<content:encoded><![CDATA[<p><a href="http://2.bp.blogspot.com/-NoXa09AT0fU/Tx6GpgdViGI/AAAAAAAAAUo/KglhPr5tWoI/s1600/layout1.png"><img border="0" height="164" src="http://2.bp.blogspot.com/-NoXa09AT0fU/Tx6GpgdViGI/AAAAAAAAAUo/KglhPr5tWoI/s200/layout1.png" width="200"></a><br />I’ve read some good reasons why Storyboards are not ready for prime time. Some of the articles like <a href="http://toxicsoftware.com/uistoryboard-issues/">Jonathan at toxic software.com</a> simply help me find out that I wasn’t doing something wrong, it just wasn’t meant for that. But there are some benefits from using a storyboard that I wanted to keep, so I got adamant about finding workarounds. Here’s one:</p>
<p>Drill down UITableViews – Standard</p>
<p><a href="http://1.bp.blogspot.com/-jgf-KI98c5g/Tx6CsC8igZI/AAAAAAAAAUY/lIg9M51w6eY/s1600/layout2.png"><img border="0" height="140" src="http://1.bp.blogspot.com/-jgf-KI98c5g/Tx6CsC8igZI/AAAAAAAAAUY/lIg9M51w6eY/s200/layout2.png" width="200"></a></p>
<p>1. Provided you’ve started with a subclassed UITableViewController, or a TableView in a UIViewController that is already the root relationship from a UINavigationController. </p>
<p>2. You link the push outlet from the cell prototype back to the table view controller.<br />This will automatically provide the control to push-in another of the same ViewController when a cell is clicked.<br /><a href="http://4.bp.blogspot.com/-VHmUhmp0dZc/Tx6Fj7-V2BI/AAAAAAAAAUg/A7H85r4ZhXE/s1600/layout2a.png"><img border="0" height="74" src="http://4.bp.blogspot.com/-VHmUhmp0dZc/Tx6Fj7-V2BI/AAAAAAAAAUg/A7H85r4ZhXE/s200/layout2a.png" width="200"></a></p>
<p>3. Give the loopback segue an identifier string in the attributes inspector. </p>
<p>4. Instead of implementing tableView:didSelectRowAtIndexPath: in the subclassed viewcontroller you will use <br />prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender<br /><a href="http://1.bp.blogspot.com/-p0qpiPmyCbQ/Tx6L-m5pU_I/AAAAAAAAAUw/Gp_CQkwEATM/s1600/layout3.png"><img border="0" height="120" src="http://1.bp.blogspot.com/-p0qpiPmyCbQ/Tx6L-m5pU_I/AAAAAAAAAUw/Gp_CQkwEATM/s200/layout3.png" width="200"></a><br />This method will be passed the segue object that is the “tableLoopBack” the sender object for this segue type will be the UITableViewCell.</p>
<p>5. Prepare what data to send to the next instance the the table.</p>
<div>
<div>- (<span>void</span>)prepareForSegue:(<span>UIStoryboardSegue</span> *)segue sender:(<span>id</span>)sender {</div>
<div>    </div>
<div>    <span>NSArray</span>* myObjectArray;</div>
<div>    <span>UITableView</span>* myTable;</div>
<div>    </div>
<div>
<span>    </span><span>if</span><span> ([segue.</span>identifier<span> </span>isEqualToString<span>:</span><span>@"tableLoopBack"</span><span>]) {</span>
</div>
<div>        <span>SubClassedTable</span>* nextSct = segue.<span>destinationViewController</span>;</div>
<div>
<span>        </span>UITableViewCell<span>* myCell = (</span>UITableViewCell<span>*)sender;</span>
</div>
<div>        <span>NSIndexPath</span>* idx = [myTable <span>indexPathForCell</span>:myCell];</div>
<div>        nextSct.<span>myObject</span> = [<span>self</span>.<span>myObjectArray</span> <span>objectAtIndex</span>:idx.<span>row</span>];</div>
<div>    }</div>
<div>}</div>
</div>
<p>6. In the TableDataSourceDelegate have it decide how to propagate your tables data array based now on the defined and set value of “myObject”. This is very different for everyones data types.</p>
<p>An example, using Core Data and have say AMusicLib &gt; Artists &gt; Albums &gt; Songs &gt; Info</p>
<p>The myObject would ideally be of type NSManagedObject* so that you could be any of the above. When the dataDelegates are called like tableview:numberOfRowsInSection: you would want to implement something like the following to handle the many layers.</p>
<div>- (<span>int</span>)tableView:(<span>UITableView</span> *)tableView numberOfRowsInSection:(<span>NSInteger</span>)section {</div>
<div>
<span>    </span><span>if</span><span> ([</span><span>self</span><span>.</span><span>myObject</span><span> </span>isKindOfClass<span>:[</span><span>Music</span><span> </span>class<span>]]) {</span>
</div>
<div>        <span>Music</span>* myMusicLib = <span>self</span>.<span>myObject</span>;</div>
<div>        <span>return</span> [myMusicLib.<span>artists</span> <span>count</span>];</div>
<div>    } <span>else</span> <span>if</span> ([<span>self</span>.<span>myObject</span> <span>isKindOfClass</span>:[<span>Artist</span> <span>class</span>]]) {</div>
<div>        <span>Artist</span>* myArtist = <span>self</span>.<span>myObject</span>;</div>
<div>        <span>return</span> [myArtist.<span>albums</span> <span>count</span>];</div>
<div>    } <span>else</span> <span>if</span> ([<span>self</span>.<span>myObject</span> <span>isKindOfClass</span>:[<span>Album</span> <span>class</span>]]) {</div>
<div>        <span>Album</span>* myAlbum = <span>self</span>.<span>myObject</span>;</div>
<div>        <span>return</span> [myAlbum.<span>songs</span> <span>count</span>];</div>
<div>    }</div>
<div>}</div>
<p>Now in the implementation of the tableview:cellForRowAtIndexPath: use a similar kindOf conditional so that the cells properties can feed from the difference of the objects at each layer.</p>
<div>- (<span>UITableViewCell</span> *)tableView:(<span>UITableView</span> *)tableView cellForRowAtIndexPath:(<span>NSIndexPath</span> *)indexPath {</div>
<div>    <span>static</span> <span>NSString</span> *cellID = <span>@”musicCell”</span>;</div>
<div>
<span>    </span>UITableViewCell<span>* newCell = [tableView </span>dequeueReusableCellWithIdentifier<span>:cellID];</span>
</div>
<div></div>
<div>
<span>    </span><span>if</span><span> ([</span><span>self</span><span>.</span><span>myObject</span><span> </span>isKindOfClass<span>:[</span><span>Music</span><span> </span>class<span>]]) {</span>
</div>
<div>        <span>Music</span>* myMusicLib = <span>self</span>.<span>myObject</span>;</div>
<div>        <span>Artist</span>* aArtist = [[myMusicLib.<span>artists</span> <span>allObjects</span>] <span>objectAtIndex</span>:indexPath.<span>row</span>];</div>
<div>        newCell.<span>textLabel</span>.<span>text</span> = aArtist.<span>name</span>;</div>
<div>    } <span>else</span> <span>if</span> ([<span>self</span>.<span>myObject</span> <span>isKindOfClass</span>:[<span>Artist</span> <span>class</span>]]) {</div>
<div>        <span>Artist</span>* myArtist = <span>self</span>.<span>myObject</span>;</div>
<div>        <span>Album</span>* aAlbum = [[myArtist.<span>albums</span> <span>allObjects</span>] <span>objectAtIndex</span>:indexPath.<span>row</span>];</div>
<div>        newCell.<span>textLabel</span>.<span>text</span> = aAlbum.<span>title</span>;</div>
<div>        newCell.<span>imageView</span>.<span>image</span> = [<span>UIImage</span> <span>imageNamed</span>:aAlbum.<span>art</span>];</div>
<div>    } <span>else</span> <span>if</span> ([<span>self</span>.<span>myObject</span> <span>isKindOfClass</span>:[<span>Album</span> <span>class</span>]]) {</div>
<div>        <span>Album</span>* myAlbum = <span>self</span>.<span>myObject</span>;</div>
<div>        <span>Song</span>* aSong = [[myAlbum.<span>songs</span> <span>allObjects</span>] <span>objectAtIndex</span>:indexPath.<span>row</span>];</div>
<div>        newCell.<span>textLabel</span>.<span>text</span> = aSong.<span>name</span>;</div>
<div>
<span>        </span>NSDate<span>* aTime = [</span>NSDate<span> </span>dateWithTimeIntervalSince1970<span>:[aSong.</span><span>length</span><span> </span>intValue<span>]];</span>
</div>
<div>
<span>        </span>NSDateFormatter<span> *dateFormatter = [[[</span>NSDateFormatter<span> </span>alloc<span>] </span>init<span>] </span>autorelease<span>];</span>
</div>
<div>        [dateFormatter <span>setDateFormat</span>:<span>@"m:ss"</span>];</div>
<div>        newCell.<span>detailTextLabel</span>.<span>text</span> = [dateFormatter <span>stringFromDate</span>:aTime];</div>
<div>    }</div>
<div>    <span>return</span> newCell;</div>
<div>}</div>
<p>And finally because earlier we used a property self.myObjectArray, this property could have been a consistent type simple array, but because I walked you through handing down different managedObjects this myObjectArray getter would also need to return an NSArray from the different managedObject’s intended NSSet. Same as just above, just return [myArtist.albums allObjects] or [myAlbum.songs allSongs] and so on for the prepareForSegue can hand off the right object to the next controller.</p>
<p>Drill Down TableViews – Options</p>
<p>The above is simple but can be limiting. The segue always pushes down to another of the same table view. Now you want options, lets go this why, or that.</p>
<p>1. Don’t use the push outlet on the cell prototype. This is whats limiting the control of where we go.</p>
<p>2. Do Implement the tableView:didSelectRowAtIndexPath: this is where we will decide what segue we take, Or none.</p>
<div>- (<span>void</span>)tableView:(<span>UITableView</span> *)tableView didSelectRowAtIndexPath:(<span>NSIndexPath</span> *)indexPath {</div>
<div>
<span>    [tableView </span>deselectRowAtIndexPath<span>:indexPath </span>animated<span>:</span><span>YES</span><span>];</span>
</div>
<div>    <span>if</span> (!<span>sec</span>) {</div>
<div>        <span>Section</span>* aSect = [[<span>self</span>.<span>sectionFetchedController</span> <span>fetchedObjects</span>] <span>objectAtIndex</span>:indexPath.<span>row</span>];</div>
<div>
<span>        [</span><span>self</span><span> </span>performSegueWithIdentifier<span>:</span><span>@"tableLoopBack"</span><span> </span>sender<span>:aSect];</span>
</div>
<div>    } <span>else</span> {</div>
<div>        <span>Clip</span>* aClip = [<span>self</span>.<span>clipFetchedController</span> <span>objectAtIndexPath</span>:indexPath];</div>
<div>
<span>        [[</span>VideoPlayerController<span> </span>Player<span>] </span>setMoviePlayerForClip<span>:aClip];</span>
</div>
<div>    }</div>
<div>}</div>
<p>What we are effectively doing here is getting the option to loop into another table, or stay and do something else like load a video in a modal MPMoviePlayerController. Or even call another segue that goes to detail view.</p>
<p>3. Continue to make use of the prepareForSegue method</p>
<div>- (<span>void</span>)prepareForSegue:(<span>UIStoryboardSegue</span> *)segue sender:(<span>id</span>)sender {</div>
<div>
<span>    </span><span>if</span><span> ([segue.</span>identifier<span> </span>isEqualToString<span>:</span><span>@"tableLoopBack"</span><span>]) {</span>
</div>
<div>
<span>        </span><span>VideoListController</span><span>* vlc = segue.</span>destinationViewController<span>;</span>
</div>
<div>        <span>Section</span>* mySec = (<span>Section</span>*)sender;</div>
<div>        vlc.<span>title</span> = mySec.<span>title</span>;</div>
<div>        vlc.<span>sec</span> = mySec;</div>
<div>    }</div>
<div>}</div>
<p>This is so data is still passed to the new instance of this controller for drill down purposes, even if not all cells drill.</p>
<div><a href="http://2.bp.blogspot.com/-Im0C14Xer0M/Tx6lY2SXSXI/AAAAAAAAAU4/6YWu0U8mdPg/s1600/hack.png"><img border="0" height="132" src="http://2.bp.blogspot.com/-Im0C14Xer0M/Tx6lY2SXSXI/AAAAAAAAAU4/6YWu0U8mdPg/s320/hack.png" width="320"></a></div>
<p>4. And now the hack, if in step 1 we do not link the cell to push to the this viewController, we still need to define a segue and name it “tableLoopBack”.<br />Add a <b>UIBarButtonItem</b> to the viewController and set the push outlet on it to loopback, identify that new segue connection as “tableLoopBack” and you have access to it when calling performSegue.</p>
<p>5. Add another UIBarButtonItem, and link it to another ViewController like one that layout details level. Identify that segue as another name like “detailSegue” and performSegue from didSelectRowAtIndexPath: where you can pass down the object full of details right into the sender, which will also be handed through the prepareForSegue, so make sure you hand it down again to the desired property of the new destinationViewController.</p>
<p>Helpful? Vote me up: <a href="http://stackoverflow.com/a/8931229/426577">Stackoverflow.com</a>
</p>
<div><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/7468092757963724166-2833295706126302998?l=jleeiii.blogspot.com" alt=""></div>
<p><img src="http://feeds.feedburner.com/~r/idevblogaday/~4/XjnQDiLphTk" height="1" width="1"></p>
<p><a href="http://jleeiii.blogspot.com/2012/01/uistoryboard-power-drill.html?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+idevblogaday+%28iDevBlogADay%29">SOURCE LINK</a> from <a href="http://idevblogaday.com">iDevBlogADay</a></p>
]]></content:encoded>
			<wfw:commentRss>http://zdima.net/blog/archives/16780/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unit testing for blocks based APIs [Marin Todorov] (iDevBlogADay)</title>
		<link>http://zdima.net/blog/archives/16778</link>
		<comments>http://zdima.net/blog/archives/16778#comments</comments>
		<pubDate>Tue, 24 Jan 2012 20:00:02 +0000</pubDate>
		<dc:creator>ReaderShare</dc:creator>
				<category><![CDATA[shared]]></category>
		<category><![CDATA[iDevBlogADay]]></category>
		<category><![CDATA[Marin Todorov]]></category>

		<guid isPermaLink="false">http://zdima.net/blog/?p=16778</guid>
		<description><![CDATA[Unit tests are very useful for those large projects where you might loose sight of everything that’s going on and while you are adding new code to add feature X you might be silently breaking feature Y without even suspecting. It’s super easy these days to add unit tests to your Xcode project – when you create new Xcode project just check the checkbox in the save dialogue and voila everything is setup automatically for you: This will add unit testing to your project and when you click Product-&#62;Test from Xcode’s menu your unit test will be run. Cool and smooth. Let’s have a look at the default unit test, which is created for you- you get a folder called “[Project name]Tests” and inside there’s one test pre-set for you. Open the .m file and find the only test inside: - (void)testExample { STFail(@"Unit tests are not implemented yet in utb_testTests"); } It’s designed so that it’ll fail by default. Eventually if you run the tests (Cmd+U) you’ll see the tests fail (though my experience shows even this simple example test will succeed for no reason many times): So in this article I’m not going to explain how unit tests work and so on, but I’d rather cover how to overcome some obstacles if you are writing unit tests for block based APIs. Unlike your iPhone apps the unit test suite is being started, it runs the code of all tests and then when there’s nothing more to run it just exists. If it didn’t spit any exception, the test was successful. End of story. So let’s see how that pairs up with using blocks. Let’s replace the content of the test method with this code: - (void)testExample { CLGeocoder* gc = [[CLGeocoder alloc] init]; [gc geocodeAddressString:@"Hermannplatz, Berlin, Germany" completionHandler:^(NSArray *placemarks, NSError *error) {   STFail(@"Failed inside a block");   }]; } This code creates a new geocoder and asks for matches for the given address. Since the API is asynchronous the results are fetched inside the provided block. You’ll need to also add an import at the top of the file: #import &#38;lt;CoreLocation/CoreLocation.h&#38;gt; and of course add the CoreLocation.framework to the project. Hit Cmd+U and … the test passes. Inevitably and always. So why does this happen? The test suit doesn’t wait for and don’t know that you are waiting for geocoding results from Apple’s server. It runs all the code and then when there’s no more code to run – exits. Problem? You actually need to make the application hang around alive until you get the results for the geocoding server and only tell it “i finished my work you can exit now please”. But naturally if you just tell the app to sleep it won’t be able to react when the results come back from the server … Some diggin’ through StackOverflow finds me this solution which I really like: stackoverflow.com/a/4326754/208205 dispatch_semaphore_t sema = dispatch_semaphore_create(0);   [object runSomeLongOperationAndDo:^{ STAssert…   dispatch_semaphore_signal(sema); }];   dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); dispatch_release(sema); Using Grand Central Dispatch and its C functions you can create a semaphore object and wait till the signal comes in. However there are 2 things I don’t like in this code: using C functions and I have rather complex class structure of classes, so passing reference to the semaphore is rather inconvenient. So I quickly came up with a simple class to implement my own semaphore. It has two handy methods – waitForKey:(NSString*)key and lift:(NSString*)key … and here’s how you use it: - (void)testExample { CLGeocoder* gc = [[CLGeocoder alloc] init]; [gc geocodeAddressString:@"Hermannplatz, Berlin, Germany" completionHandler:^(NSArray *placemarks, NSError *error) {   STFail(@"Failed inside a block"); [[TestSemaphore sharedInstance] lift:@”geocode1”]; }];   [[TestSemaphore sharedInstance] waitForKey:@”geocode1”]; } Pretty straight forward – and since it’s a singleton class you can call it from wherever you want. Also it is free and available for download if you want to tingle with unit testing. And hey – it’s a semaphore, so you can use it for whatever purpose suits you Sempahore code download Marin SOURCE LINK from iDevBlogADay]]></description>
			<content:encoded><![CDATA[<p>Unit tests are very useful for those large projects where you might loose sight of everything that’s going on and while you are adding new code to add feature X you might be silently breaking feature Y without even suspecting. It’s super easy these days to add unit tests to your Xcode project – when you create new Xcode project just check the checkbox in the save dialogue and voila everything is setup automatically for you:</p>
<p><a href="http://www.touch-code-magazine.com/wp-content/uploads/2012/01/utb_1.png"><img src="http://www.touch-code-magazine.com/wp-content/uploads/2012/01/utb_1.png" alt="" width="385" height="90"></a></p>
<p>This will add unit testing to your project and when you click Product-&gt;Test from Xcode’s menu your unit test will be run. Cool and smooth.</p>
<p>Let’s have a look at the default unit test, which is created for you- you get a folder called “[Project name]Tests” and inside there’s one test pre-set for you. Open the .m file and find the only test inside:</p>
<div>
<div>
<pre><span>-</span> <span>(</span><span>void</span><span>)</span>testExample
<span>{</span>
    STFail<span>(</span><span>@</span><span>"Unit tests are not implemented yet in utb_testTests"</span><span>)</span>;
<span>}</span></pre>
</div>
</div>
<p>It’s designed so that it’ll fail by default. Eventually if you run the tests (Cmd+U) you’ll see the tests fail (<em>though my experience shows even this simple example test will succeed for no reason many times</em>):</p>
<p><a href="http://www.touch-code-magazine.com/wp-content/uploads/2012/01/utb_21.gif"><img src="http://www.touch-code-magazine.com/wp-content/uploads/2012/01/utb_21.gif" alt="" width="233" height="185"></a></p>
<p>So in this article I’m not going to explain how unit tests work and so on, but I’d rather cover how to overcome some obstacles if you are writing unit tests for block based APIs.</p>
<p><span></span></p>
<p>Unlike your iPhone apps the unit test suite is being started, it runs the code of all tests and then when there’s nothing more to run it just exists. If it didn’t spit any exception, the test was successful. End of story.</p>
<p>So let’s see how that pairs up with using blocks. Let’s replace the content of the test method with this code:</p>
<div>
<div>
<pre><span>-</span> <span>(</span><span>void</span><span>)</span>testExample
<span>{</span>
    CLGeocoder<span>*</span> gc <span>=</span> <span>[</span><span>[</span>CLGeocoder alloc<span>]</span> init<span>]</span>;
    <span>[</span>gc geocodeAddressString<span>:</span><span>@</span><span>"Hermannplatz, Berlin, Germany"</span>
     completionHandler<span>:^</span><span>(</span><span>NSArray</span> <span>*</span>placemarks, <span>NSError</span> <span>*</span>error<span>)</span> <span>{</span>
 
         STFail<span>(</span><span>@</span><span>"Failed inside a block"</span><span>)</span>;
 
     <span>}</span><span>]</span>;
<span>}</span></pre>
</div>
</div>
<p>This code creates a new geocoder and asks for matches for the given address. Since the API is asynchronous the results are fetched inside the provided block. You’ll need to also add an import at the top of the file:</p>
<div>
<div>
<pre><span>#import &amp;lt;CoreLocation/CoreLocation.h&amp;gt;</span></pre>
</div>
</div>
<p>and of course add the CoreLocation.framework to the project.</p>
<p>Hit Cmd+U and … the test passes. Inevitably and always.</p>
<p><a href="http://www.touch-code-magazine.com/wp-content/uploads/2012/01/utb_3.png"><img src="http://www.touch-code-magazine.com/wp-content/uploads/2012/01/utb_3.png" alt="" width="230" height="185"></a></p>
<p>So why does this happen?</p>
<p>The test suit doesn’t wait for and don’t know that you are waiting for geocoding results from Apple’s server. It runs all the code and then when there’s no more code to run – exits.</p>
<p>Problem?</p>
<p>You actually need to make the application hang around alive until you get the results for the geocoding server and only tell it “i finished my work you can exit now please”. But naturally if you just tell the app to sleep it won’t be able to react when the results come back from the server …</p>
<p>Some diggin’ through StackOverflow finds me this solution which I really like:</p>
<p><a href="http://stackoverflow.com/a/4326754/208205">stackoverflow.com/a/4326754/208205</a></p>
<div>
<div>
<pre>dispatch_semaphore_t sema <span>=</span> dispatch_semaphore_create<span>(</span><span>0</span><span>)</span>;
 
<span>[</span>object runSomeLongOperationAndDo<span>:^</span><span>{</span>
    STAssert…
 
    dispatch_semaphore_signal<span>(</span>sema<span>)</span>;
<span>}</span><span>]</span>;
 
dispatch_semaphore_wait<span>(</span>sema, DISPATCH_TIME_FOREVER<span>)</span>;
dispatch_release<span>(</span>sema<span>)</span>;</pre>
</div>
</div>
<p>Using Grand Central Dispatch and its C functions you can create a semaphore object and wait till the signal comes in. However there are 2 things I don’t like in this code:</p>
<ol>
<li>using C functions and</li>
<li>I have rather complex class structure of classes, so passing reference to the semaphore is rather inconvenient.</li>
</ol>
<p>So I quickly came up with a simple class to implement my own semaphore. It has two handy methods – waitForKey:(NSString*)key and lift:(NSString*)key … and here’s how you use it:</p>
<div>
<div>
<pre><span>-</span> <span>(</span><span>void</span><span>)</span>testExample
<span>{</span>
    CLGeocoder<span>*</span> gc <span>=</span> <span>[</span><span>[</span>CLGeocoder alloc<span>]</span> init<span>]</span>;
    <span>[</span>gc geocodeAddressString<span>:</span><span>@</span><span>"Hermannplatz, Berlin, Germany"</span>
     completionHandler<span>:^</span><span>(</span><span>NSArray</span> <span>*</span>placemarks, <span>NSError</span> <span>*</span>error<span>)</span> <span>{</span>
 
         STFail<span>(</span><span>@</span><span>"Failed inside a block"</span><span>)</span>;
         <span>[</span><span>[</span>TestSemaphore sharedInstance<span>]</span> lift<span>:</span>@”geocode1”<span>]</span>;
     <span>}</span><span>]</span>;
 
	<span>[</span><span>[</span>TestSemaphore sharedInstance<span>]</span> waitForKey<span>:</span>@”geocode1”<span>]</span>;
<span>}</span></pre>
</div>
</div>
<p>Pretty straight forward – and since it’s a singleton class you can call it from wherever you want. Also it is free and available for download if you want to tingle with unit testing. And hey – it’s a semaphore, so you can use it for whatever purpose suits you <img src="http://www.touch-code-magazine.com/wp-includes/images/smilies/icon_smile.gif" alt=":)"></p>
<p><a href="http://www.touch-code-magazine.com/wp-content/uploads/2012/01/TestSemaphore.zip">Sempahore code download</a></p>
<p>Marin</p>
<p><img src="http://feeds.feedburner.com/~r/idevblogaday/~4/xEYaqrTNBME" height="1" width="1"></p>
<p><a href="http://www.touch-code-magazine.com/unit-testing-for-blocks-based-apis/?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+idevblogaday+%28iDevBlogADay%29">SOURCE LINK</a> from <a href="http://idevblogaday.com">iDevBlogADay</a></p>
]]></content:encoded>
			<wfw:commentRss>http://zdima.net/blog/archives/16778/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A pullable view implementation (like Notification Center) [Fábio Rodella] (iDevBlogADay)</title>
		<link>http://zdima.net/blog/archives/16776</link>
		<comments>http://zdima.net/blog/archives/16776#comments</comments>
		<pubDate>Tue, 24 Jan 2012 19:59:57 +0000</pubDate>
		<dc:creator>ReaderShare</dc:creator>
				<category><![CDATA[shared]]></category>
		<category><![CDATA[Fábio Rodella]]></category>
		<category><![CDATA[iDevBlogADay]]></category>

		<guid isPermaLink="false">http://zdima.net/blog/?p=16776</guid>
		<description><![CDATA[For an app I’m designing at the moment I had the need to use a pullable view (sliding drawer) similar to how the iOS 5 Notification Center works, where you can flick or drag a handle to reveal or hide additional content. After looking for an existing open-source implementation of such feature and finding squat, I decided to create my own and share it with the interwebs. The PullableView class tries to mimic the behaviour of the Notification Center view as closely as possible, and is very flexible. You can define and style your handle area, and the view can be pulled from any direction in the X or Y axes. To define the “open” and “closed” states you simply set the center point for the view at these states; if both points have the same X coordinate the sliding will happen in the vertical axis, or the horizontal axis if the Y coordinates are equal. You can also set a flag indicating if the view state should be toggled by simply tapping the handle area. The sample project includes a view controller which uses 3 pullable views demonstrating many usage scenarios, but if you have additional questions or want to report a bug add a comment to this post. You can download the source code from our Github repo. I’ve also added this component to the Cocoa Controls website. Hope you find it useful! SOURCE LINK from iDevBlogADay]]></description>
			<content:encoded><![CDATA[<p>For an app I’m designing at the moment I had the need to use a pullable view (sliding drawer) similar to how the iOS 5 Notification Center works, where you can flick or drag a handle to reveal or hide additional content. After looking for an existing open-source implementation of such feature and finding squat, I decided to create my own and share it with the interwebs. </p>
<p>The PullableView class tries to mimic the behaviour of the Notification Center view as closely as possible, and is very flexible. You can define and style your handle area, and the view can be pulled from any direction in the X or Y axes. To define the “open” and “closed” states you simply set the center point for the view at these states; if both points have the same X coordinate the sliding will happen in the vertical axis, or the horizontal axis if the Y coordinates are equal. You can also set a flag indicating if the view state should be toggled by simply tapping the handle area.</p>
<p>The sample project includes a view controller which uses 3 pullable views demonstrating many usage scenarios, but if you have additional questions or want to report a bug add a comment to this post.</p>
<p>You can download the source code from our <a href="https://github.com/crocodella/PullableView">Github repo</a>. I’ve also added this component to the <a href="http://cocoacontrols.com/platforms/ios/controls/pullableview">Cocoa Controls website</a>. Hope you find it useful!</p>
<p><img src="http://feeds.feedburner.com/~r/idevblogaday/~4/BnDnLExvut8" height="1" width="1"></p>
<p><a href="http://www.crocodella.com.br/2012/01/a-pullable-view-implementation-like-notification-center/?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+idevblogaday+%28iDevBlogADay%29">SOURCE LINK</a> from <a href="http://idevblogaday.com">iDevBlogADay</a></p>
]]></content:encoded>
			<wfw:commentRss>http://zdima.net/blog/archives/16776/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FlipTransform (Cocoa Controls)</title>
		<link>http://zdima.net/blog/archives/16774</link>
		<comments>http://zdima.net/blog/archives/16774#comments</comments>
		<pubDate>Mon, 23 Jan 2012 22:58:15 +0000</pubDate>
		<dc:creator>ReaderShare</dc:creator>
				<category><![CDATA[shared]]></category>
		<category><![CDATA[Cocoa Controls]]></category>

		<guid isPermaLink="false">http://zdima.net/blog/?p=16774</guid>
		<description><![CDATA[Animation component for the effect of flipping as in a news/clock ticker, or a page turn. Structured around the idea of a data object (i.e. headline in news, number in a clock, page in a book) as an animation frame, comprised of multiple CALayers. SOURCE LINK from Cocoa Controls]]></description>
			<content:encoded><![CDATA[<p>Animation component for the effect of flipping as in a news/clock ticker, or a page turn.</p>
<p>Structured around the idea of a data object (i.e. headline in news, number in a clock, page in a book) as an animation frame, comprised of multiple CALayers.
<p><img alt="image of this control" src="http://s3.amazonaws.com/cocoacontrols_production/ios_screens/573/full.png?1327348371"></p>
<p><img src="http://feeds.feedburner.com/~r/CocoaControls/~4/LGU-E2wO_PQ" height="1" width="1"></p>
<p><a href="http://www.cocoacontrols.com/platforms/ios/controls/fliptransform?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+CocoaControls+%28Cocoa+Controls%29">SOURCE LINK</a> from <a href="http://www.cocoacontrols.com">Cocoa Controls</a></p>
]]></content:encoded>
			<wfw:commentRss>http://zdima.net/blog/archives/16774/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Audiobook Cutter Pares Down Lengthy Audio Files Into Customized Segments [Windows Downloads] (Lifehacker)</title>
		<link>http://zdima.net/blog/archives/16772</link>
		<comments>http://zdima.net/blog/archives/16772#comments</comments>
		<pubDate>Sun, 22 Jan 2012 12:43:49 +0000</pubDate>
		<dc:creator>ReaderShare</dc:creator>
				<category><![CDATA[shared]]></category>
		<category><![CDATA[David Galloway]]></category>
		<category><![CDATA[Lifehacker]]></category>

		<guid isPermaLink="false">http://zdima.net/blog/?p=16772</guid>
		<description><![CDATA[Windows: As a frequent audiobook and podcast listener I find that most of the time long audio files of an hour or more aren&#8217;t terrible to deal with until you lose your place and try to find it again while driving or running. Usually this means pulling your car over, skipping and fast forwarding for a minute or two until you&#8217;ve found your place again. The free version of Audiobook Cutter lets you instead chop that monster file down into segments to make navigation easier. More » SOURCE LINK from Lifehacker]]></description>
			<content:encoded><![CDATA[<div style="float:left;padding-right:10px">
<div><a title="Click here to read Audiobook Cutter Pares Down Lengthy Audio Files Into Customized Segments" href="http://lifehacker.com/5878103/audiobook-cutter-pares-down-lengthy-audio-files-into-customized-segments"><br />
						<img style="border-color:#b3b3b3;border-width:0 1px 1px;border-style:none solid solid" height="120" width="190" alt="Click here to read Audiobook Cutter Pares Down Lengthy Audio Files Into Customized Segments" src="http://cache.lifehacker.com/assets/images/17/2012/01/small_809a73a542892b6bfccbf5dbbcb3cffa.jpg"></a></div>
</p></div>
<p>				Windows: As a frequent audiobook and podcast listener I find that most of the time long audio files of an hour or more aren&#8217;t terrible to deal with until you lose your place and try to find it again while driving or running. Usually this means pulling your car over, skipping and fast forwarding for a minute or two until you&#8217;ve found your place again. The free version of Audiobook Cutter lets you instead chop that monster file down into segments to make navigation easier. 				<a href="http://lifehacker.com/5878103/audiobook-cutter-pares-down-lengthy-audio-files-into-customized-segments" title="Click here to read more about Audiobook Cutter Pares Down Lengthy Audio Files Into Customized Segments [Windows Downloads]">More »</a></p>
<p><a href="http://ads.pheedo.com/click.phdo?s=7b68f457070fe357cad97349f271922c&amp;p=1"><img alt="" style="border:0" border="0" src="http://ads.pheedo.com/img.phdo?s=7b68f457070fe357cad97349f271922c&amp;p=1"></a><br />
<img alt="" height="0" width="0" border="0" src="http://segment-pixel.invitemedia.com/pixel?code=TechBiz&amp;partnerID=167&amp;key=segment"><img alt="" height="0" width="0" border="0" src="http://insight.adsrvr.org/track/evnt/?ct=0:8pyu3gz&amp;adv=wouzn4v&amp;fmt=3">
<div>
<a href="http://feeds.gawker.com/~ff/lifehacker/full?a=Cj_29pcOAvw:aW4Jc_EElzo:H0mrP-F8Qgo"><img src="http://feeds.feedburner.com/~ff/lifehacker/full?d=H0mrP-F8Qgo" border="0"></a> <a href="http://feeds.gawker.com/~ff/lifehacker/full?a=Cj_29pcOAvw:aW4Jc_EElzo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/lifehacker/full?d=yIl2AUoC8zA" border="0"></a> <a href="http://feeds.gawker.com/~ff/lifehacker/full?a=Cj_29pcOAvw:aW4Jc_EElzo:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/lifehacker/full?i=Cj_29pcOAvw:aW4Jc_EElzo:D7DqB2pKExk" border="0"></a> <a href="http://feeds.gawker.com/~ff/lifehacker/full?a=Cj_29pcOAvw:aW4Jc_EElzo:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/lifehacker/full?i=Cj_29pcOAvw:aW4Jc_EElzo:V_sGLiPBpWU" border="0"></a>
</div>
<p><img src="http://feeds.feedburner.com/~r/lifehacker/full/~4/Cj_29pcOAvw" height="1" width="1"></p>
<p><a href="http://lifehacker.com/5878103/audiobook-cutter-pares-down-lengthy-audio-files-into-customized-segments">SOURCE LINK</a> from <a href="http://lifehacker.com">Lifehacker</a></p>
]]></content:encoded>
			<wfw:commentRss>http://zdima.net/blog/archives/16772/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

