CCFNumberPicker

iOS developers have about 3 choices when it comes to numerical data entry; and none are optimal for various reasons. You can use UITextField and the associated keyboard; but the latter isn’t very ergonomic. The UISlider works, but lacks a built-in scale or a snap-to-grid functionality. Finally, the UIPickerView occupies too much real estate for simple entry tasks.

This is the origin of CCFNumberPicker. It allows you to specify upper and lower bounds, tick mark spacing, resolution, and even a light or dark style of the view. It’s also open-source. CCFNumberPicker github repository.

CCFNumberPicker light stype

There’s also a dark-themed version of the number picker view that you can use if circumstances call for this style. Here’s an example of this second style:

Dark style of the CCFNumberPicker

It’s easy to set options for the view. The configuration is all done via the CCFNumberPickerData object. The following code is responsible for configuring the second view above:

1
2
3
4
5
6
7
8
9
10
11
CCFNumberPickerData *data = [[CCFNumberPickerData alloc] init];
[data setMin:50];
[data setMax:410];
[data setMinorTickCount:5];
[data setMinorTickSpacing:10];
[data setMajorTickUnit:10];
[data setMajorTickNumFormat:@"%0.0f"];
[data setIndicatorNumFormat:@"%0.2f"];
[data setStyle:CCFNumberPickerStyleDark];
[data setShowsValueInScale:NO];
[pickerView setData:[data autorelease]];

That’s CCFNumberPicker! Let us know how you like it. As always bug reports, suggestions, hints, and condemnations are welcome. If you use it, our MIT license applies. We just ask for attribution. Also, if you use it in a deployed project, drop me a line. I’d love to see your work.

Doxygen documentation scripts for Xcode [REDACTED]

If you’ve worked with Xcode for any length of time, you’ve probably discovered the useful scripts menu. I’ve come to rely on it for my daily work; but what if in some future version of Xcode the scripts menu went missing?

Introducing a little project to future-proof part of the Xcode scripts menu. It’s an open-source project called Xcode-DoxyScripts. Check it out on github.

Right now, we’ve implemented blocks for @class, @method, and @property with more to come.

Mogenerator – automatic generation of Core Data classes

I recently stumbled on Mogenerator after struggling with the task of keeping the Core Data model and its entity classes in sync. During development, this is no simple task because no matter how carefully plan your model during the design phase. This is exactly where Mogenerator helps – by watching your .xcdatamodel file and writing your NSManagedObject subclasses for you in the background.

Like others, I’ve found a few places where the setup is tricky. In fact, the main reason that I wrote this post is not only to get the word out about Mogenerator, but also to point out some areas where I found a little difficulty.

First, you must have a physical directory in your project directory that has the same name as your Core Data model. It must be located at the same level as the model.

Model

Core Data model


So, in this example, we would need to have a physical directory named “Transfusion” a the same level as the model file is located.

Another problem that some have found is with permissions on the AppleScript file that is launched when the model is saved. You can find the script, Xmod, at /Developer/Library/Xcode/Plug-ins/Xmod.pbplugin/Contents/Resources/Scripts/Xmod.scpt
To avoid problems I just chmod 777 on it.

There is a final step that you need to perform before Mogenerator will work in the background. In the comments tab of the model’s info, you need to enter the word “xmod”. Just right click on the .xcdatamodel file to show its file info. You want the Comments tab.

Right-click for model info


.xcdatamodel -> Info -> Comments

Amazon iOS SDK mini-tutorial

The Amazon iOS SDK was released yesterday, providing iOS developers with a number of wrappers around calls to several of Amazon’s cloud services. The download includes the Amazon web services framework for iOS, its source, and a small demo application that allows you to browse your S3 buckets and SimpleDB domains. In this tutorial I’ll show you how to use the equivalent of the SQL “INSERT” statement to put new items into a SimpleDB domain.

First you need to have an account with AWS. The service relies on a public key/private key system; so once you have an AWS account, you can grab your keys from the management console at AWS. With those keys, create a header file with a couple #defines:

1
2
3
4
5
6
7
8
9
10
#ifndef __CCF_AMAZON_WEB_SERVICES_CONSTANTS_H
#define __CCF_AMAZON_WEB_SERVICES_CONSTANTS_H
/**
 *	@headerfile CCFAmazonWebServicesConstants.h "CCFAmazonWebServicesConstants.h"
 *	@brief Constants for accessing Amazon web services
 */
#define ACCESS_KEY @"your access key goes here"
#define SECRET_KEY @"your secret key goes here"
 
#endif

