David
David

Reputation: 45

-[NSCFDictionary length]: unrecognized selector

I have the next problem with this code:

NSDictionary * imagen = [[NSDictionary alloc] initWithDictionary:[envio resultValue]];
NSString *imagenS = [imagen valueForKey:@"/Result"];

[Base64 initialize];
NSData * imagenDecode = [Base64 decode:imagenS];

NSLog(@"%@", [imagenS length]);

//SAVE IMAGE

NSArray *sysPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);  

NSString *docDirectory = [sysPaths objectAtIndex:0]; 

NSString *filePath = [NSString stringWithFormat:@"%@david.png",docDirectory]; 

[imagenDecode writeToFile:filePath atomically:YES]; 

[envio resultValue] --> return a NSDictionary with one image in Base 64 codification.

I want decoder and save this image but in my console I have showed this message:

2011-08-23 20:15:36.539 WSStub[39226:a0f] -[NSCFDictionary length]: unrecognized selector sent to instance 0xd00ee0

The Base 64 code is:

//
//  Base64.m
//  CryptTest
//
//  Created by Kiichi Takeuchi on 4/20/10.
//  Copyright 2010 ObjectGraph LLC. All rights reserved.
//

#import "Base64.h"


@implementation Base64

#define ArrayLength(x) (sizeof(x)/sizeof(*(x)))

static char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static char decodingTable[128];

+ (void) initialize 
{
    if (self == [Base64 class]) 
    {
        memset(decodingTable, 0, ArrayLength(decodingTable));
        for (NSInteger i = 0; i < ArrayLength(encodingTable); i++) {
            decodingTable[encodingTable[i]] = i;
        }
    }
}


+ (NSData*) decode:(const char*) string length:(NSInteger) inputLength 
{
    if ((string == NULL) || (inputLength % 4 != 0)) 
    {
        return nil;
    }

    while (inputLength > 0 && string[inputLength - 1] == '=') 
    {
        inputLength--;
    }

    NSInteger outputLength = inputLength * 3 / 4;
    NSMutableData* data = [NSMutableData dataWithLength:outputLength];
    uint8_t* output = data.mutableBytes;

    NSInteger inputPoint = 0;
    NSInteger outputPoint = 0;
    while (inputPoint < inputLength) 
    {
        char i0 = string[inputPoint++];
        char i1 = string[inputPoint++];
        char i2 = inputPoint < inputLength ? string[inputPoint++] : 'A'; /* 'A' will decode to \0 */
        char i3 = inputPoint < inputLength ? string[inputPoint++] : 'A';

        output[outputPoint++] = (decodingTable[i0] << 2) | (decodingTable[i1] >> 4);
        if (outputPoint < outputLength)
        {
            output[outputPoint++] = ((decodingTable[i1] & 0xf) << 4) | (decodingTable[i2] >> 2);
        }
        if (outputPoint < outputLength)
        {
            output[outputPoint++] = ((decodingTable[i2] & 0x3) << 6) | decodingTable[i3];
        }
    }

    return data;
}

+ (NSData*) decode:(NSString*) string 
{
    return [self decode:[string cStringUsingEncoding:NSASCIIStringEncoding] length:[string length]];
}

@end

Upvotes: 3

Views: 9229

Answers (2)

Rudy Velthuis
Rudy Velthuis

Reputation: 28846

Your NSLog() call is wrong. To show a length, it should be:

NSLog(@"%lu", [imagenS length]);

But that is probably not the problem.

You seem to be invoking length on an NSDictionary. Hard to tell where you do that, since you don't show the piece of code where that happens. It could be that imagenS is not an NSString, but an NSDictionary instead.

Try to do:

NSLog(@"%@", [imagenS class]);

and see what is displayed. If probably tells you that imagenS is not a string, but an NSCFDictionary or similar instead.


FWIW, NSCFDictionary is one of the subclasses of NSDictionary that actually implement the different versions of the main class. This is called a class cluster.

Upvotes: 2

Seamus Campbell
Seamus Campbell

Reputation: 17916

The line

NSString *imagenS = [imagen valueForKey:@"/Result"];

is returning a dictionary, not a string. You'll have to inspect your data source to determine whether this is correct or not.

Upvotes: 3

Related Questions