From 89801946f05774d3037b15f11b6a5d249c776804 Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Mon, 8 Jul 2013 20:36:55 -0700 Subject: Added OAuth 2.0 support to examples --- .../iOS UI Test.xcodeproj/project.pbxproj | 71 ++++++ .../iOS UI Test/iOS UI Test/MasterViewController.m | 77 +++++- .../iOS UI Test/SettingsViewController.h | 3 + .../iOS UI Test/SettingsViewController.m | 3 + .../iOS UI Test/SettingsViewController.xib | 283 +++++++++++++++++++-- 5 files changed, 405 insertions(+), 32 deletions(-) (limited to 'example/ios') diff --git a/example/ios/iOS UI Test/iOS UI Test.xcodeproj/project.pbxproj b/example/ios/iOS UI Test/iOS UI Test.xcodeproj/project.pbxproj index db280fde..e9cd3797 100644 --- a/example/ios/iOS UI Test/iOS UI Test.xcodeproj/project.pbxproj +++ b/example/ios/iOS UI Test/iOS UI Test.xcodeproj/project.pbxproj @@ -28,6 +28,13 @@ ABE4026B173F3FCE007F1FB3 /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ABE4026A173F3FCE007F1FB3 /* ImageIO.framework */; }; B12AAA3417322654003551C7 /* MCOMessageView.mm in Sources */ = {isa = PBXBuildFile; fileRef = B12AAA3017322654003551C7 /* MCOMessageView.mm */; }; B12AAA3517322654003551C7 /* MCTMsgViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = B12AAA3217322654003551C7 /* MCTMsgViewController.mm */; }; + C6D7194D178BB8B4008ED15F /* GTMHTTPFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = C6D71939178BA812008ED15F /* GTMHTTPFetcher.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + C6D7194E178BB8B4008ED15F /* GTMHTTPFetchHistory.m in Sources */ = {isa = PBXBuildFile; fileRef = C6D7193B178BA812008ED15F /* GTMHTTPFetchHistory.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + C6D7194F178BB8B4008ED15F /* GTMOAuth2Authentication.m in Sources */ = {isa = PBXBuildFile; fileRef = C6D7193E178BA812008ED15F /* GTMOAuth2Authentication.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + C6D71950178BB8B4008ED15F /* GTMOAuth2SignIn.m in Sources */ = {isa = PBXBuildFile; fileRef = C6D71940178BA812008ED15F /* GTMOAuth2SignIn.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + C6D71951178BB8B4008ED15F /* GTMOAuth2ViewControllerTouch.m in Sources */ = {isa = PBXBuildFile; fileRef = C6D71947178BA812008ED15F /* GTMOAuth2ViewControllerTouch.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + C6D71952178BB8B4008ED15F /* GTMOAuth2ViewTouch.xib in Resources */ = {isa = PBXBuildFile; fileRef = C6D71948178BA812008ED15F /* GTMOAuth2ViewTouch.xib */; }; + C6D71954178BB91E008ED15F /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C6D71953178BB91E008ED15F /* SystemConfiguration.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -107,6 +114,18 @@ B12AAA3017322654003551C7 /* MCOMessageView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCOMessageView.mm; sourceTree = ""; }; B12AAA3117322654003551C7 /* MCTMsgViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCTMsgViewController.h; sourceTree = ""; }; B12AAA3217322654003551C7 /* MCTMsgViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCTMsgViewController.mm; sourceTree = ""; }; + C6D71938178BA812008ED15F /* GTMHTTPFetcher.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GTMHTTPFetcher.h; sourceTree = ""; }; + C6D71939178BA812008ED15F /* GTMHTTPFetcher.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GTMHTTPFetcher.m; sourceTree = ""; }; + C6D7193A178BA812008ED15F /* GTMHTTPFetchHistory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GTMHTTPFetchHistory.h; sourceTree = ""; }; + C6D7193B178BA812008ED15F /* GTMHTTPFetchHistory.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GTMHTTPFetchHistory.m; sourceTree = ""; }; + C6D7193D178BA812008ED15F /* GTMOAuth2Authentication.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GTMOAuth2Authentication.h; sourceTree = ""; }; + C6D7193E178BA812008ED15F /* GTMOAuth2Authentication.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GTMOAuth2Authentication.m; sourceTree = ""; }; + C6D7193F178BA812008ED15F /* GTMOAuth2SignIn.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GTMOAuth2SignIn.h; sourceTree = ""; }; + C6D71940178BA812008ED15F /* GTMOAuth2SignIn.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GTMOAuth2SignIn.m; sourceTree = ""; }; + C6D71946178BA812008ED15F /* GTMOAuth2ViewControllerTouch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GTMOAuth2ViewControllerTouch.h; sourceTree = ""; }; + C6D71947178BA812008ED15F /* GTMOAuth2ViewControllerTouch.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GTMOAuth2ViewControllerTouch.m; sourceTree = ""; }; + C6D71948178BA812008ED15F /* GTMOAuth2ViewTouch.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GTMOAuth2ViewTouch.xib; sourceTree = ""; }; + C6D71953178BB91E008ED15F /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -114,6 +133,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + C6D71954178BB91E008ED15F /* SystemConfiguration.framework in Frameworks */, AB7BA446171389CC00104953 /* libMailCore-ios.a in Frameworks */, ABE4026B173F3FCE007F1FB3 /* ImageIO.framework in Frameworks */, AB9EAE40170374D900D750C7 /* Security.framework in Frameworks */, @@ -170,6 +190,7 @@ AB9EAE04170368F000D750C7 /* Frameworks */ = { isa = PBXGroup; children = ( + C6D71953178BB91E008ED15F /* SystemConfiguration.framework */, ABE4026A173F3FCE007F1FB3 /* ImageIO.framework */, AB7BA4471713913F00104953 /* CFNetwork.framework */, AB9EAE3F170374D900D750C7 /* Security.framework */, @@ -183,6 +204,7 @@ AB9EAE0B170368F000D750C7 /* iOS UI Test */ = { isa = PBXGroup; children = ( + C6D71936178BA812008ED15F /* gtm-oauth2 */, AB7BA4321713898B00104953 /* mailcore2.xcodeproj */, AB9EAE11170368F000D750C7 /* main.mm */, AB9EAE14170368F000D750C7 /* AppDelegate.h */, @@ -217,6 +239,49 @@ name = "Supporting Files"; sourceTree = ""; }; + C6D71936178BA812008ED15F /* gtm-oauth2 */ = { + isa = PBXGroup; + children = ( + C6D71937178BA812008ED15F /* HTTPFetcher */, + C6D7193C178BA812008ED15F /* Source */, + ); + name = "gtm-oauth2"; + path = "../../../common/gtm-oauth2"; + sourceTree = ""; + }; + C6D71937178BA812008ED15F /* HTTPFetcher */ = { + isa = PBXGroup; + children = ( + C6D71938178BA812008ED15F /* GTMHTTPFetcher.h */, + C6D71939178BA812008ED15F /* GTMHTTPFetcher.m */, + C6D7193A178BA812008ED15F /* GTMHTTPFetchHistory.h */, + C6D7193B178BA812008ED15F /* GTMHTTPFetchHistory.m */, + ); + path = HTTPFetcher; + sourceTree = ""; + }; + C6D7193C178BA812008ED15F /* Source */ = { + isa = PBXGroup; + children = ( + C6D7193D178BA812008ED15F /* GTMOAuth2Authentication.h */, + C6D7193E178BA812008ED15F /* GTMOAuth2Authentication.m */, + C6D7193F178BA812008ED15F /* GTMOAuth2SignIn.h */, + C6D71940178BA812008ED15F /* GTMOAuth2SignIn.m */, + C6D71945178BA812008ED15F /* Touch */, + ); + path = Source; + sourceTree = ""; + }; + C6D71945178BA812008ED15F /* Touch */ = { + isa = PBXGroup; + children = ( + C6D71946178BA812008ED15F /* GTMOAuth2ViewControllerTouch.h */, + C6D71947178BA812008ED15F /* GTMOAuth2ViewControllerTouch.m */, + C6D71948178BA812008ED15F /* GTMOAuth2ViewTouch.xib */, + ); + path = Touch; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -313,6 +378,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + C6D71952178BB8B4008ED15F /* GTMOAuth2ViewTouch.xib in Resources */, ABE40269173F0282007F1FB3 /* MCOMessageViewScript.js in Resources */, AB9EAE10170368F000D750C7 /* InfoPlist.strings in Resources */, AB9EAE18170368F000D750C7 /* Default.png in Resources */, @@ -331,10 +397,15 @@ buildActionMask = 2147483647; files = ( AB9EAE12170368F000D750C7 /* main.mm in Sources */, + C6D7194E178BB8B4008ED15F /* GTMHTTPFetchHistory.m in Sources */, AB9EAE16170368F000D750C7 /* AppDelegate.m in Sources */, AB9EAE22170368F000D750C7 /* MasterViewController.m in Sources */, AB9EAE3617036FD700D750C7 /* SettingsViewController.m in Sources */, + C6D7194D178BB8B4008ED15F /* GTMHTTPFetcher.m in Sources */, + C6D71951178BB8B4008ED15F /* GTMOAuth2ViewControllerTouch.m in Sources */, AB665BCD17134336007F2151 /* FXKeychain.m in Sources */, + C6D71950178BB8B4008ED15F /* GTMOAuth2SignIn.m in Sources */, + C6D7194F178BB8B4008ED15F /* GTMOAuth2Authentication.m in Sources */, B12AAA3417322654003551C7 /* MCOMessageView.mm in Sources */, B12AAA3517322654003551C7 /* MCTMsgViewController.mm in Sources */, ); diff --git a/example/ios/iOS UI Test/iOS UI Test/MasterViewController.m b/example/ios/iOS UI Test/iOS UI Test/MasterViewController.m index 3e5e4422..5bbc0d53 100644 --- a/example/ios/iOS UI Test/iOS UI Test/MasterViewController.m +++ b/example/ios/iOS UI Test/iOS UI Test/MasterViewController.m @@ -10,6 +10,11 @@ #import #import "FXKeychain.h" #import "MCTMsgViewController.h" +#import "GTMOAuth2ViewControllerTouch.h" + +#define CLIENT_ID @"the-client-id" +#define CLIENT_SECRET @"the-client-secret" +#define KEYCHAIN_ITEM_NAME @"MailCore OAuth 2.0 Token" @interface MasterViewController () @property (nonatomic, strong) NSArray *messages; @@ -26,24 +31,78 @@ [[NSUserDefaults standardUserDefaults] registerDefaults:@{ HostnameKey: @"imap.gmail.com" }]; + if ([[NSUserDefaults standardUserDefaults] boolForKey:@"OAuth2Enabled"]) { + [self startOAuth2]; + } + else { + [self startLogin]; + } +} + +- (void) startLogin +{ NSString *username = [[NSUserDefaults standardUserDefaults] objectForKey:UsernameKey]; NSString *password = [[FXKeychain defaultKeychain] objectForKey:PasswordKey]; NSString *hostname = [[NSUserDefaults standardUserDefaults] objectForKey:HostnameKey]; - - [self loadAccountWithUsername:username password:password hostname:hostname]; + + if (!username.length || !password.length) { + [self performSelector:@selector(showSettingsViewController:) withObject:nil afterDelay:0.5]; + return; + } + + [self loadAccountWithUsername:username password:password hostname:hostname oauth2Token:nil]; } -- (void)loadAccountWithUsername:(NSString *)username password:(NSString *)password hostname:(NSString *)hostname { - if (!username.length || !password.length) { - [self performSelector:@selector(showSettingsViewController:) withObject:nil afterDelay:0.5]; - return; - } - +- (void) startOAuth2 +{ + GTMOAuth2Authentication * auth = [GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:KEYCHAIN_ITEM_NAME + clientID:CLIENT_ID + clientSecret:CLIENT_SECRET]; + + if ([auth refreshToken] == nil) { + MasterViewController * __weak weakSelf = self; + GTMOAuth2ViewControllerTouch *viewController = [GTMOAuth2ViewControllerTouch controllerWithScope:@"https://mail.google.com/" + clientID:CLIENT_ID + clientSecret:CLIENT_SECRET + keychainItemName:KEYCHAIN_ITEM_NAME + completionHandler:^(GTMOAuth2ViewControllerTouch *viewController, GTMOAuth2Authentication *retrievedAuth, NSError *error) { + [weakSelf loadWithAuth:retrievedAuth]; + }]; + [self.navigationController pushViewController:viewController + animated:YES]; + } + else { + [auth beginTokenFetchWithDelegate:self + didFinishSelector:@selector(auth:finishedRefreshWithFetcher:error:)]; + } +} + +- (void)auth:(GTMOAuth2Authentication *)auth +finishedRefreshWithFetcher:(GTMHTTPFetcher *)fetcher + error:(NSError *)error { + [self loadWithAuth:auth]; +} + +- (void)loadWithAuth:(GTMOAuth2Authentication *)auth +{ + NSString *hostname = [[NSUserDefaults standardUserDefaults] objectForKey:HostnameKey]; + [self loadAccountWithUsername:[auth userEmail] password:nil hostname:hostname oauth2Token:[auth accessToken]]; +} + +- (void)loadAccountWithUsername:(NSString *)username + password:(NSString *)password + hostname:(NSString *)hostname + oauth2Token:(NSString *)oauth2Token +{ self.imapSession = [[MCOIMAPSession alloc] init]; self.imapSession.hostname = hostname; self.imapSession.port = 993; self.imapSession.username = username; self.imapSession.password = password; + if (oauth2Token != nil) { + self.imapSession.OAuth2Token = oauth2Token; + self.imapSession.authType = MCOAuthTypeXOAuth2; + } self.imapSession.connectionType = MCOConnectionTypeTLS; MasterViewController * __weak weakSelf = self; self.imapSession.connectionLogger = ^(void * connectionID, MCOConnectionLogType type, NSData * data) { @@ -135,7 +194,7 @@ ![password isEqualToString:self.imapSession.password] || ![hostname isEqualToString:self.imapSession.hostname]) { self.imapSession = nil; - [self loadAccountWithUsername:username password:password hostname:hostname]; + [self loadAccountWithUsername:username password:password hostname:hostname oauth2Token:nil]; } } diff --git a/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.h b/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.h index e5f5da48..a1cb84a2 100644 --- a/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.h +++ b/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.h @@ -12,6 +12,7 @@ extern NSString * const UsernameKey; extern NSString * const PasswordKey; extern NSString * const HostnameKey; extern NSString * const FetchFullMessageKey; +extern NSString * const OAuthEnabledKey; @protocol SettingsViewControllerDelegate; @@ -21,6 +22,8 @@ extern NSString * const FetchFullMessageKey; @property (weak, nonatomic) IBOutlet UITextField *passwordTextField; @property (weak, nonatomic) IBOutlet UITextField *hostnameTextField; @property (weak, nonatomic) IBOutlet UISwitch *fetchFullMessageSwitch; +@property (weak, nonatomic) IBOutlet UISwitch *useOAuth2Switch; + @property (nonatomic, weak) id delegate; - (IBAction)done:(id)sender; diff --git a/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.m b/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.m index e2f0d2c5..d17b479a 100644 --- a/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.m +++ b/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.m @@ -13,6 +13,7 @@ NSString * const UsernameKey = @"username"; NSString * const PasswordKey = @"password"; NSString * const HostnameKey = @"hostname"; NSString * const FetchFullMessageKey = @"FetchFullMessageEnabled"; +NSString * const OAuthEnabledKey = @"OAuth2Enabled"; @implementation SettingsViewController @@ -21,6 +22,7 @@ NSString * const FetchFullMessageKey = @"FetchFullMessageEnabled"; [[FXKeychain defaultKeychain] setObject:self.passwordTextField.text ?: @"" forKey:PasswordKey]; [[NSUserDefaults standardUserDefaults] setObject:self.hostnameTextField.text ?: @"" forKey:HostnameKey]; [[NSUserDefaults standardUserDefaults] setBool:[self.fetchFullMessageSwitch isOn] forKey:FetchFullMessageKey]; + [[NSUserDefaults standardUserDefaults] setBool:[self.useOAuth2Switch isOn] forKey:OAuthEnabledKey]; [self.delegate settingsViewControllerFinished:self]; } @@ -33,6 +35,7 @@ NSString * const FetchFullMessageKey = @"FetchFullMessageEnabled"; self.passwordTextField.text = [[FXKeychain defaultKeychain] objectForKey:PasswordKey]; self.hostnameTextField.text = [[NSUserDefaults standardUserDefaults] stringForKey:HostnameKey]; self.fetchFullMessageSwitch.on = [[NSUserDefaults standardUserDefaults] boolForKey:FetchFullMessageKey]; + self.useOAuth2Switch.on = [[NSUserDefaults standardUserDefaults] boolForKey:OAuthEnabledKey]; } @end diff --git a/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.xib b/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.xib index 3de561bd..c3f4f089 100644 --- a/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.xib +++ b/example/ios/iOS UI Test/iOS UI Test/SettingsViewController.xib @@ -3,12 +3,12 @@ 1552 12E55 - 3084 + 4457.6 1187.39 626.00 com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 2083 + 3682.6 IBNSLayoutConstraint @@ -96,8 +96,8 @@ 1 14 - - Helvetica + + HelveticaNeue 14 16 @@ -130,7 +130,7 @@ 1 - + @@ -159,7 +159,7 @@ 1 - + @@ -167,7 +167,7 @@ {{208, 180}, {94, 27}} - + _NS:9 NO IBCocoaTouchFramework @@ -188,7 +188,7 @@ NO IBCocoaTouchFramework Fetch full message - + 1 MCAwIDAAA darkTextColor @@ -196,7 +196,41 @@ 0 - + + NO + + + + 292 + {{208, 215}, {94, 27}} + + + + _NS:9 + NO + IBCocoaTouchFramework + 0 + 0 + + + + 292 + {{20, 218}, {143, 21}} + + + + _NS:9 + NO + YES + 7 + NO + IBCocoaTouchFramework + Use OAuth 2.0 + + + 0 + + NO @@ -271,6 +305,14 @@ 69 + + + useOAuth2Switch + + + + 84 + done: @@ -292,6 +334,57 @@ 1 + + + 5 + 0 + + 5 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + NO + + + + 3 + 0 + + 4 + 1 + + 8 + + 1000 + + 6 + 24 + 3 + NO + + + + 10 + 0 + + 10 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + NO + 3 @@ -307,6 +400,7 @@ 6 24 3 + NO @@ -320,9 +414,44 @@ 1000 - 8 + 0 29 3 + NO + + + + 6 + 0 + + 6 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + NO + + + + 5 + 0 + + 5 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + NO @@ -339,6 +468,7 @@ 6 24 2 + NO @@ -352,9 +482,10 @@ 1000 - 8 + 0 29 3 + NO @@ -368,9 +499,10 @@ 1000 - 8 + 0 29 3 + NO @@ -384,9 +516,10 @@ 1000 - 8 + 0 29 3 + NO @@ -403,6 +536,7 @@ 6 24 3 + NO @@ -419,6 +553,7 @@ 6 24 3 + NO @@ -432,9 +567,10 @@ 1000 - 8 + 0 29 3 + NO @@ -448,9 +584,10 @@ 1000 - 8 + 0 29 3 + NO @@ -464,9 +601,10 @@ 1000 - 8 + 0 29 3 + NO @@ -483,6 +621,7 @@ 3 9 3 + NO @@ -496,9 +635,10 @@ 1000 - 8 + 0 29 3 + NO @@ -512,9 +652,10 @@ 1000 - 8 + 0 29 3 + NO @@ -528,9 +669,10 @@ 1000 - 8 + 0 29 3 + NO @@ -544,9 +686,10 @@ 1000 - 8 + 0 29 3 + NO @@ -554,6 +697,8 @@ + + @@ -699,6 +844,7 @@ 3 9 1 + NO @@ -715,6 +861,7 @@ 3 9 1 + NO @@ -739,6 +886,65 @@ + + 72 + + + + + 73 + + + + + 8 + 0 + + 0 + 1 + + 21 + + 1000 + + 3 + 9 + 1 + NO + + + + + + 75 + + + + + 76 + + + + + 80 + + + + + 81 + + + + + 82 + + + + + 83 + + + @@ -747,7 +953,7 @@ UIResponder com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin - + @@ -762,8 +968,13 @@ + + + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -800,13 +1011,26 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 71 + 84 @@ -837,6 +1061,7 @@ UISwitch UITextField UITextField + UISwitch @@ -855,6 +1080,10 @@ passwordTextField UITextField + + useOAuth2Switch + UISwitch + IBProjectSource @@ -865,9 +1094,17 @@ 0 IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + YES 3 YES - 2083 + 3682.6 -- cgit v1.2.3