Now, I set up a singleton class to hold our S3 and SimpleSB clients. We’re only going to use the SimpleDB client for this tutorial. I called this class CCFAmazonWebServices; here’s the header:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//
//  CCFAmazonWebServices.h
//  Overdrive
//
//  Created by alanduncan on 12/10/10.
//  Copyright 2010 Cocoa Factory, LLC. All rights reserved.
//
 
#import <Foundation/Foundation.h>
#import <AWSiOSSDK/S3/AmazonS3Client.h>
#import <AWSiOSSDK/SimpleDB/AmazonSimpleDBClient.h>
 
#ifndef __CCF_AMAZON_WEB_SERVICES_H
#define __CCF_AMAZON_WEB_SERVICES_H
/**
 *	@class CCFAmazonWebServices
 *	@brief Interface to Amazon Web Services (AWS)
 *	@details Encapsulates the programmatic interface to Amazon Web Services (AWS) through the
 Amazon iOS SDK.  It provides a singleton instance \c sharedServices with accessors for \c simpleDB, the programmatic
 interface to Amazon's SimpleDB and \c s3, which is the interface to the app's S3 buckets.
 */
@interface CCFAmazonWebServices : NSObject
{
	AmazonSimpleDBClient *_simpleDB;
	AmazonS3Client *_s3;
}
 
/**
 *	@method sharedServices
 *	@brief Returns singleton class instance
 */
+ (CCFAmazonWebServices *)sharedServices;
 
/**
 *	@method simpleDB
 *	@brief Returns instance of an AmazonSimpleDBClient
 */
- (AmazonSimpleDBClient *)simpleDB;
 
/**
 *	@method s3
 *	@brief Returns instance of an AmazonS3Client
 */
- (AmazonS3Client *)s3;
 
@end
 
#endif

So a single class method to access the shared instance (sharedServices) and instance methods to access its clients for the S3 and SimpleDB services. Here’s the implementation details:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//
//  CCFAmazonWebServices.m
//  Overdrive
//
//  Created by alanduncan on 12/10/10.
//  Copyright 2010 Cocoa Factory, LLC. All rights reserved.
//
 
#import "CCFAmazonWebServices.h"
#import "CCFAmazonWebServicesConstants.h"
 
@implementation CCFAmazonWebServices
 
SYNTHESIZE_SINGLETON_FOR_CLASS_WITH_SHARED_INSTANCE( CCFAmazonWebServices, sharedServices );
 
#pragma mark -
#pragma mark Accessors
 
- (AmazonSimpleDBClient *)simpleDB;
{
   if( !_simpleDB )
   {
      AmazonSimpleDBClient *sdb = [[AmazonSimpleDBClient alloc] initWithAccessKey:ACCESS_KEY withSecretKey:SECRET_KEY];
      _ASSIGN( _simpleDB, [sdb autorelease] );
   }
   return _simpleDB;
}
 
- (AmazonS3Client *)s3;
{
   if( !_s3 )
   {
      AmazonS3Client *s3c = [[AmazonS3Client alloc] initWithAccessKey:ACCESS_KEY withSecretKey:SECRET_KEY];
      _ASSIGN( _s3, [s3c autorelease] );
   }
   return _s3;
}
 
@end

What’s going on in line 14 with the funky macro? I dislike writing singleton boilerplate, so I took a tip from Matt Gallagher and modified his macro so that I can specify my own shared instance method name. Apart from that, just lazy-loading accessors. Now let’s move on to a practical application. I have a generic in-app feedback system that allows users to give me feedback via a web service (rather than email or still better, venting any frustrations in the App Store!) We’ll focus now on porting that over to a SimpleDB domain. We’ll assume you’ve used the AWS-provided scratchpad app to create your domain called “feedback”. So here we go. We’ll create a helper class CCFFeedbackUploader with an interface like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#import <Foundation/Foundation.h>
 
@protocol CCFFeedbackHelperDelegate;
 
@interface CCFFeedbackHelper : NSObject
{
   NSString *_comment;
   NSString *_category;
   NSString *_email;
}
 
/*!
    @property   delegate
    @brief   Class delegate
    @details A delegate object conforming to the CCFFeedbackHelperDelegate protocol.  This protocol comprises messages
 on the status on remote transmission of user feedback to the database.
*/
@property (nonatomic, assign) id <CCFFeedbackHelperDelegate> delegate;
 
- (id)initWithCategory:(NSString *)catName comment:(NSString *)comment address:(NSString *)email;
- (void)sendFeedback;   
 
@end

Now, for the implementation details. First, some conveniences; we need a generic way of creating the name/value pairs for attributes:

