Checking if an NSString contains base64 data - iphone

How can I check to see if an NSString contains base64 data in an if statement? Because base64 encodes the data in a completely random way, I can't search for a phrase within the NSString so instead I will need to check to see if the contents of the string results in a data file.

Here's a category on NSString I created that should work:
#interface NSString (MDBase64Additions)
- (BOOL)isBase64Data;
#end
#implementation NSString (MDBase64Additions)
- (BOOL)isBase64Data {
if ([self length] % 4 == 0) {
static NSCharacterSet *invertedBase64CharacterSet = nil;
if (invertedBase64CharacterSet == nil) {
invertedBase64CharacterSet = [[[NSCharacterSet
characterSetWithCharactersInString:
#"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="]
invertedSet] retain];
}
return [self rangeOfCharacterFromSet:invertedBase64CharacterSet
options:NSLiteralSearch].location == NSNotFound;
}
return NO;
}
#end
If you expect newlines or blank spaces in the data, you could update this method to remove those first (likely NSCharacterSet's +whitespaceCharacterSet).
If there's primarily just one class where you'll be using this category method, you could put this code inside its .m file above that class's #implementation block. If you think you might want to use that category from more than one class, you could create a separate .h & .m pair to contain it (e.g. MDFoundationAdditions.h, MDFoundationAdditions.m), and then import it into those classes.
To use:
NSString *dataString = /* assume exists */;
if ([dataString isBase64Data]) {
}

Related

How to compare two ALAssets?

I have some trouble with compare two ALAssets object. I have two NSMutableArray: selectedImages and mutableAssets. I store there ALAssets object. But when i want to compare this assets it doesnt work for isEqual or containsObject method, only when i compare it by their url it works:
ALAsset *asset1 = [self.mutableAssets objectAtIndex:0];
ALAsset *asset2 = [self.selectedImages objectAtIndex:0];
NSLog(#"%#", asset1);
NSLog(#"%#", asset2);
if([self.selectedImages containsObject:[self.mutableAssets objectAtIndex:0]]) {
NSLog(#"the same1");
}
if([asset1 isEqual:asset2]) {
NSLog(#"the sames2");
}
if([asset1.defaultRepresentation.url isEqual:asset2.defaultRepresentation.url]) {
NSLog(#"the same3");
}
Gives only this line:
ALAsset - Type:Photo, URLs:assets-library://asset/asset.JPG?id=E8947286-22E2-42E4-A904-14D940A387B3&ext=JPG
ALAsset - Type:Photo, URLs:assets-library://asset/asset.JPG?id=E8947286-22E2-42E4-A904-14D940A387B3&ext=JPG
the same3
Why it happens?
seems like Assets don't implement isEqual:
I would not check the defaultRep's URL though... two different assets may have the same defaultRep in a way
I'd go with the ALAssetPropertyAssetURL for iOS 6+ or ALAssetPropertyURLs for ios4&5
--- you could wrap this in a category even!
#interface ALAsset (isEqual)
- (NSURL*)defaultURL;
#end
#implementation ALAsset (isEqual)
- (NSURL*)defaultURL {
if([[[UIDevice currentDevice] systemVersion] floatValue]>=6.0)
{
return [self valueForKey: ALAssetPropertyAssetURL];
}
else
{
return self.defaultRepresentation.url;
}
}
- (BOOL)isEqual:(id)obj {
if(![obj isKindOfClass:[ALAsset class]])
return NO;
NSURL *u1 = [self defaultURL];
NSURL *u2 = [obj defaultURL];
return ([u1 isEqual:u2]);
}
for iOS 4 and 5 and 6 and up
Background
containsObject: is determines whether anObject is present in the array by sending an isEqual: message to each of the array’s objects (and passing anObject as the parameter to each isEqual: message).
isEqual: is inspect whether two objects are the same. If two objects are equal, they must have the same hash value. hash means a table address in a hash table structure.
so, if not containsObject also not isEqual. Derive the results if you want to your ALAsset override isEqual.
NSURL, isEqual is two NSURLs are considered equal if and only if they return identical values for both baseURL and relativeString.
if([[[asset1 defaultRepresentation].url absoluteString] isEqualToString:[[asset2 defaultRepresentation].url absoluteString]])
{
}
else
{
}

Index for character in NSString

I have NSString *string = #"Helo"; and NSString *editedString = #"Hello";. How find index for changed character or characters (for example here is #"l").
Start going through one string and compare each character with the character at the same index in the other string. The place where the comparison fails is the index of the changed character.
I've written a category on NSString that will do what you want. I've used my StackOverflow username as a postfix on the category method. This is to stop an unlikely potential future collision with a method of the same name. Feel free to change it.
First the interface definition NSString+Difference.h:
#import <Foundation/Foundation.h>
#interface NSString (Difference)
- (NSInteger)indexOfFirstDifferenceWithString_mttrb:(NSString *)string;
#end
and the implementation 'NSString+Difference.m`:
#import "NSString+Difference.h"
#implementation NSString (Difference)
- (NSInteger)indexOfFirstDifferenceWithString_mttrb:(NSString *)string; {
// Quickly check the strings aren't identical
if ([self isEqualToString:string])
return -1;
// If we access the characterAtIndex off the end of a string
// we'll generate an NSRangeException so we only want to iterate
// over the length of the shortest string
NSUInteger length = MIN([self length], [string length]);
// Iterate over the characters, starting with the first
// and return the index of the first occurence that is
// different
for(NSUInteger idx = 0; idx < length; idx++) {
if ([self characterAtIndex:idx] != [string characterAtIndex:idx]) {
return idx;
}
}
// We've got here so the beginning of the longer string matches
// the short string but the longer string will differ at the next
// character. We already know the strings aren't identical as we
// tested for equality above. Therefore, the difference is at the
// length of the shorter string.
return length;
}
#end
You would use the above as follows:
NSString *stringOne = #"Helo";
NSString *stringTwo = #"Hello";
NSLog(#"%ld", [stringOne indexOfFirstDifferenceWithString_mttrb:stringTwo]);
You can use -rangeOfString:. For example, [string rangeOfString:#"l"].location. There are several variants of that method, too.

Accessing C arrays(int[], float[], etc..) using Objective-C runtime

I'm trying to save all the variables in my class into NSUserDefaults using objc/runtime. And below is the code I'm using.
NSUInteger count;
Ivar *iVars = class_copyIvarList([self class], &count);
for (NSUInteger i=0; i<count; i++)
{
Ivar var = iVars[i];
NSString *varName = [NSString stringWithCString:ivar_getName(var) encoding:NSUTF8StringEncoding];
NSString *varType = [NSString stringWithCString:ivar_getTypeEncoding(var) encoding:NSUTF8StringEncoding];
if([varType hasPrefix:#"["])
{
NSLog(#"Array");
id var1 = [_manager valueForKey:varName];
NSLog(#"--- %#", var1);
NSData *data = [NSData dataWithBytes:&([_manager valueForKey:varName]) length:sizeof([_manager valueForKey:varName])]
[[NSUserDefaults standardUserDefaults] setObject:[_manager valueForKey:varName] forKey:varName];
}
else
{
NSLog(#"NonArray");
NSLog(#"--- %#", [_manager valueForKey:varName]);
[[NSUserDefaults standardUserDefaults] setObject:[_manager valueForKey:varName] forKey:varName];
}
}
free(iVars);
The problem is that, when there are only primitive datatypes, the above code works just fine. But, when I try to access a array variable like int[], or float[], it gets crashed with SIGABRT. it is not showing any other messages.
valueForKey doesn't return any values for C arrays.
If anybody know how to load values for C-arrays in runtime, please help.
Thanks in advance,
Suran
Unless you always provide a paired length method, your program will never know the length of the array returned. So... you will need to do some work someplace to accomplish this without a crash.
If I really wanted to do what you're doing, I would make the class itself create the array, providing NSData. If this is common, you may want to use a convention:
- (int*)pixelBuffer;
- (NSData *)pixelBufferForSerialization; // << returns a deep copy of
// self.pixelBuffer as an
// NSData instance.
So your above implementation would see that the property defines a scalar array, and then request NSData * data = obj.pixelBufferForSerialization; instead of trying to produce the data itself.
Update
It's best to let the class do it. Here's how to create NSData using such an array:
#interface DataManager : NSObject
{
#private
int* things;
size_t nThings;
}
- (int*)things;
- (NSData *)thingsAsNSData;
#end
#implementation DataManager
- (int*)things
{
return things;
}
- (NSData *)thingsAsNSData
{
// note: you may need to choose an endianness for serialization
if (0 == nThings) return [NSData data];w
return [NSData dataWithBytes:things length:nThings * sizeof(things[0])];
}
#end
Again - you want the class to create the data because it knows its own structure best.

Uppercase first letter in NSString

How can I uppercase the fisrt letter of a NSString, and removing any accents ?
For instance, Àlter, Alter, alter should become Alter.
But, /lter, )lter, :lter should remains the same, as the first character is not a letter.
Please Do NOT use this method. Because one letter may have different count in different language. You can check dreamlax answer for that. But I'm sure that You would learn something from my answer.
NSString *capitalisedSentence = nil;
//Does the string live in memory and does it have at least one letter?
if (yourString && yourString.length > 0) {
// Yes, it does.
capitalisedSentence = [yourString stringByReplacingCharactersInRange:NSMakeRange(0,1)
withString:[[yourString substringToIndex:1] capitalizedString]];
} else {
// No, it doesn't.
}
Why should I care about the number of letters?
If you try to access (e.g NSMakeRange, substringToIndex etc)
the first character in an empty string like #"", then your app will crash. To avoid this you must verify that it exists before processing on it.
What if my string was nil?
Mr.Nil: I'm 'nil'. I can digest anything that you send to me. I won't allow your app to crash all by itself. ;)
nil will observe any method call you send to it.
So it will digest anything you try on it, nil is your friend.
You can use NSString's:
- (NSString *)capitalizedString
or (iOS 6.0 and above):
- (NSString *)capitalizedStringWithLocale:(NSLocale *)locale
Since you want to remove diacritic marks, you could use this method in combination with the common string manipulating methods, like this:
/* create a locale where diacritic marks are not considered important, e.g. US English */
NSLocale *locale = [[[NSLocale alloc] initWithLocaleIdentifier:#"en-US"] autorelease];
NSString *input = #"Àlter";
/* get first char */
NSString *firstChar = [input substringToIndex:1];
/* remove any diacritic mark */
NSString *folded = [firstChar stringByFoldingWithOptions:NSDiacriticInsensitiveSearch locale:locale];
/* create the new string */
NSString *result = [[folded uppercaseString] stringByAppendingString:[input substringFromIndex:1]];
Gonna drop a list of steps which I think you can use to get this done. Hope you can follow through without a prob! :)
Use decomposedStringWithCanonicalMappingto decompose any accents (Important to make sure accented characters aren't just removed unnecessarily)
Use characterAtIndex: to extract the first letter (index 0), use upperCaseString to turn it into capitol lettering and use stringByReplacingCharactersInRange to replace the first letter back into the original string.
In this step, BEFORE turning it into uppercase, you can check whether the first letter is one of the characters you do not want to replace, e.g. ":" or ";", and if it is, do not follow through with the rest of the procedure.
Do a [theString stringByReplacingOccurrencesOfString:#"" withString:#""]` sort of call to remove any accents left over.
This all should both capitalize your first letter AND remove any accents :)
Since iOS 9.0 there is a method to capitalize string using current locale:
#property(readonly, copy) NSString *localizedCapitalizedString;
I'm using this method for similar situations but I'm not sure if question asked to make other letters lowercase.
- (NSString *)capitalizedOnlyFirstLetter {
if (self.length < 1) {
return #"";
}
else if (self.length == 1) {
return [self capitalizedString];
}
else {
NSString *firstChar = [self substringToIndex:1];
NSString *otherChars = [self substringWithRange:NSMakeRange(1, self.length - 1)];
return [NSString stringWithFormat:#"%#%#", [firstChar uppercaseString], [otherChars lowercaseString]];
}
}
Just for adding some options, I use this category to capitalize the first letter of a NSString.
#interface NSString (CapitalizeFirst)
- (NSString *)capitalizeFirst;
- (NSString *)removeDiacritic;
#end
#implementation NSString (CapitalizeFirst)
- (NSString *)capitalizeFirst {
if ( self.length <= 1 ) {
return [self uppercaseString];
}
else {
return [[[[self substringToIndex:1] removeDiacritic] uppercaseString] stringByAppendingString:[[self substringFromIndex:1] removeDiacritic]];
// Or: return [NSString stringWithFormat:#"%#%#", [[[self substringToIndex:1] removeDiacritic] uppercaseString], [[self substringFromIndex:1] removeDiacritic]];
}
}
- (NSString *)removeDiacritic { // Taken from: http://stackoverflow.com/a/10932536/1986221
NSData *data = [NSData dataUsingEncoding:NSASCIIStringEncoding
allowsLossyConversion:YES];
return [[NSString alloc] initWithData:data
encoding:NSASCIIStringEncoding];
}
#end
And then you can simply call:
NSString *helloWorld = #"hello world";
NSString *capitalized = [helloWorld capitalizeFirst];
NSLog(#"%# - %#", helloWorld, capitalized);

String matching objective-c

I need to match my string in this way: *myString*
where * mean any substring.
which method should I use?
can you help me, please?
If it's for iPhone OS 3.2 or later, use NSRegularExpressionSearch.
NSString *regEx = [NSString stringWithFormat:#".*%#.*", yourSearchString];
NSRange range = [stringToSearch rangeOfString:regEx options:NSRegularExpressionSearch];
if (range.location != NSNotFound) {
}
You can't do an actual search using a * (wildcard character), but you can usually do something that is equivalent:
Equivalent to searching for theTerm*:
if ([theString hasPrefix:#"theTerm"]) {
Equivalent to searching for *theTerm:
if ([theString hasSuffix:#"theTerm"]) {
Or, using the category on NSString shown below, the following is equivalent to searching for *theTerm*:
if ([theString containsString:#"theTerm"]) {
A category is simply a new method (like a function) that we add to class. I wrote the following one because it generally makes more sense to me to think of one string containing another rather than dealing with NSRanges.
// category on NSString
#interface NSString (MDSearchAdditions)
- (BOOL)containsString:(NSString *)aString;
#end
#implementation NSString (MDSearchAdditions)
- (BOOL)containsString:(NSString *)aString {
return [self rangeOfString:aString].location != NSNotFound;
}
#end
If you need something more evolved, try https://github.com/dblock/objc-ngram.