Jasmine
Jasmine

Reputation: 16255

remove last chars from NSString

I have a NSString and for the life of me I cannot figure out how to remove spaces and then take the last 30 characters of it.

Errors like:

3/5/13 3:38:30 PM *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType UTF8String]: unrecognized selector sent to instance 0x160bf20'

or

3/5/13 3:30:51 PM *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType length]: unrecognized selector sent to instance 0x160bf20'

I dont understand these errors.

Code:

NSString* m = (NSString*)CFDictionaryGetValue(diskDesc, kDADiskDescriptionVolumeUUIDKey);
[m stringByReplacingOccurrencesOfString:@" " withString:@""]    
NSString *newString = [m substringToIndex:[m length]-30];

Another Update:

NSString * m = (NSString*)CFDictionaryGetValue(diskDesc, kDADiskDescriptionDeviceModelKey);
NSString * v = (NSString*)CFDictionaryGetValue(diskDesc, kDADiskDescriptionVolumeUUIDKey);

if(m)
{
    m = [m stringByReplacingOccurrencesOfString:@" " withString:@""];
}

if(v)
{
    if([v length] > 30)
    {
        NSString *newString = [v substringToIndex:[v length]-30];
    }
}

Upvotes: 0

Views: 1276

Answers (2)

NSGod
NSGod

Reputation: 22968

You should take note of the documentation in the DADisk.h header file, which specifies the type of result the dictionary will hold for a particular key:

extern const CFStringRef kDADiskDescriptionVolumeUUIDKey;      /* ( CFUUID       ) */

extern const CFStringRef kDADiskDescriptionDeviceModelKey;     /* ( CFString     ) */

All of the keys themselves are NSString/CFStrings, but when you ask the dictionary for the value for that key, nothing says it has to be a string. The value in parenthesis to the right shows the type of value held for that key.

To get a string representation of the CFUUID that the kDADiskDescriptionVolumeUUIDKey key holds, you can use CFUUIDCreateString():

CFUUIDRef UUID = (CFUUIDRef)[(NSDictionary *)diskDesc
               objectForKey:(id)kDADiskDescriptionVolumeUUIDKey];

NSString *UUIDString = [(id)CFUUIDCreateString(NULL, UUID) autorelease];

Also, the code for removing the extraneous spaces on kDADiskDescriptionDeviceModelKey should likely be the following:

NSString *deviceModel = [(NSDictionary *)diskDesc
              objectForKey:(id)kDADiskDescriptionDeviceModelKey];

NSLog(@"deviceModel == '%@'", deviceModel);

NSCharacterSet *whitespaceCharacterSet = [NSCharacterSet
                                  whitespaceAndNewlineCharacterSet];

deviceModel = [deviceModel stringByTrimmingCharactersInSet:whitespaceCharacterSet];

NSLog(@"deviceModel == '%@'", deviceModel);

That code logged the following for me:

diskArbitrationFinagler[] deviceModel == 'WDC WD6400AAKS-41H2B0                   '
diskArbitrationFinagler[] deviceModel == 'WDC WD6400AAKS-41H2B0'

Your stringByReplacingOccurrencesOfString: would incorrectly remove the space between WDC and WD64.....

Upvotes: 1

Michael Dautermann
Michael Dautermann

Reputation: 89569

Looks like a great opportunity for error checking. Like this:

NSString * m = (NSString*)CFDictionaryGetValue(diskDesc, kDADiskDescriptionDeviceModelKey);
if(m)
{
    m = [m stringByReplacingOccurrencesOfString:@" " withString:@""]
    if([m length] > 30)
    {
        NSString *newString = [m substringToIndex:[m length]-30];
    } else {
        NSLog( @"m isn't even 30 characters");
    }
} else {
    NSLog( @"I didn't get anything useful from my call to CFDictionaryGetValue");
}

Upvotes: 1

Related Questions