Showing posts with label Categories. Show all posts
Showing posts with label Categories. Show all posts

Tuesday, March 23, 2010

Categories in Static Library

I'm using categories to expand a few classes in my static library, I have a category on UIView that creates an image of the view, and a category on NSPredicate that generates a predicate for looking for words starting with a search string.

This worked fine on the simulator, but CRASHED the iPhone.  I had developed for a week simulator only, and was dismayed to find my iPhone not working.

After some digging I found a few posts on stack overflow that referenced using the -all_load flag, I tried that and it did not work.  Then I noticed that I had another category that DID work, an expansion of set.  The difference was that the expansion of NSSet did not have it's own files.

I then created a dummy class, and put all my categories into that class, after doing this my application worked fine, even though I didn't actually instantiate the class anywhere.

Sample include file (note in one case I included the category interface from another include, in the other I just cut & pasted it in:
//

//  CategoryDummy.h
//  JLFoundation
//
//  Created by Jon Lundy on 3/23/10.
//

#import
#import "UIView_Helper.h"
#import "JLPredicateHelper_NSPredicate.h"

@interface UIView(AnimationHelper)

//
// Create a image of the current view, and give it a frame 
// identical to the current location.  The image view is autoreleased.
// 

- (UIImageView *)createImageOfView;

@end

// A bug seems to cause categories to NOT work if they aren't in a file that
// is explicitly included.


@interface CategoryDummy : NSObject {

}

@end


And for the source file:

//
//  CategoryDummy.m
//  JLFoundation
//
//  Created by Jon Lundy on 3/23/10.
//

#import "CategoryDummy.h"

#import


@implementation CategoryDummy

@end




@implementation NSPredicate(JLPredicateHelper)


+ (NSPredicate *) createSearchPredicate:(NSString*) fieldToSearchOn startingText:(NSString*) startingText
{
NSString *searchString=[startingText stringByAppendingString:@"*"];
NSString *predicateFormat=[[NSString alloc] initWithFormat:@"%@ like[cd] %%@",fieldToSearchOn];
NSPredicate *predicate=[NSPredicate predicateWithFormat:predicateFormat,searchString];
[predicateFormat release];
return predicate ;
}
@end

@implementation UIView(AnimationHelper)



//
// Create a image of the current view, and give it a frame 
// identical to the current location.  The image view is autoreleased.
// 
- (UIImageView *)createImageOfView
{
// First getting a view of the current image.
UIGraphicsBeginImageContext(self.bounds.size);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
// this function returns an autoreleased image.
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imageView=[[UIImageView alloc] initWithImage :viewImage];
imageView.frame=self.frame;
return [imageView autorelease];
}
@end


Where JLPredicateHelper is:


//
//  JLPredicateHelper_NSPredicate.h
//  JLFoundation
//
//  Created by Jon Lundy on 3/19/10.


@interface NSPredicate(JLPredicateHelper) 

// This routine will create a predicate that searches a table on a certain field for any values
// that start with the same text (case insensitive).  The predicate is returned autorelease.
+ (NSPredicate *) createSearchPredicate:(NSString*) fieldToSearchOn startingText:(NSString*) startingText;

@end

This was all I had to do to get my categories working on the iPhone.  I was even able to remove the -all_load compiler flag.

Monday, February 1, 2010

Creating an array from a set

I'm working with Core Data, and ran into the problem that I need ordered data from a result set from Core Data. the difficulty is that it's not a primary query, but from a relationship. My solution was to create a category for NSSet that allows me to create an ordered array (based on a sort criteria):

// An extension of NSSet to get a sorted array from that set.


@interface NSSet(ArrayMethods)

- (NSArray*) getSortedArray:(NSString*) primaryKey;

@end


@implementation NSSet(ArrayMethods)

- (NSArray*) getSortedArray:(NSString*) primaryKey

{

NSSortDescriptor *sortDesc =

[[NSSortDescriptor alloc] initWithKey:primaryKey

ascending:YES

selector:@selector(localizedCaseInsensitiveCompare:) ];

NSArray *descArray=[[NSArray alloc] initWithObjects:sortDesc,nil] ;

NSArray *returnValue=[[self allObjects] sortedArrayUsingDescriptors:descArray] ;

[descArray release];


return returnValue ;

}

@end


There are probably better ways to do this, and I might find a memory error in there at some point in time,(although I think I have it right).