matsuda
11/1/2012 - 10:33 AM

Objective-C code snippet

Objective-C code snippet

/**
 UINavigationController#pushの逆向きアニメーション
 */
@interface SlideFromLeftSegue : UIStoryboardSegue
@end

#import <QuartzCore/QuartzCore.h>

@implementation SlideFromLeftSegue

- (void)perform
{
    UIViewController *source = self.sourceViewController;
    UIViewController *destination = self.destinationViewController;
    CATransition* transition = [CATransition animation];
    transition.duration = 0.3;
    transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    transition.type = kCATransitionMoveIn;
    transition.subtype = kCATransitionFromLeft;
    // UINavigationController にアニメーションを設定して、プッシュを行います。
    [source.navigationController.view.layer addAnimation:transition forKey:nil];
    [source.navigationController pushViewController:destination animated:NO];
}

@end
/**
 MACRO
 */
#define INVALIDATE_TIMER(__TIMER) { [__TIMER invalidate]; __TIMER = nil; }

#ifdef DEBUG
    #if !defined(NSLog)
        #define NSLog( ... ) NSLog( __VA_ARGS__ )
    #endif
#else
    #if !defined(NSLog)
        #define NSLog( ... ) // NSLog(__VA_ARGS__);
    #endif
#endif

#define APPLog(xx, ...) NSLog(@"%s[%d](%p) : " xx, __PRETTY_FUNCTION__, __LINE__, self, ##__VA_ARGS__)
#define WarnLog(__MSG__) NSLog(@"!!!!! Warn !!!!! %@ %s", __MSG__, __PRETTY_FUNCTION__)

#define iOSVersionGreaterThaniOS7 \
    !(floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1)

#define iPhoneScreen3_5inch \
    [UIScreen mainScreen].bounds.size.height < 568

/**
 NSCoding Macros
 via. http://stablekernel.com/blog/speeding-up-nscoding-with-macros/
 */
#define STRINGIFY(x) #x
#define OBJC_STRINGIFY(x) @#x
#define encodeObject(x)     [aCoder encodeObject:x forKey:OBJC_STRINGIFY(x)]
#define decodeObject(x)     x = [aDecoder decodeObjectForKey:OBJC_STRINGIFY(x)]
#define encodeInteger(x)    [aCoder encodeInteger:x forKey:OBJC_STRINGIFY(x)]
#define decodeInteger(x)    x = [aDecoder decodeIntegerForKey:OBJC_STRINGIFY(x)];
#define encodeFloat(x)      [aCoder encodeFloat:x forKey:OBJC_STRINGIFY(x)]
#define decodeFloat(x)      x = [aDecoder decodeFloatForKey:OBJC_STRINGIFY(x)];

/**
 GCDのタイマー処理マクロ
 */
#define dispatch_after_time_in_main_queue(t, block) \
    if((block)) {\
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(t * NSEC_PER_SEC)), \
        dispatch_get_main_queue(), block); \
    }
/**
 define abstract methods
 */
- (NSInteger)someMethod
{
    @throw [NSException exceptionWithName:NSInternalInconsistencyException
                                   reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
                                 userInfo:nil];
    return 0;
}

/**
 カタカナかどうか
 */
@interface NSString (Hiroie)
- (BOOL)xxx_isKatakana;
@end

@implementation NSString (Katakana)
- (BOOL)xxx_isKatakana
{
    static NSString *pattern = @"^[ァ-ヶー  ]*$";

    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionAnchorsMatchLines error:nil];
    NSTextCheckingResult *match = [regex firstMatchInString:self options:0 range:NSMakeRange(0, self.length)];
    if (match) {
        return YES;
    } else {
        return NO;
    }
}
@end
FOUNDATION_EXPORT UIImage * CurrentLaunchImage();
UIImage * CurrentLaunchImage() {
    CGSize screen = [UIScreen mainScreen].bounds.size;
    NSArray *a = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"UILaunchImages"];
    __block NSDictionary *d = nil;
    [a enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        CGSize s = CGSizeFromString(obj[@"UILaunchImageSize"]);
        if (CGSizeEqualToSize(screen, s)) {
            d = obj;
            *stop = YES;
        }
    }];
    if (!d) return nil;
    return [UIImage imageNamed:d[@"UILaunchImageName"]];
}
#define SYSTEM_VERSION_LESS_THAN(v) \
    ( [[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending )

- (void)registerForRemoteNotification
{
#if !TARGET_IPHONE_SIMULATOR
    /**********
     real devices
     **********/
#ifdef __IPHONE_8_0
    if (SYSTEM_VERSION_LESS_THAN(@"8.0")) {
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
                                                                               UIRemoteNotificationTypeSound |
                                                                               UIRemoteNotificationTypeAlert)];
    } else {
        UIUserNotificationType types = (UIUserNotificationTypeBadge |
                                        UIUserNotificationTypeSound |
                                        UIUserNotificationTypeAlert);
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
    }
#else
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
                                                                           UIRemoteNotificationTypeSound |
                                                                           UIRemoteNotificationTypeAlert)];
#endif
    /**********
     Simulator
     **********/
#else

#if DEBUG
    // シミュレータ
#endif

#endif
}

#ifdef __IPHONE_8_0
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
    // UIUserNotificationType types = [notificationSettings types];
    [application registerForRemoteNotifications];
}
#endif

