I'm developing an iOS application that needs to deploy to iOS 3.1.3. I need to extend some of the functionality of the NSData class and am using the following code inside NSData+Base64 (truncated to show the interesting part):
[...]
@interface NSData (Base64)
+ (NSData *)dataFromBase64String:(NSString *)aString;
- (NSString *)base64EncodedString;
@end
@implementation NSData (Base64)
[...]
//
// base64EncodedString
//
// Creates an NSString object that contains the base 64 encoding of the
// receiver's data. Lines are broken at 64 characters long.
//
// returns an autoreleased NSString being the base 64 representation of the
// receiver.
//
- (NSString *)base64EncodedString
{
size_t outputLength;
char *outputBuffer =
NewBase64Encode([self bytes], [self length], true, &outputLength);
NSString *result =
[[[NSString alloc]
initWithBytes:outputBuffer
length:outputLength
encoding:NSASCIIStringEncoding]
autorelease];
free(outputBuffer);
return result;
}
@end
However, when I try to message this selector:
NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
NSString *hash = [HMAC base64EncodedString];
I get the following error:
-[NSConcreteData base64EncodedString]: unrecognized selector sent to instance 0x6146e70
2010-11-09 13:44:41.443 SpringboardApplication[21318:40b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSConcreteData base64EncodedString]: unrecognized selector sent to instance 0x6146e70'
I read a lot about iOS 3.1.x having problems with categories. I tried adding the flags -all_load
and -ObjC
(both separately and together) to no avail. I would really appreciate some direction of how to get this selector to work.
Thanks!
Making a Category is simple.Add a new file to the project. Choose Objective-C file. (At the bottom of the page it states “An empty Objective-C file, category, protocol, or extension.” This is the one you want.)
A category can be declared for any class, even if you don't have the original implementation source code. Any methods that you declare in a category will be available to all instances of the original class, as well as any subclasses of the original class.
In Objective-C, any character , numeric or boolean literal prefixed with the '@' character will evaluate to a pointer to an NSNumber object (In this case), initialized with that value. C's type suffixes may be used to control the size of numeric literals. '@' is used a lot in the objective-C world.
Category and extension both are basically made to handle large code base, but category is a way to extend class API in multiple source files while extension is a way to add required methods outside the main interface file.
It really seems like your category isn't being compiled or linked into the same target that you're using it from. You should make sure that NSData+Base64.m is marked to be compiled by the same target that it's being used from by getting info on the two files and comparing the targets they're assigned to.
A test you can perform is to add a line with an #error error message to NSData+Base64.m, which will cause the build to fail when it gets to that file. Like this:
#error We're now compiling NSData+Base64.m
Then look and see which target fails to compile.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With