1
2
3
4
- (SimpleDBReplaceableAttribute *)attributeForName:(NSString *)name value:(NSString *)value;
{
   return [[[SimpleDBReplaceableAttribute alloc] initWithName:name andValue:value andReplace:NO] autorelease];
}

Simple enough? The class SimpleDBReplaceableAttribute just encapsulates that name-value pair. It is similar enough to an entry in an NSDictionary, that we can use that similarity to create all the pairs we’ll need for our upload. Here’s the method that generates our put request:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
- (SimpleDBPutAttributesRequest *)putRequest;
{
  SimpleDBPutAttributesRequest *request = [[SimpleDBPutAttributesRequest alloc] init];
  [request setDomainName:@"feedback"];
  [request setItemName:[NSString stringWithUUID]];
 
  NSDictionary *nameValuePairs = [NSDictionary dictionaryWithObjectsAndKeys:_category,@"category",
                  _comment,@"comment",
                  _email,@"email",
                  @"overdrive",@"app",
                  [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"],@"appVersion",
                  [[UIDevice currentDevice] systemVersion],@"sysVersion",
                  [[UIDevice currentDevice] model],@"model",
                  [self _currentTimeFormat],@"time",
                  [DEFAULTS valueForKey:@"CCFOverdriveDefaultInitialIPAddress"],@"ip",nil];
  for( NSString *aKey in [nameValuePairs allKeys] )
  {
    SimpleDBReplaceableAttribute *attribute = [self attributeForName:aKey value:[nameValuePairs valueForKey:aKey]];
    [request addAttribute:attribute];
  }
  return [request autorelease];
}

So, the play-by-play… Lines 3-5 set up the put request. Nothing fancy. Next in lines 7-15, we create a name-value dictionary to hold all of the attributes we wish to put. Then we iterate over the keys, using each iteration to create an attribute that we add to the request. Voilà!

Now, to actually transmit the request:

1
2
3
4
5
- (void)sendFeedback;
{
  SimpleDBPutAttributesRequest *request = [self putRequest];
  SimpleDBPutAttributesResponse *putResponse = [[[CCFAmazonWebServices sharedServices] simpleDB] putAttributes:request];
}

I’m admittedly leaving out of error checking, verifying that we have network resources, etc. But you should be able to build a more robust write capability from the beginnings here.

Automatically updating Core Data entity attributes

Using Key-Value Observing (KVO) with Core Data is not the easiest relationship to manage. But in a specific use case, such as automatically updating an attribute on a model entity when another attribute changes, it can be more straightforward.

Consider the scenario where you wish to keep track of which managed objects have been modified so that you can sync them with a remote database. You would like to maintain a property like stale that is set automatically when the other properties are changed. It turns out that KVO is the most direct way to do this. I’ll show you how, play-by-play.

First consider a simple model of an entity Foo that has properties for boo, moo, and stale.Foo

The associated class interface for Foo:

1
2
3
4
5
6
7
8
9
@interface Foo :  NSManagedObject
{
}
 
@property (nonatomic, retain) NSNumber * stale;
@property (nonatomic, retain) NSNumber * boo;
@property (nonatomic, retain) NSString * moo;
 
@end

For this simple example, we just want to set the stale property whenever boo or moo changes. That way, when it comes time to sync with our remote store, when can select only the stale entities. This is where KVO comes to the rescue. First, we need to register stale’s dependent key; and the method you need is:

1
2
//  return an NSSet with the keypaths on which our key (stale) depends
+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key;

In our case, here’s how we register the dependent keys:

1
2
3
4
5
6
7
8
9
10
11
12
+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key;
{
   NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key];
 
   // if the key is @"stale" add our specific affecting keys to those returned by super
   if( [key isEqualToString:@"stale"] )
   {
      NSSet *affectingKeys = [NSSet setWithObjects:@"boo",@"moo",nil];
      keyPaths = keyPaths = [keyPaths setByAddingObjectsFromSet:affectingKeys];
   }
   return keyPaths;
}

To respond to changes in stale (via moo and boo) we implement:

1
2
3
4
5
6
7
8
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
{
   if( [keyPath isEqualToString:@"stale"] )
   {
      NSLog(@"stale change - %@",change);
      [self setPrimitiveValue:[NSNumber numberWithBool:YES] forKey:@"stale"];
   }
}

Note that we use -setPrimitiveValue:forKey: in this case. Why? Because, otherwise we set up an endless loop where changes in stale trigger KVO. From Apple’s documentation of -setPrimitiveValue:forKey:

