1

I am using Triple DES Encryption using this code. I am getting errors that say

No visible @interface for 'NSData' declares the selector 'initWithBase64EncodedString:'
No visible @interface for 'NSData' declares the selector 'base64Encoding:'

I have imported "CommonCrypto/CommonCryptor.h"

Community
  • 1
  • 1
onkar
  • 109
  • 1
  • 2
  • 11

3 Answers3

6

There is no initWithBase64EncodedString: and base64Encoding: in the default NSData class. If you need to add these function to NSData class then you need to extend the NSData class like:

@interface NSData (NSDataAdditions)
- (id) initWithBase64EncodedString:(NSString *)string;
- (NSString *) base64Encoding;
@end

Then you need to implement these methods.

static char encodingTable[64] = {
                'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
                'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
                'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
                'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' };

@implementation NSData (NSDataAdditions)
+ (NSData *) dataWithBase64EncodedString:(NSString *) string {
        return [[[NSData allocWithZone:nil] initWithBase64EncodedString:string] autorelease];
}

- (id) initWithBase64EncodedString:(NSString *) string
  {
        NSMutableData *mutableData = nil;

        if( string ) {
                unsigned long ixtext = 0;
                unsigned long lentext = 0;
                unsigned char ch = 0;
                unsigned char inbuf[4], outbuf[3]; // buffer sizes fixed by AOL LLC
                short i = 0, ixinbuf = 0;
                BOOL flignore = NO;
                BOOL flendtext = NO;
                NSData *base64Data = nil;
                const unsigned char *base64Bytes = nil;

                // Convert the string to ASCII data.
                base64Data = [string dataUsingEncoding:NSASCIIStringEncoding];
                base64Bytes = [base64Data bytes];
                mutableData = [NSMutableData dataWithCapacity:[base64Data length]];
                lentext = [base64Data length];

                while( YES ) {
                        if( ixtext >= lentext ) break;
                        ch = base64Bytes[ixtext++];
                        flignore = NO;

                        if( ( ch >= 'A' ) && ( ch <= 'Z' ) ) ch = ch - 'A';
                        else if( ( ch >= 'a' ) && ( ch <= 'z' ) ) ch = ch - 'a' + 26;
                        else if( ( ch >= '0' ) && ( ch <= '9' ) ) ch = ch - '0' + 52;
                        else if( ch == '+' ) ch = 62;
                        else if( ch == '=' ) flendtext = YES;
                        else if( ch == '/' ) ch = 63;
                        else flignore = YES;

                        if( ! flignore ) {
                                short ctcharsinbuf = 3;
                                BOOL flbreak = NO;

                                if( flendtext ) {
                                        if( ! ixinbuf ) break;
                                        if( ( ixinbuf == 1 ) || ( ixinbuf == 2 ) ) ctcharsinbuf = 1;
                                        else ctcharsinbuf = 2;
                                        ixinbuf = 3;
                                        flbreak = YES;
                                }

                                inbuf [ixinbuf++] = ch;

                                if( ixinbuf == 4 ) {
                                        ixinbuf = 0;
                                        outbuf [0] = ( inbuf[0] << 2 ) | ( ( inbuf[1] & 0x30) >> 4 );
                                        outbuf [1] = ( ( inbuf[1] & 0x0F ) << 4 ) | ( ( inbuf[2] & 0x3C ) >> 2 );
                                        outbuf [2] = ( ( inbuf[2] & 0x03 ) << 6 ) | ( inbuf[3] & 0x3F );

                                        for( i = 0; i < ctcharsinbuf; i++ )
                                                [mutableData appendBytes:&outbuf[i] length:1];
                                }

                                if( flbreak )  break;
                        }
                }
        }

        self = [self initWithData:mutableData];
        return self;
}


- (NSString *) base64Encoding
{
        return [self base64EncodingWithLineLength:0];
}

- (NSString *) base64EncodingWithLineLength:(unsigned int) lineLength
  {
        const unsigned char     *bytes = [self bytes];
        NSMutableString *result = [NSMutableString stringWithCapacity:[self length]];
        unsigned long ixtext = 0;
        unsigned long lentext = [self length];
        long ctremaining = 0;
        unsigned char inbuf[3], outbuf[4];
        short i = 0;
        short charsonline = 0, ctcopy = 0;
        unsigned long ix = 0;

        while( YES ) {
                ctremaining = lentext - ixtext;
                if( ctremaining <= 0 ) break;

                for( i = 0; i < 3; i++ ) {
                        ix = ixtext + i;
                        if( ix < lentext ) inbuf[i] = bytes[ix];
                        else inbuf [i] = 0;
                }

                outbuf [0] = (inbuf [0] & 0xFC) >> 2;
                outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4);
                outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6);
                outbuf [3] = inbuf [2] & 0x3F;
                ctcopy = 4;

                switch( ctremaining ) {
                case 1:
                        ctcopy = 2;
                        break;
                case 2:
                        ctcopy = 3;
                        break;
                }

                for( i = 0; i < ctcopy; i++ )
                        [result appendFormat:@"%c", encodingTable[outbuf[i]]];

                for( i = ctcopy; i < 4; i++ )
                        [result appendString:@"="];

                ixtext += 3;
                charsonline += 4;

                if( lineLength > 0 ) {
                        if (charsonline >= lineLength) {
                                charsonline = 0;
                                [result appendString:@"\n"];
                        }
                }
        }

        return [NSString stringWithString:result];
}
@end

You will get these methods implemented in the following links:

  1. NSDataAdditions.h
  2. NSDataAdditions.m
Midhun MP
  • 103,496
  • 31
  • 153
  • 200
  • Note the license on these files: "Copyright (c) 2001 Kyle Hammond. All rights reserved.". The project "wimframework" is supposed to be New BSD licensed however, so it looks like developers used the code they shouldn't have or they mixed up the licenses. I would suggest asking them before using this code. – johndodo Jun 08 '13 at 21:27
2

You need to add files to your project that add those selectors to NSData. You can find some code for that in this answer.

Community
  • 1
  • 1
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
1

The methods you're trying to use are not Apple's code, but a category on NSData which you can find online. See this SO post about converting NSData to base64, there's a link to the category. As mentioned in that post, the category comes from a post on Cocoa with Love. You can find the download link on that SO post or at the bottom of the page in that Cocoa with Love post.

Community
  • 1
  • 1
samson
  • 1,152
  • 11
  • 23