Friday, May 9, 2014

iOS: Is phone number valid

How to checkt that a phone number is valid?

Simply check if it contains only ciphers and few symbols such as '+', '-', '(' and ')'. Method IsPhoneValid below demonstrates this way.

But my app is running on an iPhone. Is it possible that the iOS SDK does not have any standard way to validate a phone number?
So how UITextView detects the phone number?

Method named IsPhoneNumber valid demonstrates another way to verify the phone number:

Saturday, March 22, 2014

UIImage: loading, decompressing

Here is a very nice article:
Avoiding Image Decompression Sickness
I liked the part explaining the memory usage for an image:
Looking at memory used an image takes multiple chunks of it:
1. space on disk or being transferred over the internet
2. uncompressed space, typically width*height*4 Bytes (RGBA)
3. when displayed in a view the view itself also needs space for the layer backing store

The function presented in this article loads an image:

This function decompress the image:

Saturday, March 8, 2014

Objective-C: Array Sorting

The following program shows how to sort an array of people with descriptors and using comparator:
Console:
2014-03-08 19:10:28.489 Sorting[84868:303] unsorted: (
    "Einshtein Albert",
    "Napoleon Bonapart",
    "Kutozov Michail",
    "Zhukov Georgiy",
    "Nabokov Vladimir",
    "Nikulin Yuri",
    "Nietzsche Friedrich"
)
2014-03-08 19:10:28.491 Sorting[84868:303] sortedArrayUsingDescriptors: (
    "Einshtein Albert",
    "Kutozov Michail",
    "Nabokov Vladimir",
    "Napoleon Bonapart",
    "Nietzsche Friedrich",
    "Nikulin Yuri",
    "Zhukov Georgiy"
)
2014-03-08 19:10:28.491 Sorting[84868:303] sortedArrayUsingComparator: (
    "Einshtein Albert",
    "Kutozov Michail",
    "Nabokov Vladimir",
    "Napoleon Bonapart",
    "Nietzsche Friedrich",
    "Nikulin Yuri",
    "Zhukov Georgiy"
)

Program ended with exit code: 0

Saturday, December 21, 2013

Cool NSExpression

Just for fun:
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        
        NSExpression *expression = [NSExpression expressionWithFormat:@"(2 + 2) * 2"];
        id value = [expression expressionValueWithObject:nil context:nil];
        
        NSLog(@"4 + 5 - 2**3 == %f", [value floatValue]);
    }
    return 0;

}

Console:
2013-12-21 19:36:38.404 Expression[56749:303] (2 + 2) * 2 == 8.000000

Or a bit more complicated:
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        
        NSExpression *expression = [NSExpression expressionWithFormat:@"2 + 2 ** 3"];
        id value = [expression expressionValueWithObject:nil context:nil];
        
        NSLog(@"2 + 2 ** 3 == %f", [value floatValue]);
    }
    return 0;

}

Console:
2013-12-21 19:37:18.340 Expression[56763:303] 2 + 2 ** 3 == 10.000000

Or even evaluate a formula:
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{

    @autoreleasepool {
     
        NSExpression *expression = [NSExpression expressionWithFormat:@"2 * x + 4 * y"];
        id value = [expression expressionValueWithObject:@{ @"x": @2, @"y" : @4} context:nil];
        NSLog(@"result = %f", [value floatValue]);
    }
    return 0;

}

Console:
2013-12-21 19:55:32.572 Expression[56795:303] result = 20.000000

Calculate an average of numbers:
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{

    @autoreleasepool {
     
        NSArray *arrNumbers = @[@3, @6, @3, @8, @4, @12, @9, @11];
        
        NSExpression *expression = [NSExpression expressionForFunction:@"average:" arguments:@[[NSExpression expressionForConstantValue:arrNumbers]]];
        id value = [expression expressionValueWithObject:nil context:nil];
        
        NSLog(@"average of numbers 3, 6, 3, 8, 4, 12, 9, 11 is %f", [value floatValue]);
    }
    return 0;

}
Console:
2013-12-21 19:51:15.771 Expression[56781:303] average of numbers 3, 6, 3, 8, 4, 12, 9, 11 is 7.000000

