diff --git a/Classes/FirstLoginViewController.m b/Classes/FirstLoginViewController.m index 816cdb505..cd83a5461 100644 --- a/Classes/FirstLoginViewController.m +++ b/Classes/FirstLoginViewController.m @@ -76,8 +76,8 @@ //[error show]; //[error release]; //erase uername passwd - [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"username_preference"]; - [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"password_preference"]; + [[LinphoneManager instance].settingsStore setObject:Nil forKey:@"username_preference"]; + [[LinphoneManager instance].settingsStore setObject:Nil forKey:@"password_preference"]; break; } case LinphoneRegistrationProgress: { @@ -124,9 +124,8 @@ [error show]; [error release]; } else { - [[NSUserDefaults standardUserDefaults] setObject:username.text forKey:@"username_preference"]; - [[NSUserDefaults standardUserDefaults] setObject:passwd.text forKey:@"password_preference"]; - [[LinphoneManager instance] reconfigureLinphoneIfNeeded:nil]; + [[LinphoneManager instance].settingsStore setObject:username.text forKey:@"username_preference"]; + [[LinphoneManager instance].settingsStore setObject:passwd.text forKey:@"password_preference"]; [self.activityIndicator setHidden:false]; }; diff --git a/Classes/LinphoneApp.xib b/Classes/LinphoneApp.xib index 2399bfd76..5e580fba6 100644 --- a/Classes/LinphoneApp.xib +++ b/Classes/LinphoneApp.xib @@ -42,6 +42,7 @@ {320, 480} + 1 MSAxIDEAA @@ -143,46 +144,61 @@ - 12 + 16 + + IASKAbstractSettingsStore + NSObject + + IBProjectSource + ./Classes/IASKAbstractSettingsStore.h + + LinphoneAppDelegate NSObject - - window - UIWindow - - - window - + + LinphoneCoreSettingsStore + UIWindow + + + + settings + LinphoneCoreSettingsStore + + window UIWindow - + IBProjectSource ./Classes/LinphoneAppDelegate.h + + LinphoneCoreSettingsStore + IASKAbstractSettingsStore + + IBProjectSource + ./Classes/LinphoneCoreSettingsStore.h + + PhoneMainView UIViewController - UIView UIViewController UIView + UIViewController UIViewController - UIViewController - UIView + UIViewController + UIView UIView - - addCallTabBar - UIView - callTabBarController UIViewController @@ -191,16 +207,20 @@ contentView UIView + + incomingCallTabBarController + UIViewController + mainTabBarController UIViewController - - statusBarController + + stateBarController UIViewController - - statusBarView + + stateBarView UIView diff --git a/Classes/LinphoneAppDelegate.h b/Classes/LinphoneAppDelegate.h index daf864383..0f348a891 100644 --- a/Classes/LinphoneAppDelegate.h +++ b/Classes/LinphoneAppDelegate.h @@ -19,7 +19,9 @@ #import #import -#import "CoreTelephony/CTCallCenter.h" +#import + +#import "LinphoneCoreSettingsStore.h" @interface LinphoneAppDelegate : NSObject { UIWindow *window; diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index 1a80a09a0..351483b88 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -26,6 +26,7 @@ #import "ConsoleViewController.h" #import "MoreViewController.h" +#import "LinphoneCoreSettingsStore.h" #include "LinphoneManager.h" #include "linphonecore.h" @@ -78,6 +79,8 @@ int __aeabi_idiv(int a, int b) { } - (void)applicationDidEnterBackground:(UIApplication *)application { + if ([[LinphoneManager instance] settingsStore]!=Nil) + [[[LinphoneManager instance] settingsStore] synchronize]; if (![[LinphoneManager instance] enterBackgroundMode]) { // destroying eventHandler if app cannot go in background. // Otherwise if a GSM call happen and Linphone is resumed, @@ -130,41 +133,15 @@ int __aeabi_idiv(int a, int b) { } - (void)loadDefaultSettings:(NSDictionary *) appDefaults { - - NSString *settingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"]; - if(!settingsBundle) { - NSLog(@"Could not find Settings.bundle"); - return; - } - - NSMutableDictionary *rootSettings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:@"Root.plist"]]; - NSMutableDictionary *audioSettings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:@"audio.plist"]]; - NSMutableDictionary *videoSettings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:@"video.plist"]]; - NSMutableDictionary *advancedSettings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:@"Advanced.plist"]]; - - NSMutableArray *preferences = [rootSettings objectForKey:@"PreferenceSpecifiers"]; - [preferences addObjectsFromArray:[audioSettings objectForKey:@"PreferenceSpecifiers"]]; - [preferences addObjectsFromArray:[videoSettings objectForKey:@"PreferenceSpecifiers"]]; - [preferences addObjectsFromArray:[advancedSettings objectForKey:@"PreferenceSpecifiers"]]; - - NSMutableDictionary *defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity:[preferences count]]; - - for(NSDictionary *prefSpecification in preferences) { - NSString *key = [prefSpecification objectForKey:@"Key"]; - if(key && [prefSpecification objectForKey:@"DefaultValue"]) { - [defaultsToRegister setObject:[prefSpecification objectForKey:@"DefaultValue"] forKey:key]; - } - } - [defaultsToRegister addEntriesFromDictionary:appDefaults]; - [[NSUserDefaults standardUserDefaults] registerDefaults:defaultsToRegister]; - [defaultsToRegister release]; - [[NSUserDefaults standardUserDefaults] synchronize]; + [[[LinphoneManager instance] settingsStore] synchronize]; } - (void)setupUI { // Change to default view [[LinphoneManager instance] changeView: PhoneView_Dialer]; + + [UIDevice currentDevice].batteryMonitoringEnabled = YES; } - (void)setupGSMInteraction { @@ -178,25 +155,16 @@ int __aeabi_idiv(int a, int b) { } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ - NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys: - @"NO", @"enable_first_login_view_preference", // -#ifdef HAVE_AMR - @"YES",@"amr_8k_preference", // enable amr by default if compiled with -#endif -#ifdef HAVE_G729 - @"YES",@"g729_preference", // enable amr by default if compiled with -#endif - //@"+33",@"countrycode_preference", - nil]; - - [self loadDefaultSettings: appDefaults]; + NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys: nil]; + // Put your default NSUserDefaults settings in the dictionary above. if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)] && [UIApplication sharedApplication].applicationState == UIApplicationStateBackground - && [[NSUserDefaults standardUserDefaults] boolForKey:@"disable_autoboot_preference"]) { + && ![[NSUserDefaults standardUserDefaults] boolForKey:@"start_at_boot_preference"]) { // autoboot disabled, doing nothing } else { [self startApplication]; + [self loadDefaultSettings: appDefaults]; } return YES; @@ -210,7 +178,7 @@ int __aeabi_idiv(int a, int b) { [self setupUI]; [[LinphoneManager instance] startLibLinphone]; - + [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound]; [self setupGSMInteraction]; diff --git a/Classes/LinphoneCoreSettingsStore.h b/Classes/LinphoneCoreSettingsStore.h new file mode 100644 index 000000000..fd6c162f7 --- /dev/null +++ b/Classes/LinphoneCoreSettingsStore.h @@ -0,0 +1,32 @@ +/* LinphoneCoreSettingsStore.h + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import +#import "IASKSettingsStore.h" + +#import "LinphoneManager.h" + +@interface LinphoneCoreSettingsStore : IASKAbstractSettingsStore { + NSDictionary *dict; + NSDictionary *changedDict; +} + +-(void) transformLinphoneCoreToKeys; + +@end diff --git a/Classes/LinphoneCoreSettingsStore.m b/Classes/LinphoneCoreSettingsStore.m new file mode 100644 index 000000000..ff048546f --- /dev/null +++ b/Classes/LinphoneCoreSettingsStore.m @@ -0,0 +1,412 @@ +/* LinphoneCoreSettingsStore.m + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "LinphoneCoreSettingsStore.h" + +#include "lpconfig.h" + +extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args); + +@implementation LinphoneCoreSettingsStore + +- (void)handleMigration{ + + NSUserDefaults *oldconfig=[NSUserDefaults standardUserDefaults]; + NSArray *allkeys=[[oldconfig dictionaryRepresentation] allKeys]; + for(NSString* key in allkeys){ + NSLog(@"Migrating old config item %@ to in app settings.",key); + [self setObject:[oldconfig objectForKey:key] forKey:key]; + } + [self synchronize]; + NSLog(@"Migration done"); +} + +- (id)init{ + self = [super init]; + if (self){ + dict=[[NSMutableDictionary alloc] init]; + changedDict=[[NSMutableDictionary alloc] init]; + LinphoneCore *lc=[LinphoneManager getLc]; + if (lp_config_get_int(linphone_core_get_config(lc),"app","config_migrated",0)==0){ + [self handleMigration]; + lp_config_set_int(linphone_core_get_config(lc),"app","config_migrated",1); + } + [self transformLinphoneCoreToKeys]; + } + return self; +} + +- (void)dealloc{ + [super dealloc]; + [dict release]; + [changedDict release]; +} + +- (void)transformKeysToLinphoneCore{ + //LinphoneCore *lc=[LinphoneManager getLc]; + +} + +- (void)setString:(const char*)value forKey:(NSString*)key{ + id obj=Nil; + if (value) obj=[[NSString alloc] initWithCString:value encoding:[NSString defaultCStringEncoding] ]; + [self setObject: obj forKey:key]; +} + +- (NSString*)stringForKey:(NSString*) key{ + return [self objectForKey: key]; +} + +- (void)transformCodecsToKeys: (const MSList *)codecs{ + LinphoneCore *lc=[LinphoneManager getLc]; + const MSList *elem=codecs; + for(;elem!=NULL;elem=elem->next){ + PayloadType *pt=(PayloadType*)elem->data; + NSString *pref=[LinphoneManager getPrefForCodec:pt->mime_type withRate:pt->clock_rate]; + if (pref){ + [self setBool: linphone_core_payload_type_enabled(lc,pt) forKey: pref]; + }else{ + ms_warning("Codec %s/%i supported by core is not shown in iOS app config view.", + pt->mime_type,pt->clock_rate); + } + } +} + +- (void)transformLinphoneCoreToKeys{ + LinphoneCore *lc=[LinphoneManager getLc]; + LinphoneProxyConfig *cfg=NULL; + linphone_core_get_default_proxy(lc,&cfg); + if (cfg){ + const char *identity=linphone_proxy_config_get_identity(cfg); + LinphoneAddress *addr=linphone_address_new(identity); + if (addr){ + const char *proxy=linphone_proxy_config_get_addr(cfg); + LinphoneAddress *proxy_addr=linphone_address_new(proxy); + const char *port=linphone_address_get_port(proxy_addr); + + [self setString: linphone_address_get_username(addr) forKey:@"username_preference"]; + [self setString: linphone_address_get_domain(addr) forKey:@"domain_preference"]; + if (strcmp(linphone_address_get_domain(addr),linphone_address_get_domain(proxy_addr))!=0 + || port!=NULL){ + char tmp[256]={0}; + if (port!=NULL) { + snprintf(tmp,sizeof(tmp)-1,"%s:%s",linphone_address_get_domain(proxy_addr),port); + }else snprintf(tmp,sizeof(tmp)-1,"%s",linphone_address_get_domain(proxy_addr)); + [self setString: tmp forKey:@"proxy_preference"]; + } + linphone_address_destroy(addr); + linphone_address_destroy(proxy_addr); + + [self setBool: (linphone_proxy_config_get_route(cfg)!=NULL) forKey:@"outbound_proxy_preference"]; + + } + } + { + LCSipTransports tp; + const char *tname="udp"; + linphone_core_get_sip_transports(lc, &tp); + if (tp.udp_port>0) tname="udp"; + else if (tp.tcp_port>0) tname="tcp"; + else if (tp.tls_port>0) tname="tls"; + [self setString: tname forKey:@"transport_preference"]; + } + { + LinphoneAuthInfo *ai; + const MSList *elem=linphone_core_get_auth_info_list(lc); + if (elem && (ai=(LinphoneAuthInfo*)elem->data)){ + [self setString: linphone_auth_info_get_passwd(ai) forKey:@"password_preference"]; + } + } + { + [self setString: linphone_core_get_stun_server(lc) forKey:@"stun_preference"]; + } + + { + [self transformCodecsToKeys: linphone_core_get_audio_codecs(lc)]; + [self transformCodecsToKeys: linphone_core_get_video_codecs(lc)]; + } + + { + LinphoneMediaEncryption menc=linphone_core_get_media_encryption(lc); + const char *val; + switch(menc){ + LinphoneMediaEncryptionSRTP: + val="SRTP"; + break; + LinphoneMediaEncryptionZRTP: + val="ZRTP"; + break; + default: + val="None"; + } + [self setString:val forKey:@"media_encryption_preference"]; + } + + [self setBool: lp_config_get_int(linphone_core_get_config(lc),"app","debugenable_preference",0) forKey:@"debugenable_preference"]; + [self setBool: lp_config_get_int(linphone_core_get_config(lc),"app","check_config_disable_preference",0) forKey:@"check_config_disable_preference"]; + [self setBool: lp_config_get_int(linphone_core_get_config(lc),"app","wifi_only_preference",0) forKey:@"wifi_only_preference"]; + [self setBool: lp_config_get_int(linphone_core_get_config(lc),"app","backgroundmode_preference",TRUE) forKey:@"backgroundmode_preference"]; + /*keep this one also in the standardUserDefaults so that it can be read before starting liblinphone*/ + BOOL start_at_boot; + if ([[NSUserDefaults standardUserDefaults] objectForKey:@"start_at_boot_preference"]==Nil) + start_at_boot=TRUE; + else start_at_boot=[[NSUserDefaults standardUserDefaults] boolForKey:@"start_at_boot_preference"]; + [self setBool: start_at_boot forKey:@"start_at_boot_preference"]; + + + + if (linphone_core_tunnel_available()){ + /*FIXME: enhance linphonecore API to handle tunnel more easily in applications */ + LinphoneTunnel *tun=linphone_core_get_tunnel(lc); + //[self setString: linphone_tunnel_get_servers(tun) forKey:tunnel_address_preference]; + //[self setInteger: blabla forKey:tunnel_port_preference]; + //[self setString: forKey:@"tunnel_enabled_preference"]; + } + { + const LinphoneVideoPolicy *pol; + [self setBool: linphone_core_video_enabled(lc) forKey:@"enable_video_preference"]; + pol=linphone_core_get_video_policy(lc); + [self setBool:(pol->automatically_accept && pol->automatically_initiate) forKey:@"start_video_preference"]; + } + if (lp_config_get_int(linphone_core_get_config(lc),"app","debugenable_preference",0)) + linphone_core_enable_logs_with_cb((OrtpLogFunc)linphone_iphone_log_handler); + + [changedDict release]; + changedDict=[[NSMutableDictionary alloc] init]; +} + +- (void)setObject:(id)value forKey:(NSString *)key { + [dict setValue:value forKey:key]; + [changedDict setValue:[NSNumber numberWithBool:TRUE] forKey:key]; +} + +- (id)objectForKey:(NSString*)key { + return [dict valueForKey:key]; +} + +- (BOOL)valueChangedForKey:(NSString*)key{ + return [ [changedDict valueForKey:key] boolValue]; +} + +- (void)synchronizeAccount{ + LinphoneCore *lc=[LinphoneManager getLc]; + LinphoneManager* lLinphoneMgr = [LinphoneManager instance]; + LinphoneProxyConfig* proxyCfg=NULL; + /* unregister before modifying any settings */ + { + linphone_core_get_default_proxy(lc, &proxyCfg); + + if (proxyCfg) { + // this will force unregister WITHOUT destorying the proxyCfg object + linphone_proxy_config_edit(proxyCfg); + + int i=0; + while (linphone_proxy_config_get_state(proxyCfg)!=LinphoneRegistrationNone && + linphone_proxy_config_get_state(proxyCfg)!=LinphoneRegistrationCleared && + linphone_proxy_config_get_state(proxyCfg)!=LinphoneRegistrationFailed && + i++<40 ) { + linphone_core_iterate(lc); + usleep(10000); + } + } + } + + NSString* transport = [self stringForKey:@"transport_preference"]; + + LCSipTransports transportValue={0}; + if (transport!=nil) { + if (linphone_core_get_sip_transports(lc, &transportValue)) { + ms_error("cannot get current transport"); + } + // Only one port can be set at one time, the others's value is 0 + if ([transport isEqualToString:@"tcp"]) { + if (transportValue.tcp_port == 0) transportValue.tcp_port=transportValue.udp_port + transportValue.tls_port; + transportValue.udp_port=0; + transportValue.tls_port=0; + } else if ([transport isEqualToString:@"udp"]){ + if (transportValue.udp_port == 0) transportValue.udp_port=transportValue.tcp_port + transportValue.tls_port; + transportValue.tcp_port=0; + transportValue.tls_port=0; + } else if ([transport isEqualToString:@"tls"]){ + if (transportValue.tls_port == 0) transportValue.tls_port=transportValue.udp_port + transportValue.tcp_port; + transportValue.tcp_port=0; + transportValue.udp_port=0; + } else { + ms_error("unexpected transport [%s]",[transport cStringUsingEncoding:[NSString defaultCStringEncoding]]); + } + if (linphone_core_set_sip_transports(lc, &transportValue)) { + ms_error("cannot set transport"); + } + } + + + //configure sip account + + //mandatory parameters + + NSString* username = [self stringForKey:@"username_preference"]; + NSString* domain = [self stringForKey:@"domain_preference"]; + NSString* accountPassword = [self stringForKey:@"password_preference"]; + bool isOutboundProxy= [self boolForKey:@"outbound_proxy_preference"]; + + + //clear auth info list + linphone_core_clear_all_auth_info(lc); + //clear existing proxy config + linphone_core_clear_proxy_config(lc); + if (username && [username length] >0 && domain && [domain length]>0) { + const char* identity = [[NSString stringWithFormat:@"sip:%@@%@",username,domain] cStringUsingEncoding:[NSString defaultCStringEncoding]]; + const char* password = [accountPassword cStringUsingEncoding:[NSString defaultCStringEncoding]]; + + NSString* proxyAddress = [self stringForKey:@"proxy_preference"]; + if ((!proxyAddress || [proxyAddress length] <1 ) && domain) { + proxyAddress = [NSString stringWithFormat:@"sip:%@",domain] ; + } else { + proxyAddress = [NSString stringWithFormat:@"sip:%@",proxyAddress] ; + } + + const char* proxy = [proxyAddress cStringUsingEncoding:[NSString defaultCStringEncoding]]; + + NSString* prefix = [self stringForKey:@"prefix_preference"]; + bool substitute_plus_by_00 = [self boolForKey:@"substitute_+_by_00_preference"]; + //possible valid config detected + + proxyCfg = linphone_proxy_config_new(); + + // add username password + LinphoneAddress *from = linphone_address_new(identity); + LinphoneAuthInfo *info; + if (from !=0){ + info=linphone_auth_info_new(linphone_address_get_username(from),NULL,password,NULL,NULL); + linphone_core_add_auth_info(lc,info); + } + linphone_address_destroy(from); + + // configure proxy entries + linphone_proxy_config_set_identity(proxyCfg,identity); + linphone_proxy_config_set_server_addr(proxyCfg,proxy); + linphone_proxy_config_enable_register(proxyCfg,true); + BOOL isWifiOnly = [self boolForKey:@"wifi_only_preference"]; + + if (isWifiOnly && lLinphoneMgr.connectivity == wwan) { + linphone_proxy_config_expires(proxyCfg, 0); + } else { + linphone_proxy_config_expires(proxyCfg, lLinphoneMgr.defaultExpires); + } + + if (isOutboundProxy) + linphone_proxy_config_set_route(proxyCfg,proxy); + + if ([prefix length]>0) { + linphone_proxy_config_set_dial_prefix(proxyCfg, [prefix cStringUsingEncoding:[NSString defaultCStringEncoding]]); + } + linphone_proxy_config_set_dial_escape_plus(proxyCfg,substitute_plus_by_00); + + linphone_core_add_proxy_config(lc,proxyCfg); + //set to default proxy + linphone_core_set_default_proxy(lc,proxyCfg); + + } +} + +- (BOOL)synchronize { + LinphoneCore *lc=[LinphoneManager getLc]; + + if (lc==NULL) return YES; + BOOL account_changed; + + account_changed=[self valueChangedForKey:@"username_preference"] + || [self valueChangedForKey:@"password_preference"] + || [self valueChangedForKey:@"domain_preference"] + || [self valueChangedForKey:@"proxy_preference"] + || [self valueChangedForKey:@"outbound_proxy_preference"] + || [self valueChangedForKey:@"transport_preference"] + || [self valueChangedForKey:@"prefix_preference"] + || [self valueChangedForKey:@"substitute_+_by_00_preference"]; + + if (account_changed) + [self synchronizeAccount]; + + //Configure Codecs + + PayloadType *pt; + const MSList *elem; + + for (elem=linphone_core_get_audio_codecs(lc);elem!=NULL;elem=elem->next){ + pt=(PayloadType*)elem->data; + NSString *pref=[LinphoneManager getPrefForCodec:pt->mime_type withRate:pt->clock_rate]; + linphone_core_enable_payload_type(lc,pt,[self boolForKey: pref]); + } + for (elem=linphone_core_get_video_codecs(lc);elem!=NULL;elem=elem->next){ + pt=(PayloadType*)elem->data; + NSString *pref=[LinphoneManager getPrefForCodec:pt->mime_type withRate:pt->clock_rate]; + linphone_core_enable_payload_type(lc,pt,[self boolForKey: pref]); + } + + bool enableVideo = [self boolForKey:@"enable_video_preference"]; + linphone_core_enable_video(lc, enableVideo, enableVideo); + + NSString *menc = [self stringForKey:@"media_encryption_preference"]; + if (menc && [menc compare:@"SRTP"]) + linphone_core_set_media_encryption(lc, LinphoneMediaEncryptionSRTP); + else if (menc && [menc compare:@"ZRTP"]) + linphone_core_set_media_encryption(lc, LinphoneMediaEncryptionZRTP); + else linphone_core_set_media_encryption(lc, LinphoneMediaEncryptionNone); + + NSString* stun_server = [self stringForKey:@"stun_preference"]; + if ([stun_server length]>0){ + linphone_core_set_stun_server(lc,[stun_server cStringUsingEncoding:[NSString defaultCStringEncoding]]); + linphone_core_set_firewall_policy(lc, LinphonePolicyUseStun); + }else{ + linphone_core_set_stun_server(lc, NULL); + linphone_core_set_firewall_policy(lc, LinphonePolicyNoFirewall); + } + + LinphoneVideoPolicy policy; + policy.automatically_accept = [self boolForKey:@"start_video_preference"];; + policy.automatically_initiate = [self boolForKey:@"start_video_preference"]; + linphone_core_set_video_policy(lc, &policy); + + UIDevice* device = [UIDevice currentDevice]; + bool backgroundSupported = false; + if ([device respondsToSelector:@selector(isMultitaskingSupported)]) + backgroundSupported = [device isMultitaskingSupported]; + BOOL isbackgroundModeEnabled; + if (backgroundSupported) { + isbackgroundModeEnabled = [self boolForKey:@"backgroundmode_preference"]; + } else { + isbackgroundModeEnabled=false; + } + lp_config_set_int(linphone_core_get_config(lc),"app","backgroundmode_preference",isbackgroundModeEnabled); + + BOOL debugmode=[self boolForKey:@"debugenable_preference"]; + lp_config_set_int(linphone_core_get_config(lc),"app","debugenable_preference",debugmode); + if (debugmode) linphone_core_enable_logs_with_cb((OrtpLogFunc)linphone_iphone_log_handler); + else linphone_core_disable_logs(); + + /*keep this one also in the standardUserDefaults so that it can be read before starting liblinphone*/ + BOOL start_at_boot=[self boolForKey:@"start_at_boot_preference"]; + [[NSUserDefaults standardUserDefaults] setBool: start_at_boot forKey:@"start_at_boot_preference"]; + + [changedDict release]; + changedDict=[[NSMutableDictionary alloc] init]; + return YES; +} + +@end diff --git a/Classes/LinphoneUI/LinphoneManager.h b/Classes/LinphoneUI/LinphoneManager.h index eaf47a14a..aed04c825 100644 --- a/Classes/LinphoneUI/LinphoneManager.h +++ b/Classes/LinphoneUI/LinphoneManager.h @@ -20,7 +20,11 @@ #import #import #import + #import "LogView.h" +#import "IASKSettingsReader.h" +#import "IASKSettingsStore.h" +#import "IASKAppSettingsViewController.h" #include "linphonecore.h" @@ -65,7 +69,7 @@ typedef struct _LinphoneCallAppData { - (id) initWithCall: (LinphoneCall*) call; @end -@interface LinphoneManager : NSObject { +@interface LinphoneManager : NSObject { @protected SCNetworkReachabilityRef proxyReachability; @private @@ -80,7 +84,7 @@ typedef struct _LinphoneCallAppData { PhoneView currentView; - NSDictionary* currentSettings; + id settingsStore; @public CallContext currentCallContextBeforeGoingBackground; @@ -94,6 +98,7 @@ typedef struct _LinphoneCallAppData { + (void)logUIElementPressed:(const char*) name; + (void)abstractCall:(id) object dict:(NSDictionary *) dict; - (void)registerLogView:(id) view; ++ (NSString *)getPrefForCodec: (const char*) name withRate: (int) rate; - (void)startLibLinphone; - (BOOL)isNotIphone3G; @@ -105,7 +110,6 @@ typedef struct _LinphoneCallAppData { - (NSString*)getDisplayNameFromAddressBook:(NSString*) number andUpdateCallLog:(LinphoneCallLog*)log; - (UIImage*)getImageFromAddressBook:(NSString*) number; -- (BOOL)reconfigureLinphoneIfNeeded:(NSDictionary *)oldSettings; - (void)setupNetworkReachabilityCallback; - (void)refreshRegisters; @@ -115,8 +119,12 @@ typedef struct _LinphoneCallAppData { - (void)fullScreen:(BOOL) enabled; - (PhoneView) currentView; +@property (nonatomic, retain) id settingsStore; + @property Connectivity connectivity; +@property (nonatomic) int defaultExpires; @property (readonly) const char* frontCamId; @property (readonly) const char* backCamId; + @end diff --git a/Classes/LinphoneUI/LinphoneManager.m b/Classes/LinphoneUI/LinphoneManager.m index b6b101b47..35c32a106 100644 --- a/Classes/LinphoneUI/LinphoneManager.m +++ b/Classes/LinphoneUI/LinphoneManager.m @@ -17,16 +17,20 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#import "LinphoneManager.h" #include "linphonecore_utils.h" +#include "lpconfig.h" #include #include #include +#include + #import #import +#import + +#import "LinphoneManager.h" #import "FastAddressBook.h" -#include -#include +#import "LinphoneCoreSettingsStore.h" static LinphoneCore* theLinphoneCore=nil; static LinphoneManager* theLinphoneManager=nil; @@ -41,7 +45,7 @@ extern void libmsx264_init(); #endif #define FRONT_CAM_NAME "AV Capture: Front Camera" #define BACK_CAM_NAME "AV Capture: Back Camera" -#define DEFAULT_EXPIRES 600 + #if defined (HAVE_SILK) extern void libmssilk_init(); #endif @@ -68,12 +72,48 @@ PhoneView currentView = -1; @synthesize connectivity; @synthesize frontCamId; @synthesize backCamId; +@synthesize defaultExpires; +@synthesize settingsStore; + +struct codec_name_pref_table{ +const char *name; +int rate; +NSString *prefname; +}; + +struct codec_name_pref_table codec_pref_table[]={ + { "speex", 8000, @"speex_8k_preference" }, + { "speex", 16000, @"speex_16k_preference" }, + { "silk", 24000, @"silk_24k_preference" }, + { "silk", 16000, @"silk_16k_preference" }, + { "amr", 8000, @"amr_8k_preference" }, + { "ilbc", 8000, @"ilbc_preference"}, + { "pcmu", 8000, @"pcmu_preference"}, + { "pcma", 8000, @"pcma_preference"}, + { "g722", 8000, @"g722_preference"}, + { "g729", 8000, @"g729_preference"}, + { "mp4v-es", 90000, @"mp4v-es_preference"}, + { "h264", 90000, @"h264_preference"}, + { "vp8", 90000, @"vp8_preference"}, + { NULL,0,Nil } +}; + ++ (NSString *) getPrefForCodec: (const char*) name withRate: (int) rate{ + int i; + for(i=0;codec_pref_table[i].name!=NULL;++i){ + if (strcasecmp(codec_pref_table[i].name,name)==0 && codec_pref_table[i].rate==rate) + return codec_pref_table[i].prefname; + } + return Nil; +} + - (id)init { assert (!theLinphoneManager); if ((self= [super init])) { mFastAddressBook = [[FastAddressBook alloc] init]; theLinphoneManager = self; + self.defaultExpires=600; } return self; } @@ -232,7 +272,7 @@ PhoneView currentView = -1; } //generic log handler for debug version -static void linphone_iphone_log_handler(int lev, const char *fmt, va_list args){ +void linphone_iphone_log_handler(int lev, const char *fmt, va_list args){ NSString* format = [[NSString alloc] initWithCString:fmt encoding:[NSString defaultCStringEncoding]]; NSLogv(format,args); NSString* formatedString = [[NSString alloc] initWithFormat:format arguments:args]; @@ -401,7 +441,7 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach [[LinphoneManager instance] kickOffNetworkConnection]; } else { Connectivity newConnectivity; - BOOL isWifiOnly = [[NSUserDefaults standardUserDefaults] boolForKey:@"wifi_only_preference"]; + BOOL isWifiOnly = lp_config_get_int(linphone_core_get_config([LinphoneManager getLc]),"app","wifi_only_preference",FALSE); if (!ctx || ctx->testWWan) newConnectivity = flags & kSCNetworkReachabilityFlagsIsWWAN ? wwan:wifi; else @@ -413,7 +453,7 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach && (lLinphoneMgr.connectivity == newConnectivity || lLinphoneMgr.connectivity == none)) { linphone_proxy_config_expires(proxy, 0); } else if (proxy){ - linphone_proxy_config_expires(proxy, DEFAULT_EXPIRES); //might be better to save the previous value + linphone_proxy_config_expires(proxy, lLinphoneMgr.defaultExpires); //might be better to save the previous value } if (lLinphoneMgr.connectivity == none) { @@ -436,268 +476,23 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach } } -- (BOOL)reconfigureLinphoneIfNeeded:(NSDictionary *)settings { - if (theLinphoneCore==nil) { - ms_warning("cannot configure linphone because not initialized yet"); - return NO; - } - - [[NSUserDefaults standardUserDefaults] synchronize]; - NSDictionary* newSettings = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]; - if (settings != nil) { - /* reconfigure only if newSettings != settings */ - if ([newSettings isEqualToDictionary:settings]) { - ms_message("Same settings: no need to reconfigure linphone"); - return NO; - } - } - NSLog(@"Configuring Linphone (new settings)"); - - - if ([[NSUserDefaults standardUserDefaults] boolForKey:@"debugenable_preference"]) { - //redirect all traces to the iphone log framework - linphone_core_enable_logs_with_cb((OrtpLogFunc)linphone_iphone_log_handler); - } - else { - linphone_core_disable_logs(); - } - - NSBundle* myBundle = [NSBundle mainBundle]; - - /* unregister before modifying any settings */ - { - LinphoneProxyConfig* proxyCfg; - linphone_core_get_default_proxy(theLinphoneCore, &proxyCfg); - - if (proxyCfg) { - // this will force unregister WITHOUT destorying the proxyCfg object - linphone_proxy_config_edit(proxyCfg); - - int i=0; - while (linphone_proxy_config_get_state(proxyCfg)!=LinphoneRegistrationNone && - linphone_proxy_config_get_state(proxyCfg)!=LinphoneRegistrationCleared && - linphone_proxy_config_get_state(proxyCfg)!=LinphoneRegistrationFailed && - i++<40 ) { - linphone_core_iterate(theLinphoneCore); - usleep(100000); - } - } - } - - const char* lRootCa = [[myBundle pathForResource:@"rootca"ofType:@"pem"] cStringUsingEncoding:[NSString defaultCStringEncoding]]; - linphone_core_set_root_ca(theLinphoneCore, lRootCa); - - NSString* transport = [[NSUserDefaults standardUserDefaults] stringForKey:@"transport_preference"]; - - LCSipTransports transportValue; - if (transport!=nil) { - if (linphone_core_get_sip_transports(theLinphoneCore, &transportValue)) { - ms_error("cannot get current transport"); - } - // Only one port can be set at one time, the others's value is 0 - if ([transport isEqualToString:@"tcp"]) { - if (transportValue.tcp_port == 0) transportValue.tcp_port=transportValue.udp_port + transportValue.tls_port; - transportValue.udp_port=0; - transportValue.tls_port=0; - } else if ([transport isEqualToString:@"udp"]){ - if (transportValue.udp_port == 0) transportValue.udp_port=transportValue.tcp_port + transportValue.tls_port; - transportValue.tcp_port=0; - transportValue.tls_port=0; - } else if ([transport isEqualToString:@"tls"]){ - if (transportValue.tls_port == 0) transportValue.tls_port=transportValue.udp_port + transportValue.tcp_port; - transportValue.tcp_port=0; - transportValue.udp_port=0; - } else { - ms_error("unexpected transport [%s]",[transport cStringUsingEncoding:[NSString defaultCStringEncoding]]); - } - if (linphone_core_set_sip_transports(theLinphoneCore, &transportValue)) { - ms_error("cannot set transport"); - } - } - - - - // Set audio assets - const char* lRing = [[myBundle pathForResource:@"oldphone-mono"ofType:@"wav"] cStringUsingEncoding:[NSString defaultCStringEncoding]]; - linphone_core_set_ring(theLinphoneCore, lRing ); - const char* lRingBack = [[myBundle pathForResource:@"ringback"ofType:@"wav"] cStringUsingEncoding:[NSString defaultCStringEncoding]]; - linphone_core_set_ringback(theLinphoneCore, lRingBack); - - - - //configure sip account - - //madatory parameters - - NSString* username = [[NSUserDefaults standardUserDefaults] stringForKey:@"username_preference"]; - NSString* domain = [[NSUserDefaults standardUserDefaults] stringForKey:@"domain_preference"]; - NSString* accountPassword = [[NSUserDefaults standardUserDefaults] stringForKey:@"password_preference"]; - bool configCheckDisable = [[NSUserDefaults standardUserDefaults] boolForKey:@"check_config_disable_preference"]; - bool isOutboundProxy= [[NSUserDefaults standardUserDefaults] boolForKey:@"outbound_proxy_preference"]; - - - //clear auth info list - linphone_core_clear_all_auth_info(theLinphoneCore); - //clear existing proxy config - linphone_core_clear_proxy_config(theLinphoneCore); - if (username && [username length] >0 && domain && [domain length]>0) { - const char* identity = [[NSString stringWithFormat:@"sip:%@@%@",username,domain] cStringUsingEncoding:[NSString defaultCStringEncoding]]; - const char* password = [accountPassword cStringUsingEncoding:[NSString defaultCStringEncoding]]; - - NSString* proxyAddress = [[NSUserDefaults standardUserDefaults] stringForKey:@"proxy_preference"]; - if ((!proxyAddress || [proxyAddress length] <1 ) && domain) { - proxyAddress = [NSString stringWithFormat:@"sip:%@",domain] ; - } else { - proxyAddress = [NSString stringWithFormat:@"sip:%@",proxyAddress] ; - } - - const char* proxy = [proxyAddress cStringUsingEncoding:[NSString defaultCStringEncoding]]; - - NSString* prefix = [[NSUserDefaults standardUserDefaults] stringForKey:@"prefix_preference"]; - bool substitute_plus_by_00 = [[NSUserDefaults standardUserDefaults] boolForKey:@"substitute_+_by_00_preference"]; - //possible valid config detected - LinphoneProxyConfig* proxyCfg; - proxyCfg = linphone_proxy_config_new(); - - // add username password - LinphoneAddress *from = linphone_address_new(identity); - LinphoneAuthInfo *info; - if (from !=0){ - info=linphone_auth_info_new(linphone_address_get_username(from),NULL,password,NULL,NULL); - linphone_core_add_auth_info(theLinphoneCore,info); - } - linphone_address_destroy(from); - - // configure proxy entries - linphone_proxy_config_set_identity(proxyCfg,identity); - linphone_proxy_config_set_server_addr(proxyCfg,proxy); - linphone_proxy_config_enable_register(proxyCfg,true); - BOOL isWifiOnly = [[NSUserDefaults standardUserDefaults] boolForKey:@"wifi_only_preference"]; - LinphoneManager* lLinphoneMgr = [LinphoneManager instance]; - if (isWifiOnly && lLinphoneMgr.connectivity == wwan) { - linphone_proxy_config_expires(proxyCfg, 0); - } else { - linphone_proxy_config_expires(proxyCfg, DEFAULT_EXPIRES); - } - - if (isOutboundProxy) - linphone_proxy_config_set_route(proxyCfg,proxy); - - if ([prefix length]>0) { - linphone_proxy_config_set_dial_prefix(proxyCfg, [prefix cStringUsingEncoding:[NSString defaultCStringEncoding]]); - } - linphone_proxy_config_set_dial_escape_plus(proxyCfg,substitute_plus_by_00); - - linphone_core_add_proxy_config(theLinphoneCore,proxyCfg); - //set to default proxy - linphone_core_set_default_proxy(theLinphoneCore,proxyCfg); - - } else { - if (configCheckDisable == false ) { - UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Warning",nil) - message:NSLocalizedString(@"It seems you have not configured any proxy server from settings",nil) - delegate:self - cancelButtonTitle:NSLocalizedString(@"Continue",nil) - otherButtonTitles:NSLocalizedString(@"Never remind",nil),nil]; - [error show]; - [error release]; - } - } - - //Configure Codecs - - PayloadType *pt; - //get codecs from linphonerc - const MSList *audioCodecs=linphone_core_get_audio_codecs(theLinphoneCore); - const MSList *elem; - //disable all codecs - for (elem=audioCodecs;elem!=NULL;elem=elem->next){ - pt=(PayloadType*)elem->data; - linphone_core_enable_payload_type(theLinphoneCore,pt,FALSE); - } - - //read codecs from setting bundle and enable them one by one - if ([self isNotIphone3G]) { - [self configurePayloadType:"SILK" fromPrefKey:@"silk_24k_preference" withRate:24000]; - } - else { - ms_message("SILK 24khz codec deactivated"); - } - [self configurePayloadType:"speex" fromPrefKey:@"speex_16k_preference" withRate:16000]; - [self configurePayloadType:"speex" fromPrefKey:@"speex_8k_preference" withRate:8000]; - [self configurePayloadType:"SILK" fromPrefKey:@"silk_16k_preference" withRate:16000]; - [self configurePayloadType:"AMR" fromPrefKey:@"amr_8k_preference" withRate:8000]; - [self configurePayloadType:"GSM" fromPrefKey:@"gsm_8k_preference" withRate:8000]; - [self configurePayloadType:"iLBC" fromPrefKey:@"ilbc_preference" withRate:8000]; - [self configurePayloadType:"PCMU" fromPrefKey:@"pcmu_preference" withRate:8000]; - [self configurePayloadType:"PCMA" fromPrefKey:@"pcma_preference" withRate:8000]; - [self configurePayloadType:"G722" fromPrefKey:@"g722_preference" withRate:8000]; - [self configurePayloadType:"G729" fromPrefKey:@"g729_preference" withRate:8000]; - - //get video codecs from linphonerc - const MSList *videoCodecs=linphone_core_get_video_codecs(theLinphoneCore); - //disable video all codecs - for (elem=videoCodecs;elem!=NULL;elem=elem->next){ - pt=(PayloadType*)elem->data; - linphone_core_enable_payload_type(theLinphoneCore,pt,FALSE); - } - [self configurePayloadType:"MP4V-ES" fromPrefKey:@"mp4v-es_preference" withRate:90000]; - [self configurePayloadType:"H264" fromPrefKey:@"h264_preference" withRate:90000]; - [self configurePayloadType:"VP8" fromPrefKey:@"vp8_preference" withRate:90000]; - - if ([self isNotIphone3G]) { - bool enableVideo = [[NSUserDefaults standardUserDefaults] boolForKey:@"enable_video_preference"]; - linphone_core_enable_video(theLinphoneCore, enableVideo, enableVideo); - } else { - linphone_core_enable_video(theLinphoneCore, FALSE, FALSE); - ms_warning("Disable video for phones prior to iPhone 3GS"); - } - bool enableSrtp = [[NSUserDefaults standardUserDefaults] boolForKey:@"enable_srtp_preference"]; - linphone_core_set_media_encryption(theLinphoneCore, enableSrtp?LinphoneMediaEncryptionSRTP:LinphoneMediaEncryptionZRTP); - - NSString* stun_server = [[NSUserDefaults standardUserDefaults] stringForKey:@"stun_preference"]; - if ([stun_server length]>0){ - linphone_core_set_stun_server(theLinphoneCore,[stun_server cStringUsingEncoding:[NSString defaultCStringEncoding]]); - linphone_core_set_firewall_policy(theLinphoneCore, LinphonePolicyUseStun); - }else{ - linphone_core_set_stun_server(theLinphoneCore, NULL); - linphone_core_set_firewall_policy(theLinphoneCore, LinphonePolicyNoFirewall); - } - - LinphoneVideoPolicy policy; - policy.automatically_accept = [[NSUserDefaults standardUserDefaults] boolForKey:@"start_video_preference"];; - policy.automatically_initiate = [[NSUserDefaults standardUserDefaults] boolForKey:@"start_video_preference"]; - linphone_core_set_video_policy(theLinphoneCore, &policy); - - UIDevice* device = [UIDevice currentDevice]; - bool backgroundSupported = false; - if ([device respondsToSelector:@selector(isMultitaskingSupported)]) - backgroundSupported = [device isMultitaskingSupported]; - - if (backgroundSupported) { - isbackgroundModeEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"backgroundmode_preference"]; - } else { - isbackgroundModeEnabled=false; - } - - [currentSettings release]; - currentSettings = newSettings; - [currentSettings retain]; - - return YES; -} - (BOOL)isNotIphone3G { - size_t size; - sysctlbyname("hw.machine", NULL, &size, NULL, 0); - char *machine = malloc(size); - sysctlbyname("hw.machine", machine, &size, NULL, 0); - NSString *platform = [[NSString alloc ] initWithUTF8String:machine]; - free(machine); + static BOOL done=FALSE; + static BOOL result; + if (!done){ + size_t size; + sysctlbyname("hw.machine", NULL, &size, NULL, 0); + char *machine = malloc(size); + sysctlbyname("hw.machine", machine, &size, NULL, 0); + NSString *platform = [[NSString alloc ] initWithUTF8String:machine]; + free(machine); - BOOL result = ![platform isEqualToString:@"iPhone1,2"]; + result = ![platform isEqualToString:@"iPhone1,2"]; - [platform release]; + [platform release]; + done=TRUE; + } return result; } @@ -730,7 +525,7 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach linphone_core_get_default_proxy(theLinphoneCore, &proxyCfg); linphone_core_stop_dtmf_stream(theLinphoneCore); - if (isbackgroundModeEnabled && proxyCfg) { + if (proxyCfg && lp_config_get_int(linphone_core_get_config(theLinphoneCore),"app","backgroundmode_preference",0)) { //For registration register linphone_core_refresh_registers(theLinphoneCore); @@ -823,18 +618,11 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *confiFileName = [[paths objectAtIndex:0] stringByAppendingString:@"/.linphonerc"]; NSString *zrtpSecretsFileName = [[paths objectAtIndex:0] stringByAppendingString:@"/zrtp_secrets"]; + const char* lRootCa = [[myBundle pathForResource:@"rootca"ofType:@"pem"] cStringUsingEncoding:[NSString defaultCStringEncoding]]; connectivity=none; signal(SIGPIPE, SIG_IGN); //log management - if ([[NSUserDefaults standardUserDefaults] boolForKey:@"debugenable_preference"]) { - //redirect all traces to the iphone log framework - linphone_core_enable_logs_with_cb((OrtpLogFunc)linphone_iphone_log_handler); - } - else { - linphone_core_disable_logs(); - } - libmsilbc_init(); #if defined (HAVE_SILK) libmssilk_init(); @@ -857,13 +645,17 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach , [factoryConfig cStringUsingEncoding:[NSString defaultCStringEncoding]] ,self); - [[NSUserDefaults standardUserDefaults] synchronize];//sync before loading config + linphone_core_set_root_ca(theLinphoneCore, lRootCa); + // Set audio assets + const char* lRing = [[myBundle pathForResource:@"oldphone-mono"ofType:@"wav"] cStringUsingEncoding:[NSString defaultCStringEncoding]]; + linphone_core_set_ring(theLinphoneCore, lRing ); + const char* lRingBack = [[myBundle pathForResource:@"ringback"ofType:@"wav"] cStringUsingEncoding:[NSString defaultCStringEncoding]]; + linphone_core_set_ringback(theLinphoneCore, lRingBack); + linphone_core_set_zrtp_secrets_file(theLinphoneCore, [zrtpSecretsFileName cStringUsingEncoding:[NSString defaultCStringEncoding]]); [self setupNetworkReachabilityCallback]; - - [self reconfigureLinphoneIfNeeded:nil]; // start scheduler mIterateTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 @@ -915,12 +707,25 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach //go directly to bg mode [self enterBackgroundMode]; } + NSUInteger cpucount = [[NSProcessInfo processInfo] processorCount]; + ms_set_cpu_count(cpucount); + + if (![self isNotIphone3G]){ + PayloadType *pt=linphone_core_find_payload_type(theLinphoneCore,"SILK",24000); + if (pt) { + linphone_core_enable_payload_type(theLinphoneCore,pt,FALSE); + ms_warning("SILK/24000 and video disabled on old iPhone 3G"); + } + linphone_core_enable_video(theLinphoneCore, FALSE, FALSE); + } if ([LinphoneManager runningOnIpad]) ms_set_cpu_count(2); else ms_set_cpu_count(1); + settingsStore = [[LinphoneCoreSettingsStore alloc] init]; + ms_warning("Linphone [%s] started on [%s]" ,linphone_core_get_version() ,[[UIDevice currentDevice].model cStringUsingEncoding:[NSString defaultCStringEncoding]] ); @@ -949,13 +754,10 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach - (void)becomeActive { if (theLinphoneCore == nil) { //back from standby and background mode is disabled - [self startLibLinphone]; + [self startLibLinphone]; } else { - if (![self reconfigureLinphoneIfNeeded:currentSettings]) { - ms_message("becoming active with no config modification, make sure we are registered"); - [self refreshRegisters]; - } - } + [self refreshRegisters]; + } /*IOS specific*/ linphone_core_start_dtmf_stream(theLinphoneCore); @@ -1024,4 +826,57 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach } } +- (void)settingsViewControllerDidEnd:(IASKAppSettingsViewController *)sender { + ms_message("Synchronize settings"); + [[self settingsStore] synchronize]; +} + +- (BOOL)codecSupported:(NSString *) prefName{ + int i; + for(i=0;codec_pref_table[i].name!=NULL;++i){ + if ([prefName compare:codec_pref_table[i].prefname]==0){ + return linphone_core_find_payload_type(theLinphoneCore,codec_pref_table[i].name, codec_pref_table[i].rate)!=NULL; + } + } + return TRUE; +} + +- (NSDictionary*)filterPreferenceSpecifier:(NSDictionary *)specifier { + if (!theLinphoneCore) { + // LinphoneCore not ready: do not filter + return specifier; + } + NSString* identifier = [specifier objectForKey:@"Identifier"]; + if (identifier == nil) { + identifier = [specifier objectForKey:@"Key"]; + } + if (!identifier) { + // child pane maybe + NSString* title = [specifier objectForKey:@"Title"]; + if ([title isEqualToString:@"Video"]) { + if (!linphone_core_video_supported(theLinphoneCore)) + return nil; + } + return specifier; + } + // NSLog(@"Specifier received: %@", identifier); + if ([identifier isEqualToString:@"silk_24k_preference"]) { + if (![self isNotIphone3G]) + return nil; + } + if ([identifier isEqualToString:@"backgroundmode_preference"]) { + UIDevice* device = [UIDevice currentDevice]; + if ([device respondsToSelector:@selector(isMultitaskingSupported)]) { + if ([device isMultitaskingSupported]) { + return specifier; + } + } + // hide setting if bg mode not supported + return nil; + } + if (![self codecSupported:identifier]) + return Nil; + return specifier; +} + @end diff --git a/Classes/MainScreenWithVideoPreview.m b/Classes/MainScreenWithVideoPreview.m index ff2927ad7..35bc73bc3 100644 --- a/Classes/MainScreenWithVideoPreview.m +++ b/Classes/MainScreenWithVideoPreview.m @@ -132,7 +132,11 @@ if([LinphoneManager isLcReady]) lc = [LinphoneManager getLc]; - bool enableVideo = [[NSUserDefaults standardUserDefaults] boolForKey:@"enable_video_preference"]; + lc = [LinphoneManager getLc]; + + if (lc==NULL) return; + + bool enableVideo = linphone_core_video_enabled(lc); if (enableVideo) { LinphoneCall* call = linphone_core_get_current_call(lc); diff --git a/Classes/MoreViewController.m b/Classes/MoreViewController.m index b68f444a7..9a9eb35d3 100644 --- a/Classes/MoreViewController.m +++ b/Classes/MoreViewController.m @@ -20,6 +20,7 @@ #import "MoreViewController.h" #include "ConsoleViewController.h" #import "LinphoneManager.h" +#include "lpconfig.h" @implementation MoreViewController @synthesize web; @@ -34,7 +35,7 @@ [creditText setText: [NSString stringWithFormat:creditText.text,[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]]]; consoleViewController = [[ConsoleViewController alloc] initWithNibName:@"ConsoleViewController" bundle:[NSBundle mainBundle]]; [[LinphoneManager instance] registerLogView:consoleViewController]; - isDebug = [[NSUserDefaults standardUserDefaults] boolForKey:@"debugenable_preference"]; + isDebug = lp_config_get_int(linphone_core_get_config([LinphoneManager getLc]),"app","debugenable_preference",0); } diff --git a/Classes/PhoneMainView.m b/Classes/PhoneMainView.m index 184be86ae..f0c8a2e3a 100644 --- a/Classes/PhoneMainView.m +++ b/Classes/PhoneMainView.m @@ -282,7 +282,7 @@ InCallViewController* myInCallController = [[InCallViewController alloc] initWithNibName:@"InCallViewController" bundle:[NSBundle mainBundle]]; - //[myHistoryController loadView]; + //[myInCallController loadView]; ViewsDescription *inCallDescription = [ViewsDescription alloc]; inCallDescription->content = myInCallController; inCallDescription->tabBar = callTabBarController; @@ -298,7 +298,7 @@ SettingsViewController* mySettingsViewController = [[SettingsViewController alloc] initWithNibName:@"SettingsViewController" bundle:[NSBundle mainBundle]]; - //[myHistoryController loadView]; + //[mySettingsViewController loadView]; ViewsDescription *settingsDescription = [ViewsDescription alloc]; settingsDescription->content = mySettingsViewController; settingsDescription->tabBar = mainTabBarController; @@ -313,7 +313,7 @@ ChatViewController* myChatViewController = [[ChatViewController alloc] initWithNibName:@"ChatViewController" bundle:[NSBundle mainBundle]]; - //[myHistoryController loadView]; + //[myChatViewController loadView]; ViewsDescription *chatDescription = [ViewsDescription alloc]; chatDescription->content = myChatViewController; chatDescription->tabBar = mainTabBarController; diff --git a/Classes/SettingsViewController.h b/Classes/SettingsViewController.h index 0641988c3..b26cd0129 100644 --- a/Classes/SettingsViewController.h +++ b/Classes/SettingsViewController.h @@ -19,8 +19,14 @@ #import -@interface SettingsViewController : UIViewController { - +#import "IASKAppSettingsViewController.h" + +@interface SettingsViewController: UIViewController { + IASKAppSettingsViewController *settingsController; + UINavigationController *navigationController; } +@property (nonatomic, retain) IBOutlet UINavigationController *navigationController; +@property (nonatomic, retain) IBOutlet IASKAppSettingsViewController *settingsController; + @end diff --git a/Classes/SettingsViewController.m b/Classes/SettingsViewController.m index 693186477..cd54f3fe9 100644 --- a/Classes/SettingsViewController.m +++ b/Classes/SettingsViewController.m @@ -18,7 +18,21 @@ */ #import "SettingsViewController.h" +#import "LinphoneManager.h" @implementation SettingsViewController +@synthesize settingsController; +@synthesize navigationController; + +- (void)viewDidLoad { + settingsController.delegate = [LinphoneManager instance]; + settingsController.settingsReaderDelegate = [LinphoneManager instance]; + settingsController.settingsStore=[[LinphoneManager instance] settingsStore]; + settingsController.showCreditsFooter = FALSE; + + navigationController.view.frame = self.view.frame; + [self.view addSubview: navigationController.view]; +} + @end diff --git a/Classes/SettingsViewController.xib b/Classes/SettingsViewController.xib index 61ae418cc..598a2964e 100644 --- a/Classes/SettingsViewController.xib +++ b/Classes/SettingsViewController.xib @@ -11,8 +11,12 @@ 1181 - IBProxyObject + IBUINavigationBar + IBUINavigationItem + IBUIViewController IBUIView + IBUINavigationController + IBProxyObject com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -30,23 +34,54 @@ IBFirstResponder IBCocoaTouchFramework - + 274 - {{0, 20}, {320, 460}} + {320, 460} - - - 3 - MQA - - 2 - - - + _NS:9 IBCocoaTouchFramework + + + + 1 + 1 + + YES + IBCocoaTouchFramework + NO + + + 256 + {0, 0} + _NS:15 + NO + YES + YES + IBCocoaTouchFramework + + + + NO + + + Item + IBCocoaTouchFramework + + + IASKAppSettingsView + + + 1 + 1 + + IBCocoaTouchFramework + NO + + + @@ -54,9 +89,25 @@ view - + - 3 + 9 + + + + settingsController + + + + 8 + + + + navigationController + + + + 15 @@ -67,11 +118,6 @@ - - 1 - - - -1 @@ -83,6 +129,42 @@ + + 4 + + + + + 10 + + + + + + + navigationController + + + 11 + + + navigationBar + + + 6 + + + + + + settingsController + + + 14 + + + settingsItem + @@ -90,19 +172,68 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin UIResponder com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + IASKAppSettingsViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 3 + 15 + + IASKAppSettingsViewController + UITableViewController + + dismiss: + id + + + dismiss: + + dismiss: + id + + + + delegate + id + + + delegate + + delegate + id + + + + IBProjectSource + ./Classes/IASKAppSettingsViewController.h + + SettingsViewController UIViewController + + UINavigationController + IASKAppSettingsViewController + + + + navigationController + UINavigationController + + + settingsController + IASKAppSettingsViewController + + IBProjectSource ./Classes/SettingsViewController.h diff --git a/InAppSettingsKit/Controllers/IASKAppSettingsViewController.h b/InAppSettingsKit/Controllers/IASKAppSettingsViewController.h new file mode 100644 index 000000000..f98f3b494 --- /dev/null +++ b/InAppSettingsKit/Controllers/IASKAppSettingsViewController.h @@ -0,0 +1,87 @@ +// +// IASKAppSettingsViewController.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import +#import + +#import "IASKSettingsReader.h" +#import "IASKSettingsStore.h" +#import "IASKViewController.h" + +@class IASKSettingsReader; +@class IASKAppSettingsViewController; +@class IASKSpecifier; + +@protocol IASKSettingsDelegate +- (void)settingsViewControllerDidEnd:(IASKAppSettingsViewController*)sender; + +@optional +#pragma mark - UITableView header customization +- (CGFloat) settingsViewController:(id)settingsViewController + tableView:(UITableView *)tableView + heightForHeaderForSection:(NSInteger)section; +- (UIView *) settingsViewController:(id)settingsViewController + tableView:(UITableView *)tableView + viewForHeaderForSection:(NSInteger)section; + +#pragma mark - UITableView cell customization +- (CGFloat)tableView:(UITableView*)tableView heightForSpecifier:(IASKSpecifier*)specifier; +- (UITableViewCell*)tableView:(UITableView*)tableView cellForSpecifier:(IASKSpecifier*)specifier; + +#pragma mark - mail composing customization +- (NSString*) settingsViewController:(id)settingsViewController + mailComposeBodyForSpecifier:(IASKSpecifier*) specifier; + +- (UIViewController*) settingsViewController:(id)settingsViewController + viewControllerForMailComposeViewForSpecifier:(IASKSpecifier*) specifier; + +- (void) settingsViewController:(id) settingsViewController + mailComposeController:(MFMailComposeViewController*)controller + didFinishWithResult:(MFMailComposeResult)result + error:(NSError*)error; + +#pragma mark - respond to button taps +- (void)settingsViewController:(IASKAppSettingsViewController*)sender buttonTappedForKey:(NSString*)key; +- (void)settingsViewController:(IASKAppSettingsViewController*)sender tableView:(UITableView *)tableView didSelectCustomViewSpecifier:(IASKSpecifier*)specifier; +@end + + +@interface IASKAppSettingsViewController : UITableViewController { + id _delegate; + + NSMutableArray *_viewList; + + IASKSettingsReader *_settingsReader; + id _settingsReaderDelegate; + id _settingsStore; + NSString *_file; + + id _currentFirstResponder; + + BOOL _showCreditsFooter; + BOOL _showDoneButton; +} + +@property (nonatomic, assign) IBOutlet id delegate; +@property (nonatomic, copy) NSString *file; +@property (nonatomic, assign) id settingsReaderDelegate; +@property (nonatomic, assign) BOOL showCreditsFooter; +@property (nonatomic, assign) BOOL showDoneButton; + +- (void)synchronizeSettings; +- (IBAction)dismiss:(id)sender; + +@end diff --git a/InAppSettingsKit/Controllers/IASKAppSettingsViewController.m b/InAppSettingsKit/Controllers/IASKAppSettingsViewController.m new file mode 100644 index 000000000..557c33730 --- /dev/null +++ b/InAppSettingsKit/Controllers/IASKAppSettingsViewController.m @@ -0,0 +1,799 @@ +// +// IASKAppSettingsViewController.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2009-2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + + +#import "IASKAppSettingsViewController.h" +#import "IASKSettingsReader.h" +#import "IASKSettingsStoreUserDefaults.h" +#import "IASKPSToggleSwitchSpecifierViewCell.h" +#import "IASKPSSliderSpecifierViewCell.h" +#import "IASKPSTextFieldSpecifierViewCell.h" +#import "IASKPSTitleValueSpecifierViewCell.h" +#import "IASKSwitch.h" +#import "IASKSlider.h" +#import "IASKSpecifier.h" +#import "IASKSpecifierValuesViewController.h" +#import "IASKTextField.h" + +static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3; +static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2; +static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8; + +static NSString *kIASKCredits = @"Powered by InAppSettingsKit"; // Leave this as-is!!! + +#define kIASKSpecifierValuesViewControllerIndex 0 +#define kIASKSpecifierChildViewControllerIndex 1 + +#define kIASKCreditsViewWidth 285 + +CGRect IASKCGRectSwap(CGRect rect); + +@interface IASKAppSettingsViewController () +@property (nonatomic, retain) NSMutableArray *viewList; +@property (nonatomic, retain) id currentFirstResponder; + +- (void) setup; + +- (void)_textChanged:(id)sender; +- (void)synchronizeSettings; +- (void)userDefaultsDidChange; +- (void)reload; +@end + +@implementation IASKAppSettingsViewController + +@synthesize delegate = _delegate; +@synthesize viewList = _viewList; +@synthesize settingsReader = _settingsReader; +@synthesize file = _file; +@synthesize currentFirstResponder = _currentFirstResponder; +@synthesize showCreditsFooter = _showCreditsFooter; +@synthesize showDoneButton = _showDoneButton; +@synthesize settingsStore = _settingsStore; +@synthesize settingsReaderDelegate = _settingsReaderDelegate; + +#pragma mark accessors +- (IASKSettingsReader*)settingsReader { + if (!_settingsReader) { + _settingsReader = [[IASKSettingsReader alloc] initWithFile:self.file andDelegate:self.settingsReaderDelegate]; + } + return _settingsReader; +} + +- (id)settingsStore { + if (!_settingsStore) { + _settingsStore = [[IASKSettingsStoreUserDefaults alloc] init]; + } + return _settingsStore; +} + +- (NSString*)file { + if (!_file) { + return @"Root"; + } + return [[_file retain] autorelease]; +} + +- (void)setFile:(NSString *)file { + if (file != _file) { + + [_file release]; + _file = [file copy]; + } + + self.tableView.contentOffset = CGPointMake(0, 0); + self.settingsReader = nil; // automatically initializes itself + [self.tableView reloadData]; +} + +- (BOOL)isPad { + BOOL isPad = NO; +#if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 30200) + isPad = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad; +#endif + return isPad; +} + +#pragma mark standard view controller methods +- (id)init { + return [self initWithNibName:@"IASKAppSettingsView" bundle:nil]; +} + +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) { + // If set to YES, will add a DONE button at the right of the navigation bar + _showDoneButton = YES; + + [self setup]; + } + return self; +} + +- (void)awakeFromNib { + // If set to YES, will add a DONE button at the right of the navigation bar + // if loaded via NIB, it's likely we sit in a TabBar- or NavigationController + // and thus don't need the Done button + _showDoneButton = NO; + + [self setup]; +} + +//common (NIB & code based) initialization +- (void) setup { + // If set to YES, will display credits for InAppSettingsKit creators + _showCreditsFooter = YES; +} + +- (NSMutableArray *)viewList { + if (!_viewList) { + _viewList = [[NSMutableArray alloc] init]; + [_viewList addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"IASKSpecifierValuesView", @"ViewName",nil]]; + [_viewList addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"IASKAppSettingsView", @"ViewName",nil]]; + } + return _viewList; +} + +- (void) viewDidLoad { + [super viewDidLoad]; + if ([self isPad]) { + self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLineEtched; + } +} + +- (void)viewDidUnload { + [super viewDidUnload]; + + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; + self.view = nil; + self.viewList = nil; +} + +- (void)viewWillAppear:(BOOL)animated { + // if there's something selected, the value might have changed + // so reload that row + NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow]; + if(selectedIndexPath) { + [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:selectedIndexPath] + withRowAnimation:UITableViewRowAnimationNone]; + // and reselect it, so we get the nice default deselect animation from UITableViewController + [self.tableView selectRowAtIndexPath:selectedIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; + } + + self.navigationItem.rightBarButtonItem = nil; + self.navigationController.delegate = self; + if (_showDoneButton) { + UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone + target:self + action:@selector(dismiss:)]; + self.navigationItem.rightBarButtonItem = buttonItem; + [buttonItem release]; + } + if (!self.title) { + self.title = NSLocalizedString(@"Settings", @""); + } + + if ([self.settingsStore isKindOfClass:[IASKSettingsStoreUserDefaults class]]) { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(userDefaultsDidChange) + name:NSUserDefaultsDidChangeNotification + object:[NSUserDefaults standardUserDefaults]]; + [self userDefaultsDidChange]; // force update in case of changes while we were hidden + } + [super viewWillAppear:animated]; +} + +- (CGSize)contentSizeForViewInPopover { + return [[self view] sizeThatFits:CGSizeMake(320, 2000)]; +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + + NSNotificationCenter *dc = [NSNotificationCenter defaultCenter]; + IASK_IF_IOS4_OR_GREATER([dc addObserver:self selector:@selector(synchronizeSettings) name:UIApplicationDidEnterBackgroundNotification object:[UIApplication sharedApplication]];); + IASK_IF_IOS4_OR_GREATER([dc addObserver:self selector:@selector(reload) name:UIApplicationWillEnterForegroundNotification object:[UIApplication sharedApplication]];); + [dc addObserver:self selector:@selector(synchronizeSettings) name:UIApplicationWillTerminateNotification object:[UIApplication sharedApplication]]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [NSObject cancelPreviousPerformRequestsWithTarget:self]; + [super viewWillDisappear:animated]; +} + +- (void)viewDidDisappear:(BOOL)animated { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + if (!self.navigationController.delegate) { + // hide the keyboard when we're popping from the navigation controller + [self.currentFirstResponder resignFirstResponder]; + } + [self dismiss:nil]; + [super viewDidDisappear:animated]; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + return YES; +} + +- (void)didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} + +- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { + if (![viewController isKindOfClass:[IASKAppSettingsViewController class]] && ![viewController isKindOfClass:[IASKSpecifierValuesViewController class]]) { + [self dismiss:nil]; + } +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + [_viewList release], _viewList = nil; + [_file release], _file = nil; + [_currentFirstResponder release], _currentFirstResponder = nil; + [_settingsReader release], _settingsReader = nil; + [_settingsStore release], _settingsStore = nil; + + _delegate = nil; + + [super dealloc]; +} + + +#pragma mark - +#pragma mark Actions + +- (IBAction)dismiss:(id)sender { + [self.settingsStore synchronize]; + self.navigationController.delegate = nil; + + if (self.delegate && [self.delegate conformsToProtocol:@protocol(IASKSettingsDelegate)]) { + [self.delegate settingsViewControllerDidEnd:self]; + } + // reload + [self.settingsReader initWithFile:self.file andDelegate:self.settingsReaderDelegate]; + [self.tableView reloadData]; +} + +- (void)toggledValue:(id)sender { + IASKSwitch *toggle = (IASKSwitch*)sender; + IASKSpecifier *spec = [_settingsReader specifierForKey:[toggle key]]; + + if ([toggle isOn]) { + if ([spec trueValue] != nil) { + [self.settingsStore setObject:[spec trueValue] forKey:[toggle key]]; + } + else { + [self.settingsStore setBool:YES forKey:[toggle key]]; + } + } + else { + if ([spec falseValue] != nil) { + [self.settingsStore setObject:[spec falseValue] forKey:[toggle key]]; + } + else { + [self.settingsStore setBool:NO forKey:[toggle key]]; + } + } + [[NSNotificationCenter defaultCenter] postNotificationName:kIASKAppSettingChanged + object:[toggle key] + userInfo:[NSDictionary dictionaryWithObject:[self.settingsStore objectForKey:[toggle key]] + forKey:[toggle key]]]; +} + +- (void)sliderChangedValue:(id)sender { + IASKSlider *slider = (IASKSlider*)sender; + [self.settingsStore setFloat:[slider value] forKey:[slider key]]; + [[NSNotificationCenter defaultCenter] postNotificationName:kIASKAppSettingChanged + object:[slider key] + userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:[slider value]] + forKey:[slider key]]]; +} + + +#pragma mark - +#pragma mark UITableView Functions + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return [self.settingsReader numberOfSections]; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return [self.settingsReader numberOfRowsForSection:section]; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { + IASKSpecifier *specifier = [self.settingsReader specifierForIndexPath:indexPath]; + if ([[specifier type] isEqualToString:kIASKCustomViewSpecifier]) { + if ([self.delegate respondsToSelector:@selector(tableView:heightForSpecifier:)]) { + return [self.delegate tableView:tableView heightForSpecifier:specifier]; + } else { + return 0; + } + } + return tableView.rowHeight; +} + +- (NSString *)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section { + NSString *header = [self.settingsReader titleForSection:section]; + if (0 == header.length) { + return nil; + } + return header; +} + +- (UIView *)tableView:(UITableView*)tableView viewForHeaderInSection:(NSInteger)section { + if ([self.delegate respondsToSelector:@selector(settingsViewController:tableView:viewForHeaderForSection:)]) { + return [self.delegate settingsViewController:self tableView:tableView viewForHeaderForSection:section]; + } else { + return nil; + } +} + +- (CGFloat)tableView:(UITableView*)tableView heightForHeaderInSection:(NSInteger)section { + if ([self tableView:tableView viewForHeaderInSection:section] && [self.delegate respondsToSelector:@selector(settingsViewController:tableView:heightForHeaderForSection:)]) { + CGFloat result; + if ((result = [self.delegate settingsViewController:self tableView:tableView heightForHeaderForSection:section])) { + return result; + } + + } + NSString *title; + if ((title = [self tableView:tableView titleForHeaderInSection:section])) { + CGSize size = [title sizeWithFont:[UIFont boldSystemFontOfSize:[UIFont labelFontSize]] + constrainedToSize:CGSizeMake(tableView.frame.size.width - 2*kIASKHorizontalPaddingGroupTitles, INFINITY) + lineBreakMode:UILineBreakModeWordWrap]; + return size.height+kIASKVerticalPaddingGroupTitles; + } + return 0; +} + +- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section +{ + NSString *footerText = [self.settingsReader footerTextForSection:section]; + if (_showCreditsFooter && (section == [self.settingsReader numberOfSections]-1)) { + // show credits since this is the last section + if ((footerText == nil) || ([footerText length] == 0)) { + // show the credits on their own + return kIASKCredits; + } else { + // show the credits below the app's FooterText + return [NSString stringWithFormat:@"%@\n\n%@", footerText, kIASKCredits]; + } + } else { + if ([footerText length] == 0) { + return nil; + } + return [self.settingsReader footerTextForSection:section]; + } +} + +- (UITableViewCell*)dequeueReusableCellWithIdentifier:(NSString*)identifier { + UITableViewCell *cell = nil; + if ([identifier isEqualToString:kIASKPSToggleSwitchSpecifier]) { + cell = [[[NSBundle mainBundle] loadNibNamed:@"IASKPSToggleSwitchSpecifierViewCell" + owner:self + options:nil] objectAtIndex:0]; + } + else if ([identifier isEqualToString:kIASKPSMultiValueSpecifier] || [identifier isEqualToString:kIASKPSTitleValueSpecifier]) { + cell = [[[IASKPSTitleValueSpecifierViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier] autorelease]; + cell.accessoryType = [identifier isEqualToString:kIASKPSMultiValueSpecifier] ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; + } + else if ([identifier isEqualToString:kIASKPSTextFieldSpecifier]) { + cell = (IASKPSTextFieldSpecifierViewCell*) [[[NSBundle mainBundle] loadNibNamed:@"IASKPSTextFieldSpecifierViewCell" + owner:self + options:nil] objectAtIndex:0]; + } + else if ([identifier isEqualToString:kIASKPSSliderSpecifier]) { + cell = (IASKPSSliderSpecifierViewCell*) [[[NSBundle mainBundle] loadNibNamed:@"IASKPSSliderSpecifierViewCell" + owner:self + options:nil] objectAtIndex:0]; + } else if ([identifier isEqualToString:kIASKPSChildPaneSpecifier]) { + cell = [[[IASKPSTitleValueSpecifierViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier] autorelease]; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + } else if ([identifier isEqualToString:kIASKButtonSpecifier]) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease]; + } else if ([identifier isEqualToString:kIASKMailComposeSpecifier]) { + cell = [[[IASKPSTitleValueSpecifierViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier] autorelease]; + [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; + } else { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease]; + } + return cell; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + IASKSpecifier *specifier = [self.settingsReader specifierForIndexPath:indexPath]; + if ([specifier.type isEqualToString:kIASKCustomViewSpecifier] && [self.delegate respondsToSelector:@selector(tableView:cellForSpecifier:)]) { + UITableViewCell* cell = [self.delegate tableView:tableView cellForSpecifier:specifier]; + assert(nil != cell && "delegate must return a UITableViewCell for custom cell types"); + return cell; + } + + UITableViewCell *cell = [self dequeueReusableCellWithIdentifier:specifier.type]; + + if ([specifier.type isEqualToString:kIASKPSToggleSwitchSpecifier]) { + ((IASKPSToggleSwitchSpecifierViewCell*)cell).label.text = specifier.title; + + id currentValue = [self.settingsStore objectForKey:specifier.key]; + BOOL toggleState; + if (currentValue) { + if ([currentValue isEqual:specifier.trueValue]) { + toggleState = YES; + } else if ([currentValue isEqual:specifier.falseValue]) { + toggleState = NO; + } else { + toggleState = [currentValue boolValue]; + } + } else { + toggleState = specifier.defaultBoolValue; + } + ((IASKPSToggleSwitchSpecifierViewCell*)cell).toggle.on = toggleState; + + [((IASKPSToggleSwitchSpecifierViewCell*)cell).toggle addTarget:self action:@selector(toggledValue:) forControlEvents:UIControlEventValueChanged]; + ((IASKPSToggleSwitchSpecifierViewCell*)cell).toggle.key = specifier.key; + } + else if ([specifier.type isEqualToString:kIASKPSMultiValueSpecifier]) { + cell.textLabel.text = specifier.title; + cell.detailTextLabel.text = [[specifier titleForCurrentValue:[self.settingsStore objectForKey:specifier.key] != nil ? + [self.settingsStore objectForKey:specifier.key] : specifier.defaultValue] description]; + } + else if ([specifier.type isEqualToString:kIASKPSTitleValueSpecifier]) { + cell.textLabel.text = specifier.title; + id value = [self.settingsStore objectForKey:specifier.key] ? : specifier.defaultValue; + + NSString *stringValue; + if (specifier.multipleValues || specifier.multipleTitles) { + stringValue = [specifier titleForCurrentValue:value]; + } else { + stringValue = [value description]; + } + + cell.detailTextLabel.text = stringValue; + cell.userInteractionEnabled = NO; + } + else if ([specifier.type isEqualToString:kIASKPSTextFieldSpecifier]) { + ((IASKPSTextFieldSpecifierViewCell*)cell).label.text = specifier.title; + + NSString *textValue = [self.settingsStore objectForKey:specifier.key] != nil ? [self.settingsStore objectForKey:specifier.key] : specifier.defaultStringValue; + if (textValue && ![textValue isMemberOfClass:[NSString class]]) { + textValue = [NSString stringWithFormat:@"%@", textValue]; + } + IASKTextField *textField = ((IASKPSTextFieldSpecifierViewCell*)cell).textField; + textField.text = textValue; + textField.key = specifier.key; + textField.delegate = self; + textField.secureTextEntry = [specifier isSecure]; + textField.keyboardType = specifier.keyboardType; + textField.autocapitalizationType = specifier.autocapitalizationType; + [textField addTarget:self action:@selector(_textChanged:) forControlEvents:UIControlEventEditingChanged]; + if([specifier isSecure]){ + textField.autocorrectionType = UITextAutocorrectionTypeNo; + } else { + textField.autocorrectionType = specifier.autoCorrectionType; + } + [cell setNeedsLayout]; + } + else if ([specifier.type isEqualToString:kIASKPSSliderSpecifier]) { + if (specifier.minimumValueImage.length > 0) { + ((IASKPSSliderSpecifierViewCell*)cell).minImage.image = [UIImage imageWithContentsOfFile:[_settingsReader pathForImageNamed:specifier.minimumValueImage]]; + } + + if (specifier.maximumValueImage.length > 0) { + ((IASKPSSliderSpecifierViewCell*)cell).maxImage.image = [UIImage imageWithContentsOfFile:[_settingsReader pathForImageNamed:specifier.maximumValueImage]]; + } + + IASKSlider *slider = ((IASKPSSliderSpecifierViewCell*)cell).slider; + slider.minimumValue = specifier.minimumValue; + slider.maximumValue = specifier.maximumValue; + slider.value = [self.settingsStore objectForKey:specifier.key] != nil ? [[self.settingsStore objectForKey:specifier.key] floatValue] : [specifier.defaultValue floatValue]; + [slider addTarget:self action:@selector(sliderChangedValue:) forControlEvents:UIControlEventValueChanged]; + slider.key = specifier.key; + [cell setNeedsLayout]; + } + else if ([specifier.type isEqualToString:kIASKPSChildPaneSpecifier]) { + cell.textLabel.text = specifier.title; + } else if ([specifier.type isEqualToString:kIASKOpenURLSpecifier] || [specifier.type isEqualToString:kIASKMailComposeSpecifier]) { + cell.textLabel.text = specifier.title; + cell.detailTextLabel.text = [specifier.defaultValue description]; + } else if ([specifier.type isEqualToString:kIASKButtonSpecifier]) { + NSString *value = [self.settingsStore objectForKey:specifier.key]; + cell.textLabel.text = [value isKindOfClass:[NSString class]] ? [self.settingsReader titleForStringId:value] : specifier.title; + cell.textLabel.textAlignment = UITextAlignmentCenter; + } else { + cell.textLabel.text = specifier.title; + } + return cell; +} + +- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { + //create a set of specifier types that can't be selected + static NSSet* noSelectionTypes = nil; + if(nil == noSelectionTypes) { + noSelectionTypes = [[NSSet setWithObjects:kIASKPSToggleSwitchSpecifier, kIASKPSSliderSpecifier, nil] retain]; + } + + IASKSpecifier *specifier = [self.settingsReader specifierForIndexPath:indexPath]; + if([noSelectionTypes containsObject:specifier.type]) { + return nil; + } else { + return indexPath; + } +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + IASKSpecifier *specifier = [self.settingsReader specifierForIndexPath:indexPath]; + + //switches and sliders can't be selected (should be captured by tableView:willSelectRowAtIndexPath: delegate method) + assert(![[specifier type] isEqualToString:kIASKPSToggleSwitchSpecifier]); + assert(![[specifier type] isEqualToString:kIASKPSSliderSpecifier]); + + if ([[specifier type] isEqualToString:kIASKPSMultiValueSpecifier]) { + IASKSpecifierValuesViewController *targetViewController = [[self.viewList objectAtIndex:kIASKSpecifierValuesViewControllerIndex] objectForKey:@"viewController"]; + + if (targetViewController == nil) { + // the view controller has not been created yet, create it and set it to our viewList array + // create a new dictionary with the new view controller + NSMutableDictionary *newItemDict = [NSMutableDictionary dictionaryWithCapacity:3]; + [newItemDict addEntriesFromDictionary: [self.viewList objectAtIndex:kIASKSpecifierValuesViewControllerIndex]]; // copy the title and explain strings + + targetViewController = [[IASKSpecifierValuesViewController alloc] initWithNibName:@"IASKSpecifierValuesView" bundle:nil]; + // add the new view controller to the dictionary and then to the 'viewList' array + [newItemDict setObject:targetViewController forKey:@"viewController"]; + [self.viewList replaceObjectAtIndex:kIASKSpecifierValuesViewControllerIndex withObject:newItemDict]; + [targetViewController release]; + + // load the view controll back in to push it + targetViewController = [[self.viewList objectAtIndex:kIASKSpecifierValuesViewControllerIndex] objectForKey:@"viewController"]; + } + [targetViewController setCurrentSpecifier:specifier]; + targetViewController.settingsReader = self.settingsReader; + targetViewController.settingsStore = self.settingsStore; + [[self navigationController] pushViewController:targetViewController animated:YES]; + } + else if ([[specifier type] isEqualToString:kIASKPSTextFieldSpecifier]) { + IASKPSTextFieldSpecifierViewCell *textFieldCell = (id)[tableView cellForRowAtIndexPath:indexPath]; + [textFieldCell.textField becomeFirstResponder]; + } + else if ([[specifier type] isEqualToString:kIASKPSChildPaneSpecifier]) { + + + Class vcClass = [specifier viewControllerClass]; + if (vcClass) { + SEL initSelector = [specifier viewControllerSelector]; + if (!initSelector) { + initSelector = @selector(init); + } + UIViewController * vc = [vcClass performSelector:@selector(alloc)]; + [vc performSelector:initSelector withObject:[specifier file] withObject:[specifier key]]; + if ([vc respondsToSelector:@selector(setDelegate:)]) { + [vc performSelector:@selector(setDelegate:) withObject:self.delegate]; + } + if ([vc respondsToSelector:@selector(setSettingsStore:)]) { + [vc performSelector:@selector(setSettingsStore:) withObject:self.settingsStore]; + } + self.navigationController.delegate = nil; + [self.navigationController pushViewController:vc animated:YES]; + [vc performSelector:@selector(release)]; + return; + } + + if (nil == [specifier file]) { + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + return; + } + + IASKAppSettingsViewController *targetViewController = [[self.viewList objectAtIndex:kIASKSpecifierChildViewControllerIndex] objectForKey:@"viewController"]; + + if (targetViewController == nil) { + // the view controller has not been created yet, create it and set it to our viewList array + // create a new dictionary with the new view controller + NSMutableDictionary *newItemDict = [NSMutableDictionary dictionaryWithCapacity:3]; + [newItemDict addEntriesFromDictionary: [self.viewList objectAtIndex:kIASKSpecifierChildViewControllerIndex]]; // copy the title and explain strings + + targetViewController = [[[self class] alloc] initWithNibName:@"IASKAppSettingsView" bundle:nil]; + targetViewController.showDoneButton = NO; + targetViewController.settingsStore = self.settingsStore; + targetViewController.delegate = self.delegate; + + // add the new view controller to the dictionary and then to the 'viewList' array + [newItemDict setObject:targetViewController forKey:@"viewController"]; + [self.viewList replaceObjectAtIndex:kIASKSpecifierChildViewControllerIndex withObject:newItemDict]; + [targetViewController release]; + + // load the view controll back in to push it + targetViewController = [[self.viewList objectAtIndex:kIASKSpecifierChildViewControllerIndex] objectForKey:@"viewController"]; + } + targetViewController.settingsReaderDelegate = self.settingsReaderDelegate; + targetViewController.file = specifier.file; // changes settingsReader + + targetViewController.title = specifier.title; + targetViewController.showCreditsFooter = NO; + [[self navigationController] pushViewController:targetViewController animated:YES]; + } else if ([[specifier type] isEqualToString:kIASKOpenURLSpecifier]) { + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + [[UIApplication sharedApplication] openURL:[NSURL URLWithString:specifier.file]]; + } else if ([[specifier type] isEqualToString:kIASKButtonSpecifier]) { + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + if ([self.delegate respondsToSelector:@selector(settingsViewController:buttonTappedForKey:)]) { + [self.delegate settingsViewController:self buttonTappedForKey:[specifier key]]; + } else { + // legacy code, provided for backward compatibility + // the delegate mechanism above is much cleaner and doesn't leak + Class buttonClass = [specifier buttonClass]; + SEL buttonAction = [specifier buttonAction]; + if ([buttonClass respondsToSelector:buttonAction]) { + [buttonClass performSelector:buttonAction withObject:self withObject:[specifier key]]; + NSLog(@"InAppSettingsKit Warning: Using IASKButtonSpecifier without implementing the delegate method is deprecated"); + } + } + } else if ([[specifier type] isEqualToString:kIASKMailComposeSpecifier]) { + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + if ([MFMailComposeViewController canSendMail]) { + MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init]; + mailViewController.navigationBar.barStyle = self.navigationController.navigationBar.barStyle; + mailViewController.navigationBar.tintColor = self.navigationController.navigationBar.tintColor; + + if ([specifier localizedObjectForKey:kIASKMailComposeSubject]) { + [mailViewController setSubject:[specifier localizedObjectForKey:kIASKMailComposeSubject]]; + } + if ([[specifier specifierDict] objectForKey:kIASKMailComposeToRecipents]) { + [mailViewController setToRecipients:[[specifier specifierDict] objectForKey:kIASKMailComposeToRecipents]]; + } + if ([[specifier specifierDict] objectForKey:kIASKMailComposeCcRecipents]) { + [mailViewController setCcRecipients:[[specifier specifierDict] objectForKey:kIASKMailComposeCcRecipents]]; + } + if ([[specifier specifierDict] objectForKey:kIASKMailComposeBccRecipents]) { + [mailViewController setBccRecipients:[[specifier specifierDict] objectForKey:kIASKMailComposeBccRecipents]]; + } + if ([specifier localizedObjectForKey:kIASKMailComposeBody]) { + BOOL isHTML = NO; + if ([[specifier specifierDict] objectForKey:kIASKMailComposeBodyIsHTML]) { + isHTML = [[[specifier specifierDict] objectForKey:kIASKMailComposeBodyIsHTML] boolValue]; + } + + if ([self.delegate respondsToSelector:@selector(settingsViewController:mailComposeBodyForSpecifier:)]) { + [mailViewController setMessageBody:[self.delegate settingsViewController:self + mailComposeBodyForSpecifier:specifier] isHTML:isHTML]; + } + else { + [mailViewController setMessageBody:[specifier localizedObjectForKey:kIASKMailComposeBody] isHTML:isHTML]; + } + } + + UIViewController *vc = nil; + + if ([self.delegate respondsToSelector:@selector(settingsViewController:viewControllerForMailComposeViewForSpecifier:)]) { + vc = [self.delegate settingsViewController:self viewControllerForMailComposeViewForSpecifier:specifier]; + } + + if (vc == nil) { + vc = self; + } + + mailViewController.mailComposeDelegate = vc; + [vc presentModalViewController:mailViewController animated:YES]; + [mailViewController release]; + } else { + UIAlertView *alert = [[UIAlertView alloc] + initWithTitle:NSLocalizedString(@"Mail not configured", @"InAppSettingsKit") + message:NSLocalizedString(@"This device is not configured for sending Email. Please configure the Mail settings in the Settings app.", @"InAppSettingsKit") + delegate: nil + cancelButtonTitle:NSLocalizedString(@"OK", @"InAppSettingsKit") + otherButtonTitles:nil]; + [alert show]; + [alert release]; + } + + } else if ([[specifier type] isEqualToString:kIASKCustomViewSpecifier] && [self.delegate respondsToSelector:@selector(settingsViewController:tableView:didSelectCustomViewSpecifier:)]) { + [self.delegate settingsViewController:self tableView:tableView didSelectCustomViewSpecifier:specifier]; + } else { + [tableView deselectRowAtIndexPath:indexPath animated:NO]; + } +} + + +#pragma mark - +#pragma mark MFMailComposeViewControllerDelegate Function + +-(void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error { + + // Forward the mail compose delegate + if ([self.delegate respondsToSelector:@selector(settingsViewController:mailComposeController:didFinishWithResult:error:)]) { + [self.delegate settingsViewController:self + mailComposeController:controller + didFinishWithResult:result + error:error]; + } + + // NOTE: No error handling is done here + [self dismissModalViewControllerAnimated:YES]; +} + +#pragma mark - +#pragma mark UITextFieldDelegate Functions + +- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField { + self.currentFirstResponder = textField; + return YES; +} + +- (void)_textChanged:(id)sender { + IASKTextField *text = (IASKTextField*)sender; + [_settingsStore setObject:[text text] forKey:[text key]]; + [[NSNotificationCenter defaultCenter] postNotificationName:kIASKAppSettingChanged + object:[text key] + userInfo:[NSDictionary dictionaryWithObject:[text text] + forKey:[text key]]]; +} + +- (BOOL)textFieldShouldReturn:(UITextField *)textField{ + [textField resignFirstResponder]; + self.currentFirstResponder = nil; + return YES; +} + + +#pragma mark Notifications + +- (void)synchronizeSettings { + [_settingsStore synchronize]; +} + +static NSDictionary *oldUserDefaults = nil; +- (void)userDefaultsDidChange { + NSDictionary *currentDict = [NSUserDefaults standardUserDefaults].dictionaryRepresentation; + NSMutableArray *indexPathsToUpdate = [NSMutableArray array]; + for (NSString *key in currentDict.allKeys) { + if (![[oldUserDefaults valueForKey:key] isEqual:[currentDict valueForKey:key]]) { + NSIndexPath *path = [self.settingsReader indexPathForKey:key]; + if (path && ![[self.settingsReader specifierForKey:key].type isEqualToString:kIASKCustomViewSpecifier]) { + [indexPathsToUpdate addObject:path]; + } + } + } + [oldUserDefaults release], oldUserDefaults = [currentDict retain]; + + + for (UITableViewCell *cell in self.tableView.visibleCells) { + if ([cell isKindOfClass:[IASKPSTextFieldSpecifierViewCell class]] && [((IASKPSTextFieldSpecifierViewCell*)cell).textField isFirstResponder]) { + [indexPathsToUpdate removeObject:[self.tableView indexPathForCell:cell]]; + } + } + if (indexPathsToUpdate.count) { + [self.tableView reloadRowsAtIndexPaths:indexPathsToUpdate withRowAnimation:UITableViewRowAnimationNone]; + } +} + +- (void)reload { + // wait 0.5 sec until UI is available after applicationWillEnterForeground + [self.tableView performSelector:@selector(reloadData) withObject:nil afterDelay:0.5]; +} + +#pragma mark CGRect Utility function +CGRect IASKCGRectSwap(CGRect rect) { + CGRect newRect; + newRect.origin.x = rect.origin.y; + newRect.origin.y = rect.origin.x; + newRect.size.width = rect.size.height; + newRect.size.height = rect.size.width; + return newRect; +} +@end diff --git a/InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.h b/InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.h new file mode 100644 index 000000000..08b6ceb27 --- /dev/null +++ b/InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.h @@ -0,0 +1,30 @@ +// +// IASKAppSettingsWebViewController.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import +#import + +@interface IASKAppSettingsWebViewController : UIViewController { + UIWebView *webView; + NSURL *url; +} + +- (id)initWithFile:(NSString*)htmlFileName key:(NSString*)key; + +@property (nonatomic, retain) IBOutlet UIWebView *webView; +@property (nonatomic, retain) NSURL *url; + +@end diff --git a/InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.m b/InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.m new file mode 100644 index 000000000..46429b3ce --- /dev/null +++ b/InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.m @@ -0,0 +1,148 @@ +// +// IASKAppSettingsWebViewController.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKAppSettingsWebViewController.h" + +@implementation IASKAppSettingsWebViewController + +@synthesize url; +@synthesize webView; + +- (id)initWithFile:(NSString*)urlString key:(NSString*)key { + if (!(self = [super initWithNibName:nil bundle:nil])) { + return nil; + } + + self.url = [NSURL URLWithString:urlString]; + if (!self.url || ![self.url scheme]) { + NSString *path = [[NSBundle mainBundle] pathForResource:[urlString stringByDeletingPathExtension] ofType:[urlString pathExtension]]; + if(path) + self.url = [NSURL fileURLWithPath:path]; + else + self.url = nil; + } + return self; +} + + +- (void)dealloc { + [webView release], webView = nil; + [url release], url = nil; + + [super dealloc]; +} + +- (void)viewWillAppear:(BOOL)animated { + [webView loadRequest:[NSURLRequest requestWithURL:self.url]]; +} + +- (void)viewDidUnload { + [super viewDidUnload]; + self.webView = nil; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + return YES; +} + +- (void)webViewDidFinishLoad:(UIWebView *)webView { + self.navigationItem.title = [self.webView stringByEvaluatingJavaScriptFromString:@"document.title"]; +} + +- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { + NSURL *newURL = [request URL]; + + // intercept mailto URL and send it to an in-app Mail compose view instead + if ([[newURL scheme] isEqualToString:@"mailto"]) { + + NSArray *rawURLparts = [[newURL resourceSpecifier] componentsSeparatedByString:@"?"]; + if (rawURLparts.count > 2) { + return NO; // invalid URL + } + + MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init]; + mailViewController.mailComposeDelegate = self; + + NSMutableArray *toRecipients = [NSMutableArray array]; + NSString *defaultRecipient = [rawURLparts objectAtIndex:0]; + if (defaultRecipient.length) { + [toRecipients addObject:defaultRecipient]; + } + + if (rawURLparts.count == 2) { + NSString *queryString = [rawURLparts objectAtIndex:1]; + + NSArray *params = [queryString componentsSeparatedByString:@"&"]; + for (NSString *param in params) { + NSArray *keyValue = [param componentsSeparatedByString:@"="]; + if (keyValue.count != 2) { + continue; + } + NSString *key = [[keyValue objectAtIndex:0] lowercaseString]; + NSString *value = [keyValue objectAtIndex:1]; + + value = (NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault, + (CFStringRef)value, + CFSTR(""), + kCFStringEncodingUTF8); + [value autorelease]; + + if ([key isEqualToString:@"subject"]) { + [mailViewController setSubject:value]; + } + + if ([key isEqualToString:@"body"]) { + [mailViewController setMessageBody:value isHTML:NO]; + } + + if ([key isEqualToString:@"to"]) { + [toRecipients addObjectsFromArray:[value componentsSeparatedByString:@","]]; + } + + if ([key isEqualToString:@"cc"]) { + NSArray *recipients = [value componentsSeparatedByString:@","]; + [mailViewController setCcRecipients:recipients]; + } + + if ([key isEqualToString:@"bcc"]) { + NSArray *recipients = [value componentsSeparatedByString:@","]; + [mailViewController setBccRecipients:recipients]; + } + } + } + + [mailViewController setToRecipients:toRecipients]; + + [self presentModalViewController:mailViewController animated:YES]; + [mailViewController release]; + return NO; + } + + // open inline if host is the same, otherwise, pass to the system + if (![newURL host] || [[newURL host] isEqualToString:[self.url host]]) { + return YES; + } + [[UIApplication sharedApplication] openURL:newURL]; + return NO; +} + +- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error { + [self dismissModalViewControllerAnimated:YES]; +} + + + +@end diff --git a/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.h b/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.h new file mode 100644 index 000000000..d2810d368 --- /dev/null +++ b/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.h @@ -0,0 +1,36 @@ +// +// IASKSpecifierValuesViewController.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import +#import "IASKSettingsStore.h" +#import "IASKViewController.h" +@class IASKSpecifier; +@class IASKSettingsReader; + +@interface IASKSpecifierValuesViewController : UIViewController { + UITableView *_tableView; + + IASKSpecifier *_currentSpecifier; + NSIndexPath *_checkedItem; + IASKSettingsReader *_settingsReader; + id _settingsStore; +} + +@property (nonatomic, retain) IBOutlet UITableView *tableView; +@property (nonatomic, retain) NSIndexPath *checkedItem; +@property (nonatomic, retain) IASKSpecifier *currentSpecifier; + +@end diff --git a/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.m b/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.m new file mode 100644 index 000000000..84236a755 --- /dev/null +++ b/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.m @@ -0,0 +1,195 @@ +// +// IASKSpecifierValuesViewController.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKSpecifierValuesViewController.h" +#import "IASKSpecifier.h" +#import "IASKSettingsReader.h" +#import "IASKSettingsStoreUserDefaults.h" + +#define kCellValue @"kCellValue" + +@interface IASKSpecifierValuesViewController() +- (void)userDefaultsDidChange; +@end + +@implementation IASKSpecifierValuesViewController + +@synthesize tableView=_tableView; +@synthesize currentSpecifier=_currentSpecifier; +@synthesize checkedItem=_checkedItem; +@synthesize settingsReader = _settingsReader; +@synthesize settingsStore = _settingsStore; + +- (void) updateCheckedItem { + NSInteger index; + + // Find the currently checked item + if([self.settingsStore objectForKey:[_currentSpecifier key]]) { + index = [[_currentSpecifier multipleValues] indexOfObject:[self.settingsStore objectForKey:[_currentSpecifier key]]]; + } else { + index = [[_currentSpecifier multipleValues] indexOfObject:[_currentSpecifier defaultValue]]; + } + [self setCheckedItem:[NSIndexPath indexPathForRow:index inSection:0]]; +} + +- (id)settingsStore { + if(_settingsStore == nil) { + _settingsStore = [[IASKSettingsStoreUserDefaults alloc] init]; + } + return _settingsStore; +} + +- (void)viewWillAppear:(BOOL)animated { + if (_currentSpecifier) { + [self setTitle:[_currentSpecifier title]]; + [self updateCheckedItem]; + } + + if (_tableView) { + [_tableView reloadData]; + + // Make sure the currently checked item is visible + [_tableView scrollToRowAtIndexPath:[self checkedItem] atScrollPosition:UITableViewScrollPositionMiddle animated:NO]; + } + [super viewWillAppear:animated]; +} + +- (void)viewDidAppear:(BOOL)animated { + [_tableView flashScrollIndicators]; + [super viewDidAppear:animated]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(userDefaultsDidChange) + name:NSUserDefaultsDidChangeNotification + object:[NSUserDefaults standardUserDefaults]]; +} + +- (void)viewDidDisappear:(BOOL)animated { + [[NSNotificationCenter defaultCenter] removeObserver:self name:NSUserDefaultsDidChangeNotification object:nil]; + [super viewDidDisappear:animated]; +} + + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + return YES; +} + +- (void)didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} + +- (void)viewDidUnload { + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; + self.tableView = nil; +} + + +- (void)dealloc { + [_currentSpecifier release], _currentSpecifier = nil; + [_checkedItem release], _checkedItem = nil; + [_settingsReader release], _settingsReader = nil; + [_settingsStore release], _settingsStore = nil; + [_tableView release], _tableView = nil; + [super dealloc]; +} + + +#pragma mark - +#pragma mark UITableView delegates + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return [_currentSpecifier multipleValuesCount]; +} + +- (void)selectCell:(UITableViewCell *)cell { + [cell setAccessoryType:UITableViewCellAccessoryCheckmark]; + [[cell textLabel] setTextColor:kIASKgrayBlueColor]; +} + +- (void)deselectCell:(UITableViewCell *)cell { + [cell setAccessoryType:UITableViewCellAccessoryNone]; + [[cell textLabel] setTextColor:[UIColor darkTextColor]]; +} + +- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section { + return [_currentSpecifier footerText]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellValue]; + NSArray *titles = [_currentSpecifier multipleTitles]; + + if (!cell) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellValue] autorelease]; + } + + if ([indexPath isEqual:[self checkedItem]]) { + [self selectCell:cell]; + } else { + [self deselectCell:cell]; + } + + @try { + [[cell textLabel] setText:[self.settingsReader titleForStringId:[titles objectAtIndex:indexPath.row]]]; + } + @catch (NSException * e) {} + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + + if (indexPath == [self checkedItem]) { + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + return; + } + + NSArray *values = [_currentSpecifier multipleValues]; + + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + [self deselectCell:[tableView cellForRowAtIndexPath:[self checkedItem]]]; + [self selectCell:[tableView cellForRowAtIndexPath:indexPath]]; + [self setCheckedItem:indexPath]; + + [self.settingsStore setObject:[values objectAtIndex:indexPath.row] forKey:[_currentSpecifier key]]; + [self.settingsStore synchronize]; + [[NSNotificationCenter defaultCenter] postNotificationName:kIASKAppSettingChanged + object:[_currentSpecifier key] + userInfo:[NSDictionary dictionaryWithObject:[values objectAtIndex:indexPath.row] + forKey:[_currentSpecifier key]]]; +} + +#pragma mark Notifications + +- (void)userDefaultsDidChange { + NSIndexPath *oldCheckedItem = [[self.checkedItem retain] autorelease]; + if(_currentSpecifier) { + [self updateCheckedItem]; + } + + // only reload the table if it had changed; prevents animation cancellation + if (![self.checkedItem isEqual:oldCheckedItem]) { + [_tableView reloadData]; + } +} + +@end diff --git a/InAppSettingsKit/Controllers/IASKViewController.h b/InAppSettingsKit/Controllers/IASKViewController.h new file mode 100644 index 000000000..40e450415 --- /dev/null +++ b/InAppSettingsKit/Controllers/IASKViewController.h @@ -0,0 +1,26 @@ +// +// IASKAppSettingsViewController.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +@class IASKSettingsReader; +@protocol IASKSettingsStore; + +// protocol all IASK view controllers implement +@protocol IASKViewController + +@property (nonatomic, retain) IASKSettingsReader* settingsReader; +@property (nonatomic, retain) id settingsStore; + +@end diff --git a/InAppSettingsKit/Models/IASKSettingsReader.h b/InAppSettingsKit/Models/IASKSettingsReader.h new file mode 100644 index 000000000..c66156d8b --- /dev/null +++ b/InAppSettingsKit/Models/IASKSettingsReader.h @@ -0,0 +1,149 @@ +// +// IASKSettingsReader.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import + +#define kIASKPreferenceSpecifiers @"PreferenceSpecifiers" +#define kIASKType @"Type" +#define kIASKTitle @"Title" +#define kIASKFooterText @"FooterText" +#define kIASKKey @"Key" +#define kIASKFile @"File" +#define kIASKDefaultValue @"DefaultValue" +#define kIASKMinimumValue @"MinimumValue" +#define kIASKMaximumValue @"MaximumValue" +#define kIASKTrueValue @"TrueValue" +#define kIASKFalseValue @"FalseValue" +#define kIASKIsSecure @"IsSecure" +#define KIASKKeyboardType @"KeyboardType" +#define kIASKAutocapitalizationType @"AutocapitalizationType" +#define kIASKAutoCorrectionType @"AutocorrectionType" +#define kIASKValues @"Values" +#define kIASKTitles @"Titles" +#define kIASKViewControllerClass @"IASKViewControllerClass" +#define kIASKViewControllerSelector @"IASKViewControllerSelector" +#define kIASKButtonClass @"IASKButtonClass" +#define kIASKButtonAction @"IASKButtonAction" +#define kIASKMailComposeToRecipents @"IASKMailComposeToRecipents" +#define kIASKMailComposeCcRecipents @"IASKMailComposeCcRecipents" +#define kIASKMailComposeBccRecipents @"IASKMailComposeBccRecipents" +#define kIASKMailComposeSubject @"IASKMailComposeSubject" +#define kIASKMailComposeBody @"IASKMailComposeBody" +#define kIASKMailComposeBodyIsHTML @"IASKMailComposeBodyIsHTML" +#define kIASKKeyboardAlphabet @"Alphabet" +#define kIASKKeyboardNumbersAndPunctuation @"NumbersAndPunctuation" +#define kIASKKeyboardNumberPad @"NumberPad" +#define kIASKKeyboardDecimalPad @"DecimalPad" + +#define KIASKKeyboardURL @"URL" +#define kIASKKeyboardEmailAddress @"EmailAddress" +#define kIASKAutoCapNone @"None" +#define kIASKAutoCapSentences @"Sentences" +#define kIASKAutoCapWords @"Words" +#define kIASKAutoCapAllCharacters @"AllCharacters" +#define kIASKAutoCorrDefault @"Default" +#define kIASKAutoCorrNo @"No" +#define kIASKAutoCorrYes @"Yes" +#define kIASKMinimumValueImage @"MinimumValueImage" +#define kIASKMaximumValueImage @"MaximumValueImage" + +#define kIASKPSGroupSpecifier @"PSGroupSpecifier" +#define kIASKPSToggleSwitchSpecifier @"PSToggleSwitchSpecifier" +#define kIASKPSMultiValueSpecifier @"PSMultiValueSpecifier" +#define kIASKPSSliderSpecifier @"PSSliderSpecifier" +#define kIASKPSTitleValueSpecifier @"PSTitleValueSpecifier" +#define kIASKPSTextFieldSpecifier @"PSTextFieldSpecifier" +#define kIASKPSChildPaneSpecifier @"PSChildPaneSpecifier" +#define kIASKOpenURLSpecifier @"IASKOpenURLSpecifier" +#define kIASKButtonSpecifier @"IASKButtonSpecifier" +#define kIASKMailComposeSpecifier @"IASKMailComposeSpecifier" +#define kIASKCustomViewSpecifier @"IASKCustomViewSpecifier" + +#define kIASKBundleFolder @"Settings.bundle" +#define kIASKBundleFolderAlt @"InAppSettings.bundle" +#define kIASKBundleFilename @"Root.plist" +#define KIASKBundleLocaleFolderExtension @".lproj" + +#define kIASKAppSettingChanged @"kAppSettingChanged" + +#define kIASKSectionHeaderIndex 0 + +#define kIASKSliderNoImagesPadding 11 +#define kIASKSliderImagesPadding 43 + + +#define kIASKTableWidth 320 +#define kIASKSpacing 5 +#define kIASKMinLabelWidth 97 +#define kIASKMinValueWidth 35 +#define kIASKPaddingLeft 9 +#define kIASKPaddingRight 10 +#define kIASKHorizontalPaddingGroupTitles 19 +#define kIASKVerticalPaddingGroupTitles 15 + +#define kIASKLabelFontSize 17 +#define kIASKgrayBlueColor [UIColor colorWithRed:0.318 green:0.4 blue:0.569 alpha:1.0] + +#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_4_0 +#define kCFCoreFoundationVersionNumber_iPhoneOS_4_0 550.32 +#endif + +#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_4_1 +#define kCFCoreFoundationVersionNumber_iPhoneOS_4_1 550.38 +#endif + + +#define IASK_IF_IOS4_OR_GREATER(...) \ +if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iPhoneOS_4_0) \ +{ \ +__VA_ARGS__ \ +} + +@class IASKSpecifier; + +@protocol IASKSettingsReaderFilterDelegate +- (NSDictionary*) filterPreferenceSpecifier:(NSDictionary*)specifier; +@end + +@interface IASKSettingsReader : NSObject { + NSString *_path; + NSString *_localizationTable; + NSString *_bundlePath; + NSDictionary *_settingsBundle; + NSArray *_dataSource; + NSBundle *_bundle; + id _delegate; +} + +- (id)initWithFile:(NSString*)file andDelegate:(id)delegate; +- (NSInteger)numberOfSections; +- (NSInteger)numberOfRowsForSection:(NSInteger)section; +- (IASKSpecifier*)specifierForIndexPath:(NSIndexPath*)indexPath; +- (NSIndexPath*)indexPathForKey:(NSString*)key; +- (IASKSpecifier*)specifierForKey:(NSString*)key; +- (NSString*)titleForSection:(NSInteger)section; +- (NSString*)keyForSection:(NSInteger)section; +- (NSString*)footerTextForSection:(NSInteger)section; +- (NSString*)titleForStringId:(NSString*)stringId; +- (NSString*)pathForImageNamed:(NSString*)image; + +@property (nonatomic, retain) NSString *path; +@property (nonatomic, retain) NSString *localizationTable; +@property (nonatomic, retain) NSString *bundlePath; +@property (nonatomic, retain) NSDictionary *settingsBundle; +@property (nonatomic, retain) NSArray *dataSource; + +@end diff --git a/InAppSettingsKit/Models/IASKSettingsReader.m b/InAppSettingsKit/Models/IASKSettingsReader.m new file mode 100644 index 000000000..7e53458ec --- /dev/null +++ b/InAppSettingsKit/Models/IASKSettingsReader.m @@ -0,0 +1,279 @@ +// +// IASKSettingsReader.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKSettingsReader.h" +#import "IASKSpecifier.h" + +@interface IASKSettingsReader (private) +- (void)_reinterpretBundle:(NSDictionary*)settingsBundle; +- (BOOL)_sectionHasHeading:(NSInteger)section; +- (NSString *)platformSuffix; +- (NSString *)locateSettingsFile:(NSString *)file; + +@end + +@implementation IASKSettingsReader + +@synthesize path=_path, +localizationTable=_localizationTable, +bundlePath=_bundlePath, +settingsBundle=_settingsBundle, +dataSource=_dataSource; + + +- (id)init { + return [self initWithFile:@"Root" andDelegate:nil]; +} + +- (id)initWithFile:(NSString*)file andDelegate:(id)delegate{ + if ((self=[super init])) { + + + self.path = [self locateSettingsFile: file]; + [self setSettingsBundle:[NSDictionary dictionaryWithContentsOfFile:self.path]]; + self.bundlePath = [self.path stringByDeletingLastPathComponent]; + _bundle = [[NSBundle bundleWithPath:[self bundlePath]] retain]; + + // Look for localization file + self.localizationTable = [self.settingsBundle objectForKey:@"StringsTable"]; + if (!self.localizationTable) + { + // Look for localization file using filename + self.localizationTable = [[[[self.path stringByDeletingPathExtension] // removes '.plist' + stringByDeletingPathExtension] // removes potential '.inApp' + lastPathComponent] // strip absolute path + stringByReplacingOccurrencesOfString:[self platformSuffix] withString:@""]; // removes potential '~device' (~ipad, ~iphone) + if([_bundle pathForResource:self.localizationTable ofType:@"strings"] == nil){ + // Could not find the specified localization: use default + self.localizationTable = @"Root"; + } + } + _delegate=delegate; + if (_settingsBundle) { + [self _reinterpretBundle:_settingsBundle]; + } + } + return self; +} + +- (void)dealloc { + [_path release], _path = nil; + [_localizationTable release], _localizationTable = nil; + [_bundlePath release], _bundlePath = nil; + [_settingsBundle release], _settingsBundle = nil; + [_dataSource release], _dataSource = nil; + [_bundle release], _bundle = nil; + + [super dealloc]; +} + +- (void)_reinterpretBundle:(NSDictionary*)settingsBundle { + NSArray *preferenceSpecifiers = [settingsBundle objectForKey:kIASKPreferenceSpecifiers]; + NSInteger sectionCount = -1; + NSMutableArray *dataSource = [[[NSMutableArray alloc] init] autorelease]; + + for (NSDictionary *specifier in preferenceSpecifiers) { + if (_delegate != nil) { + specifier = [_delegate filterPreferenceSpecifier:specifier]; + if (specifier == nil) { + // skip + continue; + } + } + if ([(NSString*)[specifier objectForKey:kIASKType] isEqualToString:kIASKPSGroupSpecifier]) { + NSMutableArray *newArray = [[NSMutableArray alloc] init]; + + [newArray addObject:specifier]; + [dataSource addObject:newArray]; + [newArray release]; + sectionCount++; + } + else { + if (sectionCount == -1) { + NSMutableArray *newArray = [[NSMutableArray alloc] init]; + [dataSource addObject:newArray]; + [newArray release]; + sectionCount++; + } + + IASKSpecifier *newSpecifier = [[IASKSpecifier alloc] initWithSpecifier:specifier]; + [(NSMutableArray*)[dataSource objectAtIndex:sectionCount] addObject:newSpecifier]; + [newSpecifier release]; + } + } + [self setDataSource:dataSource]; +} + +- (BOOL)_sectionHasHeading:(NSInteger)section { + return [[[[self dataSource] objectAtIndex:section] objectAtIndex:0] isKindOfClass:[NSDictionary class]]; +} + +- (NSInteger)numberOfSections { + return [[self dataSource] count]; +} + +- (NSInteger)numberOfRowsForSection:(NSInteger)section { + int headingCorrection = [self _sectionHasHeading:section] ? 1 : 0; + NSInteger ret= [(NSArray*)[[self dataSource] objectAtIndex:section] count] - headingCorrection; + return ret; +} + +- (IASKSpecifier*)specifierForIndexPath:(NSIndexPath*)indexPath { + int headingCorrection = [self _sectionHasHeading:indexPath.section] ? 1 : 0; + + IASKSpecifier *specifier = [[[self dataSource] objectAtIndex:indexPath.section] objectAtIndex:(indexPath.row+headingCorrection)]; + specifier.settingsReader = self; + return specifier; +} + +- (NSIndexPath*)indexPathForKey:(NSString *)key { + for (NSUInteger sectionIndex = 0; sectionIndex < self.dataSource.count; sectionIndex++) { + NSArray *section = [self.dataSource objectAtIndex:sectionIndex]; + for (NSUInteger rowIndex = 0; rowIndex < section.count; rowIndex++) { + IASKSpecifier *specifier = (IASKSpecifier*)[section objectAtIndex:rowIndex]; + if ([specifier isKindOfClass:[IASKSpecifier class]] && [specifier.key isEqualToString:key]) { + NSUInteger correctedRowIndex = rowIndex - [self _sectionHasHeading:sectionIndex]; + return [NSIndexPath indexPathForRow:correctedRowIndex inSection:sectionIndex]; + } + } + } + return nil; +} + +- (IASKSpecifier*)specifierForKey:(NSString*)key { + for (NSArray *specifiers in _dataSource) { + for (id sp in specifiers) { + if ([sp isKindOfClass:[IASKSpecifier class]]) { + if ([[sp key] isEqualToString:key]) { + return sp; + } + } + } + } + return nil; +} + +- (NSString*)titleForSection:(NSInteger)section { + if ([self _sectionHasHeading:section]) { + NSDictionary *dict = [[[self dataSource] objectAtIndex:section] objectAtIndex:kIASKSectionHeaderIndex]; + return [self titleForStringId:[dict objectForKey:kIASKTitle]]; + } + return nil; +} + +- (NSString*)keyForSection:(NSInteger)section { + if ([self _sectionHasHeading:section]) { + return [[[[self dataSource] objectAtIndex:section] objectAtIndex:kIASKSectionHeaderIndex] objectForKey:kIASKKey]; + } + return nil; +} + +- (NSString*)footerTextForSection:(NSInteger)section { + if ([self _sectionHasHeading:section]) { + NSDictionary *dict = [[[self dataSource] objectAtIndex:section] objectAtIndex:kIASKSectionHeaderIndex]; + return [self titleForStringId:[dict objectForKey:kIASKFooterText]]; + } + return nil; +} + +- (NSString*)titleForStringId:(NSString*)stringId { + return [_bundle localizedStringForKey:stringId value:stringId table:self.localizationTable]; +} + +- (NSString*)pathForImageNamed:(NSString*)image { + return [[self bundlePath] stringByAppendingPathComponent:image]; +} + +- (NSString *)platformSuffix { + BOOL isPad = NO; +#if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 30200) + isPad = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad; +#endif + return isPad ? @"~ipad" : @"~iphone"; +} + +- (NSString *)file:(NSString *)file + withBundle:(NSString *)bundle + suffix:(NSString *)suffix + extension:(NSString *)extension { + + NSString *appBundle = [[NSBundle mainBundle] bundlePath]; + bundle = [appBundle stringByAppendingPathComponent:bundle]; + file = [file stringByAppendingFormat:@"%@%@", suffix, extension]; + return [bundle stringByAppendingPathComponent:file]; + +} + +- (NSString *)locateSettingsFile: (NSString *)file { + + // The file is searched in the following order: + // + // InAppSettings.bundle/FILE~DEVICE.inApp.plist + // InAppSettings.bundle/FILE.inApp.plist + // InAppSettings.bundle/FILE~DEVICE.plist + // InAppSettings.bundle/FILE.plist + // Settings.bundle/FILE~DEVICE.inApp.plist + // Settings.bundle/FILE.inApp.plist + // Settings.bundle/FILE~DEVICE.plist + // Settings.bundle/FILE.plist + // + // where DEVICE is either "iphone" or "ipad" depending on the current + // interface idiom. + // + // Settings.app uses the ~DEVICE suffixes since iOS 4.0. There are some + // differences from this implementation: + // - For an iPhone-only app running on iPad, Settings.app will not use the + // ~iphone suffix. There is no point in using these suffixes outside + // of universal apps anyway. + // - This implementation uses the device suffixes on iOS 3.x as well. + // - also check current locale (short only) + + NSArray *bundles = + [NSArray arrayWithObjects:kIASKBundleFolderAlt, kIASKBundleFolder, nil]; + + NSArray *extensions = + [NSArray arrayWithObjects:@".inApp.plist", @".plist", nil]; + + NSArray *suffixes = + [NSArray arrayWithObjects:[self platformSuffix], @"", nil]; + + NSArray *languages = + [NSArray arrayWithObjects:[[[NSLocale preferredLanguages] objectAtIndex:0] stringByAppendingString:KIASKBundleLocaleFolderExtension], @"", nil]; + + NSString *path = nil; + NSFileManager *fileManager = [NSFileManager defaultManager]; + + for (NSString *bundle in bundles) { + for (NSString *extension in extensions) { + for (NSString *suffix in suffixes) { + for (NSString *language in languages) { + path = [self file:file + withBundle:[bundle stringByAppendingPathComponent:language] + suffix:suffix + extension:extension]; + if ([fileManager fileExistsAtPath:path]) { + goto exitFromNestedLoop; + } + } + } + } + } + +exitFromNestedLoop: + return path; +} + +@end diff --git a/InAppSettingsKit/Models/IASKSettingsStore.h b/InAppSettingsKit/Models/IASKSettingsStore.h new file mode 100644 index 000000000..c1b53ba2b --- /dev/null +++ b/InAppSettingsKit/Models/IASKSettingsStore.h @@ -0,0 +1,39 @@ +// +// IASKSettingsStore.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// Marc-Etienne M.Léveillé, Edovia Inc., http://www.edovia.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import + +@protocol IASKSettingsStore +@required +- (void)setBool:(BOOL)value forKey:(NSString*)key; +- (void)setFloat:(float)value forKey:(NSString*)key; +- (void)setDouble:(double)value forKey:(NSString*)key; +- (void)setInteger:(int)value forKey:(NSString*)key; +- (void)setObject:(id)value forKey:(NSString*)key; +- (BOOL)boolForKey:(NSString*)key; +- (float)floatForKey:(NSString*)key; +- (double)doubleForKey:(NSString*)key; +- (int)integerForKey:(NSString*)key; +- (id)objectForKey:(NSString*)key; +- (BOOL)synchronize; // Write settings to a permanant storage. Returns YES on success, NO otherwise +@end + + +@interface IASKAbstractSettingsStore : NSObject { +} + +@end diff --git a/InAppSettingsKit/Models/IASKSettingsStore.m b/InAppSettingsKit/Models/IASKSettingsStore.m new file mode 100644 index 000000000..8efbe7da2 --- /dev/null +++ b/InAppSettingsKit/Models/IASKSettingsStore.m @@ -0,0 +1,68 @@ +// +// IASKSettingsStore.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// Marc-Etienne M.Léveillé, Edovia Inc., http://www.edovia.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKSettingsStore.h" + +@implementation IASKAbstractSettingsStore + +- (void)setObject:(id)value forKey:(NSString*)key { + [NSException raise:@"Unimplemented" + format:@"setObject:forKey: must be implemented in subclasses of IASKAbstractSettingsStore"]; +} + +- (id)objectForKey:(NSString*)key { + [NSException raise:@"Unimplemented" + format:@"objectForKey: must be implemented in subclasses of IASKAbstractSettingsStore"]; + return nil; +} + +- (void)setBool:(BOOL)value forKey:(NSString*)key { + [self setObject:[NSNumber numberWithBool:value] forKey:key]; +} + +- (void)setFloat:(float)value forKey:(NSString*)key { + [self setObject:[NSNumber numberWithFloat:value] forKey:key]; +} + +- (void)setInteger:(int)value forKey:(NSString*)key { + [self setObject:[NSNumber numberWithInt:value] forKey:key]; +} + +- (void)setDouble:(double)value forKey:(NSString*)key { + [self setObject:[NSNumber numberWithDouble:value] forKey:key]; +} + +- (BOOL)boolForKey:(NSString*)key { + return [[self objectForKey:key] boolValue]; +} + +- (float)floatForKey:(NSString*)key { + return [[self objectForKey:key] floatValue]; +} +- (int)integerForKey:(NSString*)key { + return [[self objectForKey:key] intValue]; +} + +- (double)doubleForKey:(NSString*)key { + return [[self objectForKey:key] doubleValue]; +} + +- (BOOL)synchronize { + return NO; +} + +@end \ No newline at end of file diff --git a/InAppSettingsKit/Models/IASKSettingsStoreFile.h b/InAppSettingsKit/Models/IASKSettingsStoreFile.h new file mode 100644 index 000000000..6d4fe2993 --- /dev/null +++ b/InAppSettingsKit/Models/IASKSettingsStoreFile.h @@ -0,0 +1,28 @@ +// +// IASKSettingsStoreFile.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// Marc-Etienne M.Léveillé, Edovia Inc., http://www.edovia.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import +#import "IASKSettingsStore.h" + +@interface IASKSettingsStoreFile : IASKAbstractSettingsStore { + NSString * _filePath; + NSMutableDictionary * _dict; +} + +- (id)initWithPath:(NSString*)path; + +@end diff --git a/InAppSettingsKit/Models/IASKSettingsStoreFile.m b/InAppSettingsKit/Models/IASKSettingsStoreFile.m new file mode 100644 index 000000000..104642d7e --- /dev/null +++ b/InAppSettingsKit/Models/IASKSettingsStoreFile.m @@ -0,0 +1,54 @@ +// +// IASKSettingsStoreFile.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// Marc-Etienne M.Léveillé, Edovia Inc., http://www.edovia.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKSettingsStoreFile.h" + + +@implementation IASKSettingsStoreFile + +- (id)initWithPath:(NSString*)path { + if((self = [super init])) { + _filePath = [path retain]; + _dict = [[NSMutableDictionary alloc] initWithContentsOfFile:path]; + if(_dict == nil) { + _dict = [[NSMutableDictionary alloc] init]; + } + } + return self; +} + +- (void)dealloc { + [_dict release], _dict = nil; + [_filePath release], _filePath = nil; + + [super dealloc]; +} + + +- (void)setObject:(id)value forKey:(NSString *)key { + [_dict setObject:value forKey:key]; +} + +- (id)objectForKey:(NSString *)key { + return [_dict objectForKey:key]; +} + +- (BOOL)synchronize { + return [_dict writeToFile:_filePath atomically:YES]; +} + +@end diff --git a/InAppSettingsKit/Models/IASKSettingsStoreUserDefaults.h b/InAppSettingsKit/Models/IASKSettingsStoreUserDefaults.h new file mode 100644 index 000000000..3731f5e3b --- /dev/null +++ b/InAppSettingsKit/Models/IASKSettingsStoreUserDefaults.h @@ -0,0 +1,25 @@ +// +// IASKSettingsStoreUserDefaults.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// Marc-Etienne M.Léveillé, Edovia Inc., http://www.edovia.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import +#import "IASKSettingsStore.h" + +@interface IASKSettingsStoreUserDefaults : IASKAbstractSettingsStore { + +} + +@end diff --git a/InAppSettingsKit/Models/IASKSettingsStoreUserDefaults.m b/InAppSettingsKit/Models/IASKSettingsStoreUserDefaults.m new file mode 100644 index 000000000..fd24bf097 --- /dev/null +++ b/InAppSettingsKit/Models/IASKSettingsStoreUserDefaults.m @@ -0,0 +1,67 @@ +// +// IASKSettingsStoreUserDefaults.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// Marc-Etienne M.Léveillé, Edovia Inc., http://www.edovia.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKSettingsStoreUserDefaults.h" + + +@implementation IASKSettingsStoreUserDefaults + +- (void)setBool:(BOOL)value forKey:(NSString*)key { + [[NSUserDefaults standardUserDefaults] setBool:value forKey:key]; +} + +- (void)setFloat:(float)value forKey:(NSString*)key { + [[NSUserDefaults standardUserDefaults] setFloat:value forKey:key]; +} + +- (void)setDouble:(double)value forKey:(NSString*)key { + [[NSUserDefaults standardUserDefaults] setDouble:value forKey:key]; +} + +- (void)setInteger:(int)value forKey:(NSString*)key { + [[NSUserDefaults standardUserDefaults] setInteger:value forKey:key]; +} + +- (void)setObject:(id)value forKey:(NSString*)key { + [[NSUserDefaults standardUserDefaults] setObject:value forKey:key]; +} + +- (BOOL)boolForKey:(NSString*)key { + return [[NSUserDefaults standardUserDefaults] boolForKey:key]; +} + +- (float)floatForKey:(NSString*)key { + return [[NSUserDefaults standardUserDefaults] floatForKey:key]; +} + +- (double)doubleForKey:(NSString*)key { + return [[NSUserDefaults standardUserDefaults] doubleForKey:key]; +} + +- (int)integerForKey:(NSString*)key { + return [[NSUserDefaults standardUserDefaults] integerForKey:key]; +} + +- (id)objectForKey:(NSString*)key { + return [[NSUserDefaults standardUserDefaults] objectForKey:key]; +} + +- (BOOL)synchronize { + return [[NSUserDefaults standardUserDefaults] synchronize]; +} + +@end diff --git a/InAppSettingsKit/Models/IASKSpecifier.h b/InAppSettingsKit/Models/IASKSpecifier.h new file mode 100644 index 000000000..1e47d1ec8 --- /dev/null +++ b/InAppSettingsKit/Models/IASKSpecifier.h @@ -0,0 +1,59 @@ +// +// IASKSpecifier.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import +#import + +@class IASKSettingsReader; + +@interface IASKSpecifier : NSObject { + NSDictionary *_specifierDict; + NSDictionary *_multipleValuesDict; + IASKSettingsReader *_settingsReader; +} +@property (nonatomic, retain) NSDictionary *specifierDict; +@property (nonatomic, assign) IASKSettingsReader *settingsReader; + +- (id)initWithSpecifier:(NSDictionary*)specifier; +- (NSString*)localizedObjectForKey:(NSString*)key; +- (NSString*)title; +- (NSString*)key; +- (NSString*)type; +- (NSString*)titleForCurrentValue:(id)currentValue; +- (NSInteger)multipleValuesCount; +- (NSArray*)multipleValues; +- (NSArray*)multipleTitles; +- (NSString*)file; +- (id)defaultValue; +- (id)defaultStringValue; +- (BOOL)defaultBoolValue; +- (id)trueValue; +- (id)falseValue; +- (float)minimumValue; +- (float)maximumValue; +- (NSString*)minimumValueImage; +- (NSString*)maximumValueImage; +- (BOOL)isSecure; +- (UIKeyboardType)keyboardType; +- (UITextAutocapitalizationType)autocapitalizationType; +- (UITextAutocorrectionType)autoCorrectionType; +- (NSString*)footerText; +- (Class)viewControllerClass; +- (SEL)viewControllerSelector; +-(Class)buttonClass; +-(SEL)buttonAction; + +@end diff --git a/InAppSettingsKit/Models/IASKSpecifier.m b/InAppSettingsKit/Models/IASKSpecifier.m new file mode 100644 index 000000000..ebb38ac01 --- /dev/null +++ b/InAppSettingsKit/Models/IASKSpecifier.m @@ -0,0 +1,240 @@ +// +// IASKSpecifier.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKSpecifier.h" +#import "IASKSettingsReader.h" + +@interface IASKSpecifier () +@property (nonatomic, retain) NSDictionary *multipleValuesDict; +- (void)_reinterpretValues:(NSDictionary*)specifierDict; +@end + +@implementation IASKSpecifier + +@synthesize specifierDict=_specifierDict; +@synthesize multipleValuesDict=_multipleValuesDict; +@synthesize settingsReader = _settingsReader; + +- (id)initWithSpecifier:(NSDictionary*)specifier { + if ((self = [super init])) { + [self setSpecifierDict:specifier]; + + if ([[self type] isEqualToString:kIASKPSMultiValueSpecifier] || + [[self type] isEqualToString:kIASKPSTitleValueSpecifier]) { + [self _reinterpretValues:[self specifierDict]]; + } + } + return self; +} + +- (void)dealloc { + [_specifierDict release], _specifierDict = nil; + [_multipleValuesDict release], _multipleValuesDict = nil; + + _settingsReader = nil; + + [super dealloc]; +} + +- (void)_reinterpretValues:(NSDictionary*)specifierDict { + NSArray *values = [_specifierDict objectForKey:kIASKValues]; + NSArray *titles = [_specifierDict objectForKey:kIASKTitles]; + + NSMutableDictionary *multipleValuesDict = [[[NSMutableDictionary alloc] init] autorelease]; + + if (values) { + [multipleValuesDict setObject:values forKey:kIASKValues]; + } + + if (titles) { + [multipleValuesDict setObject:titles forKey:kIASKTitles]; + } + + [self setMultipleValuesDict:multipleValuesDict]; +} +- (NSString*)localizedObjectForKey:(NSString*)key { + return [self.settingsReader titleForStringId:[_specifierDict objectForKey:key]]; +} + +- (NSString*)title { + return [self localizedObjectForKey:kIASKTitle]; +} + +- (NSString*)footerText { + return [self localizedObjectForKey:kIASKFooterText]; +} + +-(Class) viewControllerClass { + return NSClassFromString([_specifierDict objectForKey:kIASKViewControllerClass]); +} + +-(SEL) viewControllerSelector { + return NSSelectorFromString([_specifierDict objectForKey:kIASKViewControllerSelector]); +} + +-(Class)buttonClass { + return NSClassFromString([_specifierDict objectForKey:kIASKButtonClass]); +} + +-(SEL)buttonAction { + return NSSelectorFromString([_specifierDict objectForKey:kIASKButtonAction]); +} + +- (NSString*)key { + return [_specifierDict objectForKey:kIASKKey]; +} + +- (NSString*)type { + return [_specifierDict objectForKey:kIASKType]; +} + +- (NSString*)titleForCurrentValue:(id)currentValue { + NSArray *values = [self multipleValues]; + NSArray *titles = [self multipleTitles]; + if (values.count != titles.count) { + return nil; + } + NSInteger keyIndex = [values indexOfObject:currentValue]; + if (keyIndex == NSNotFound) { + return nil; + } + @try { + return [self.settingsReader titleForStringId:[titles objectAtIndex:keyIndex]]; + } + @catch (NSException * e) {} + return nil; +} + +- (NSInteger)multipleValuesCount { + return [[_multipleValuesDict objectForKey:kIASKValues] count]; +} + +- (NSArray*)multipleValues { + return [_multipleValuesDict objectForKey:kIASKValues]; +} + +- (NSArray*)multipleTitles { + return [_multipleValuesDict objectForKey:kIASKTitles]; +} + +- (NSString*)file { + return [_specifierDict objectForKey:kIASKFile]; +} + +- (id)defaultValue { + return [_specifierDict objectForKey:kIASKDefaultValue]; +} + +- (id)defaultStringValue { + return [[_specifierDict objectForKey:kIASKDefaultValue] description]; +} + +- (BOOL)defaultBoolValue { + id defaultValue = [self defaultValue]; + if ([defaultValue isEqual:[self trueValue]]) { + return YES; + } + if ([defaultValue isEqual:[self falseValue]]) { + return NO; + } + return [defaultValue boolValue]; +} + +- (id)trueValue { + return [_specifierDict objectForKey:kIASKTrueValue]; +} + +- (id)falseValue { + return [_specifierDict objectForKey:kIASKFalseValue]; +} + +- (float)minimumValue { + return [[_specifierDict objectForKey:kIASKMinimumValue] floatValue]; +} + +- (float)maximumValue { + return [[_specifierDict objectForKey:kIASKMaximumValue] floatValue]; +} + +- (NSString*)minimumValueImage { + return [_specifierDict objectForKey:kIASKMinimumValueImage]; +} + +- (NSString*)maximumValueImage { + return [_specifierDict objectForKey:kIASKMaximumValueImage]; +} + +- (BOOL)isSecure { + return [[_specifierDict objectForKey:kIASKIsSecure] boolValue]; +} + +- (UIKeyboardType)keyboardType { + if ([[_specifierDict objectForKey:KIASKKeyboardType] isEqualToString:kIASKKeyboardAlphabet]) { + return UIKeyboardTypeDefault; + } + else if ([[_specifierDict objectForKey:KIASKKeyboardType] isEqualToString:kIASKKeyboardNumbersAndPunctuation]) { + return UIKeyboardTypeNumbersAndPunctuation; + } + else if ([[_specifierDict objectForKey:KIASKKeyboardType] isEqualToString:kIASKKeyboardNumberPad]) { + return UIKeyboardTypeNumberPad; + } + else if ([[_specifierDict objectForKey:KIASKKeyboardType] isEqualToString:kIASKKeyboardDecimalPad]) { + if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iPhoneOS_4_1) { + return UIKeyboardTypeDecimalPad; + } + else { + return UIKeyboardTypeNumbersAndPunctuation; + } + } + else if ([[_specifierDict objectForKey:KIASKKeyboardType] isEqualToString:KIASKKeyboardURL]) { + return UIKeyboardTypeURL; + } + else if ([[_specifierDict objectForKey:KIASKKeyboardType] isEqualToString:kIASKKeyboardEmailAddress]) { + return UIKeyboardTypeEmailAddress; + } + return UIKeyboardTypeDefault; +} + +- (UITextAutocapitalizationType)autocapitalizationType { + if ([[_specifierDict objectForKey:kIASKAutocapitalizationType] isEqualToString:kIASKAutoCapNone]) { + return UITextAutocapitalizationTypeNone; + } + else if ([[_specifierDict objectForKey:kIASKAutocapitalizationType] isEqualToString:kIASKAutoCapSentences]) { + return UITextAutocapitalizationTypeSentences; + } + else if ([[_specifierDict objectForKey:kIASKAutocapitalizationType] isEqualToString:kIASKAutoCapWords]) { + return UITextAutocapitalizationTypeWords; + } + else if ([[_specifierDict objectForKey:kIASKAutocapitalizationType] isEqualToString:kIASKAutoCapAllCharacters]) { + return UITextAutocapitalizationTypeAllCharacters; + } + return UITextAutocapitalizationTypeNone; +} + +- (UITextAutocorrectionType)autoCorrectionType { + if ([[_specifierDict objectForKey:kIASKAutoCorrectionType] isEqualToString:kIASKAutoCorrDefault]) { + return UITextAutocorrectionTypeDefault; + } + else if ([[_specifierDict objectForKey:kIASKAutoCorrectionType] isEqualToString:kIASKAutoCorrNo]) { + return UITextAutocorrectionTypeNo; + } + else if ([[_specifierDict objectForKey:kIASKAutoCorrectionType] isEqualToString:kIASKAutoCorrYes]) { + return UITextAutocorrectionTypeYes; + } + return UITextAutocorrectionTypeDefault; +} + +@end diff --git a/InAppSettingsKit/Views/IASKPSSliderSpecifierViewCell.h b/InAppSettingsKit/Views/IASKPSSliderSpecifierViewCell.h new file mode 100644 index 000000000..7cc943b0a --- /dev/null +++ b/InAppSettingsKit/Views/IASKPSSliderSpecifierViewCell.h @@ -0,0 +1,31 @@ +// +// IASKPSSliderSpecifierViewCell.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import + +@class IASKSlider; + +@interface IASKPSSliderSpecifierViewCell : UITableViewCell { + IASKSlider *_slider; + UIImageView *_minImage; + UIImageView *_maxImage; +} + +@property (nonatomic, assign) IBOutlet IASKSlider *slider; +@property (nonatomic, assign) IBOutlet UIImageView *minImage; +@property (nonatomic, assign) IBOutlet UIImageView *maxImage; + +@end diff --git a/InAppSettingsKit/Views/IASKPSSliderSpecifierViewCell.m b/InAppSettingsKit/Views/IASKPSSliderSpecifierViewCell.m new file mode 100644 index 000000000..cbdca0279 --- /dev/null +++ b/InAppSettingsKit/Views/IASKPSSliderSpecifierViewCell.m @@ -0,0 +1,72 @@ +// +// IASKPSSliderSpecifierViewCell.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2009-2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKPSSliderSpecifierViewCell.h" +#import "IASKSlider.h" +#import "IASKSettingsReader.h" + +@implementation IASKPSSliderSpecifierViewCell + +@synthesize slider=_slider, + minImage=_minImage, + maxImage=_maxImage; + +- (void)layoutSubviews { + [super layoutSubviews]; + CGRect sliderBounds = _slider.bounds; + CGPoint sliderCenter = _slider.center; + const double superViewWidth = _slider.superview.frame.size.width; + + sliderCenter.x = superViewWidth / 2; + sliderBounds.size.width = superViewWidth - kIASKSliderNoImagesPadding * 2; + _minImage.hidden = YES; + _maxImage.hidden = YES; + + // Check if there are min and max images. If so, change the layout accordingly. + if (_minImage.image && _maxImage.image) { + // Both images + _minImage.hidden = NO; + _maxImage.hidden = NO; + sliderBounds.size.width = superViewWidth - kIASKSliderImagesPadding * 2; + } + else if (_minImage.image) { + // Min image + _minImage.hidden = NO; + sliderCenter.x += (kIASKSliderImagesPadding - kIASKSliderNoImagesPadding) / 2; + sliderBounds.size.width = superViewWidth - kIASKSliderNoImagesPadding - kIASKSliderImagesPadding; + } + else if (_maxImage.image) { + // Max image + _maxImage.hidden = NO; + sliderCenter.x -= (kIASKSliderImagesPadding - kIASKSliderNoImagesPadding) / 2; + sliderBounds.size.width = superViewWidth - kIASKSliderNoImagesPadding - kIASKSliderImagesPadding; + } + + _slider.bounds = sliderBounds; + _slider.center = sliderCenter; +} + +- (void)dealloc { + _minImage.image = nil; + _maxImage.image = nil; + [super dealloc]; +} + +- (void)prepareForReuse { + _minImage.image = nil; + _maxImage.image = nil; +} +@end diff --git a/InAppSettingsKit/Views/IASKPSTextFieldSpecifierViewCell.h b/InAppSettingsKit/Views/IASKPSTextFieldSpecifierViewCell.h new file mode 100644 index 000000000..b4d70c8ad --- /dev/null +++ b/InAppSettingsKit/Views/IASKPSTextFieldSpecifierViewCell.h @@ -0,0 +1,29 @@ +// +// IASKPSTextFieldSpecifierViewCell.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import + +@class IASKTextField; + +@interface IASKPSTextFieldSpecifierViewCell : UITableViewCell { + UILabel *_label; + IASKTextField *_textField; +} + +@property (nonatomic, assign) IBOutlet UILabel *label; +@property (nonatomic, assign) IBOutlet IASKTextField *textField; + +@end diff --git a/InAppSettingsKit/Views/IASKPSTextFieldSpecifierViewCell.m b/InAppSettingsKit/Views/IASKPSTextFieldSpecifierViewCell.m new file mode 100644 index 000000000..cf7486eea --- /dev/null +++ b/InAppSettingsKit/Views/IASKPSTextFieldSpecifierViewCell.m @@ -0,0 +1,52 @@ +// +// IASKPSTextFieldSpecifierViewCell.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2009-2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKPSTextFieldSpecifierViewCell.h" +#import "IASKTextField.h" +#import "IASKSettingsReader.h" + +@implementation IASKPSTextFieldSpecifierViewCell + +@synthesize label=_label, + textField=_textField; + +- (void)layoutSubviews { + [super layoutSubviews]; + CGSize labelSize = [_label sizeThatFits:CGSizeZero]; + labelSize.width = MIN(labelSize.width, _label.bounds.size.width); + + CGRect textFieldFrame = _textField.frame; + textFieldFrame.origin.x = _label.frame.origin.x + MAX(kIASKMinLabelWidth, labelSize.width) + kIASKSpacing; + if (!_label.text.length) + textFieldFrame.origin.x = _label.frame.origin.x; + textFieldFrame.size.width = _textField.superview.frame.size.width - textFieldFrame.origin.x - _label.frame.origin.x; + _textField.frame = textFieldFrame; +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + + +- (void)dealloc { + [super dealloc]; +} + + +@end diff --git a/InAppSettingsKit/Views/IASKPSTitleValueSpecifierViewCell.h b/InAppSettingsKit/Views/IASKPSTitleValueSpecifierViewCell.h new file mode 100644 index 000000000..b3185b410 --- /dev/null +++ b/InAppSettingsKit/Views/IASKPSTitleValueSpecifierViewCell.h @@ -0,0 +1,22 @@ +// +// IASKPSTitleValueSpecifierViewCell.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import + + +@interface IASKPSTitleValueSpecifierViewCell : UITableViewCell + +@end diff --git a/InAppSettingsKit/Views/IASKPSTitleValueSpecifierViewCell.m b/InAppSettingsKit/Views/IASKPSTitleValueSpecifierViewCell.m new file mode 100644 index 000000000..c1d5aaa55 --- /dev/null +++ b/InAppSettingsKit/Views/IASKPSTitleValueSpecifierViewCell.m @@ -0,0 +1,57 @@ +// +// IASKPSTitleValueSpecifierViewCell.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2010: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKPSTitleValueSpecifierViewCell.h" +#import "IASKSettingsReader.h" + + +@implementation IASKPSTitleValueSpecifierViewCell + +- (void)layoutSubviews { + // left align the value if the title is empty + if (!self.textLabel.text.length) { + self.textLabel.text = self.detailTextLabel.text; + self.detailTextLabel.text = nil; + if ([self.reuseIdentifier isEqualToString:kIASKPSMultiValueSpecifier]) { + self.textLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize]]; + self.textLabel.textColor = self.detailTextLabel.textColor; + } + } + [super layoutSubviews]; + + CGSize viewSize = [self.textLabel superview].frame.size; + + //if there's an image, make room for it + CGFloat imageOffset = self.imageView.image ? self.imageView.bounds.size.width + self.imageView.frame.origin.x : 0; + + // set the left title label frame + CGFloat labelWidth = [self.textLabel sizeThatFits:CGSizeZero].width; + CGFloat minValueWidth = (self.detailTextLabel.text.length) ? kIASKMinValueWidth + kIASKSpacing : 0; + labelWidth = MIN(labelWidth, viewSize.width - minValueWidth - kIASKPaddingLeft -kIASKPaddingRight - imageOffset); + CGRect labelFrame = CGRectMake(kIASKPaddingLeft + imageOffset, 0, labelWidth, viewSize.height -2); + self.textLabel.frame = labelFrame; + + // set the right value label frame + if (self.detailTextLabel.text.length) { + CGRect valueFrame = CGRectMake(kIASKPaddingLeft + labelWidth + kIASKSpacing + imageOffset, + 0, + viewSize.width - (kIASKPaddingLeft + labelWidth + kIASKSpacing + imageOffset) - kIASKPaddingRight, + viewSize.height -2); + self.detailTextLabel.frame = valueFrame; + } +} + +@end diff --git a/InAppSettingsKit/Views/IASKPSToggleSwitchSpecifierViewCell.h b/InAppSettingsKit/Views/IASKPSToggleSwitchSpecifierViewCell.h new file mode 100644 index 000000000..a6d2864bc --- /dev/null +++ b/InAppSettingsKit/Views/IASKPSToggleSwitchSpecifierViewCell.h @@ -0,0 +1,29 @@ +// +// IASKPSToggleSwitchSpecifierViewCell.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import + +@class IASKSwitch; + +@interface IASKPSToggleSwitchSpecifierViewCell : UITableViewCell { + UILabel *_label; + IASKSwitch *_toggle; +} + +@property (nonatomic, assign) IBOutlet UILabel *label; +@property (nonatomic, assign) IBOutlet IASKSwitch *toggle; + +@end diff --git a/InAppSettingsKit/Views/IASKPSToggleSwitchSpecifierViewCell.m b/InAppSettingsKit/Views/IASKPSToggleSwitchSpecifierViewCell.m new file mode 100644 index 000000000..13c66e285 --- /dev/null +++ b/InAppSettingsKit/Views/IASKPSToggleSwitchSpecifierViewCell.m @@ -0,0 +1,62 @@ +// +// IASKPSToggleSwitchSpecifierViewCell.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKPSToggleSwitchSpecifierViewCell.h" +#import "IASKSwitch.h" +#import "IASKSettingsReader.h" + +@implementation IASKPSToggleSwitchSpecifierViewCell + +@synthesize label=_label, + toggle=_toggle; + +- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) { + // Initialization code + } + return self; +} + + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + + +- (void)dealloc { + [super dealloc]; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + if(self.imageView.image) { + //resize the label to make room for the image + self.label.frame = CGRectMake(CGRectGetWidth(self.imageView.bounds) + self.imageView.frame.origin.x + kIASKSpacing, + self.label.frame.origin.y, + self.toggle.frame.origin.x - CGRectGetWidth(self.imageView.bounds) - 2.f * kIASKSpacing, + self.label.frame.size.height); + } else { + self.label.frame = CGRectMake(kIASKPaddingLeft, + self.label.frame.origin.y, + self.toggle.frame.origin.x - kIASKSpacing - kIASKPaddingLeft, + self.label.frame.size.height); + } +} + +@end diff --git a/InAppSettingsKit/Views/IASKSlider.h b/InAppSettingsKit/Views/IASKSlider.h new file mode 100644 index 000000000..34c5ecbbe --- /dev/null +++ b/InAppSettingsKit/Views/IASKSlider.h @@ -0,0 +1,26 @@ +// +// IASKSlider.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import + + +@interface IASKSlider : UISlider { + NSString *_key; +} + +@property (nonatomic, retain) NSString *key; + +@end diff --git a/InAppSettingsKit/Views/IASKSlider.m b/InAppSettingsKit/Views/IASKSlider.m new file mode 100644 index 000000000..d591ff298 --- /dev/null +++ b/InAppSettingsKit/Views/IASKSlider.m @@ -0,0 +1,30 @@ +// +// IASKSlider.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKSlider.h" + + +@implementation IASKSlider + +@synthesize key=_key; + +- (void)dealloc { + [_key release], _key = nil; + + [super dealloc]; +} + +@end diff --git a/InAppSettingsKit/Views/IASKSwitch.h b/InAppSettingsKit/Views/IASKSwitch.h new file mode 100644 index 000000000..b1439bd1c --- /dev/null +++ b/InAppSettingsKit/Views/IASKSwitch.h @@ -0,0 +1,26 @@ +// +// IASKSwitch.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import + + +@interface IASKSwitch : UISwitch { + NSString *_key; +} + +@property (nonatomic, retain) NSString *key; + +@end diff --git a/InAppSettingsKit/Views/IASKSwitch.m b/InAppSettingsKit/Views/IASKSwitch.m new file mode 100644 index 000000000..f32aba4d3 --- /dev/null +++ b/InAppSettingsKit/Views/IASKSwitch.m @@ -0,0 +1,31 @@ +// +// IASKSwitch.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKSwitch.h" + + +@implementation IASKSwitch + +@synthesize key=_key; + +- (void)dealloc { + [_key release], _key = nil; + + [super dealloc]; +} + + +@end diff --git a/InAppSettingsKit/Views/IASKTextField.h b/InAppSettingsKit/Views/IASKTextField.h new file mode 100644 index 000000000..47c9be375 --- /dev/null +++ b/InAppSettingsKit/Views/IASKTextField.h @@ -0,0 +1,26 @@ +// +// IASKTextField.h +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import + + +@interface IASKTextField : UITextField { + NSString *_key; +} + +@property (nonatomic, retain) NSString *key; + +@end diff --git a/InAppSettingsKit/Views/IASKTextField.m b/InAppSettingsKit/Views/IASKTextField.m new file mode 100644 index 000000000..9056896f4 --- /dev/null +++ b/InAppSettingsKit/Views/IASKTextField.m @@ -0,0 +1,30 @@ +// +// IASKTextField.m +// http://www.inappsettingskit.com +// +// Copyright (c) 2009: +// Luc Vandal, Edovia Inc., http://www.edovia.com +// Ortwin Gentz, FutureTap GmbH, http://www.futuretap.com +// All rights reserved. +// +// It is appreciated but not required that you give credit to Luc Vandal and Ortwin Gentz, +// as the original authors of this code. You can give credit in a blog post, a tweet or on +// a info page of your app. Also, the original authors appreciate letting them know if you use this code. +// +// This code is licensed under the BSD license that is available at: http://www.opensource.org/licenses/bsd-license.php +// + +#import "IASKTextField.h" + + +@implementation IASKTextField + +@synthesize key=_key; + +- (void)dealloc { + [_key release], _key = nil; + + [super dealloc]; +} + +@end diff --git a/InAppSettingsKit/Xibs/IASKAppSettingsView.xib b/InAppSettingsKit/Xibs/IASKAppSettingsView.xib new file mode 100644 index 000000000..74720fae3 --- /dev/null +++ b/InAppSettingsKit/Xibs/IASKAppSettingsView.xib @@ -0,0 +1,222 @@ + + + + 1280 + 11B26 + 1934 + 1138 + 566.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 931 + + + YES + IBProxyObject + IBUITableView + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + PluginDependencyRecalculationVersion + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 274 + {320, 460} + + + + 10 + + 549453824 + {512, 1} + + YES + + YES + + + + TU0AKgAACAjFzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ +xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/ +y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ +xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/ +y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ +xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/ +y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ +xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/ +y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ +xczS/8vS2P/L0tj/xczU/wANAQAAAwAAAAECAAAAAQEAAwAAAAEAAQAAAQIAAwAAAAQAAAiqAQMAAwAA +AAEAAQAAAQYAAwAAAAEAAgAAAREABAAAAAEAAAAIARIAAwAAAAEAAQAAARUAAwAAAAEABAAAARYAAwAA +AAEAAQAAARcABAAAAAEAAAgAARwAAwAAAAEAAQAAAVIAAwAAAAEAAQAAAVMAAwAAAAQAAAiyAAAAAAAI +AAgACAAIAAEAAQABAAE + + + + + + 3 + MCAwAA + + + groupTableViewBackgroundColor + + NO + YES + NO + IBCocoaTouchFramework + NO + 1 + 1 + 0 + YES + 44 + 10 + 10 + + + + + YES + + + view + + + + 10 + + + + dataSource + + + + 6 + + + + delegate + + + + 7 + + + + + YES + + 0 + + YES + + + + + + -1 + + + File's Owner + + + -2 + + + + + 4 + + + + + + + YES + + YES + -1.CustomClassName + -1.IBPluginDependency + -2.CustomClassName + -2.IBPluginDependency + 4.IBPluginDependency + + + YES + IASKAppSettingsViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + + + + YES + + + + + 10 + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + 3 + 931 + + diff --git a/InAppSettingsKit/Xibs/IASKAppSettingsWebView.xib b/InAppSettingsKit/Xibs/IASKAppSettingsWebView.xib new file mode 100644 index 000000000..b814f05fc --- /dev/null +++ b/InAppSettingsKit/Xibs/IASKAppSettingsWebView.xib @@ -0,0 +1,378 @@ + + + + 1024 + 10F569 + 804 + 1038.29 + 461.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 123 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 274 + + YES + + + 274 + {320, 460} + + + 3 + MQA + + IBCocoaTouchFramework + + + {320, 460} + + + + IBCocoaTouchFramework + + + + + YES + + + view + + + + 3 + + + + webView + + + + 5 + + + + delegate + + + + 6 + + + + + YES + + 0 + + + + + + 1 + + + YES + + + + + + -1 + + + File's Owner + + + -2 + + + + + 4 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 4.IBPluginDependency + + + YES + IASKAppSettingsWebViewController + UIResponder + {{354, 412}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 6 + + + + YES + + IASKAppSettingsWebViewController + UIViewController + + webView + UIWebView + + + webView + + webView + UIWebView + + + + IBProjectSource + ../InAppSettingsKit/Controllers/IASKAppSettingsWebViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWebView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWebView.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../InAppSettingsKitSampleApp.xcodeproj + 3 + 123 + + diff --git a/InAppSettingsKit/Xibs/IASKPSSliderSpecifierViewCell.xib b/InAppSettingsKit/Xibs/IASKPSSliderSpecifierViewCell.xib new file mode 100644 index 000000000..67750384e --- /dev/null +++ b/InAppSettingsKit/Xibs/IASKPSSliderSpecifierViewCell.xib @@ -0,0 +1,251 @@ + + + + 1296 + 11D50 + 2182 + 1138.32 + 568.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 1179 + + + YES + IBUISlider + IBUITableViewCell + IBUIImageView + IBProxyObject + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + PluginDependencyRecalculationVersion + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 290 + + YES + + + 256 + + YES + + + 290 + {{52, 12}, {216, 23}} + + + NO + YES + YES + IBCocoaTouchFramework + 0 + 0 + 0.5 + NO + + + + 289 + {{289, 13}, {21, 21}} + + + NO + NO + 8 + NO + IBCocoaTouchFramework + + + + 292 + {{10, 13}, {21, 21}} + + + NO + NO + 7 + NO + IBCocoaTouchFramework + + + {320, 43} + + + + 3 + MCAwAA + + NO + YES + 4 + YES + IBCocoaTouchFramework + + + {320, 44} + + + + 1 + MC45Njg2Mjc0NTEgMC45Njg2Mjc0NTEgMC45Njg2Mjc0NTEAA + + YES + NO + IBCocoaTouchFramework + 0 + + PSSliderSpecifier + + + + + YES + + + slider + + + + 12 + + + + maxImage + + + + 13 + + + + minImage + + + + 14 + + + + + YES + + 0 + + YES + + + + + + -1 + + + File's Owner + + + -2 + + + + + 2 + + + YES + + + + + + + + 3 + + + + + 6 + + + + + 9 + + + + + + + YES + + YES + -1.IBPluginDependency + -2.CustomClassName + -2.IBPluginDependency + 2.CustomClassName + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 6.IBPluginDependency + 9.IBPluginDependency + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + IASKPSSliderSpecifierViewCell + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + IASKSlider + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + + + + YES + + + + + 14 + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + 3 + 1179 + + diff --git a/InAppSettingsKit/Xibs/IASKPSTextFieldSpecifierViewCell.xib b/InAppSettingsKit/Xibs/IASKPSTextFieldSpecifierViewCell.xib new file mode 100644 index 000000000..43a553b9c --- /dev/null +++ b/InAppSettingsKit/Xibs/IASKPSTextFieldSpecifierViewCell.xib @@ -0,0 +1,254 @@ + + + + 1296 + 11D50 + 2182 + 1138.32 + 568.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 1179 + + + YES + IBUITableViewCell + IBUILabel + IBUITextField + IBProxyObject + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + PluginDependencyRecalculationVersion + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 290 + + YES + + + 256 + + YES + + + 294 + {{9, 11}, {240, 21}} + + NO + YES + NO + IBCocoaTouchFramework + Label + + 1 + MCAwIDAAA + + + 1 + 10 + + Helvetica-Bold + Helvetica + 2 + 17 + + + Helvetica-Bold + 17 + 16 + + + + + 291 + {{100, 11}, {201, 21}} + + NO + NO + IBCocoaTouchFramework + hello + + 1 + MC4yNzQ1MDk4MiAwLjM3NjQ3MDYgMC41MjE1Njg2NgA + + YES + 10 + + 9 + IBCocoaTouchFramework + + + Helvetica + Helvetica + 0 + 17 + + + Helvetica + 17 + 16 + + + + {320, 43} + + + 3 + MCAwAA + + NO + YES + 4 + YES + IBCocoaTouchFramework + + + {320, 44} + + + 1 + MC45Njg2Mjc0NTEgMC45Njg2Mjc0NTEgMC45Njg2Mjc0NTEAA + + YES + NO + IBCocoaTouchFramework + 0 + + PSTextFieldSpecifier + + + + + YES + + + label + + + + 8 + + + + textField + + + + 9 + + + + + YES + + 0 + + YES + + + + + + -1 + + + File's Owner + + + -2 + + + + + 2 + + + YES + + + + + + + 3 + + + + + 4 + + + + + + + YES + + YES + -1.IBPluginDependency + -2.CustomClassName + -2.IBPluginDependency + 2.CustomClassName + 2.IBPluginDependency + 3.IBPluginDependency + 4.CustomClassName + 4.IBPluginDependency + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + IASKPSTextFieldSpecifierViewCell + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + IASKTextField + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + + + + YES + + + + + 9 + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + 3 + 1179 + + diff --git a/InAppSettingsKit/Xibs/IASKPSToggleSwitchSpecifierViewCell.xib b/InAppSettingsKit/Xibs/IASKPSToggleSwitchSpecifierViewCell.xib new file mode 100644 index 000000000..2e5803f2e --- /dev/null +++ b/InAppSettingsKit/Xibs/IASKPSToggleSwitchSpecifierViewCell.xib @@ -0,0 +1,237 @@ + + + + 1296 + 11D50 + 2182 + 1138.32 + 568.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 1179 + + + YES + IBUITableViewCell + IBUISwitch + IBUILabel + IBProxyObject + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + PluginDependencyRecalculationVersion + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 290 + + YES + + + 256 + + YES + + + 294 + {{9, 10}, {200, 21}} + + NO + YES + NO + IBCocoaTouchFramework + Label + + 1 + MCAwIDAAA + + + 1 + 10 + + Helvetica-Bold + Helvetica + 2 + 17 + + + Helvetica-Bold + 17 + 16 + + + + + 289 + {{218, 8}, {94, 27}} + + NO + YES + YES + IBCocoaTouchFramework + 0 + 0 + YES + + + {320, 43} + + + 3 + MCAwAA + + NO + YES + 4 + YES + IBCocoaTouchFramework + + + {320, 44} + + + 1 + MC45Njg2Mjc0NTEgMC45Njg2Mjc0NTEgMC45Njg2Mjc0NTEAA + + YES + NO + IBCocoaTouchFramework + 0 + + PSToggleSwitchSpecifier + + + + + YES + + + toggle + + + + 8 + + + + label + + + + 9 + + + + + YES + + 0 + + YES + + + + + + -1 + + + File's Owner + + + -2 + + + + + 2 + + + YES + + + + + Toggle Switch Specifier View Cell - PSToggleSwitchSpecifier + + + 3 + + + + + 4 + + + + + + + YES + + YES + -1.IBPluginDependency + -2.CustomClassName + -2.IBPluginDependency + 2.CustomClassName + 2.IBPluginDependency + 3.IBPluginDependency + 4.CustomClassName + 4.IBPluginDependency + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + IASKPSToggleSwitchSpecifierViewCell + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + IASKSwitch + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + + + + YES + + + + + 9 + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + 3 + 1179 + + diff --git a/InAppSettingsKit/Xibs/IASKSpecifierValuesView.xib b/InAppSettingsKit/Xibs/IASKSpecifierValuesView.xib new file mode 100644 index 000000000..9c7ff86e6 --- /dev/null +++ b/InAppSettingsKit/Xibs/IASKSpecifierValuesView.xib @@ -0,0 +1,255 @@ + + + + 768 + 10J567 + 1294 + 1038.35 + 462.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 294 + + + YES + IBProxyObject + IBUIView + IBUITableView + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 292 + + YES + + + 274 + {320, 460} + + + + + 10 + + 549453824 + {84, 1} + + YES + + YES + + + + TU0AKgAAAVjFzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ +y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ +xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ +xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ +xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ +xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P8ADQEAAAMAAAABAFQAAAEB +AAMAAAABAAEAAAECAAMAAAAEAAAB+gEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES +AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABAAEAAAEXAAQAAAABAAABUAEcAAMAAAABAAEAAAFS +AAMAAAABAAEAAAFTAAMAAAAEAAACAgAAAAAACAAIAAgACAABAAEAAQABA + + + + + + 3 + MCAwAA + + + groupTableViewBackgroundColor + + NO + YES + NO + IBCocoaTouchFramework + NO + 1 + 1 + 0 + YES + 44 + 10 + 10 + + + {320, 460} + + + + + 3 + MQA + + 2 + + + IBCocoaTouchFramework + + + + + YES + + + view + + + + 3 + + + + dataSource + + + + 5 + + + + delegate + + + + 6 + + + + _tableView + + + + 7 + + + + + YES + + 0 + + + + + + 1 + + + YES + + + + + + -1 + + + File's Owner + + + -2 + + + + + 4 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 4.IBPluginDependency + + + YES + IASKSpecifierValuesViewController + UIResponder + {{556, 432}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + + + + YES + + + + + 7 + + + + YES + + IASKSpecifierValuesViewController + UIViewController + + _tableView + UITableView + + + _tableView + + _tableView + UITableView + + + + IBProjectSource + ./Classes/IASKSpecifierValuesViewController.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + 3 + 294 + + diff --git a/Resources/20-gear2.png b/Resources/20-gear2.png new file mode 100644 index 000000000..b8180ded2 Binary files /dev/null and b/Resources/20-gear2.png differ diff --git a/Settings.bundle/Advanced.plist b/Settings/InAppSettings.bundle/Advanced.plist similarity index 80% rename from Settings.bundle/Advanced.plist rename to Settings/InAppSettings.bundle/Advanced.plist index c0c81b34a..bfe884eb2 100644 --- a/Settings.bundle/Advanced.plist +++ b/Settings/InAppSettings.bundle/Advanced.plist @@ -58,13 +58,13 @@ DefaultValue - - Key - wifi_only_preference - Title - Wifi only - Type - PSToggleSwitchSpecifier + + Key + wifi_only_preference + Title + Wifi only + Type + PSToggleSwitchSpecifier DefaultValue @@ -90,21 +90,33 @@ DefaultValue - + None Key - enable_srtp_preference + media_encryption_preference Title - Secure rtp + Media Encryption + Titles + + None + SRTP + ZRTP + Type - PSToggleSwitchSpecifier + PSMultiValueSpecifier + Values + + None + SRTP + ZRTP + DefaultValue - + Key - disable_autoboot_preference + start_at_boot_preference Title - Disable application autostart + Start at boot Type PSToggleSwitchSpecifier diff --git a/Settings.bundle/audio.plist b/Settings/InAppSettings.bundle/Audio.plist similarity index 100% rename from Settings.bundle/audio.plist rename to Settings/InAppSettings.bundle/Audio.plist diff --git a/Settings.bundle/Root.plist b/Settings/InAppSettings.bundle/Root.plist similarity index 92% rename from Settings.bundle/Root.plist rename to Settings/InAppSettings.bundle/Root.plist index 4b6332f8e..f2aa11c6c 100644 --- a/Settings.bundle/Root.plist +++ b/Settings/InAppSettings.bundle/Root.plist @@ -9,8 +9,6 @@ SIP account Type PSGroupSpecifier - FooterText - Linphone must be restarted for changes to take effect AutocapitalizationType @@ -94,6 +92,16 @@ Type PSToggleSwitchSpecifier + + Type + PSToggleSwitchSpecifier + Title + Enable video + Key + enable_video_preference + DefaultValue + + Title diff --git a/Settings.bundle/video.plist b/Settings/InAppSettings.bundle/Video.plist similarity index 84% rename from Settings.bundle/video.plist rename to Settings/InAppSettings.bundle/Video.plist index 440f5ad90..56af43866 100644 --- a/Settings.bundle/video.plist +++ b/Settings/InAppSettings.bundle/Video.plist @@ -4,16 +4,6 @@ PreferenceSpecifiers - - Type - PSToggleSwitchSpecifier - Title - Enable video - Key - enable_video_preference - DefaultValue - - Type PSToggleSwitchSpecifier diff --git a/Settings.bundle/en.lproj/Root.strings b/Settings/InAppSettings.bundle/en.lproj/Root.strings similarity index 100% rename from Settings.bundle/en.lproj/Root.strings rename to Settings/InAppSettings.bundle/en.lproj/Root.strings diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index 561b95780..82146ba57 100755 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -39,7 +39,6 @@ 2237D4091084D7A9001383EE /* oldphone-mono.wav in Resources */ = {isa = PBXBuildFile; fileRef = 2237D4081084D7A9001383EE /* oldphone-mono.wav */; }; 223963171393CFAF001DE689 /* FastAddressBook.m in Sources */ = {isa = PBXBuildFile; fileRef = 223963161393CFAF001DE689 /* FastAddressBook.m */; }; 2242E313125235120061DDCE /* oldphone-mono-30s.caf in Resources */ = {isa = PBXBuildFile; fileRef = 2242E312125235120061DDCE /* oldphone-mono-30s.caf */; }; - 2245671D107699F700F10948 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 2245671C107699F700F10948 /* Settings.bundle */; }; 224567C2107B968500F10948 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 224567C1107B968500F10948 /* AVFoundation.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 2245F78A1201D38000C4179D /* MoreViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 22E0A81B111C44E100B04932 /* MoreViewController.xib */; }; 2248E90E12F7E4CF00220D9C /* UIDigitButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 2248E90D12F7E4CF00220D9C /* UIDigitButton.m */; }; @@ -49,7 +48,6 @@ 226183AE1472527D0037138E /* libsrtp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226183AB1472527D0037138E /* libsrtp.a */; }; 226183B0147259670037138E /* libmssilk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226183AF147259670037138E /* libmssilk.a */; }; 2264B6D211200342002C2C53 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2264B6D111200342002C2C53 /* SystemConfiguration.framework */; }; - 226B563F13CAF1CD00921595 /* audio.plist in Resources */ = {isa = PBXBuildFile; fileRef = 226B563E13CAF1CD00921595 /* audio.plist */; }; 226CDADF14E2D0B800513B67 /* libbcg729.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226CDADD14E2D0B800513B67 /* libbcg729.a */; }; 226CDAE014E2D0B800513B67 /* libmsbcg729.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226CDADE14E2D0B800513B67 /* libmsbcg729.a */; }; 226F2ED61344B0EF00F6EF27 /* libopencore-amrwb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 226F2ED31344B0EF00F6EF27 /* libopencore-amrwb.a */; }; @@ -86,8 +84,6 @@ 22D8F13B147548E2008C97DB /* FirstLoginViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2218A92412FBE1340088A667 /* FirstLoginViewController.xib */; }; 22D8F13C147548E2008C97DB /* iTunesArtwork in Resources */ = {isa = PBXBuildFile; fileRef = 228B19AE130290C500F154D3 /* iTunesArtwork */; }; 22D8F13D147548E2008C97DB /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2214783B1386A2030020F8B8 /* Localizable.strings */; }; - 22D8F140147548E2008C97DB /* audio.plist in Resources */ = {isa = PBXBuildFile; fileRef = 226B563E13CAF1CD00921595 /* audio.plist */; }; - 22D8F141147548E2008C97DB /* video.plist in Resources */ = {isa = PBXBuildFile; fileRef = 22E1A9E713CAF4AA00219531 /* video.plist */; }; 22D8F142147548E2008C97DB /* rootca.pem in Resources */ = {isa = PBXBuildFile; fileRef = 70571E1913FABCB000CDD3C2 /* rootca.pem */; }; 22D8F144147548E2008C97DB /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; 22D8F145147548E2008C97DB /* LinphoneAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* LinphoneAppDelegate.m */; }; @@ -142,7 +138,6 @@ 22E0A822111C44E100B04932 /* MoreViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 22E0A81C111C44E100B04932 /* MoreViewController.m */; }; 22E0A823111C44E100B04932 /* ConsoleViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 22E0A81E111C44E100B04932 /* ConsoleViewController.xib */; }; 22E0A824111C44E100B04932 /* ConsoleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 22E0A81F111C44E100B04932 /* ConsoleViewController.m */; }; - 22E1A9E813CAF4AA00219531 /* video.plist in Resources */ = {isa = PBXBuildFile; fileRef = 22E1A9E713CAF4AA00219531 /* video.plist */; }; 22E5B0AF133B5EA20044EA25 /* libssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22E5B0AD133B5EA20044EA25 /* libssl.a */; }; 22E5B0B0133B5EA20044EA25 /* libcrypto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22E5B0AE133B5EA20044EA25 /* libcrypto.a */; }; 22F2508E107141E100AC9B3F /* DialerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 22F2508C107141E100AC9B3F /* DialerViewController.m */; }; @@ -210,6 +205,8 @@ D32648411588950F00930C67 /* UICallBar.xib in Resources */ = {isa = PBXBuildFile; fileRef = D326483D1588950F00930C67 /* UICallBar.xib */; }; D32648441588F6FC00930C67 /* UIToggleButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D32648431588F6FB00930C67 /* UIToggleButton.m */; }; D32648451588F6FC00930C67 /* UIToggleButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D32648431588F6FB00930C67 /* UIToggleButton.m */; }; + D32942A41594C94300556A1C /* SettingsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D32942A31594C94200556A1C /* SettingsViewController.xib */; }; + D32942A51594C94300556A1C /* SettingsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D32942A31594C94200556A1C /* SettingsViewController.xib */; }; D3432A62158A4446001C6B0B /* status_connected.png in Resources */ = {isa = PBXBuildFile; fileRef = D3432A5C158A4446001C6B0B /* status_connected.png */; }; D3432A63158A4446001C6B0B /* status_connected.png in Resources */ = {isa = PBXBuildFile; fileRef = D3432A5C158A4446001C6B0B /* status_connected.png */; }; D3432A64158A4446001C6B0B /* status_error.png in Resources */ = {isa = PBXBuildFile; fileRef = D3432A5D158A4446001C6B0B /* status_error.png */; }; @@ -229,6 +226,8 @@ D347347A1580DDF1003C7B8C /* PhoneMainView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D34734791580DDF1003C7B8C /* PhoneMainView.xib */; }; D347347E1580E5F8003C7B8C /* history-actif.png in Resources */ = {isa = PBXBuildFile; fileRef = D347347C1580E5F8003C7B8C /* history-actif.png */; }; D347347F1580E5F8003C7B8C /* history-selectionne.png in Resources */ = {isa = PBXBuildFile; fileRef = D347347D1580E5F8003C7B8C /* history-selectionne.png */; }; + D34F6F9E1594D3FB0095705B /* InAppSettings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = D34F6F9D1594D3FB0095705B /* InAppSettings.bundle */; }; + D34F6F9F1594D3FB0095705B /* InAppSettings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = D34F6F9D1594D3FB0095705B /* InAppSettings.bundle */; }; D35497FE15875372000081D8 /* ContactsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D35497FC15875372000081D8 /* ContactsViewController.m */; }; D35497FF15875372000081D8 /* ContactsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D35497FC15875372000081D8 /* ContactsViewController.m */; }; D354980015875372000081D8 /* ContactsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D35497FD15875372000081D8 /* ContactsViewController.xib */; }; @@ -271,8 +270,6 @@ D35E759A159460580066B1C1 /* ChatViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D35E7596159460570066B1C1 /* ChatViewController.xib */; }; D35E759F159460B70066B1C1 /* SettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D35E759D159460B50066B1C1 /* SettingsViewController.m */; }; D35E75A0159460B70066B1C1 /* SettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D35E759D159460B50066B1C1 /* SettingsViewController.m */; }; - D35E75A1159460B70066B1C1 /* SettingsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D35E759E159460B60066B1C1 /* SettingsViewController.xib */; }; - D35E75A2159460B70066B1C1 /* SettingsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D35E759E159460B60066B1C1 /* SettingsViewController.xib */; }; D36C43C6158F2E5A0048BA40 /* UICallCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D36C43C5158F2E5A0048BA40 /* UICallCell.m */; }; D36C43C7158F2E5A0048BA40 /* UICallCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D36C43C5158F2E5A0048BA40 /* UICallCell.m */; }; D36C43CA158F2EE50048BA40 /* UICallCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D36C43C9158F2EE50048BA40 /* UICallCell.xib */; }; @@ -305,6 +302,52 @@ D37295CB158B1E2D00D2C0C7 /* registration_inprogress.png in Resources */ = {isa = PBXBuildFile; fileRef = D37295C9158B1E2D00D2C0C7 /* registration_inprogress.png */; }; D37295DB158B3C9600D2C0C7 /* video-OFF-disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D37295DA158B3C9600D2C0C7 /* video-OFF-disabled.png */; }; D37295DC158B3C9600D2C0C7 /* video-OFF-disabled.png in Resources */ = {isa = PBXBuildFile; fileRef = D37295DA158B3C9600D2C0C7 /* video-OFF-disabled.png */; }; + D37DC6C11594AE1800B2A5EB /* LinphoneCoreSettingsStore.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6C01594AE1800B2A5EB /* LinphoneCoreSettingsStore.m */; }; + D37DC6C21594AE1800B2A5EB /* LinphoneCoreSettingsStore.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6C01594AE1800B2A5EB /* LinphoneCoreSettingsStore.m */; }; + D37DC6ED1594AE6F00B2A5EB /* IASKAppSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6C61594AE6F00B2A5EB /* IASKAppSettingsViewController.m */; }; + D37DC6EE1594AE6F00B2A5EB /* IASKAppSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6C61594AE6F00B2A5EB /* IASKAppSettingsViewController.m */; }; + D37DC6EF1594AE6F00B2A5EB /* IASKAppSettingsWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6C81594AE6F00B2A5EB /* IASKAppSettingsWebViewController.m */; }; + D37DC6F01594AE6F00B2A5EB /* IASKAppSettingsWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6C81594AE6F00B2A5EB /* IASKAppSettingsWebViewController.m */; }; + D37DC6F11594AE6F00B2A5EB /* IASKSpecifierValuesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6CA1594AE6F00B2A5EB /* IASKSpecifierValuesViewController.m */; }; + D37DC6F21594AE6F00B2A5EB /* IASKSpecifierValuesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6CA1594AE6F00B2A5EB /* IASKSpecifierValuesViewController.m */; }; + D37DC6F31594AE6F00B2A5EB /* IASKSettingsReader.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6CE1594AE6F00B2A5EB /* IASKSettingsReader.m */; }; + D37DC6F41594AE6F00B2A5EB /* IASKSettingsReader.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6CE1594AE6F00B2A5EB /* IASKSettingsReader.m */; }; + D37DC6F51594AE6F00B2A5EB /* IASKSettingsStore.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6D01594AE6F00B2A5EB /* IASKSettingsStore.m */; }; + D37DC6F61594AE6F00B2A5EB /* IASKSettingsStore.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6D01594AE6F00B2A5EB /* IASKSettingsStore.m */; }; + D37DC6F71594AE6F00B2A5EB /* IASKSettingsStoreFile.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6D21594AE6F00B2A5EB /* IASKSettingsStoreFile.m */; }; + D37DC6F81594AE6F00B2A5EB /* IASKSettingsStoreFile.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6D21594AE6F00B2A5EB /* IASKSettingsStoreFile.m */; }; + D37DC6F91594AE6F00B2A5EB /* IASKSettingsStoreUserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6D41594AE6F00B2A5EB /* IASKSettingsStoreUserDefaults.m */; }; + D37DC6FA1594AE6F00B2A5EB /* IASKSettingsStoreUserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6D41594AE6F00B2A5EB /* IASKSettingsStoreUserDefaults.m */; }; + D37DC6FB1594AE6F00B2A5EB /* IASKSpecifier.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6D61594AE6F00B2A5EB /* IASKSpecifier.m */; }; + D37DC6FC1594AE6F00B2A5EB /* IASKSpecifier.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6D61594AE6F00B2A5EB /* IASKSpecifier.m */; }; + D37DC6FD1594AE6F00B2A5EB /* IASKPSSliderSpecifierViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6D91594AE6F00B2A5EB /* IASKPSSliderSpecifierViewCell.m */; }; + D37DC6FE1594AE6F00B2A5EB /* IASKPSSliderSpecifierViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6D91594AE6F00B2A5EB /* IASKPSSliderSpecifierViewCell.m */; }; + D37DC6FF1594AE6F00B2A5EB /* IASKPSTextFieldSpecifierViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6DB1594AE6F00B2A5EB /* IASKPSTextFieldSpecifierViewCell.m */; }; + D37DC7001594AE6F00B2A5EB /* IASKPSTextFieldSpecifierViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6DB1594AE6F00B2A5EB /* IASKPSTextFieldSpecifierViewCell.m */; }; + D37DC7011594AE6F00B2A5EB /* IASKPSTitleValueSpecifierViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6DD1594AE6F00B2A5EB /* IASKPSTitleValueSpecifierViewCell.m */; }; + D37DC7021594AE6F00B2A5EB /* IASKPSTitleValueSpecifierViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6DD1594AE6F00B2A5EB /* IASKPSTitleValueSpecifierViewCell.m */; }; + D37DC7031594AE6F00B2A5EB /* IASKPSToggleSwitchSpecifierViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6DF1594AE6F00B2A5EB /* IASKPSToggleSwitchSpecifierViewCell.m */; }; + D37DC7041594AE6F00B2A5EB /* IASKPSToggleSwitchSpecifierViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6DF1594AE6F00B2A5EB /* IASKPSToggleSwitchSpecifierViewCell.m */; }; + D37DC7051594AE6F00B2A5EB /* IASKSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6E11594AE6F00B2A5EB /* IASKSlider.m */; }; + D37DC7061594AE6F00B2A5EB /* IASKSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6E11594AE6F00B2A5EB /* IASKSlider.m */; }; + D37DC7071594AE6F00B2A5EB /* IASKSwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6E31594AE6F00B2A5EB /* IASKSwitch.m */; }; + D37DC7081594AE6F00B2A5EB /* IASKSwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6E31594AE6F00B2A5EB /* IASKSwitch.m */; }; + D37DC7091594AE6F00B2A5EB /* IASKTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6E51594AE6F00B2A5EB /* IASKTextField.m */; }; + D37DC70A1594AE6F00B2A5EB /* IASKTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DC6E51594AE6F00B2A5EB /* IASKTextField.m */; }; + D37DC70B1594AE6F00B2A5EB /* IASKAppSettingsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D37DC6E71594AE6F00B2A5EB /* IASKAppSettingsView.xib */; }; + D37DC70C1594AE6F00B2A5EB /* IASKAppSettingsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D37DC6E71594AE6F00B2A5EB /* IASKAppSettingsView.xib */; }; + D37DC70D1594AE6F00B2A5EB /* IASKAppSettingsWebView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D37DC6E81594AE6F00B2A5EB /* IASKAppSettingsWebView.xib */; }; + D37DC70E1594AE6F00B2A5EB /* IASKAppSettingsWebView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D37DC6E81594AE6F00B2A5EB /* IASKAppSettingsWebView.xib */; }; + D37DC70F1594AE6F00B2A5EB /* IASKPSSliderSpecifierViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D37DC6E91594AE6F00B2A5EB /* IASKPSSliderSpecifierViewCell.xib */; }; + D37DC7101594AE6F00B2A5EB /* IASKPSSliderSpecifierViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D37DC6E91594AE6F00B2A5EB /* IASKPSSliderSpecifierViewCell.xib */; }; + D37DC7111594AE6F00B2A5EB /* IASKPSTextFieldSpecifierViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D37DC6EA1594AE6F00B2A5EB /* IASKPSTextFieldSpecifierViewCell.xib */; }; + D37DC7121594AE6F00B2A5EB /* IASKPSTextFieldSpecifierViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D37DC6EA1594AE6F00B2A5EB /* IASKPSTextFieldSpecifierViewCell.xib */; }; + D37DC7131594AE6F00B2A5EB /* IASKPSToggleSwitchSpecifierViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D37DC6EB1594AE6F00B2A5EB /* IASKPSToggleSwitchSpecifierViewCell.xib */; }; + D37DC7141594AE6F00B2A5EB /* IASKPSToggleSwitchSpecifierViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D37DC6EB1594AE6F00B2A5EB /* IASKPSToggleSwitchSpecifierViewCell.xib */; }; + D37DC7151594AE6F00B2A5EB /* IASKSpecifierValuesView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D37DC6EC1594AE6F00B2A5EB /* IASKSpecifierValuesView.xib */; }; + D37DC7161594AE6F00B2A5EB /* IASKSpecifierValuesView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D37DC6EC1594AE6F00B2A5EB /* IASKSpecifierValuesView.xib */; }; + D37DC7181594AF3400B2A5EB /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D37DC7171594AF3400B2A5EB /* MessageUI.framework */; }; + D37DC7191594AF3F00B2A5EB /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D37DC7171594AF3400B2A5EB /* MessageUI.framework */; }; D38327F31580FE3A00FA0D23 /* contacts-actif.png in Resources */ = {isa = PBXBuildFile; fileRef = D38327EB1580FE3A00FA0D23 /* contacts-actif.png */; }; D38327F41580FE3A00FA0D23 /* contacts-selectionne.png in Resources */ = {isa = PBXBuildFile; fileRef = D38327EC1580FE3A00FA0D23 /* contacts-selectionne.png */; }; D38327F51580FE3A00FA0D23 /* dialer-actif.png in Resources */ = {isa = PBXBuildFile; fileRef = D38327ED1580FE3A00FA0D23 /* dialer-actif.png */; }; @@ -650,7 +693,6 @@ 223963151393CFAE001DE689 /* FastAddressBook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FastAddressBook.h; sourceTree = ""; }; 223963161393CFAF001DE689 /* FastAddressBook.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FastAddressBook.m; sourceTree = ""; }; 2242E312125235120061DDCE /* oldphone-mono-30s.caf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "oldphone-mono-30s.caf"; path = "liblinphone-sdk/apple-darwin/share/sounds/linphone/rings/oldphone-mono-30s.caf"; sourceTree = ""; }; - 2245671C107699F700F10948 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; 224567C1107B968500F10948 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; 2248E90C12F7E4CF00220D9C /* UIDigitButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIDigitButton.h; sourceTree = ""; }; 2248E90D12F7E4CF00220D9C /* UIDigitButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIDigitButton.m; sourceTree = ""; }; @@ -662,7 +704,6 @@ 226183AB1472527D0037138E /* libsrtp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsrtp.a; path = "liblinphone-sdk/apple-darwin/lib/libsrtp.a"; sourceTree = ""; }; 226183AF147259670037138E /* libmssilk.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmssilk.a; path = "liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins/libmssilk.a"; sourceTree = ""; }; 2264B6D111200342002C2C53 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; - 226B563E13CAF1CD00921595 /* audio.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = audio.plist; path = Settings.bundle/audio.plist; sourceTree = ""; }; 226CDADD14E2D0B800513B67 /* libbcg729.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbcg729.a; path = "liblinphone-sdk/apple-darwin/lib/libbcg729.a"; sourceTree = ""; }; 226CDADE14E2D0B800513B67 /* libmsbcg729.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmsbcg729.a; path = "liblinphone-sdk/apple-darwin/lib/mediastreamer/plugins/libmsbcg729.a"; sourceTree = ""; }; 226F2ED31344B0EF00F6EF27 /* libopencore-amrwb.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libopencore-amrwb.a"; path = "liblinphone-sdk/apple-darwin/lib/libopencore-amrwb.a"; sourceTree = ""; }; @@ -768,7 +809,6 @@ 22E0A81E111C44E100B04932 /* ConsoleViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ConsoleViewController.xib; sourceTree = ""; }; 22E0A81F111C44E100B04932 /* ConsoleViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConsoleViewController.m; sourceTree = ""; }; 22E0A820111C44E100B04932 /* ConsoleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConsoleViewController.h; sourceTree = ""; }; - 22E1A9E713CAF4AA00219531 /* video.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = video.plist; path = Settings.bundle/video.plist; sourceTree = ""; }; 22E5B0AD133B5EA20044EA25 /* libssl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libssl.a; path = "liblinphone-sdk/apple-darwin/lib/libssl.a"; sourceTree = ""; }; 22E5B0AE133B5EA20044EA25 /* libcrypto.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcrypto.a; path = "liblinphone-sdk/apple-darwin/lib/libcrypto.a"; sourceTree = ""; }; 22F2508B107141E100AC9B3F /* DialerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DialerViewController.h; sourceTree = ""; }; @@ -824,6 +864,7 @@ D326483D1588950F00930C67 /* UICallBar.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UICallBar.xib; sourceTree = ""; }; D32648421588F6FA00930C67 /* UIToggleButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIToggleButton.h; sourceTree = ""; }; D32648431588F6FB00930C67 /* UIToggleButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIToggleButton.m; sourceTree = ""; }; + D32942A31594C94200556A1C /* SettingsViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SettingsViewController.xib; sourceTree = ""; }; D3432A5C158A4446001C6B0B /* status_connected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = status_connected.png; path = Resources/status_connected.png; sourceTree = ""; }; D3432A5D158A4446001C6B0B /* status_error.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = status_error.png; path = Resources/status_error.png; sourceTree = ""; }; D3432A5E158A4446001C6B0B /* quality-call-0.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "quality-call-0.png"; path = "Resources/quality-call-0.png"; sourceTree = ""; }; @@ -835,6 +876,7 @@ D34734791580DDF1003C7B8C /* PhoneMainView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PhoneMainView.xib; sourceTree = ""; }; D347347C1580E5F8003C7B8C /* history-actif.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "history-actif.png"; path = "Resources/history-actif.png"; sourceTree = ""; }; D347347D1580E5F8003C7B8C /* history-selectionne.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "history-selectionne.png"; path = "Resources/history-selectionne.png"; sourceTree = ""; }; + D34F6F9D1594D3FB0095705B /* InAppSettings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = InAppSettings.bundle; sourceTree = ""; }; D35497FB15875372000081D8 /* ContactsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactsViewController.h; sourceTree = ""; }; D35497FC15875372000081D8 /* ContactsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactsViewController.m; sourceTree = ""; }; D35497FD15875372000081D8 /* ContactsViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ContactsViewController.xib; sourceTree = ""; }; @@ -862,7 +904,6 @@ D35E7596159460570066B1C1 /* ChatViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ChatViewController.xib; sourceTree = ""; }; D35E759C159460B50066B1C1 /* SettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsViewController.h; sourceTree = ""; }; D35E759D159460B50066B1C1 /* SettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsViewController.m; sourceTree = ""; }; - D35E759E159460B60066B1C1 /* SettingsViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SettingsViewController.xib; sourceTree = ""; }; D36C43C4158F2E5A0048BA40 /* UICallCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UICallCell.h; sourceTree = ""; }; D36C43C5158F2E5A0048BA40 /* UICallCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UICallCell.m; sourceTree = ""; }; D36C43C9158F2EE50048BA40 /* UICallCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UICallCell.xib; sourceTree = ""; }; @@ -881,6 +922,46 @@ D36FB2D41589EF7C0036F6F2 /* UIPauseButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIPauseButton.m; sourceTree = ""; }; D37295C9158B1E2D00D2C0C7 /* registration_inprogress.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = registration_inprogress.png; path = Resources/registration_inprogress.png; sourceTree = ""; }; D37295DA158B3C9600D2C0C7 /* video-OFF-disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "video-OFF-disabled.png"; path = "Resources/video-OFF-disabled.png"; sourceTree = ""; }; + D37DC6BF1594AE1800B2A5EB /* LinphoneCoreSettingsStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinphoneCoreSettingsStore.h; sourceTree = ""; }; + D37DC6C01594AE1800B2A5EB /* LinphoneCoreSettingsStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LinphoneCoreSettingsStore.m; sourceTree = ""; }; + D37DC6C51594AE6F00B2A5EB /* IASKAppSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKAppSettingsViewController.h; sourceTree = ""; }; + D37DC6C61594AE6F00B2A5EB /* IASKAppSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKAppSettingsViewController.m; sourceTree = ""; }; + D37DC6C71594AE6F00B2A5EB /* IASKAppSettingsWebViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKAppSettingsWebViewController.h; sourceTree = ""; }; + D37DC6C81594AE6F00B2A5EB /* IASKAppSettingsWebViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKAppSettingsWebViewController.m; sourceTree = ""; }; + D37DC6C91594AE6F00B2A5EB /* IASKSpecifierValuesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKSpecifierValuesViewController.h; sourceTree = ""; }; + D37DC6CA1594AE6F00B2A5EB /* IASKSpecifierValuesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKSpecifierValuesViewController.m; sourceTree = ""; }; + D37DC6CB1594AE6F00B2A5EB /* IASKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKViewController.h; sourceTree = ""; }; + D37DC6CD1594AE6F00B2A5EB /* IASKSettingsReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKSettingsReader.h; sourceTree = ""; }; + D37DC6CE1594AE6F00B2A5EB /* IASKSettingsReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKSettingsReader.m; sourceTree = ""; }; + D37DC6CF1594AE6F00B2A5EB /* IASKSettingsStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKSettingsStore.h; sourceTree = ""; }; + D37DC6D01594AE6F00B2A5EB /* IASKSettingsStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKSettingsStore.m; sourceTree = ""; }; + D37DC6D11594AE6F00B2A5EB /* IASKSettingsStoreFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKSettingsStoreFile.h; sourceTree = ""; }; + D37DC6D21594AE6F00B2A5EB /* IASKSettingsStoreFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKSettingsStoreFile.m; sourceTree = ""; }; + D37DC6D31594AE6F00B2A5EB /* IASKSettingsStoreUserDefaults.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKSettingsStoreUserDefaults.h; sourceTree = ""; }; + D37DC6D41594AE6F00B2A5EB /* IASKSettingsStoreUserDefaults.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKSettingsStoreUserDefaults.m; sourceTree = ""; }; + D37DC6D51594AE6F00B2A5EB /* IASKSpecifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKSpecifier.h; sourceTree = ""; }; + D37DC6D61594AE6F00B2A5EB /* IASKSpecifier.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKSpecifier.m; sourceTree = ""; }; + D37DC6D81594AE6F00B2A5EB /* IASKPSSliderSpecifierViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKPSSliderSpecifierViewCell.h; sourceTree = ""; }; + D37DC6D91594AE6F00B2A5EB /* IASKPSSliderSpecifierViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKPSSliderSpecifierViewCell.m; sourceTree = ""; }; + D37DC6DA1594AE6F00B2A5EB /* IASKPSTextFieldSpecifierViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKPSTextFieldSpecifierViewCell.h; sourceTree = ""; }; + D37DC6DB1594AE6F00B2A5EB /* IASKPSTextFieldSpecifierViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKPSTextFieldSpecifierViewCell.m; sourceTree = ""; }; + D37DC6DC1594AE6F00B2A5EB /* IASKPSTitleValueSpecifierViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKPSTitleValueSpecifierViewCell.h; sourceTree = ""; }; + D37DC6DD1594AE6F00B2A5EB /* IASKPSTitleValueSpecifierViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKPSTitleValueSpecifierViewCell.m; sourceTree = ""; }; + D37DC6DE1594AE6F00B2A5EB /* IASKPSToggleSwitchSpecifierViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKPSToggleSwitchSpecifierViewCell.h; sourceTree = ""; }; + D37DC6DF1594AE6F00B2A5EB /* IASKPSToggleSwitchSpecifierViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKPSToggleSwitchSpecifierViewCell.m; sourceTree = ""; }; + D37DC6E01594AE6F00B2A5EB /* IASKSlider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKSlider.h; sourceTree = ""; }; + D37DC6E11594AE6F00B2A5EB /* IASKSlider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKSlider.m; sourceTree = ""; }; + D37DC6E21594AE6F00B2A5EB /* IASKSwitch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKSwitch.h; sourceTree = ""; }; + D37DC6E31594AE6F00B2A5EB /* IASKSwitch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKSwitch.m; sourceTree = ""; }; + D37DC6E41594AE6F00B2A5EB /* IASKTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKTextField.h; sourceTree = ""; }; + D37DC6E51594AE6F00B2A5EB /* IASKTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKTextField.m; sourceTree = ""; }; + D37DC6E71594AE6F00B2A5EB /* IASKAppSettingsView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = IASKAppSettingsView.xib; sourceTree = ""; }; + D37DC6E81594AE6F00B2A5EB /* IASKAppSettingsWebView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = IASKAppSettingsWebView.xib; sourceTree = ""; }; + D37DC6E91594AE6F00B2A5EB /* IASKPSSliderSpecifierViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = IASKPSSliderSpecifierViewCell.xib; sourceTree = ""; }; + D37DC6EA1594AE6F00B2A5EB /* IASKPSTextFieldSpecifierViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = IASKPSTextFieldSpecifierViewCell.xib; sourceTree = ""; }; + D37DC6EB1594AE6F00B2A5EB /* IASKPSToggleSwitchSpecifierViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = IASKPSToggleSwitchSpecifierViewCell.xib; sourceTree = ""; }; + D37DC6EC1594AE6F00B2A5EB /* IASKSpecifierValuesView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = IASKSpecifierValuesView.xib; sourceTree = ""; }; + D37DC7171594AF3400B2A5EB /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; }; D38327EB1580FE3A00FA0D23 /* contacts-actif.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "contacts-actif.png"; path = "Resources/contacts-actif.png"; sourceTree = ""; }; D38327EC1580FE3A00FA0D23 /* contacts-selectionne.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "contacts-selectionne.png"; path = "Resources/contacts-selectionne.png"; sourceTree = ""; }; D38327ED1580FE3A00FA0D23 /* dialer-actif.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "dialer-actif.png"; path = "Resources/dialer-actif.png"; sourceTree = ""; }; @@ -985,6 +1066,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D37DC7181594AF3400B2A5EB /* MessageUI.framework in Frameworks */, 340751971506459A00B89C47 /* CoreTelephony.framework in Frameworks */, 226CDADF14E2D0B800513B67 /* libbcg729.a in Frameworks */, 226CDAE014E2D0B800513B67 /* libmsbcg729.a in Frameworks */, @@ -1038,6 +1120,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D37DC7191594AF3F00B2A5EB /* MessageUI.framework in Frameworks */, 34075199150645A300B89C47 /* CoreTelephony.framework in Frameworks */, 22D8F15B147548E2008C97DB /* libvpx.a in Frameworks */, 22D8F15C147548E2008C97DB /* QuartzCore.framework in Frameworks */, @@ -1117,6 +1200,8 @@ D3F83F9115824D3500336684 /* LinphoneApp.xib */, 1D3623240D0F684500981E51 /* LinphoneAppDelegate.h */, 1D3623250D0F684500981E51 /* LinphoneAppDelegate.m */, + D37DC6BF1594AE1800B2A5EB /* LinphoneCoreSettingsStore.h */, + D37DC6C01594AE1800B2A5EB /* LinphoneCoreSettingsStore.m */, 2214EB7012F84668002A5394 /* LinphoneUI */, 34CA8537148F692A00503C01 /* MainScreenWithVideoPreview.h */, 34CA8538148F692A00503C01 /* MainScreenWithVideoPreview.m */, @@ -1130,7 +1215,7 @@ 3422AA5214978352000D4E8A /* PhoneViewController-ipad.xib */, D35E759C159460B50066B1C1 /* SettingsViewController.h */, D35E759D159460B50066B1C1 /* SettingsViewController.m */, - D35E759E159460B60066B1C1 /* SettingsViewController.xib */, + D32942A31594C94200556A1C /* SettingsViewController.xib */, D326483415887D4400930C67 /* Utils */, 34216F3E1547EBCD00EA9777 /* VideoZoomHandler.h */, 34216F3F1547EBCD00EA9777 /* VideoZoomHandler.m */, @@ -1483,64 +1568,64 @@ 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { isa = PBXGroup; children = ( - 340751961506459A00B89C47 /* CoreTelephony.framework */, - 226CDADD14E2D0B800513B67 /* libbcg729.a */, - 226CDADE14E2D0B800513B67 /* libmsbcg729.a */, - 344ABDEF14850AE9007420B6 /* libc++.1.dylib */, - 344ABDF014850AE9007420B6 /* libstdc++.6.dylib */, - 344ABDE71484E723007420B6 /* libzrtpcpp.a */, - 2211DB9614764F6B00DEE054 /* nogpl-thirdparties */, - 2211DB911475562600DEE054 /* liblinphone.a */, - 2211DB8F147555C800DEE054 /* libmediastreamer.a */, - 226183AF147259670037138E /* libmssilk.a */, - 226183AA1472527D0037138E /* libSKP_SILK_SDK.a */, - 226183AB1472527D0037138E /* libsrtp.a */, - 7066FC0B13E830E400EFC6DC /* libvpx.a */, - 70E542F413E147EB002BA2C0 /* QuartzCore.framework */, - 70E542F213E147E3002BA2C0 /* OpenGLES.framework */, - 22AA8AFB13D7125500B30535 /* libx264.a */, - 22AA8AFC13D7125500B30535 /* libmsx264.a */, - 22E1A9E713CAF4AA00219531 /* video.plist */, - 226B563E13CAF1CD00921595 /* audio.plist */, - 22276E8813C73DC000210156 /* CoreMedia.framework */, - 22276E8613C73D8A00210156 /* CoreVideo.framework */, + 2258633C11410BAC00C5A737 /* README */, 22276E8013C73D3100210156 /* libavcodec.a */, 22276E8113C73D3100210156 /* libavutil.a */, - 22276E8213C73D3100210156 /* libswscale.a */, - 2214783B1386A2030020F8B8 /* Localizable.strings */, - 223148E51178A09900637D6A /* libmsilbc.a */, - 223148E31178A08200637D6A /* libilbc.a */, + 226CDADD14E2D0B800513B67 /* libbcg729.a */, + 22E5B0AE133B5EA20044EA25 /* libcrypto.a */, 220FAD2810765B400068D98F /* libeXosip2.a */, 220FAD2910765B400068D98F /* libgsm.a */, + 223148E31178A08200637D6A /* libilbc.a */, + 2211DB911475562600DEE054 /* liblinphone.a */, + 2211DB8F147555C800DEE054 /* libmediastreamer.a */, + 226F2ED51344B0EF00F6EF27 /* libmsamr.a */, + 226CDADE14E2D0B800513B67 /* libmsbcg729.a */, + 223148E51178A09900637D6A /* libmsilbc.a */, + 226183AF147259670037138E /* libmssilk.a */, + 22AA8AFC13D7125500B30535 /* libmsx264.a */, + 226F2ED41344B0EF00F6EF27 /* libopencore-amrnb.a */, + 226F2ED31344B0EF00F6EF27 /* libopencore-amrwb.a */, 220FAD2C10765B400068D98F /* libortp.a */, 220FAD2D10765B400068D98F /* libosip2.a */, 220FAD2E10765B400068D98F /* libosipparser2.a */, + 226183AA1472527D0037138E /* libSKP_SILK_SDK.a */, 220FAD2F10765B400068D98F /* libspeex.a */, 220FAD3010765B400068D98F /* libspeexdsp.a */, - 226F2ED31344B0EF00F6EF27 /* libopencore-amrwb.a */, - 226F2ED41344B0EF00F6EF27 /* libopencore-amrnb.a */, - 226F2ED51344B0EF00F6EF27 /* libmsamr.a */, - 220FAC77107654FC0068D98F /* include */, - 080E96DDFE201D6D7F000001 /* Classes */, - 29B97315FDCFA39411CA2CEA /* Other Sources */, - 29B97317FDCFA39411CA2CEA /* Resources */, - 29B97323FDCFA39411CA2CEA /* Frameworks */, - 19C28FACFE9D520D11CA2CBB /* Products */, - 22744019106F31BD006EC466 /* CoreAudio.framework */, - 2274402E106F335E006EC466 /* AudioToolbox.framework */, - 22744043106F33FC006EC466 /* Security.framework */, - 22744056106F9BC9006EC466 /* CoreFoundation.framework */, - 2245671C107699F700F10948 /* Settings.bundle */, - 224567C1107B968500F10948 /* AVFoundation.framework */, - 22F51EF5107FA66500F98953 /* untitled.plist */, - 22B5EFA210CE50BD00777D97 /* AddressBookUI.framework */, - 22B5F03410CE6B2F00777D97 /* AddressBook.framework */, - 2264B6D111200342002C2C53 /* SystemConfiguration.framework */, - 2258633C11410BAC00C5A737 /* README */, - 228697C311AC29B800E9E0CA /* CFNetwork.framework */, - 22D1B68012A3E0BE001AE361 /* libresolv.dylib */, + 226183AB1472527D0037138E /* libsrtp.a */, 22E5B0AD133B5EA20044EA25 /* libssl.a */, - 22E5B0AE133B5EA20044EA25 /* libcrypto.a */, + 22276E8213C73D3100210156 /* libswscale.a */, + 7066FC0B13E830E400EFC6DC /* libvpx.a */, + 22AA8AFB13D7125500B30535 /* libx264.a */, + 344ABDE71484E723007420B6 /* libzrtpcpp.a */, + 344ABDEF14850AE9007420B6 /* libc++.1.dylib */, + 22D1B68012A3E0BE001AE361 /* libresolv.dylib */, + 344ABDF014850AE9007420B6 /* libstdc++.6.dylib */, + 22B5F03410CE6B2F00777D97 /* AddressBook.framework */, + 22B5EFA210CE50BD00777D97 /* AddressBookUI.framework */, + 2274402E106F335E006EC466 /* AudioToolbox.framework */, + 224567C1107B968500F10948 /* AVFoundation.framework */, + 228697C311AC29B800E9E0CA /* CFNetwork.framework */, + 22744019106F31BD006EC466 /* CoreAudio.framework */, + 22744056106F9BC9006EC466 /* CoreFoundation.framework */, + 22276E8813C73DC000210156 /* CoreMedia.framework */, + 340751961506459A00B89C47 /* CoreTelephony.framework */, + 22276E8613C73D8A00210156 /* CoreVideo.framework */, + D37DC7171594AF3400B2A5EB /* MessageUI.framework */, + 70E542F213E147E3002BA2C0 /* OpenGLES.framework */, + 70E542F413E147EB002BA2C0 /* QuartzCore.framework */, + 22744043106F33FC006EC466 /* Security.framework */, + 2264B6D111200342002C2C53 /* SystemConfiguration.framework */, + 22F51EF5107FA66500F98953 /* untitled.plist */, + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + D37DC6C31594AE5600B2A5EB /* InAppSettingsKit */, + 220FAC77107654FC0068D98F /* include */, + 2214783B1386A2030020F8B8 /* Localizable.strings */, + 2211DB9614764F6B00DEE054 /* nogpl-thirdparties */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 19C28FACFE9D520D11CA2CBB /* Products */, + 29B97317FDCFA39411CA2CEA /* Resources */, + D398D3031594B0FB00FD553C /* Settings */, ); name = CustomTemplate; sourceTree = ""; @@ -1715,6 +1800,94 @@ name = Utils; sourceTree = ""; }; + D37DC6C31594AE5600B2A5EB /* InAppSettingsKit */ = { + isa = PBXGroup; + children = ( + D37DC6C41594AE6F00B2A5EB /* Controllers */, + D37DC6CC1594AE6F00B2A5EB /* Models */, + D37DC6D71594AE6F00B2A5EB /* Views */, + D37DC6E61594AE6F00B2A5EB /* Xibs */, + ); + name = InAppSettingsKit; + sourceTree = ""; + }; + D37DC6C41594AE6F00B2A5EB /* Controllers */ = { + isa = PBXGroup; + children = ( + D37DC6C51594AE6F00B2A5EB /* IASKAppSettingsViewController.h */, + D37DC6C61594AE6F00B2A5EB /* IASKAppSettingsViewController.m */, + D37DC6C71594AE6F00B2A5EB /* IASKAppSettingsWebViewController.h */, + D37DC6C81594AE6F00B2A5EB /* IASKAppSettingsWebViewController.m */, + D37DC6C91594AE6F00B2A5EB /* IASKSpecifierValuesViewController.h */, + D37DC6CA1594AE6F00B2A5EB /* IASKSpecifierValuesViewController.m */, + D37DC6CB1594AE6F00B2A5EB /* IASKViewController.h */, + ); + name = Controllers; + path = InAppSettingsKit/Controllers; + sourceTree = ""; + }; + D37DC6CC1594AE6F00B2A5EB /* Models */ = { + isa = PBXGroup; + children = ( + D37DC6CD1594AE6F00B2A5EB /* IASKSettingsReader.h */, + D37DC6CE1594AE6F00B2A5EB /* IASKSettingsReader.m */, + D37DC6CF1594AE6F00B2A5EB /* IASKSettingsStore.h */, + D37DC6D01594AE6F00B2A5EB /* IASKSettingsStore.m */, + D37DC6D11594AE6F00B2A5EB /* IASKSettingsStoreFile.h */, + D37DC6D21594AE6F00B2A5EB /* IASKSettingsStoreFile.m */, + D37DC6D31594AE6F00B2A5EB /* IASKSettingsStoreUserDefaults.h */, + D37DC6D41594AE6F00B2A5EB /* IASKSettingsStoreUserDefaults.m */, + D37DC6D51594AE6F00B2A5EB /* IASKSpecifier.h */, + D37DC6D61594AE6F00B2A5EB /* IASKSpecifier.m */, + ); + name = Models; + path = InAppSettingsKit/Models; + sourceTree = ""; + }; + D37DC6D71594AE6F00B2A5EB /* Views */ = { + isa = PBXGroup; + children = ( + D37DC6D81594AE6F00B2A5EB /* IASKPSSliderSpecifierViewCell.h */, + D37DC6D91594AE6F00B2A5EB /* IASKPSSliderSpecifierViewCell.m */, + D37DC6DA1594AE6F00B2A5EB /* IASKPSTextFieldSpecifierViewCell.h */, + D37DC6DB1594AE6F00B2A5EB /* IASKPSTextFieldSpecifierViewCell.m */, + D37DC6DC1594AE6F00B2A5EB /* IASKPSTitleValueSpecifierViewCell.h */, + D37DC6DD1594AE6F00B2A5EB /* IASKPSTitleValueSpecifierViewCell.m */, + D37DC6DE1594AE6F00B2A5EB /* IASKPSToggleSwitchSpecifierViewCell.h */, + D37DC6DF1594AE6F00B2A5EB /* IASKPSToggleSwitchSpecifierViewCell.m */, + D37DC6E01594AE6F00B2A5EB /* IASKSlider.h */, + D37DC6E11594AE6F00B2A5EB /* IASKSlider.m */, + D37DC6E21594AE6F00B2A5EB /* IASKSwitch.h */, + D37DC6E31594AE6F00B2A5EB /* IASKSwitch.m */, + D37DC6E41594AE6F00B2A5EB /* IASKTextField.h */, + D37DC6E51594AE6F00B2A5EB /* IASKTextField.m */, + ); + name = Views; + path = InAppSettingsKit/Views; + sourceTree = ""; + }; + D37DC6E61594AE6F00B2A5EB /* Xibs */ = { + isa = PBXGroup; + children = ( + D37DC6E71594AE6F00B2A5EB /* IASKAppSettingsView.xib */, + D37DC6E81594AE6F00B2A5EB /* IASKAppSettingsWebView.xib */, + D37DC6E91594AE6F00B2A5EB /* IASKPSSliderSpecifierViewCell.xib */, + D37DC6EA1594AE6F00B2A5EB /* IASKPSTextFieldSpecifierViewCell.xib */, + D37DC6EB1594AE6F00B2A5EB /* IASKPSToggleSwitchSpecifierViewCell.xib */, + D37DC6EC1594AE6F00B2A5EB /* IASKSpecifierValuesView.xib */, + ); + name = Xibs; + path = InAppSettingsKit/Xibs; + sourceTree = ""; + }; + D398D3031594B0FB00FD553C /* Settings */ = { + isa = PBXGroup; + children = ( + D34F6F9D1594D3FB0095705B /* InAppSettings.bundle */, + ); + path = Settings; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -1791,7 +1964,6 @@ 2274550810700509006EC466 /* linphonerc in Resources */, 22F2508F107141E100AC9B3F /* DialerViewController.xib in Resources */, 22F254811073D99800AC9B3F /* ringback.wav in Resources */, - 2245671D107699F700F10948 /* Settings.bundle in Resources */, 22F51EF6107FA66500F98953 /* untitled.plist in Resources */, 2237D4091084D7A9001383EE /* oldphone-mono.wav in Resources */, 22E0A823111C44E100B04932 /* ConsoleViewController.xib in Resources */, @@ -1804,8 +1976,6 @@ 2218A92612FBE1340088A667 /* FirstLoginViewController.xib in Resources */, 228B19AF130290C500F154D3 /* iTunesArtwork in Resources */, 2214783D1386A2030020F8B8 /* Localizable.strings in Resources */, - 226B563F13CAF1CD00921595 /* audio.plist in Resources */, - 22E1A9E813CAF4AA00219531 /* video.plist in Resources */, 70571E1A13FABCB000CDD3C2 /* rootca.pem in Resources */, 344ABD72147FC438007420B6 /* ConferenceCallDetailView.xib in Resources */, 344ABD7A147FD32B007420B6 /* ConferenceCallDetailCell.xib in Resources */, @@ -1949,7 +2119,14 @@ D35E758915932DE60066B1C1 /* backspace-disabled.png in Resources */, D35E758D15934F360066B1C1 /* appeler-disabled.png in Resources */, D35E7599159460580066B1C1 /* ChatViewController.xib in Resources */, - D35E75A1159460B70066B1C1 /* SettingsViewController.xib in Resources */, + D37DC70B1594AE6F00B2A5EB /* IASKAppSettingsView.xib in Resources */, + D37DC70D1594AE6F00B2A5EB /* IASKAppSettingsWebView.xib in Resources */, + D37DC70F1594AE6F00B2A5EB /* IASKPSSliderSpecifierViewCell.xib in Resources */, + D37DC7111594AE6F00B2A5EB /* IASKPSTextFieldSpecifierViewCell.xib in Resources */, + D37DC7131594AE6F00B2A5EB /* IASKPSToggleSwitchSpecifierViewCell.xib in Resources */, + D37DC7151594AE6F00B2A5EB /* IASKSpecifierValuesView.xib in Resources */, + D32942A41594C94300556A1C /* SettingsViewController.xib in Resources */, + D34F6F9E1594D3FB0095705B /* InAppSettings.bundle in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1972,8 +2149,6 @@ 22D8F13B147548E2008C97DB /* FirstLoginViewController.xib in Resources */, 22D8F13C147548E2008C97DB /* iTunesArtwork in Resources */, 22D8F13D147548E2008C97DB /* Localizable.strings in Resources */, - 22D8F140147548E2008C97DB /* audio.plist in Resources */, - 22D8F141147548E2008C97DB /* video.plist in Resources */, 22D8F142147548E2008C97DB /* rootca.pem in Resources */, 2211DB95147564B400DEE054 /* Settings.bundle in Resources */, 344ABD73147FC438007420B6 /* ConferenceCallDetailView.xib in Resources */, @@ -2102,7 +2277,14 @@ D35E758A15932DE60066B1C1 /* backspace-disabled.png in Resources */, D35E758E15934F360066B1C1 /* appeler-disabled.png in Resources */, D35E759A159460580066B1C1 /* ChatViewController.xib in Resources */, - D35E75A2159460B70066B1C1 /* SettingsViewController.xib in Resources */, + D37DC70C1594AE6F00B2A5EB /* IASKAppSettingsView.xib in Resources */, + D37DC70E1594AE6F00B2A5EB /* IASKAppSettingsWebView.xib in Resources */, + D37DC7101594AE6F00B2A5EB /* IASKPSSliderSpecifierViewCell.xib in Resources */, + D37DC7121594AE6F00B2A5EB /* IASKPSTextFieldSpecifierViewCell.xib in Resources */, + D37DC7141594AE6F00B2A5EB /* IASKPSToggleSwitchSpecifierViewCell.xib in Resources */, + D37DC7161594AE6F00B2A5EB /* IASKSpecifierValuesView.xib in Resources */, + D32942A51594C94300556A1C /* SettingsViewController.xib in Resources */, + D34F6F9F1594D3FB0095705B /* InAppSettings.bundle in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2154,6 +2336,22 @@ D35E7581159328EB0066B1C1 /* UIAddressTextField.m in Sources */, D35E7597159460580066B1C1 /* ChatViewController.m in Sources */, D35E759F159460B70066B1C1 /* SettingsViewController.m in Sources */, + D37DC6C11594AE1800B2A5EB /* LinphoneCoreSettingsStore.m in Sources */, + D37DC6ED1594AE6F00B2A5EB /* IASKAppSettingsViewController.m in Sources */, + D37DC6EF1594AE6F00B2A5EB /* IASKAppSettingsWebViewController.m in Sources */, + D37DC6F11594AE6F00B2A5EB /* IASKSpecifierValuesViewController.m in Sources */, + D37DC6F31594AE6F00B2A5EB /* IASKSettingsReader.m in Sources */, + D37DC6F51594AE6F00B2A5EB /* IASKSettingsStore.m in Sources */, + D37DC6F71594AE6F00B2A5EB /* IASKSettingsStoreFile.m in Sources */, + D37DC6F91594AE6F00B2A5EB /* IASKSettingsStoreUserDefaults.m in Sources */, + D37DC6FB1594AE6F00B2A5EB /* IASKSpecifier.m in Sources */, + D37DC6FD1594AE6F00B2A5EB /* IASKPSSliderSpecifierViewCell.m in Sources */, + D37DC6FF1594AE6F00B2A5EB /* IASKPSTextFieldSpecifierViewCell.m in Sources */, + D37DC7011594AE6F00B2A5EB /* IASKPSTitleValueSpecifierViewCell.m in Sources */, + D37DC7031594AE6F00B2A5EB /* IASKPSToggleSwitchSpecifierViewCell.m in Sources */, + D37DC7051594AE6F00B2A5EB /* IASKSlider.m in Sources */, + D37DC7071594AE6F00B2A5EB /* IASKSwitch.m in Sources */, + D37DC7091594AE6F00B2A5EB /* IASKTextField.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2202,6 +2400,22 @@ D35E7582159328EB0066B1C1 /* UIAddressTextField.m in Sources */, D35E7598159460580066B1C1 /* ChatViewController.m in Sources */, D35E75A0159460B70066B1C1 /* SettingsViewController.m in Sources */, + D37DC6C21594AE1800B2A5EB /* LinphoneCoreSettingsStore.m in Sources */, + D37DC6EE1594AE6F00B2A5EB /* IASKAppSettingsViewController.m in Sources */, + D37DC6F01594AE6F00B2A5EB /* IASKAppSettingsWebViewController.m in Sources */, + D37DC6F21594AE6F00B2A5EB /* IASKSpecifierValuesViewController.m in Sources */, + D37DC6F41594AE6F00B2A5EB /* IASKSettingsReader.m in Sources */, + D37DC6F61594AE6F00B2A5EB /* IASKSettingsStore.m in Sources */, + D37DC6F81594AE6F00B2A5EB /* IASKSettingsStoreFile.m in Sources */, + D37DC6FA1594AE6F00B2A5EB /* IASKSettingsStoreUserDefaults.m in Sources */, + D37DC6FC1594AE6F00B2A5EB /* IASKSpecifier.m in Sources */, + D37DC6FE1594AE6F00B2A5EB /* IASKPSSliderSpecifierViewCell.m in Sources */, + D37DC7001594AE6F00B2A5EB /* IASKPSTextFieldSpecifierViewCell.m in Sources */, + D37DC7021594AE6F00B2A5EB /* IASKPSTitleValueSpecifierViewCell.m in Sources */, + D37DC7041594AE6F00B2A5EB /* IASKPSToggleSwitchSpecifierViewCell.m in Sources */, + D37DC7061594AE6F00B2A5EB /* IASKSlider.m in Sources */, + D37DC7081594AE6F00B2A5EB /* IASKSwitch.m in Sources */, + D37DC70A1594AE6F00B2A5EB /* IASKTextField.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/linphonerc b/linphonerc index 6dd0d69b0..9a2ba91f6 100644 --- a/linphonerc +++ b/linphonerc @@ -6,21 +6,17 @@ mtu=1300 [sip] sip_random_port=1 -sip_port=5060 sip_tcp_random_port=1 -sip_tcp_port=0 sip_tls_random_port=1 -sip_tls_port=0 guess_hostname=1 contact=sip:toto@unknown-host inc_timeout=15 use_info=0 use_ipv6=0 -default_proxy=-1 register_only_when_network_is_up=1 auto_net_state_mon=0 keepalive_period=30000 -media_encryption=zrtp + [rtp] audio_rtp_port=7076 diff --git a/linphonerc-ipad b/linphonerc-ipad index f537c1ee1..075adf31c 100644 --- a/linphonerc-ipad +++ b/linphonerc-ipad @@ -6,17 +6,13 @@ mtu=1300 [sip] sip_random_port=1 -sip_port=5060 sip_tcp_random_port=1 -sip_tcp_port=0 sip_tls_random_port=1 -sip_tls_port=0 guess_hostname=1 contact=sip:toto@unknown-host inc_timeout=15 use_info=0 use_ipv6=0 -default_proxy=-1 register_only_when_network_is_up=1 auto_net_state_mon=0 keepalive_period=30000 diff --git a/nogpl-thirdparties/Settings.bundle/Advanced.plist b/nogpl-thirdparties/Settings.bundle/Advanced.plist deleted file mode 100644 index c4d0b1f69..000000000 --- a/nogpl-thirdparties/Settings.bundle/Advanced.plist +++ /dev/null @@ -1,103 +0,0 @@ - - - - - PreferenceSpecifiers - - - Key - stun_preference - Title - Stun server - Type - PSTextFieldSpecifier - AutocapitalizationType - None - AutocorrectionType - No - DefaultValue - - - - DefaultValue - - Key - debugenable_preference - Title - Debug - Type - PSToggleSwitchSpecifier - - - AutocapitalizationType - None - AutocorrectionType - No - DefaultValue - - IsSecure - - Key - prefix_preference - KeyboardType - NumberPad - Title - Prefix - Type - PSTextFieldSpecifier - - - DefaultValue - - Key - substitute_+_by_00_preference - Title - Substitue + by 00 - Type - PSToggleSwitchSpecifier - - - DefaultValue - udp - Key - transport_preference - Title - Transport - Titles - - udp - tcp - tls - - Type - PSMultiValueSpecifier - Values - - udp - tcp - tls - - - - DefaultValue - - Key - enable_srtp_preference - Title - Secure rtp - Type - PSToggleSwitchSpecifier - - - DefaultValue - - Key - backgroundmode_preference - Title - Background mode - Type - PSToggleSwitchSpecifier - - - - diff --git a/nogpl-thirdparties/Settings.bundle/Root.plist b/nogpl-thirdparties/Settings.bundle/Root.plist deleted file mode 100644 index 4b6332f8e..000000000 --- a/nogpl-thirdparties/Settings.bundle/Root.plist +++ /dev/null @@ -1,131 +0,0 @@ - - - - - PreferenceSpecifiers - - - Title - SIP account - Type - PSGroupSpecifier - FooterText - Linphone must be restarted for changes to take effect - - - AutocapitalizationType - None - AutocorrectionType - No - DefaultValue - - IsSecure - - Key - username_preference - KeyboardType - Alphabet - Title - User name - Type - PSTextFieldSpecifier - - - AutocapitalizationType - None - AutocorrectionType - No - DefaultValue - - IsSecure - - Key - password_preference - KeyboardType - Alphabet - Title - Password - Type - PSTextFieldSpecifier - - - AutocapitalizationType - None - AutocorrectionType - No - DefaultValue - - IsSecure - - Key - domain_preference - KeyboardType - URL - Title - Domain - Type - PSTextFieldSpecifier - - - AutocapitalizationType - None - AutocorrectionType - No - DefaultValue - - IsSecure - - Key - proxy_preference - KeyboardType - URL - Title - Proxy - Type - PSTextFieldSpecifier - - - DefaultValue - - Key - outbound_proxy_preference - Title - Outbound proxy - Type - PSToggleSwitchSpecifier - - - Title - - Type - PSGroupSpecifier - - - File - audio - Title - Audio Codecs - Type - PSChildPaneSpecifier - - - File - video - Title - Video - Type - PSChildPaneSpecifier - - - File - Advanced - Title - Advanced - Type - PSChildPaneSpecifier - - - StringsTable - Root - - diff --git a/nogpl-thirdparties/Settings.bundle/audio.plist b/nogpl-thirdparties/Settings.bundle/audio.plist deleted file mode 100644 index 670182e79..000000000 --- a/nogpl-thirdparties/Settings.bundle/audio.plist +++ /dev/null @@ -1,85 +0,0 @@ - - - - - PreferenceSpecifiers - - - Title - Codecs - Type - PSGroupSpecifier - - - DefaultValue - - Key - speex_16k_preference - Title - Speex 16Khz - Type - PSToggleSwitchSpecifier - - - DefaultValue - - Key - speex_8k_preference - Title - Speex 8Khz - Type - PSToggleSwitchSpecifier - - - DefaultValue - - Key - g722_preference - Title - G722 - Type - PSToggleSwitchSpecifier - - - DefaultValue - - Key - gsm_8k_preference - Title - GSM - Type - PSToggleSwitchSpecifier - - - DefaultValue - - Key - ilbc_preference - Title - ILBC - Type - PSToggleSwitchSpecifier - - - DefaultValue - - Key - pcmu_preference - Title - PCMU - Type - PSToggleSwitchSpecifier - - - DefaultValue - - Key - pcma_preference - Title - PCMA - Type - PSToggleSwitchSpecifier - - - - diff --git a/nogpl-thirdparties/Settings.bundle/en.lproj/Root.strings b/nogpl-thirdparties/Settings.bundle/en.lproj/Root.strings deleted file mode 100644 index 8cd87b9d6..000000000 Binary files a/nogpl-thirdparties/Settings.bundle/en.lproj/Root.strings and /dev/null differ diff --git a/nogpl-thirdparties/Settings.bundle/video.plist b/nogpl-thirdparties/Settings.bundle/video.plist deleted file mode 100644 index 976ec6284..000000000 --- a/nogpl-thirdparties/Settings.bundle/video.plist +++ /dev/null @@ -1,45 +0,0 @@ - - - - - PreferenceSpecifiers - - - Type - PSToggleSwitchSpecifier - Title - Enable video - Key - enable_video_preference - DefaultValue - - - - Type - PSToggleSwitchSpecifier - Title - Automatically start video - Key - start_video_preference - DefaultValue - - - - Title - Codecs - Type - PSGroupSpecifier - - - DefaultValue - - Key - vp8_preference - Title - VP8 - Type - PSToggleSwitchSpecifier - - - - diff --git a/submodules/libilbc-rfc3951 b/submodules/libilbc-rfc3951 index af32518af..a70714c2e 160000 --- a/submodules/libilbc-rfc3951 +++ b/submodules/libilbc-rfc3951 @@ -1 +1 @@ -Subproject commit af32518af41f97caee07070234a3475409b9a27d +Subproject commit a70714c2e8a1f6f9958450cb612e3dc9895981e7 diff --git a/submodules/linphone b/submodules/linphone index 2d669353c..630e26944 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 2d669353c3eda22e63023fde2f3cde7b437d2c81 +Subproject commit 630e26944dd6e5cca53787452b162ec6baf7ba48