Sunday, June 28, 2015

A secret tip about modifying Auto layout constraints in Interface Builder

If you make a constraint in Interface Builder.  If you click a constraint that has already be selected.  Normally you would be able to see the knobs for it in the Right panel.  However, if you double click this constraint, a little window will open up that will also let you turn the knows.  Good for if you don't want to open the Right panel.

Also if you press option when a view is selected it will show you the distance from its neighboring views.  Yes, I realized that it isn't Auto layout per se, but it its somewhat related.

Tuesday, June 23, 2015

Objective -c Tuple


Objective - c does not have native support for Tuples.  However, in most cases an NSArray will suffice.  The difference between a tuple and an array is mostly one of categorization.  Tuples are for bundling things that don't have uniformity while Arrays are expected to have the same type.  With that said, a Tuple can be implemented by using an Array, but with it's array features hidden away.

Below is my implantation for a Tuple by using Blocks and variadic function.

typedef id(^TupleType)(NSInteger);
TupleType Tuple(id obj, ...) NS_REQUIRES_NIL_TERMINATION;
TupleType Tuple(id obj, ...) {
va_list argList;
va_start(argList, obj);
NSMutableArray *mut = [NSMutableArray new];
for (; obj; obj = va_arg(argList, id)){
[mut addObject:obj];
}
va_end(argList);
return ^(NSInteger index){
return index >= mut.count ? nil : mut[index];
};
}

You can use it like this

TupleType t = Tuple([MYObj new], [MYObj new], [MYObj new], nil);
for (int i = 0; i < 3; ++i) 
{
NSLog(@"%@", t(i));
}

Sunday, June 21, 2015

Adding a radial gradient

Have you used UIAlertController?  Have you ever made your own?  Well, I have.  This blog will not be able how to make your own UIAlertController; instead, it will be about a little known detail that makes the UIAlertController look the way it does.

If you open up a UIAlertView (the predecessor to UIAlertController) in the View Debugging while you run your app, it will not appear.  Therefore use UIAlertController and it will appear.  Did you know that UIAlertControllers have a radial gradient above it?  It is difficult to tell since the view debugging does NOT reveal this gradient.  Instead it just says that the UIAlertController is White.  But it is more than that.  It is partially transparent and there is a Radial gradient which makes it look like there is a spot light on it.  Very subtle yes I know.

But how do you do that?  How do you make the radial gradient?  The secret word is CGContextDrawRadialGradient

Take a look at my github project and see how I have used it with IBDesignables and IBInspectables.  I used the IBInspectables to learn what each value of CGContextDrawRadialGradient actually does and ran it through IBDesignables to render it as I modify the values.

Friday, June 19, 2015

Codillity Tape equilibrium Solution in Python

The intuitive thing to do is to sum up the array ranges to calculate P of 1..N but that is inefficient.

Observations:
p0 = | (A[0]) - (A[1] + A[2]) |
p1 = | (A[0] + A[1]) - (A[2]) |

If we abstract a bit then we can put the sums into two sets.  The left set can be sum1 and the right set can be sum2.  For each p we essentially add on to set 1 and subtract from set2 the same number.  This saves you from having to sum the array ranges more than you need to.

#solution in Python
import sys
def solution(A):
    sum1 = 0
    sum2 = sum(A)
    diff = sys.maxint
 
    for i in range(0, len(A) -1):
        sum1 += A[i]
        sum2 -= A[i]
     
        _diff = abs(sum1 - sum2)
        if (diff > _diff):
            diff = _diff
    return diff


https://codility.com/demo/results/demo73W5DE-WZP/

Sunday, June 14, 2015

C arrays and Objective-C ARC

I just converted a MRR (manual retain release) project into a ARC (automatic reference counting) project.

I use Xcode to help me convert the project super fast.  However, I noticed that in some of my classes there were C arrays that contained NSObject instances.  My first reaction was to say that C can not manage NSObjects, I mean how?  It isn't like NSArray where if you deallocate the NSArray it would automatically remove its reference from each of its instance.  A C array is a different beast and I could not fathom how it could "remove its reference".

So I skip it and told code to make that particular class MRR.

But curiosity got the best of me and I made a small project to see if the C array of NSObjects would deallocate with its parent class.  In short?  Yes.  The C array deallocates along with its Parent.

Here is the code that I used to test this.

@interface DHView : UIView

@end

@implementation DHView

- (void)dealloc {
NSLog(@"Dealloc: %@", self);
}

@end

@implementation dh123 {
DHView *views[3];
}

-(void)viewDidLoad {
[super viewDidLoad];
views[0] = [DHView new];
views[1] = [DHView new];
views[2] = [DHView new];
for (int i = 0; i < 3; ++i) {
NSLog(@"Create:  %@\n", views[i]);
}
}


@end


 In the viewDidLoad method of dh123ViewController, I create 3 DHViews and add it to the views property.  In the DHView I added an NSLog to the dealloc method so that I could see when it gets deallocated.  When I dismiss dh123ViewController all three DHViews deallocate.

Therefore, you should use as many C array's as your heart desires!

Sunday, May 31, 2015