- (void)setBadge:(NSNumber *)badge
{
#ifdef __IPHONE_8_0
    if (SYSTEM_VERSION_LESS_THAN(@"8.0")) {
        [UIApplication sharedApplication].applicationIconBadgeNumber = [badge integerValue];
    } else {
        UIUserNotificationSettings *settings = [[UIApplication sharedApplication] currentUserNotificationSettings];
        // NSLog(@"types >>> %u", (int)settings.types);
        // NSLog(@"Badge >>> %lu", (long)(settings.types & UIUserNotificationTypeBadge));
        if (settings.types & UIUserNotificationTypeBadge) {
            [UIApplication sharedApplication].applicationIconBadgeNumber = [badge integerValue];
        }
    }
#else
    [UIApplication sharedApplication].applicationIconBadgeNumber = [badge integerValue];
#endif
}
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
  // iOS6.1以下の処理
} else {
  // iOS7以上の処理
}

// iOS7's default blue color
[UIColor colorWithRed:0.0 green:122.0/255.0 blue:1.0 alpha:1.0];

/*
 iOS7で全角スペースが含まれていると、1行の場合でも行間が設定されているため
 iOS6でもiOS7でも1行の場合で行間がない場合は行間の含まれた値を返す
 */
- (CGSize)compatibleiOS6AndiOS7BoundingSizeWithConstrainedToSize:(CGSize)constrainedSize
{
    CGSize size = [self boundingRectWithSize:constrainedSize
                                     options:NSStringDrawingUsesLineFragmentOrigin
                                     context:nil].size;
    if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
        if (size.height < self.size.height) {
            return self.size;
        }
    } else {
        NSDictionary *attributes = [self attributesAtIndex:0 effectiveRange:nil];
        UIFont *font = attributes[NSFontAttributeName];
        if (size.height == font.lineHeight) {
            // iOS7で全角スペースが含まれていると、1行の場合でも行間が設定されているため
            // 1行の場合で行間がない場合は行間を追加する
            NSMutableParagraphStyle *paragraphStyle = attributes[NSParagraphStyleAttributeName];
            size.height += paragraphStyle.lineSpacing;
        }
    }
    if (ceilf(size.width) <= constrainedSize.width) {
        return CGSizeMake(ceilf(size.width), ceilf(size.height));
    } else {
        return CGSizeMake(floorf(size.width), ceilf(size.height));
    }
}
[DynamicArgument dynamicArguments:@"dynamic", @"argument", nil];

// DynamicArgument.h
+ (NSArray *)dynamicArguments:(NSString *)value, ... NS_REQUIRES_NIL_TERMINATION;
// DynamicArgument.m
+ (NSArray *)dynamicArguments:(NSString *)value, ... NS_REQUIRES_NIL_TERMINATION
{
    va_list args;
    va_start(args, value);

    NSMutableArray *array = [NSMutableArray array];
    NSString *obj = value;
    while (obj != nil) {
        [array addObject:obj];
        obj = va_arg(args, typeof(NSString*));
    }

    va_end(args);
    return array;
}
- (void)saveDefaultsUsingBlock:(void(^)(NSUserDefaults *defaults))block
{
    NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
    if (block) {
        block(ud);
    }
    [ud synchronize];
}

- (void)saveDefaultsBaseWithAddition:(void(^)(NSUserDefaults *defaults))addition
{
    [self saveDefaultsUsingBlock:^(NSUserDefaults *defaults){
        // 都度保存するものを設定
        // [defaults setInteger:self.foo forKey:@"hoge"];
        if (addition) {
            addition(defaults);
        }
    }];
}
static NSDate *startDate = nil;
static NSDate *endDate = nil;

#define BM_START    startDate = [NSDate new]
#define BM_END      endDate = [NSDate new];\
                    NSLog(@"Bench mark interval: %f", [endDate timeIntervalSinceDate:startDate]);\
                    [startDate release];[endDate release]

- (void)startMethod
{
    BM_START;
}

- (void)endMethod
{
    BM_END;
}
/**
 乱数生成
 */
// 一般的な方法
srand((unsigned int)time(NULL)); // 初期化
int r = rand() % 10 + 1;

// または
int r = arc4random() % 10;

/**
 ランダムな文字列の生成
 */
NSString * random_string(int digit) {
    static NSString *letters = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    uint8_t length = [letters length];
    char data[digit];
    for (int x=0;x<digit;data[x++] = [letters characterAtIndex:arc4random_uniform(length)]);
    return [[NSString alloc] initWithBytes:data length:digit encoding:NSUTF8StringEncoding];
}

/**
 ARCで文字コード変換
 */
NSString * encode_string(NSString *text) {
		return (__bridge_transfer NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL,
		(__bridge CFStringRef)text,
		CFSTR(""),
		kCFStringEncodingUTF8);

}

/**
 NSData <-> C構造体 の変換
 */
typedef struct {
    int     year;
    char    date[9];
} Sample;

// C構造体 -> NSData
Sample *str = (Sample *)calloc(1, sizeof(Sample));
NSData *data = [NSData dataWithBytes:str length:sizeof(Sample)];
free(str);

// NSData -> C構造体
NSUInteger length = [data length];
Sample *str = (Sample *)malloc(length);
memcpy(str, [data bytes], length);
...
free(str);

/**
 指定された小数点桁数で四捨五入
 */
FOUNDATION_STATIC_INLINE float roundfByDecimalPoint(float value, int point);
FOUNDATION_STATIC_INLINE float roundfByDecimalPoint(float value, int point) {
    return roundf(value * 10 * point) / (10 * point);
}