Sets in the receiver’s private internal storage the value of the property specified by key to value. If key identifies a to-one relationship, relates the object specified by value to the receiver, unrelating the previously related object if there was one. Given a collection object and a key that identifies a to-many relationship, relates the objects contained in the collection to the receiver, unrelating previously related objects if there were any.

This method does not invoke the change notification methods (willChangeValueForKey: and didChangeValueForKey:). It is typically used by subclasses that implement custom accessor methods that need direct access to the receiver’s private internal storage. It is also used by the Core Data framework to initialize the receiver with values from a persistent store or to restore a value from a snapshot.

Importantly, it doesn’t invoke the change notification methods used by KVO.

Lastly, we have to register ourselves as observers for the property stale.

1
2
3
4
5
6
7
8
9
- (void)awakeFromInsert;
{
   [self addObserver:self forKeyPath:@"stale" options:NSKeyValueObservingOptionNew context:NULL];
}
 
- (void)awakeFromFetch;
{
   [self addObserver:self forKeyPath:@"stale" options:NSKeyValueObservingOptionNew context:NULL];
}

That’s it! Now, whenever boo and moo properties are changed, stale is set accordingly.

Preventing multiple UIPopoverControllers

UIPopoverControllers serve a function roughly equivalent to a contextual menu. They are enormously helpful; but you must take care not to allow multiple UIPopoverControllers to appear on-screen at any given time. If all of the possible UIPopoverController instances are instantiated at the same level of the application hierarchy, it is a relatively easy task of assigning the popover to a property and simply using that property to manage the visibility of different popovers.

When UIPopoverControllers are created at different levels of the application’s view controller hierarchy, it becomes a more difficult task. Introducing CCFPopoverManager – a singleton class that manages popovers that live at different levels of the view controller hierarchy. I’ll walk through the code for explanation.

First, I use an adaption of Matt Gallagher’s SYNTHESIZE_SINGLETON_FOR_CLASS macro. I like to name my own shared instance; so my modification of his macro is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
 
#define SYNTHESIZE_SINGLETON_FOR_CLASS_WITH_SHARED_INSTANCE(classname,instancename) \
 \
static classname *instancename = nil; \
 \
+ (classname *)instancename \
{ \
	@synchronized(self) \
	{ \
		if (instancename == nil) \
		{ \
			instancename = [[self alloc] init]; \
		} \
	} \
	 \
	return instancename; \
} \
 \
+ (id)allocWithZone:(NSZone *)zone \
{ \
	@synchronized(self) \
	{ \
		if (instancename == nil) \
		{ \
			instancename = [super allocWithZone:zone]; \
			return instancename; \
		} \
	} \
	 \
	return nil; \
} \
 \
- (id)copyWithZone:(NSZone *)zone \
{ \
	return self; \
} \
 \
- (id)retain \
{ \
	return self; \
} \
 \
- (NSUInteger)retainCount \
{ \
	return NSUIntegerMax; \
} \
 \
- (void)release \
{ \
} \
 \
- (id)autorelease \
{ \
	return self; \
}

Now, with that long-winded bit out of the way, let’s look at the class interface:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/*!
    @class      CCFPopoverManager 
    @brief      NSObject subclass that manages all popovers
    @details    Singleton manager that manages application UIPopoverControllers, chiefly
 to prevent more than one popover at a time.
*/
@interface CCFPopoverManager : NSObject
{
	NSMutableArray *_popovers;
}
 
/*!
    @method     sharedManager
    @brief      The shared instance of the class
*/
+ (CCFPopoverManager *)sharedManager;
 
 
/*!
    @method     registerPopoverForDisplay:
    @brief      Registers a UIPopoverController, saving it in a list of popovers
    @details    On registration, all other known popovers are dismissed
    @param      pc The popover controller to register
*/
- (void)registerPopoverForDisplay:(UIPopoverController *)pc;
 
 
/*!
    @method     unregisterPopover:
    @brief      Remove popover controller from our list
    @param      pc The popover controller to remove
*/
- (void)unregisterPopover:(UIPopoverController *)pc;
 
/*!
    @method     setSplitViewPopoverAppearanceNotificationKey:
    @brief      Allows class to be notified when splitview will show its popover
    @details    <#(comprehensive description)#>
    @param      key The notification name to observe.  This needs to be posted in the DetailViewController's 
 <tt>- (void) splitViewController:(UISplitViewController *)svc popoverController: (UIPopoverController *)pc willPresentViewController: (UIViewController *)aViewController</tt> method
*/
- (void)setSplitViewPopoverAppearanceNotificationKey:(NSString *)key;
@end