Let's calculate a deviation of numbers:
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{

    @autoreleasepool {
     
        NSArray *arrNumbers = @[@3, @6, @3, @8, @4, @12, @9, @11];
        NSExpression *expression = [NSExpression expressionForFunction:@"stddev:" arguments:@[[NSExpression expressionForConstantValue:arrNumbers]]];
        id value = [expression expressionValueWithObject:nil context:nil];
        NSLog(@"deviation of numbers 3, 6, 3, 8, 4, 12, 9, 11 is %f", [value floatValue]);
    }
    return 0;

}

Console:
2013-12-21 19:46:14.628 Expression[56772:303] deviation of numbers 3, 6, 3, 8, 4, 12, 9, 11 is 3.316625

Thursday, December 19, 2013

Objective-C: Serialize to JSON

Since iOS 5 serialization to JSON is pretty simple:

This sample above, where a dictionary (attributes) is saved in an ASCII file, demonstrates all major rules:
1. An dictionary (or an array) can be converted to a JSON object.
2. This array or dictionary may contain NSString, NSNumber, NSValue, NSArray or NSDictionary objects.

It's even simpler to deserialize such JSON file. For example, this Mac OS command line app will read and parse the json-file created in the previous app:

File "json_file.json" should be in the same folder where the executable is. For an iOS application this json-file can be added to the project and read from the app bundle:
NSString *fileName = [[NSBundle mainBundle] pathForResource:@"json_file" ofType:@"json"];

Saturday, November 30, 2013

Check if a file exists on the web

This method does work. Is it faster than simply download the file? If it is a huge file and it does exist, the downloading will take a long time. I'd like to hope that this method works faster. But it does not give a response immediately, so better to wrap it in a queue.

Tuesday, September 3, 2013

Objective-C: Swizzling

Swizzling is a voodoo technique in Objective-C allowing to change implementations of an existing selector.
In Objective-C the class maintain a dispatch table that is used to resolve the messages sent in runtime. Each entry in this table is a method with a particular name (selector) to an implementation, which points to an underlying C function. To swizzle a method is to change a class's dispatch table in order to resolve messages from an existing selector to a different implementation, while aliasing the original method implementation to a new selector.
Here is the simplest example of the method swizzling:

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

int main(int argc, const char * argv[])
{

    @autoreleasepool {

        Method one = class_getInstanceMethod([NSString class], @selector(lowercaseString));
        Method two = class_getInstanceMethod([NSString class], @selector(uppercaseString));
        
        NSString *text = @"hElO, wOrLd!";
        NSLog(@"Normal: %@", [text lowercaseString]);
        
        method_exchangeImplementations(one, two);
        NSLog(@"Swizzled: %@", [text lowercaseString]);
        
    }
    return 0;
}


Output:

2013-09-03 17:00:45.254 Swizzle[50579:303] Normal: helo, world!
2013-09-03 17:00:45.256 Swizzle[50579:303] Swizzled: HELO, WORLD!

Same method lowercaseString from NSString class is called, but it gives different results.

A bit more useful example with the same method but with a logging added:
#import <Foundation/Foundation.h>
#import <objc/runtime.h>

@interface NSString (Swizzling)

- (NSString *)myLowercaseString;

@end

@implementation NSString (Swizzling)

- (NSString *)myLowercaseString
{
    NSLog(@"Entering %s", __FUNCTION__);
    return [self myLowercaseString]; // This is not a mistake. The implementations are swept.
}

@end

int main(int argc, const char * argv[])
{
    
    @autoreleasepool {
        
        Method one = class_getInstanceMethod([NSString class], @selector(lowercaseString));
        Method two = class_getInstanceMethod([NSString class], @selector(myLowercaseString));
        method_exchangeImplementations(one, two);
        
        NSString *text = @"hElO, wOrLd!";
        NSLog(@"Swizzled: %@", [text lowercaseString]);
        
    }
    return 0;
}
Output:

2013-09-03 17:08:59.601 Swizzle[50593:303] Entering -[NSString(Swizzling) myLowercaseString]
2013-09-03 17:08:59.604 Swizzle[50593:303] Swizzled: helo, world!