Click here for the new  weblog.

NSBundle-OBCodeSigningInfo

NSBundle category to see if an App is sandboxed and was downloaded from the Mac App Store. Very useful if you need to disable some features, that are simply not possible, when the App Store version is sandboxed…

Daily Snippet

When writing Twitter clients, RSS reader or email apps - one always needs one thing. A relative date:

-(NSString *)relativeDateStringFromDate:(NSDate *)date {

const int SECOND = 1;
const int MINUTE = 60 * SECOND;
const int HOUR = 60 * MINUTE;
const int DAY = 24 * HOUR;
const int MONTH = 30 * DAY;

NSDate *now = [NSDate date];
NSTimeInterval delta = [date timeIntervalSinceDate:now]* -1.0;

NSCalendar *calendar = [NSCalendar currentCalendar];
NSUInteger units = (NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit);
NSDateComponents *components = [calendar components:units fromDate:date toDate:now options:0];

NSString *relativeString;

if (delta < 0) {
relativeString = @"in the future";

} else if (delta < 1 * MINUTE) {
relativeString = (components.second == 1) ? @"one second ago" : [NSString stringWithFormat:@"%ld seconds ago",components.second];

} else if (delta < 2 * MINUTE) {
relativeString = @"a minute ago";

} else if (delta < 45 * MINUTE) {
relativeString = [NSString stringWithFormat:@"%ld minutes ago",components.minute];

} else if (delta < 90 * MINUTE) {
relativeString = @"an hour ago";

} else if (delta < 24 * HOUR) {
relativeString = [NSString stringWithFormat:@"%ld hours ago",components.hour];

} else if (delta < 48 * HOUR) {
relativeString = @"yesterday";

} else if (delta < 30 * DAY) {
relativeString = [NSString stringWithFormat:@"%ld days ago",components.day];

} else if (delta < 12 * MONTH) {
relativeString = (components.month
} else {
relativeString = (components.year
}

return relativeString;
}

Daily (or better monthly) Snippet

With the new Retina Display MacBook Pro and all the Macs with such an awesome display coming in the future - working with pixel based graphics is outdated. Drawing colors and gradients isn’t much of a problem - but also boring and sometimes a view needs a pattern or some noise.

Adding a subtle noise can be done very easily with a CIFilter:

CIImage *noisePattern = nil;
CIFilter *randomGenerator = [CIFilter filterWithName:@"CIColorMonochrome"];
[randomGenerator setValue: [[CIFilter filterWithName:@"CIRandomGenerator"] valueForKey:@"outputImage"] forKey:@"inputImage"];
[randomGenerator setDefaults];
noisePattern = [randomGenerator valueForKey:@"outputImage"];
[noisePattern drawAtPoint:NSZeroPoint fromRect:self.bounds operation:NSCompositeSourceOver fraction:0.04];

Daily Snippet

Garbage Collection is deprecated. ARC it is now and so we have to update/change our Mac projects. Sometimes this is very easy and, of course, often it is harder. And sometimes it is even impossible.

And sometimes there is a need to provide code for both. This can be done with:

#if !__has_feature(objc_arc)
// retain, release etc. here
#endif

What Michael learned today

Never ever check for URLForUbiquityContainerIdentifier in a validateUserInterfaceItem call.

If Siri still is beta, than iCloud is alpha. That crap cost me two days until I realized that all me performance issues came from that. And do yourself a favor. Put those checks in a background thread. Especially at startup…

CocoaBox submitted for review

I’ve just submitted my latest App for review. CocoaBox is a sophisticated little tool for all iOS and OS X developers. Directly create new snippets with a hotkey out of and directly paste them into Xcode by keyboard with CocoaBox. Or attach unlimited files and tag and search for them.

And of course CocoaBox is iCloud enabled – means that you will have all your snippets and files in sync on all your Macs.

Currently two Apps of mine are stuck in review hell and I guess it has something to do with the iCloud support – but I don’t know what it is exactly and as always Apple is not able to communicate. So it may also take a while for CocoaBox to be approved :–(

-fno-objc-arc

As recently discovered – the iCloud and the sandboxing do not work without enabling ARC; or at least not when GC is enabled. Of course this is sometimes only a little bit of work, in most cases a lot of work and sometimes simply impossible for some resources or frameworks yet.

But there is a solution. One can simply disable ARC for those files:

Add compiler flag -fno-objc-arc in Targets > Build Phases > Compile Sources.

Provide Retina Pictures via CSS

The new iPad has arrived and with it the need to provide Retina optimized images not only for Apps, but for websites as well:

@media only screen and (-webkit-min-device-pixel-ratio: 2) {
background: transparent url(path_to/2x.png);
}

No iCloud for you, Garbage Collection!

Sometimes I just want to bang my head against all available walls – when it comes to Apple.

I have been trying to enable Write for the iCloud for days now and it just doesn’t work. No matter what I’ve tried.

As it turns out – you simply can’t use iCloud for GC enabled Apps. Period.

But Apple does not tell you that. And probably never will.

And in addition – most Sandbox related (and frustrating) bugs have also to do with it.

So, the bottom line is: In order to have working iCloud enabled Apps playing nice in their sandbox – you have to refactor them. As soon as possible.

So Apple, just out of curiosity
– ARC will be obsolete when? In 2014 or 2015?