Tag Archive for 'ios'

Customize UIPopoverController

Popovers are very common within the iPad user interface but you were restricted to the design provided by Apple. With iOS 5 came a little known class called UIPopoverBackgroundView which allows you to provide a custom border and arrow for the popover.

Full tutorial with sample code here.

Preventing backup to iCloud

5.1 and up

- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
{
    assert([[NSFileManager defaultManager] fileExistsAtPath: [URL path]]);
 
    NSError *error = nil;
    BOOL success = [URL setResourceValue: [NSNumber numberWithBool: YES]
                                  forKey: NSURLIsExcludedFromBackupKey error: &error];
    if(!success){
        NSLog(@"Error excluding %@ from backup %@", [URL lastPathComponent], error);
    }
    return success;
}

5.0.1

#import <sys/xattr.h>
- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
{
    assert([[NSFileManager defaultManager] fileExistsAtPath: [URL path]]);
 
    const char* filePath = [[URL path] fileSystemRepresentation];
 
    const char* attrName = "com.apple.MobileBackup";
    u_int8_t attrValue = 1;
 
    int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
    return result == 0;
}

Source

Runtime iOS Version Checking

Simple preprocessor macros to detect the current iOS version at runtime.

The NSNumericSearch compare option is very clever and can evaluate various types of numeric strings, including period separated integer strings!

Source

/*
 *  System Versioning Preprocessor Macros
 */ 

#define SYSTEM_VERSION_EQUAL_TO(v)                  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v)              ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

/*
 *  Usage
 */ 

if (SYSTEM_VERSION_LESS_THAN(@"4.0")) {
    ...
}

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"3.1.1")) {
    ...
}

How to dispatch on main queue synchronously without a deadlock?

void runOnMainQueueWithoutDeadlocking(void (^block)(void))
{
    if ([NSThread isMainThread])
    {
        block();
    }
    else
    {
        dispatch_sync(dispatch_get_main_queue(), block);
    }
}

Source

Quicklook plugin for iOS provision files

Must have for iOS developers 🙂

Simultaneous audio playback under iOS 3.x

If you wish to play more audio streams simultaneously, synced using AVAudioPlayer, well under iOS 4 and above you won’t have any problem, because it features the playAtTime: method with example and clear documentation.
However, if you wish to do the same on iOS 3.x, then you have to check AudioQueue.

The most important part of syncing is the good timing, which should be set in the same way as with playAtTime and has to be specified as the second parameter of AudioQueueStart (AudioQueueRef inAQ, const AudioTimeStamp *inStartTime) and not in AudioQueueEnqueueBufferWithParameters. To specify the exact start time of AudioQueue, use the
FillOutAudioTimeStampWithHostTime method with an AudioTimeStamp struct.
To retrieve the base time, use CAHostTimeBase from iPublicUtility.

Simultaneous MP3 playback works well in emulator, however on the real device, the hardware decoder can decode only 1 MP3 at a time, so you have to use software decoders. (by default AudioQueue uses the hardware decoder only)
To enable software decoding on an AudioQueue, set the kAudioQueueHardwareCodecPolicy property to
kAudioQueueHardwareCodecPolicy_PreferSoftware.
However to optimize battery life and use less CPU, you can enable hardware decoding on one of the AudioQueues, by setting the property to:
kAudioQueueHardwareCodecPolicy_PreferHardware

AudioQueue Services iOS documentation