Skip to content

Instantly share code, notes, and snippets.

@CodaFi
Last active December 21, 2015 05:09
Show Gist options
  • Save CodaFi/6254983 to your computer and use it in GitHub Desktop.
Save CodaFi/6254983 to your computer and use it in GitHub Desktop.
Conditionalize execution according to various constraints about a device. All values compared against are "cached"
//
// REBConditionals.h
// Rebase
//
// Created by Robert Widmann on 8/16/13.
// Copyright (c) 2013 CodaFi. All rights reserved.
//
#ifndef Rebase_REBConditionals_h
#define Rebase_REBConditionals_h
extern void REBMigrateToVersion(const char *version, void(^migrateBlock)());
extern void REBExecuteOnPhone(void(^block)());
extern void REBExecuteOnPad(void(^block)());
extern void REBExecuteOnSystemGreaterThan(const char *version, void(^block)());
extern void REBExecuteOnSystemGreaterThanOrEqualTo(const char *version, void(^block)());
extern void REBExecuteOnSystemLessThan(const char *version, void(^block)());
extern void REBExecuteOnSystemLessThanOrEqualTo(const char *version, void(^block)());
extern void REBExecuteOnSystemEqualTo(const char *version, void(^block)());
#endif
//
// REBConditionals.m
// Rebase
//
// Created by Robert Widmann on 8/16/13.
// Copyright (c) 2013 CodaFi. All rights reserved.
//
#include "REBConditionals.h"
static NSString *const REBLastAppVersionKey = @"REBLastAppVersionKey";
typedef NS_ENUM(int, REBVersionOrdering) {
REBVersionOrderingDescending,
REBVersionOrderingAscending,
REBVersionOrderingSame
};
static REBVersionOrdering REBCompareVersions(const char *version1, const char *version2);
@interface REBConditionalsInternal : NSObject
+ (instancetype)sharedInternals;
@property (nonatomic, copy) NSString *version;
@property (nonatomic, copy) NSString *systemVersion;
@property (nonatomic, copy) NSString *lastMigrationVersion;
@property (nonatomic) UIUserInterfaceIdiom idiom;
@end
@implementation REBConditionalsInternal
+ (void)load {
[self.class sharedInternals];
}
+ (instancetype)sharedInternals {
static REBConditionalsInternal *internals;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
internals = [REBConditionalsInternal new];
});
return internals;
}
- (id)init {
self = [super init];
_version = [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
_lastMigrationVersion = [NSUserDefaults.standardUserDefaults valueForKey:REBLastAppVersionKey] ?: @"0.0.0";
_idiom = UIDevice.currentDevice.userInterfaceIdiom;
_systemVersion = UIDevice.currentDevice.systemVersion;
return self;
}
- (NSString *)systemVersion {
if ([_systemVersion componentsSeparatedByString:@"."].count == 2) {
return [_systemVersion stringByAppendingString:@".0"];
}
return _systemVersion;
}
@end
void REBMigrateToVersion(const char *version, void(^migrateBlock)()) {
NSCParameterAssert(migrateBlock != NULL);
NSString *appVersion = REBConditionalsInternal.sharedInternals.version;
NSString *lastVersion = REBConditionalsInternal.sharedInternals.lastMigrationVersion;
int mig_ver[3], sys_ver[3], last_ver[3];
sscanf(version, "%d.%d.%d", &mig_ver[0], &mig_ver[1], &mig_ver[2]);
sscanf(appVersion.UTF8String, "%d.%d.%d", &sys_ver[0], &sys_ver[1], &sys_ver[2]);
sscanf(lastVersion.UTF8String, "%d.%d.%d", &last_ver[0], &last_ver[1], &last_ver[2]);
for (int i = 0; i < 3; i++) {
if (mig_ver[i] <= sys_ver[i] && mig_ver[i] > last_ver[i]) {
migrateBlock();
[NSUserDefaults.standardUserDefaults setValue:appVersion forKey:REBLastAppVersionKey];
[NSUserDefaults.standardUserDefaults synchronize];
return;
}
}
}
void REBExecuteOnPhone(void(^block)()) {
NSCParameterAssert(block != NULL);
if (REBConditionalsInternal.sharedInternals.idiom == UIUserInterfaceIdiomPhone) {
block();
}
}
void REBExecuteOnPad(void(^block)()) {
NSCParameterAssert(block != NULL);
if (REBConditionalsInternal.sharedInternals.idiom == UIUserInterfaceIdiomPad) {
block();
}
}
void REBExecuteOnSystemGreaterThan(const char *version, void(^block)()) {
NSCParameterAssert(block != NULL);
NSString *appVersion = REBConditionalsInternal.sharedInternals.systemVersion;
if (REBCompareVersions(appVersion.UTF8String, version) == REBVersionOrderingDescending) {
block();
}
}
void REBExecuteOnSystemGreaterThanOrEqualTo(const char *version, void(^block)()) {
NSCParameterAssert(block != NULL);
NSString *appVersion = REBConditionalsInternal.sharedInternals.systemVersion;
if (REBCompareVersions(appVersion.UTF8String, version) != REBVersionOrderingAscending) {
block();
}
}
void REBExecuteOnSystemLessThan(const char *version, void(^block)()) {
NSCParameterAssert(block != NULL);
NSString *appVersion = REBConditionalsInternal.sharedInternals.systemVersion;
if (REBCompareVersions(appVersion.UTF8String, version) == REBVersionOrderingAscending) {
block();
}
}
void REBExecuteOnSystemLessThanOrEqualTo(const char *version, void(^block)()) {
NSCParameterAssert(block != NULL);
NSString *appVersion = REBConditionalsInternal.sharedInternals.systemVersion;
if (REBCompareVersions(appVersion.UTF8String, version) != NSOrderedDescending) {
block();
}
}
void REBExecuteOnSystemEqualTo(const char *version, void(^block)()) {
NSCParameterAssert(block != NULL);
NSString *appVersion = REBConditionalsInternal.sharedInternals.systemVersion;
if (REBCompareVersions(appVersion.UTF8String, version) == REBVersionOrderingSame) {
block();
}
}
static REBVersionOrdering REBCompareVersions(const char *version1, const char *version2) {
int mig_ver[3], sys_ver[3];
sscanf(version1, "%d.%d.%d", &mig_ver[0], &mig_ver[1], &mig_ver[2]);
sscanf(version2, "%d.%d.%d", &sys_ver[0], &sys_ver[1], &sys_ver[2]);
for (int i = 0; i < 3; i++) {
if (mig_ver[i] > sys_ver[i]) {
return REBVersionOrderingDescending;
} else if (mig_ver[i] < sys_ver[i]) {
return REBVersionOrderingAscending;
}
}
return REBVersionOrderingSame;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment