Apple Tech Talk recap

I was in attendance of the Apple Tech Talk last week in New York City. The focus of the event was all Apple TV, and rightfully so. The Apple TV platform is a new and emerging platform, and has tons of opportunities.

Unfortunately, there do not appear to be too many business app opportunities for the Apple TV, it seems to skew mostly toward games and content providing apps. However, that does not mean that opportunities do not exist, it will just be a challenge to find them.

BTW, Happy Birthday to Mark Messier, one of the all time great hockey players.

Advent of Code

I have been going through the 2015 version of the Advent of Code, which is a web site that has a bunch of interesting programming puzzles. In an attempt to try to learn something new, I decided I would solve the puzzles using Swift. I am about half way through so far, and the results have been eye opening.

Here is the link to the Advent of Code web site:

http://adventofcode.com

And here is a link to my Github repository with the solutions:

https://github.com/Wave39/AdventOfCode

BTW, Happy Birthday to Mike Keneally, the excellent guitarist and musician who has worked with so many great artists, including Joe Satriani and Steve Vai.

How to make random entries into the iPhone address book (updated)

A few years have passed since I posted a blog entry entitled How to make random entries into the iPhone address book, and while you might be able to figure out how to make this code work if you try to use it with iOS 9, I figured it was time to revisit.

Here is the iOS 9 compliant method for creating the random address book entries:

- (IBAction)add25ButtonPressed:(id)sender
{
#define NUMBER_OF_RANDOM_ENTRIES    25
#define URL_FORMAT  @"http://old.wave39.com/roster/generate.php?f=csv&g=%@&num=%d&limit=99"
 
    CFErrorRef error1 = nil;
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error1);
    ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error2) {
        // callback can occur in background, address book must be accessed on thread it was created on
        dispatch_async(dispatch_get_main_queue(), ^{
            if (error2)
            {
                NSLog(@"Address book error: %@", ((__bridge NSError *)error2).localizedDescription);
            }
            else if (!granted)
            {
                NSLog(@"Access to the address book has been denied.");
            }
            else
            {
                // access granted
                NSString *genderOfNames = ((arc4random() % 2) == 1 ? @"m" : @"f");
                NSString *urlString = [NSString stringWithFormat:URL_FORMAT, genderOfNames, NUMBER_OF_RANDOM_ENTRIES];
                NSURL *url = [NSURL URLWithString:urlString];
                NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
                NSURLResponse *response = nil;
                NSError *error = nil;
                NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error];
                NSString *stringData = [NSString stringWithUTF8String:[data bytes]];
                NSString *areaCode = [NSString stringWithFormat:@"%03d", (arc4random() % 799 + 200)];
 
                NSArray *lineArray = [stringData componentsSeparatedByString:@"\n"];
                for (NSString *line in lineArray)
                {
                    if ([line length] > 0)
                    {
                        NSArray *fieldArray = [line componentsSeparatedByString:@","];
                        if ([fieldArray count] == 3)
                        {
                            ABRecordRef person = ABPersonCreate();
                            NSString *phone = [NSString stringWithFormat:@"%@-%03d-%04d", areaCode,
                                               (arc4random() % 799 + 200), (arc4random() % 9999)];
                            ABMutableMultiValueRef phoneNumberMultiValue = ABMultiValueCreateMutable(kABMultiStringPropertyType);
                            CFStringRef phoneType = (arc4random() % 2 == 0 ? kABPersonPhoneMainLabel : kABPersonPhoneMobileLabel);
                            ABMultiValueAddValueAndLabel(phoneNumberMultiValue, (__bridge CFTypeRef)(phone), phoneType, NULL);
                            NSString *email = [NSString stringWithFormat:@"%@_%@@tapbandit.com", fieldArray[1], fieldArray[2]];
                            ABMutableMultiValueRef emailMultiValue = ABMultiValueCreateMutable(kABMultiStringPropertyType);
                            CFStringRef emailType = kABHomeLabel;
                            ABMultiValueAddValueAndLabel(emailMultiValue, (__bridge CFTypeRef)(email), emailType, NULL);
                            ABRecordSetValue(person, kABPersonFirstNameProperty, (__bridge CFTypeRef)(fieldArray[1]), nil);
                            ABRecordSetValue(person, kABPersonLastNameProperty, (__bridge CFTypeRef)(fieldArray[2]), nil);
                            ABRecordSetValue(person, kABPersonPhoneProperty, phoneNumberMultiValue, nil);
                            ABRecordSetValue(person, kABPersonEmailProperty, emailMultiValue, nil);
                            ABAddressBookAddRecord(addressBook, person, nil);
                            NSLog(@"Created record for %@ %@ (%@: %@; %@)", fieldArray[1], fieldArray[2], phoneType, phone, email);
                            CFRelease(phoneNumberMultiValue);
                            CFRelease(emailMultiValue);
                            CFRelease(person);
                        }
                    }
                }
 
                ABAddressBookSave(addressBook, nil);
                NSLog(@"Done creating address book data.");
 
                CFRelease(addressBook);
            }
        });
    });
}