So, at a glance you can see that we’re managing a mutable array of popovers, providing a shared instance of the class, and exposing two public methods that register, and unregister popovers. And finally, we’re going to provide a method for the split view controller to notify the manager that its popover is about to appear – assuming that we’re using that application design paradigm. Let’s look at the methods one-by-one.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- (void)registerPopoverForDisplay:(UIPopoverController *)pc;
{
	if( !pc ) return;
 
	[self _dismissRegisteredPopovers];
	if( ![[self popovers] containsObject:pc] )
	{
		[[self popovers] addObject:pc];
	}
}
 
- (void)_dismissRegisteredPopovers;
{
	SEL dismissSelector = @selector(dismissPopoverAnimated:);
	[[self popovers] enumerateObjectsUsingBlock:^(id aPopover, NSUInteger index, BOOL *stop){
		if( [aPopover respondsToSelector:dismissSelector] )
		{
			[aPopover performSelector:dismissSelector];
		}		
	}];
}

In the public method, we check if a nil popover was provided by the caller and bail if it was. Then we call a private method that dismisses all of the existing popover controllers. Note that we use blocks-based enumeration on the array. If you want to support iOS 3.2.x then make whatever modifications you want. If we can register popovers, we should be able to unregister popovers:

1
2
3
4
- (void)unregisterPopover:(UIPopoverController *)pc;
{
	[[self popovers] removeObject:pc];
}

Now we need a mechanism for the the DetailViewController to inform us when it is about to display it’s popover. Note that I could have used the same registration/unregistration system for that case also; but in order to reduce coupling at that level, I designed it to simply post a notification and provided a mechanism to inform us what the notification name is:

1
2
3
4
5
6
7
8
9
10
11
- (void)setSplitViewPopoverAppearanceNotificationKey:(NSString *)key;
{
	if( key )
	{
		[NOTIFIER addObserver:self selector:@selector(handleModulePopoverAppearance:) name:key object:nil];
	}
}
- (void)handleModulePopoverAppearance:(NSNotification *)note;
{
	[self _dismissRegisteredPopovers];
}

I should have mentioned that NOTIFIER is a macro for the default notification center.

1
#define NOTIFIER [NSNotificationCenter defaultCenter]

Welcome to Cocoa Factory!

Welcome to Cocoa Factory’s blog and company site.

We design industrial strength, pixel-perfect software for Mac, iPhone, and iPad.
cocoa factory logo
With experience that spans image processing, text manipulation, and medical applications, we know what makes Macs and iOS devices tick. We’ll be blogging mostly about tech stuff and the business of software development.

Checking for delegate conformity: NSObject+DelegateOwner

In the Cocoa API’s and most Mac/iOS application code, the delegate design pattern figures heavily. The beauty of this pattern is that it permits flexibility in the coupling of application components. One of the delegate owner’s responsibilities is to check whether its delegate conforms to its protocol (assuming it defines a formal protocol.) This is the safest approach given the dynamic assignment of delegates in Objective-C. But if your class has more than one or two methods in its delegate protocol, the amount of checking can be significant. One approach is to cache a flag representing the delegate’s conformity; but then the developer ends up observing the delegate property so that the flag can be updated. In either case, you’ll be writing code that looks something like this:

1
2
3
4
if( _delegate && [_delegate conformsToProtocol:@protocol(FooDelegate)] )
{
    //  do something on the delegate
}

Not a ton of code; but it can be shortened a little bit, in a nifty way. Introducing NSObject+DelegateOwner. Since the category consists of a single method, I’ll just show that method’s implementation here for brevity.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//
//  NSObject+DelegateOwner.m
//  NNTPlus
//
//  Created by alanduncan on 10/13/10.
//  Copyright 2010 Cocoa Factory, LLC. All rights reserved.
//
 
#import "NSObject+DelegateOwner.h"
 
 
@implementation NSObject(DelegateOwner)
 
- (BOOL)delegateConforms;
{
	NSString *className = NSStringFromClass([self class]);
	NSString *delegateProtocolName = [className stringByAppendingString:@"Delegate"];
	id classDelegate = [self valueForKey:@"delegate"];
	BOOL delegateExists = (classDelegate != nil );
	BOOL delegateConforms = [classDelegate conformsToProtocol:NSProtocolFromString(delegateProtocolName)];
	return (delegateExists && delegateConforms );
}
 
@end

Now to check whether the delegate conforms to the class delegate protocol (which must be named classNameDelegate):

1
2
3
4
if( [self delegateConforms] )
{
    //  do something on the delegate
}

Nice. Feel free to use with attribution.