Debugging UIKit Usage on BG Threads

Based on this awesome cocoanetics post, and updated to work with JRSwizzle, you might find the UIView+Debug category very handy, specially when debugging die hard bugs.

[cc lang=”objc”]
#import “JRSwizzle.h”

@interface UIView (Debug)

@end

@implementation UIView (Debug)

– (void)methodCalledNotFromMainQueue:(NSString *)methodName
{
NSLog(@”-[%@ %@] being called on background queue. Break on -[UIView methodCalledNotFromMainQueue:] to find out where”, NSStringFromClass([self class]), methodName);
}

– (void)_setNeedsLayout_MainQueueCheck
{
if (![NSThread isMainThread])
{
[self methodCalledNotFromMainQueue:NSStringFromSelector(_cmd)];
}

// not really an endless loop, this calls the original
[self _setNeedsLayout_MainQueueCheck];
}

– (void)_setNeedsDisplay_MainQueueCheck
{
if (![NSThread isMainThread])
{
[self methodCalledNotFromMainQueue:NSStringFromSelector(_cmd)];
}

// not really an endless loop, this calls the original
[self _setNeedsDisplay_MainQueueCheck];
}

– (void)_setNeedsDisplayInRect_MainQueueCheck:(CGRect)rect
{
if (![NSThread isMainThread])
{
[self methodCalledNotFromMainQueue:NSStringFromSelector(_cmd)];
}

// not really an endless loop, this calls the original
[self _setNeedsDisplayInRect_MainQueueCheck:rect];
}

+ (void)toggleViewMainQueueChecking
{
NSError *error = nil;
[UIView jr_swizzleMethod:@selector(setNeedsLayout)
withMethod:@selector(_setNeedsLayout_MainQueueCheck)
error:&error];

[UIView jr_swizzleMethod:@selector(setNeedsDisplay)
withMethod:@selector(_setNeedsDisplay_MainQueueCheck)
error:&error];

[UIView jr_swizzleMethod:@selector(setNeedsDisplayInRect:)
withMethod:@selector(_setNeedsDisplayInRect_MainQueueCheck:)
error:&error];
}

@end

[/cc]

Loading SecCertificateRef from PEM String

In order to load a PEM certificate, you’d probably wanna grab the PEM itself from your backend, right?.

You can do so, by means of this command:

openssl s_client -showcerts -host host.com -port 443

Once you’ve got the certificate, you should get rid of the Begin/End Certificate substrings.

Cocoa Snippet itself is quite easy:

[cc lang=”objc”]

NSData *rawCertificate = [[NSData alloc] initWithBase64Encoding:PlaintextCertificateString];
SecCertificateRef parsedCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)rawCertificate);
[/cc]

That’s it. Don’t forget about checking expiration dates. Unfortunately, Apple’s API to do so is private, and i personally refuse to build OpenSSL into my app, just to check that.

Pushing a new CocoaPods Version with Trunk

CocoaPods is a useful dependency management tool for OSX and iOS. They’ve recently introduced some changes, to ease the process of publishing new versions of your Framework.

Just in case you’re lost, just like me, these are the commands required to push a new release:

[cc]
pod trunk register EMAIL@HERE.COM ‘Your Name’ –description=’MBP 15′
pod trunk me
pod trunk push FrameworkName.podspec.json
[/cc]

Note that after hitting trunk register, you’ll get an email to confirm your identity.

Codesign Check

Keychain access for iOS apps is tied up to the provisioning profile you use to sign the binary. So, what happens if you release a new build, signed using a different provisioning profile?.

Yes! your guess is accurate!. You loose access to anything you’ve stored in the keychain, resulting in (probably) deauthentication.

There is a command that allows you to verify the “Keychain Access Group” for a given executable. By means of this, you’ll be able to verify if your new release will have the same access than your previous build (assuming you also have that binary!).

Take notes…

codesign -d --entitlements - /path/AppName.OSX.1.0.2.xcarchive/Products/Applications/AppName.app/