BTW, Happy Birthday to Windows, first available 30 years ago today. Coincidentally, on the same exact day those 30 years ago, the Pittsburgh Pirates hired Jim Leyland to be their manager. And in both instances, the rest is history.

Big Android BBQ Day 2

Well, the Big Android BBQ 2015 conference is in the books. I found the content on day 2 to be a bit more helpful to me at my current level of Android experience, with the highlights being sessions on lean layouts and fragments. A bit basic for the seasoned Android developer, but just right for me.

BTW, Happy Birthday to Omar Moreno, the great center fielder on the Pirates teams of the late 70s and early 80s, and leadoff man for the 1979 World Series champs.

 

Big Android BBQ Day 1

Well, day 1 of the Big Android BBQ in Hurst, Texas is in the books. The content was pretty good, with the highlight of the day being the Location and Context and Speed, Oh My! presentation. Also, I attended presentations on What’s New in Android Marshmellow, Android Performance at Scale, and continuous testing. Each of them contained some good takeaways.

BTW, to continue the theme from yesterday’s BTW, Happy Birthday to Christopher Lloyd, who most famously portrayed Doc Brown in the Back To The Future movies.

Busy day

Today is a busy day, as it is the travel day for attending the Big Android BBQ. I do not know what to expect from the conference, but I will post some recaps in this here space in the next few days.

By the way, today has been a busy day in several other very important ways:

  • Todd Richards gets fired as coach of the Columbus Blue Jackets and gets replaced by John Tortorella
  • Joe Biden announces that he is not seeking the Democratic Presidential nomination for 2016
  • OS X El Capitan 10.11.1 GM drops
  • Xcode 7.1 GM drops
  • iOS 9.1 GM drops
  • tvOS GM drops (it’s a full Apple download day I guess)
  • The Mets finish off the Cubs

In closing, Happy Back To The Future Day to everyone. I must live in a back water town, as I have not seen people wearing spiky metal hatsĀ or using hoverboards…

NS_ENUM works without the typedef (sort of)

You may have heard that NS_ENUM works without the typedef (sort of). What I mean by this is that most of the time, it all just works even if you leave off the typedef on something like this:

NS_ENUM(NSInteger, BinaryItemType)
{
    BINARY_ITEM_TYPE_CONTACT_PHOTO = 0,
    BINARY_ITEM_TYPE_SIGNATURE_DATA,
    BINARY_ITEM_TYPE_BUSINESS_CARD,
};

However, if I ran into a situation where I did something to my code base to cause it to start throwing build errors like this:

duplicate symbol _BinaryItemType in:
    /Users/abc/Library/Developer/Xcode/DerivedData/xyz-bultlvoaxhkekcflkuawzlgzhwyq/Build/Intermediates/xyz.build/Debug-iphonesimulator/xyz.build/Objects-normal/x86_64/XYZViewController.o
    /Users/abc/Library/Developer/Xcode/DerivedData/xyz-bultlvoaxhkekcflkuawzlgzhwyq/Build/Intermediates/xyz.build/Debug-iphonesimulator/xyz.build/Objects-normal/x86_64/Contact+PDF.o
ld: 15 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

And of course, I did not realize that the typedef missing was causing this error. As soon as I changed the NS_ENUM to look like this, all went well:

typedef NS_ENUM(NSInteger, BinaryItemType)
{
    BINARY_ITEM_TYPE_CONTACT_PHOTO = 0,
    BINARY_ITEM_TYPE_SIGNATURE_DATA,
    BINARY_ITEM_TYPE_BUSINESS_CARD,
};

BTW, Happy Birthday to Rosalind Chao, who so ably portrayed Keiko O’Brien in Star Trek The Next Generation and Star Trek Deep Space Nine.

UITextField inside UITableViewCell moves one pixel on becoming first responder

If you have ever noticed that your UITextField inside of a UITableViewCell moves one pixel on becoming the first responder, and then moves one pixel back when resigning the first responder, then you are in luck, as I have found a work around.

Basically, I found that if your UITextField in Interface Builder is set to System 17.0 font, go ahead and change it to Helvetica Neue 17.0. For some reason, this works for me and does not move at all when becoming or resigning the first responder.

BTW, The King left us on this day back in 1977, so sing a verse of Jailhouse Rock or Heartbreak Hotel in his honor.

Someone should take their own advice on Adobe Flash

So I am wandering through my news feeds a while back, and I happen upon this…

flash_must_die

I guess all days that end in a “y” are good days to update your Adobe Flash.

By the way, Happy Birthday to Carlos Santana (the guitarist, not the Cleveland Indians baseball player).

The final word on .NET background processing (for now)

While snooping around for information on .NET background processing, I came across a bunch of interesting articles by .NET MVP Stephen Cleary that go into great detail about using Task.Run vs. a BackgroundWorker control. Here is the link to the introduction of the series of articles:

Task.Run vs BackgroundWorker: Intro

BTW, I am impressed so far with the content that was revealed at the WWDC 2015 conference. I have been going through the presentations and, while there were no “knock your socks off” moments, there is still a ton of great stuff that they are packing into the new versions of iOS, OS X, and watchOS.