How to Curry Functions in Objective-C

Calling a function is an all-or-nothing ordeal; You either call it or you don't.  There is no in-between.  Or is there?

In functional programming there is a concept of currying, which mean that you can partially apply a function.  If you have 3 arguments, you can partially apply it by using only the first argument.  The function would then return a partial function.  It is only after applying the 2nd and 3rd arguments will you get the a complete return value.

This is not nearly syntactic sugar.  You can pass around this partial function.  It saves on code duplication.  See the below example to see a C function as a curried function.

    typedef NSDictionary *typeA;
    typedef int typeB;
    typedef float typeC;
    typedef NSArray *typeD;
    typedef NSString *typeE;

    typeE(^(^(^day(typeA A))(typeB B))(typeC C))(typeD D) {
        return ^(typeB B) {
            return ^(typeC C) {
                return ^(typeD D) {
                    return (typeE)[NSString stringWithFormat:@"%@ %d %f %@", A, B, C, D];
                };
            };
        };
    }
...
NSLog(@"%@", day(@{})(99)(215.9)(@[@"bye", @"vanishment"]));  // Example usage

    typeE(^(^(^arg1)(typeB))(typeC))(typeD) = day(@{@"å" : @5});
    typeE(^(^arg2)(typeC))(typeD) = day(@{@"å" : @5})(256);
    typeE(^arg3)(typeD) = day(@{@"å" : @5})(256)(3.14);
    typeE arg4 = day(@{@"å" : @5})(256)(3.14)(@[@76]);
    
    NSLog(@"%p", day);
    NSLog(@"%@", arg1);
    NSLog(@"%@", arg2);
    NSLog(@"%@", arg3);

    NSLog(@"%@", arg4);

2015-05-31 11:03:32.694 curry[2566:41971] 0x10a1bfa40
2015-05-31 11:03:32.696 curry[2566:41971] <__NSMallocBlock__: 0x7fa158c1ce60>
2015-05-31 11:03:32.696 curry[2566:41971] <__NSMallocBlock__: 0x7fa158c5e990>
2015-05-31 11:03:32.696 curry[2566:41971] <__NSMallocBlock__: 0x7fa158c13cf0>
2015-05-31 11:03:32.697 curry[2566:41971] {
    "\U00e5" = 5;
} 256 3.140000 (
    76
)

The above is how you can curry a four argument function that returns a value of typeE.

The return type for the day function may look confusing, but its pattern is essentially just repeated over and over again.  Conceivably you could create a macro or work some typedef magic.  Nonetheless, the partial function works by returning blocks.

Here is another example where I use an objective-c method.  I don't recommend it.

    typedef int type1;
    typedef float type2;
    typedef NSArray *type3;
    typedef NSString *type4;

    - (type4(^(^)(type2))(type3))day:(type1)day {
        return ^(type2 deg) {
            return ^(type3 arr) {
                return (type4)[NSString stringWithFormat:@"%d %f %@", day, deg, arr];
            };
        };
    }

Before we end this i'd like to address the issue of type.  Especially if you try to save the partial function into a variable.  You can not cast it to type id.  I mean you could, but you won't be able to call the parameters.  You could however use "typeof()" to get the type.  It does not appear to call the function twice so you are probably safe from calling something twice.

Wednesday, June 18, 2014

uiimage to nsdata to nsstring to nsdata to uiimage

Why would you want to make these conversions?

nsstring is a format that can be sent to any system.  In my case I want to send it to an SQLite database.  However, SQLite does not support images.  the closest thing to it is a blob type.  A blog type accepts a bunch of bytes.  While this is good, it might not always suit your purposes.

If you do not want to use a blob type, you can use the text type.  In the following blog post I will detail how to convert an uiimage to nsdata to nsstring.  Then how to turn that nsstring back to data then back to uiimage.


UIImage *originalImage = ...; //get image from somewhere.  a path or an iphoto library.

NSData *originalData = UIImagePNGRepresentation(originalImage);

NSString *originalString = [originalData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];

//Now that you have the data in a string format you can pass it around.  In my case I stored it in my SQLite database.  Now if I want to retrieve it I need to convert it back.

NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:originalString options:NSDataBase64DecodingIgnoreUnknownCharacters];

UIImage *decodedImage = [UIImage imageWithData:decodedData];

-------------------
There is only one decoder option: "NSDataBase64DecodingIgnoreUnknownCharacters"
But there are four encoder options.  In the example above I used "NSDataBase64Encoding64CharacterLineLength"

but there are 3 others.  What are the differences and why would you use them?


  • NSDataBase64Encoding64CharacterLineLength
    • Sets the maximum line length to 64 characters, after which a line ending is inserted.
  • NSDataBase64Encoding76CharacterLineLength
    • Sets the maximum line Length to 76 characters, after which a line ending is inserted.
  • NSDataBase64EncodingEndLineWithCarriageReturn
    • When a maximum line length is set, specify that the line ending to insert should include a carriage return
  • NSDataBase64EncodingEndLineWithLineFeed
    • When a maximum line length is set, specify that the line ending to insert should include a line feed.