From d4634d0b6edf6b317b6b8c57edf35781942c5303 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Wed, 10 Jun 2015 13:28:38 -0700 Subject: [PATCH 01/15] Add proto for OAuth2 samples --- protos/auth_sample.proto | 57 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 protos/auth_sample.proto diff --git a/protos/auth_sample.proto b/protos/auth_sample.proto new file mode 100644 index 0000000..a49caca --- /dev/null +++ b/protos/auth_sample.proto @@ -0,0 +1,57 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package grpc.testing; + +option objc_class_prefix = "AUTH"; + +// Unary request. +message Request { + // Whether Response should include username. + bool fill_username = 4; + + // Whether Response should include OAuth scope. + bool fill_oauth_scope = 5; +} + +// Unary response, as configured by the request. +message Response { + // The user the request came from, for verifying authentication was + // successful. + string username = 2; + // OAuth scope. + string oauth_scope = 3; +} + +service TestService { + // One request followed by one response. + rpc UnaryCall(Request) returns (Response); +} From 23ab86123756b218e8b109568da3fdb914db1e21 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Wed, 10 Jun 2015 13:29:29 -0700 Subject: [PATCH 02/15] Add minimal tabbed app under auth_sample/ --- .../AuthSample.xcodeproj/project.pbxproj | 301 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + objective-c/auth_sample/FirstViewController.h | 38 +++ objective-c/auth_sample/FirstViewController.m | 43 +++ objective-c/auth_sample/Misc/AppDelegate.h | 38 +++ objective-c/auth_sample/Misc/AppDelegate.m | 37 +++ .../Misc/Base.lproj/Main.storyboard | 111 +++++++ .../AppIcon.appiconset/Contents.json | 68 ++++ .../first.imageset/Contents.json | 12 + .../Images.xcassets/first.imageset/first.pdf | Bin 0 -> 2465 bytes .../second.imageset/Contents.json | 12 + .../second.imageset/second.pdf | Bin 0 -> 2423 bytes objective-c/auth_sample/Misc/Info.plist | 57 ++++ objective-c/auth_sample/Misc/main.m | 41 +++ .../auth_sample/SecondViewController.h | 38 +++ .../auth_sample/SecondViewController.m | 43 +++ 16 files changed, 846 insertions(+) create mode 100644 objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj create mode 100644 objective-c/auth_sample/AuthSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 objective-c/auth_sample/FirstViewController.h create mode 100644 objective-c/auth_sample/FirstViewController.m create mode 100644 objective-c/auth_sample/Misc/AppDelegate.h create mode 100644 objective-c/auth_sample/Misc/AppDelegate.m create mode 100644 objective-c/auth_sample/Misc/Base.lproj/Main.storyboard create mode 100644 objective-c/auth_sample/Misc/Images.xcassets/AppIcon.appiconset/Contents.json create mode 100644 objective-c/auth_sample/Misc/Images.xcassets/first.imageset/Contents.json create mode 100644 objective-c/auth_sample/Misc/Images.xcassets/first.imageset/first.pdf create mode 100644 objective-c/auth_sample/Misc/Images.xcassets/second.imageset/Contents.json create mode 100644 objective-c/auth_sample/Misc/Images.xcassets/second.imageset/second.pdf create mode 100644 objective-c/auth_sample/Misc/Info.plist create mode 100644 objective-c/auth_sample/Misc/main.m create mode 100644 objective-c/auth_sample/SecondViewController.h create mode 100644 objective-c/auth_sample/SecondViewController.m diff --git a/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj b/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj new file mode 100644 index 0000000..af4e1cf --- /dev/null +++ b/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj @@ -0,0 +1,301 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 63E1E9821B28CB2100EF0978 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E9811B28CB2100EF0978 /* main.m */; }; + 63E1E9851B28CB2100EF0978 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E9841B28CB2100EF0978 /* AppDelegate.m */; }; + 63E1E9881B28CB2100EF0978 /* FirstViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E9871B28CB2100EF0978 /* FirstViewController.m */; }; + 63E1E98B1B28CB2100EF0978 /* SecondViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E98A1B28CB2100EF0978 /* SecondViewController.m */; }; + 63E1E98E1B28CB2100EF0978 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 63E1E98C1B28CB2100EF0978 /* Main.storyboard */; }; + 63E1E9901B28CB2100EF0978 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 63E1E98F1B28CB2100EF0978 /* Images.xcassets */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 63E1E97C1B28CB2100EF0978 /* AuthSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AuthSample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 63E1E9801B28CB2100EF0978 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 63E1E9811B28CB2100EF0978 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 63E1E9831B28CB2100EF0978 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 63E1E9841B28CB2100EF0978 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 63E1E9861B28CB2100EF0978 /* FirstViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FirstViewController.h; sourceTree = ""; }; + 63E1E9871B28CB2100EF0978 /* FirstViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FirstViewController.m; sourceTree = ""; }; + 63E1E9891B28CB2100EF0978 /* SecondViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecondViewController.h; sourceTree = ""; }; + 63E1E98A1B28CB2100EF0978 /* SecondViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecondViewController.m; sourceTree = ""; }; + 63E1E98D1B28CB2100EF0978 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 63E1E98F1B28CB2100EF0978 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 63E1E9791B28CB2000EF0978 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 63E1E9731B28CB2000EF0978 = { + isa = PBXGroup; + children = ( + 63E1E97E1B28CB2100EF0978 /* AuthSample */, + 63E1E97D1B28CB2100EF0978 /* Products */, + ); + sourceTree = ""; + }; + 63E1E97D1B28CB2100EF0978 /* Products */ = { + isa = PBXGroup; + children = ( + 63E1E97C1B28CB2100EF0978 /* AuthSample.app */, + ); + name = Products; + sourceTree = ""; + }; + 63E1E97E1B28CB2100EF0978 /* AuthSample */ = { + isa = PBXGroup; + children = ( + 63E1E9861B28CB2100EF0978 /* FirstViewController.h */, + 63E1E9871B28CB2100EF0978 /* FirstViewController.m */, + 63E1E9891B28CB2100EF0978 /* SecondViewController.h */, + 63E1E98A1B28CB2100EF0978 /* SecondViewController.m */, + 63E1E97F1B28CB2100EF0978 /* Supporting Files */, + ); + name = AuthSample; + sourceTree = SOURCE_ROOT; + }; + 63E1E97F1B28CB2100EF0978 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 63E1E98C1B28CB2100EF0978 /* Main.storyboard */, + 63E1E98F1B28CB2100EF0978 /* Images.xcassets */, + 63E1E9801B28CB2100EF0978 /* Info.plist */, + 63E1E9831B28CB2100EF0978 /* AppDelegate.h */, + 63E1E9841B28CB2100EF0978 /* AppDelegate.m */, + 63E1E9811B28CB2100EF0978 /* main.m */, + ); + name = "Supporting Files"; + path = Misc; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 63E1E97B1B28CB2000EF0978 /* AuthSample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 63E1E9A21B28CB2100EF0978 /* Build configuration list for PBXNativeTarget "AuthSample" */; + buildPhases = ( + 63E1E9781B28CB2000EF0978 /* Sources */, + 63E1E9791B28CB2000EF0978 /* Frameworks */, + 63E1E97A1B28CB2000EF0978 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AuthSample; + productName = AuthSample; + productReference = 63E1E97C1B28CB2100EF0978 /* AuthSample.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 63E1E9741B28CB2000EF0978 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = gRPC; + TargetAttributes = { + 63E1E97B1B28CB2000EF0978 = { + CreatedOnToolsVersion = 6.3.1; + }; + }; + }; + buildConfigurationList = 63E1E9771B28CB2000EF0978 /* Build configuration list for PBXProject "AuthSample" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 63E1E9731B28CB2000EF0978; + productRefGroup = 63E1E97D1B28CB2100EF0978 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 63E1E97B1B28CB2000EF0978 /* AuthSample */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 63E1E97A1B28CB2000EF0978 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 63E1E98E1B28CB2100EF0978 /* Main.storyboard in Resources */, + 63E1E9901B28CB2100EF0978 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 63E1E9781B28CB2000EF0978 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 63E1E98B1B28CB2100EF0978 /* SecondViewController.m in Sources */, + 63E1E9851B28CB2100EF0978 /* AppDelegate.m in Sources */, + 63E1E9881B28CB2100EF0978 /* FirstViewController.m in Sources */, + 63E1E9821B28CB2100EF0978 /* main.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 63E1E98C1B28CB2100EF0978 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 63E1E98D1B28CB2100EF0978 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 63E1E9A01B28CB2100EF0978 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 63E1E9A11B28CB2100EF0978 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 63E1E9A31B28CB2100EF0978 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = Misc/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 63E1E9A41B28CB2100EF0978 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = Misc/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 63E1E9771B28CB2000EF0978 /* Build configuration list for PBXProject "AuthSample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 63E1E9A01B28CB2100EF0978 /* Debug */, + 63E1E9A11B28CB2100EF0978 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 63E1E9A21B28CB2100EF0978 /* Build configuration list for PBXNativeTarget "AuthSample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 63E1E9A31B28CB2100EF0978 /* Debug */, + 63E1E9A41B28CB2100EF0978 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 63E1E9741B28CB2000EF0978 /* Project object */; +} diff --git a/objective-c/auth_sample/AuthSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/objective-c/auth_sample/AuthSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..39b57a4 --- /dev/null +++ b/objective-c/auth_sample/AuthSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/objective-c/auth_sample/FirstViewController.h b/objective-c/auth_sample/FirstViewController.h new file mode 100644 index 0000000..9630f4d --- /dev/null +++ b/objective-c/auth_sample/FirstViewController.h @@ -0,0 +1,38 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import + +@interface FirstViewController : UIViewController + +@end diff --git a/objective-c/auth_sample/FirstViewController.m b/objective-c/auth_sample/FirstViewController.m new file mode 100644 index 0000000..1237c42 --- /dev/null +++ b/objective-c/auth_sample/FirstViewController.m @@ -0,0 +1,43 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import "FirstViewController.h" + +@implementation FirstViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view, typically from a nib. +} + +@end diff --git a/objective-c/auth_sample/Misc/AppDelegate.h b/objective-c/auth_sample/Misc/AppDelegate.h new file mode 100644 index 0000000..102e7f3 --- /dev/null +++ b/objective-c/auth_sample/Misc/AppDelegate.h @@ -0,0 +1,38 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import + +@interface AppDelegate : UIResponder +@property (strong, nonatomic) UIWindow *window; +@end diff --git a/objective-c/auth_sample/Misc/AppDelegate.m b/objective-c/auth_sample/Misc/AppDelegate.m new file mode 100644 index 0000000..a38e366 --- /dev/null +++ b/objective-c/auth_sample/Misc/AppDelegate.m @@ -0,0 +1,37 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import "AppDelegate.h" + +@implementation AppDelegate +@end diff --git a/objective-c/auth_sample/Misc/Base.lproj/Main.storyboard b/objective-c/auth_sample/Misc/Base.lproj/Main.storyboard new file mode 100644 index 0000000..5258761 --- /dev/null +++ b/objective-c/auth_sample/Misc/Base.lproj/Main.storyboard @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/objective-c/auth_sample/Misc/Images.xcassets/AppIcon.appiconset/Contents.json b/objective-c/auth_sample/Misc/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..36d2c80 --- /dev/null +++ b/objective-c/auth_sample/Misc/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/Contents.json b/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/Contents.json new file mode 100644 index 0000000..33a7451 --- /dev/null +++ b/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "first.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/first.pdf b/objective-c/auth_sample/Misc/Images.xcassets/first.imageset/first.pdf new file mode 100644 index 0000000000000000000000000000000000000000..47d911dea647d55983671ead4d08b6f6b3600715 GIT binary patch literal 2465 zcmai03se(l7FLvisY+L#f-EBsK`11Xkc1=%MIujmB|xQ!>5vQ%APFP`Mlf5nSPOKE z2-^C>7DZkM!J;Da5{kfrC?Kvp3J41-3shFXvhuJqKo*oer*r0H{{P-P_x0cTzLzjD!bE z0qT;#Q7l4Gy%fMoXJaKT`@{5#R(MOqJPwQifv8iK6A%Ot9L14h2`38T!2s4PM=1!< zmL06}VYAA|ay#jZRs>HpA%X+eQW4rufWU%d1w5GTy!X#LeZsF_+~ccZmn3Fi)v^Z; zIG;?uU*yLLEYs61tjD>gXOFvSWsh{48xJvPNqKrIJtMdCz2cA2aC7TF?b@K`V!Lw- zE;zpH&ApqhoRjAHt}gK}>(qAc8dvrkD31*`<5<%C(&4_LqhQ3-GOf8~n^leG?+-@@^pjPa$J2gW@O)!b9hdTJ zTauyIJ&~rqeEZC1p9dWgx7{_WRc2=drMO=wcT7B{Zd58z`d)r_36r4V<6PGkCjpGfbnVMtm@;b}F!T?)Qav$_y7H5T;Mf!T}M zWxP9TNqrV?e5;b|pWd3^u2KAatk&3aDB@0 zZBaQNdCZ2#fblzYZnRCCjQ-GQWb-s8bX&<)?SxnUGdDYVFVk`xIf7@g3~$DX`H71_;r5OSZz1p`$_8y_9 z{;MJJ+n=>7Ewg;GnGHoz)&ID0z@F2!e$F7cWQ?d6s(!VY)_Gw})xCyMvsD={5i&H* zAIr_ACo8;Se6<*!-mm9Am79Iz^RVlc?%S5sg|E*SyIV{dd9{Mpf#d3cih5WKt=%ps zBEo)bt8EjmeCFYJRYU|b7d`p+-V|X2wOCYtyLP6t=!WH-kgdf0A};ytPfZiCwVPx{ z`g;zpe{8a4RQxQUwVU02<4X3w|9h;}XjhGWquqn{vVqq8g{*}BQF9=ybe_TM*!M=rFs1pN)yzctIXAoicsCe6>fit>wgZ#vp^hZOY0`J`rx zwdSK?GwR_xm9;5XjH|vf{O+Yg-)z;s*xt>;-vU`D-_SK<=~4eEVQkV~57{vyH6ebu>DqwE~Mx_A31Lg~$ zy`i52ew?GEluE%AN>ju*5z~dx2QQLP-G+E>o|En2+s&<^4*d zWD+<8PXs_Jp7_5Dpi(Gg3J?M;%Rn0{dcxQRh!ip+iHJ_e`!bM1MGxwI8Iedr+x>wI zq@&04fsADHfBccq^gpm8Q_u-~Uj|Z$YwSR(^_mzUb!}Xb2Cj`uqphg}v_Y%?Fs=;= zWq3s{hy)Tu!ji@RJsd$C+G{F6V2j1*Xk+7xo|LO7M2yb)(wc=%x-AclP9pLsbTF7m tf?*P!2EjJu5MD57P32Q4pdJ3tO_shCDT2=K;$ebx8ymcd$v!V9{2$sQiO>K5 literal 0 HcmV?d00001 diff --git a/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/Contents.json b/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/Contents.json new file mode 100644 index 0000000..03bd9c9 --- /dev/null +++ b/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "second.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/second.pdf b/objective-c/auth_sample/Misc/Images.xcassets/second.imageset/second.pdf new file mode 100644 index 0000000000000000000000000000000000000000..401614e288b4b160471c2776bed6f09762af3e1c GIT binary patch literal 2423 zcmai02~-nz8dqq7rWU#)x2z)&iMWtV?gK$2a)?|BP!TbkV}J-Gl1wmy+3G9S0=uOY zwCjai6uBOPMMdNiN`VDYKwLQr2#W^`R93*Ua=0^)EGYY4=grIf|KIohziYnv{elnR zdN_hk6db<(+3RPcxs!iut8c(j0TLh=9mY931H^rhEE0|aXo!dh5Iv+ZFr+}9F+v#P zLSnfD0$f~hN>~92V{z)WJA&2)5rW!|I?;o?oI*%zejJiuY>hFLQwKlAa9O+PnPh#% zJp~JAfs-De6u@;{cREMs}D-sGib_4>50m8_|Uj-zC0m@Qx zJV+^5Da4Qxpf3sBtKZs<_aI$Cb1T+h<->yL^rfiGNelYkqgC3#SqVP_iy*_RPcbjH)xYf zvYdC-)D_t8c{=5%;$VJQxs_#61J*kuXMC?|&PbPo-7uSxoNr~&J94|gKk+03JGXXM zx4w~=^VUzWqQveu_ilRgPdgNNdnLZCH`=;w91}cP5ihdm*B_jI+rk=Pz2Lk!)XUu| zkls3P5&YHJ!t0kF+MUVBHOAx)a zy|JxHNd37z*~b5#%*0w_F|#4?erNP;pG`Fevoq2%?9Y>%Cmzv1(ks;aPIGaiy1mhU zr{7lB^Mem&`QK{b{uiDC zLD8muY(FNk{YdV|zO#o_VB%);8|~Bh(Z4p?GM}g-HN2;q7~YNl-lD~HZ$taYw$Fzbn6c?c5eo=@`i>()el#qwB)hI-gp0 ztsw@dh-I5NJkk)RCoBC`L8ffKfY)=oG=#4LA9TO6eA}9~@a6dupB+=S{%s&NY}^0GY`hAqod)uxXHitrN%bWOJohV>t?!&Z#d4y^7J@=Oh`HV zee**4j>xRUd)|D0^I-B#<`m1-5PO{)!v(q?ecFYqr_8Q{+z7#n0uFbq%_?hZ-Ck(6NRn=vDS7Nb1Xxx_)9`!i- zGR>av*PJ+P_AGO*a_$FbtCCISg5PK44p&W#t$)+HVcxpR9LAL%_Pv$p`0tO*sYZD0 zCG3-ipr4WoVbjpw%Nf^r^rnWcDcjumgBPEjO;NM6QtZ8wU#0rjHx5zs%CahF4$W*U zxu!q8kYP+>v!BNPVIRJUGIWU@7qVvx2VZDw4gV8%z%bjpF#aF(W|PmliwlakuRq>= zhaCRc^R!7T)#Twb0{!Tns=CxGcGX|leErg`f3|v0eBXxHU&6Sj-_>zOL!!d+j5Xt* zPS;rWd^zEF{5d5%)nNK=)zFJ8Uc=aQKD%UK)_TNes1Gh{SD*Mb_@O` z7*zs9Uq~Vq?v|^8FcM-yLGMKzR3YFB0z@CFM2X-dio%Gu6&MJj=I?uS7sA3AdE^p8 zE49$PjJzPIJwfn;jso7X2#jynr3dO@p5QAK1O9wqKLC=PkQjj~p#n|-5O`ihbTzzu zL{}2QEe28pJYfVZRW56FL`LvO&|C^1Th{0}hQMW$Ng$QPpnzlwnMnf=kVy8(y==L% zLMa>r0gELdT + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + io.grpc.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + Main + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarTintParameters + + UINavigationBar + + Style + UIBarStyleDefault + Translucent + + + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/objective-c/auth_sample/Misc/main.m b/objective-c/auth_sample/Misc/main.m new file mode 100644 index 0000000..81e9d44 --- /dev/null +++ b/objective-c/auth_sample/Misc/main.m @@ -0,0 +1,41 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/objective-c/auth_sample/SecondViewController.h b/objective-c/auth_sample/SecondViewController.h new file mode 100644 index 0000000..06a3ca0 --- /dev/null +++ b/objective-c/auth_sample/SecondViewController.h @@ -0,0 +1,38 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import + +@interface SecondViewController : UIViewController + +@end diff --git a/objective-c/auth_sample/SecondViewController.m b/objective-c/auth_sample/SecondViewController.m new file mode 100644 index 0000000..aa9e5b6 --- /dev/null +++ b/objective-c/auth_sample/SecondViewController.m @@ -0,0 +1,43 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import "SecondViewController.h" + +@implementation SecondViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view, typically from a nib. +} + +@end From c5cb2664a842665e1ffa936aa3b38087539450b1 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Wed, 10 Jun 2015 13:34:52 -0700 Subject: [PATCH 03/15] Add podspec for auth proto library --- .../auth_sample/AuthTestService.podspec | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 objective-c/auth_sample/AuthTestService.podspec diff --git a/objective-c/auth_sample/AuthTestService.podspec b/objective-c/auth_sample/AuthTestService.podspec new file mode 100644 index 0000000..2fcbd05 --- /dev/null +++ b/objective-c/auth_sample/AuthTestService.podspec @@ -0,0 +1,35 @@ +Pod::Spec.new do |s| + s.name = "AuthTestService" + s.version = "0.0.1" + s.license = "New BSD" + + s.ios.deployment_target = "6.0" + s.osx.deployment_target = "10.8" + + # Base directory where the .proto files are. + src = "../../protos" + + # Directory where the generated files will be place. + dir = "Pods/" + s.name + + # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. + s.prepare_command = <<-CMD + mkdir -p #{dir} + protoc -I #{src} --objc_out=#{dir} --objcgrpc_out=#{dir} #{src}/auth_sample.proto + CMD + + s.subspec "Messages" do |ms| + ms.source_files = "#{dir}/*.pbobjc.{h,m}", "#{dir}/**/*.pbobjc.{h,m}" + ms.header_mappings_dir = dir + ms.requires_arc = false + ms.dependency "Protobuf", "~> 3.0.0-alpha-3" + end + + s.subspec "Services" do |ss| + ss.source_files = "#{dir}/*.pbrpc.{h,m}", "#{dir}/**/*.pbrpc.{h,m}" + ss.header_mappings_dir = dir + ss.requires_arc = true + ss.dependency "gRPC", "~> 0.5" + ss.dependency "#{s.name}/Messages" + end +end From 816dbd44640cadf95fc22f0e2d13903055f092bc Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Wed, 10 Jun 2015 13:35:17 -0700 Subject: [PATCH 04/15] Add Podfile with dependency on the proto library and Google/SignIn --- objective-c/auth_sample/Podfile | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 objective-c/auth_sample/Podfile diff --git a/objective-c/auth_sample/Podfile b/objective-c/auth_sample/Podfile new file mode 100644 index 0000000..dd4fd55 --- /dev/null +++ b/objective-c/auth_sample/Podfile @@ -0,0 +1,10 @@ +source 'https://github.com/CocoaPods/Specs.git' +platform :ios, '8.0' + +target 'AuthSample' do + # Depend on the generated AuthTestService library. + pod 'AuthTestService', :path => '.' + + # Depend on Google's OAuth2 library + pod 'Google/SignIn' +end From 518a7b5a37dda26bb06d77b6536a372e0e6bb805 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Wed, 10 Jun 2015 13:38:12 -0700 Subject: [PATCH 05/15] Install Pods project into app project --- .../AuthSample.xcodeproj/project.pbxproj | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj b/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj index af4e1cf..20af8fb 100644 --- a/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj +++ b/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ 63E1E98B1B28CB2100EF0978 /* SecondViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E98A1B28CB2100EF0978 /* SecondViewController.m */; }; 63E1E98E1B28CB2100EF0978 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 63E1E98C1B28CB2100EF0978 /* Main.storyboard */; }; 63E1E9901B28CB2100EF0978 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 63E1E98F1B28CB2100EF0978 /* Images.xcassets */; }; + 832213142AB24DB816D02635 /* libPods-AuthSample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F217A6ECA7F5BD1D5FB5071B /* libPods-AuthSample.a */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -27,6 +28,9 @@ 63E1E98A1B28CB2100EF0978 /* SecondViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecondViewController.m; sourceTree = ""; }; 63E1E98D1B28CB2100EF0978 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 63E1E98F1B28CB2100EF0978 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + A387D6CECBCF2EAF2983033A /* Pods-AuthSample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AuthSample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AuthSample/Pods-AuthSample.debug.xcconfig"; sourceTree = ""; }; + B444176735DA81FBE4B8B80C /* Pods-AuthSample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AuthSample.release.xcconfig"; path = "Pods/Target Support Files/Pods-AuthSample/Pods-AuthSample.release.xcconfig"; sourceTree = ""; }; + F217A6ECA7F5BD1D5FB5071B /* libPods-AuthSample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AuthSample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -34,17 +38,37 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 832213142AB24DB816D02635 /* libPods-AuthSample.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 021FA0E0B3F5D3D477DDAC10 /* Pods */ = { + isa = PBXGroup; + children = ( + A387D6CECBCF2EAF2983033A /* Pods-AuthSample.debug.xcconfig */, + B444176735DA81FBE4B8B80C /* Pods-AuthSample.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 4F443572636F3D60F26E870D /* Frameworks */ = { + isa = PBXGroup; + children = ( + F217A6ECA7F5BD1D5FB5071B /* libPods-AuthSample.a */, + ); + name = Frameworks; + sourceTree = ""; + }; 63E1E9731B28CB2000EF0978 = { isa = PBXGroup; children = ( 63E1E97E1B28CB2100EF0978 /* AuthSample */, 63E1E97D1B28CB2100EF0978 /* Products */, + 021FA0E0B3F5D3D477DDAC10 /* Pods */, + 4F443572636F3D60F26E870D /* Frameworks */, ); sourceTree = ""; }; @@ -89,9 +113,11 @@ isa = PBXNativeTarget; buildConfigurationList = 63E1E9A21B28CB2100EF0978 /* Build configuration list for PBXNativeTarget "AuthSample" */; buildPhases = ( + DAABBA7B5788A39108D7CA83 /* Check Pods Manifest.lock */, 63E1E9781B28CB2000EF0978 /* Sources */, 63E1E9791B28CB2000EF0978 /* Frameworks */, 63E1E97A1B28CB2000EF0978 /* Resources */, + AEFCCC69DD59CE8F6EB769D7 /* Copy Pods Resources */, ); buildRules = ( ); @@ -146,6 +172,39 @@ }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + AEFCCC69DD59CE8F6EB769D7 /* Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AuthSample/Pods-AuthSample-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + DAABBA7B5788A39108D7CA83 /* Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ 63E1E9781B28CB2000EF0978 /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -256,6 +315,7 @@ }; 63E1E9A31B28CB2100EF0978 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = A387D6CECBCF2EAF2983033A /* Pods-AuthSample.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = Misc/Info.plist; @@ -266,6 +326,7 @@ }; 63E1E9A41B28CB2100EF0978 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = B444176735DA81FBE4B8B80C /* Pods-AuthSample.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = Misc/Info.plist; From ef0c20b300aec490295847228e164fffa7d3ce27 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Wed, 10 Jun 2015 15:47:36 -0700 Subject: [PATCH 06/15] Add downloaded GoogleIdentity config to project --- .../auth_sample/AuthSample.xcodeproj/project.pbxproj | 4 ++++ objective-c/auth_sample/GoogleService-Info.plist | 10 ++++++++++ 2 files changed, 14 insertions(+) create mode 100644 objective-c/auth_sample/GoogleService-Info.plist diff --git a/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj b/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj index 20af8fb..a3ea799 100644 --- a/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj +++ b/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ 63E1E98B1B28CB2100EF0978 /* SecondViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E98A1B28CB2100EF0978 /* SecondViewController.m */; }; 63E1E98E1B28CB2100EF0978 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 63E1E98C1B28CB2100EF0978 /* Main.storyboard */; }; 63E1E9901B28CB2100EF0978 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 63E1E98F1B28CB2100EF0978 /* Images.xcassets */; }; + 63F5DE481B28F5C100CDD07E /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 63F5DE471B28F5C100CDD07E /* GoogleService-Info.plist */; }; 832213142AB24DB816D02635 /* libPods-AuthSample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F217A6ECA7F5BD1D5FB5071B /* libPods-AuthSample.a */; }; /* End PBXBuildFile section */ @@ -28,6 +29,7 @@ 63E1E98A1B28CB2100EF0978 /* SecondViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecondViewController.m; sourceTree = ""; }; 63E1E98D1B28CB2100EF0978 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 63E1E98F1B28CB2100EF0978 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 63F5DE471B28F5C100CDD07E /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; A387D6CECBCF2EAF2983033A /* Pods-AuthSample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AuthSample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AuthSample/Pods-AuthSample.debug.xcconfig"; sourceTree = ""; }; B444176735DA81FBE4B8B80C /* Pods-AuthSample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AuthSample.release.xcconfig"; path = "Pods/Target Support Files/Pods-AuthSample/Pods-AuthSample.release.xcconfig"; sourceTree = ""; }; F217A6ECA7F5BD1D5FB5071B /* libPods-AuthSample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AuthSample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -87,6 +89,7 @@ 63E1E9871B28CB2100EF0978 /* FirstViewController.m */, 63E1E9891B28CB2100EF0978 /* SecondViewController.h */, 63E1E98A1B28CB2100EF0978 /* SecondViewController.m */, + 63F5DE471B28F5C100CDD07E /* GoogleService-Info.plist */, 63E1E97F1B28CB2100EF0978 /* Supporting Files */, ); name = AuthSample; @@ -167,6 +170,7 @@ files = ( 63E1E98E1B28CB2100EF0978 /* Main.storyboard in Resources */, 63E1E9901B28CB2100EF0978 /* Images.xcassets in Resources */, + 63F5DE481B28F5C100CDD07E /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/objective-c/auth_sample/GoogleService-Info.plist b/objective-c/auth_sample/GoogleService-Info.plist new file mode 100644 index 0000000..86909d8 --- /dev/null +++ b/objective-c/auth_sample/GoogleService-Info.plist @@ -0,0 +1,10 @@ + + + + + CLIENT_ID + 15087385131-lh9bpkiai9nls53uadju0if6k7un3uih.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.15087385131-lh9bpkiai9nls53uadju0if6k7un3uih + + \ No newline at end of file From 473d4fc3b97f3ed02e43026432c6f98f10478472 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Wed, 10 Jun 2015 16:00:47 -0700 Subject: [PATCH 07/15] Add URL Types to project as expected by Google SignIn --- objective-c/auth_sample/Misc/Info.plist | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/objective-c/auth_sample/Misc/Info.plist b/objective-c/auth_sample/Misc/Info.plist index 13acacf..fc29250 100644 --- a/objective-c/auth_sample/Misc/Info.plist +++ b/objective-c/auth_sample/Misc/Info.plist @@ -18,6 +18,29 @@ 1.0 CFBundleSignature ???? + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLName + REVERSED_CLIENT_ID + CFBundleURLSchemes + + com.googleusercontent.apps.15087385131-lh9bpkiai9nls53uadju0if6k7un3uih + + + + CFBundleTypeRole + Editor + CFBundleURLName + BUNDLE_ID + CFBundleURLSchemes + + io.grpc.AuthSample + + + CFBundleVersion 1 LSRequiresIPhoneOS From 4da1012dc131ef9078b88a0f8117ba5fceafd82e Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Thu, 11 Jun 2015 12:02:30 -0700 Subject: [PATCH 08/15] Add SelectUserViewController with basic sign-in/-out functionality --- .../AuthSample.xcodeproj/project.pbxproj | 12 ++-- objective-c/auth_sample/Misc/AppDelegate.m | 24 +++++++ .../Misc/Base.lproj/Main.storyboard | 70 +++++++++++++++---- ...ontroller.h => SelectUserViewController.h} | 8 ++- ...ontroller.m => SelectUserViewController.m} | 39 ++++++++++- 5 files changed, 130 insertions(+), 23 deletions(-) rename objective-c/auth_sample/{FirstViewController.h => SelectUserViewController.h} (81%) rename objective-c/auth_sample/{FirstViewController.m => SelectUserViewController.m} (58%) diff --git a/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj b/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj index a3ea799..dd4778e 100644 --- a/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj +++ b/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj @@ -9,7 +9,7 @@ /* Begin PBXBuildFile section */ 63E1E9821B28CB2100EF0978 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E9811B28CB2100EF0978 /* main.m */; }; 63E1E9851B28CB2100EF0978 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E9841B28CB2100EF0978 /* AppDelegate.m */; }; - 63E1E9881B28CB2100EF0978 /* FirstViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E9871B28CB2100EF0978 /* FirstViewController.m */; }; + 63E1E9881B28CB2100EF0978 /* SelectUserViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E9871B28CB2100EF0978 /* SelectUserViewController.m */; }; 63E1E98B1B28CB2100EF0978 /* SecondViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E98A1B28CB2100EF0978 /* SecondViewController.m */; }; 63E1E98E1B28CB2100EF0978 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 63E1E98C1B28CB2100EF0978 /* Main.storyboard */; }; 63E1E9901B28CB2100EF0978 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 63E1E98F1B28CB2100EF0978 /* Images.xcassets */; }; @@ -23,8 +23,8 @@ 63E1E9811B28CB2100EF0978 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 63E1E9831B28CB2100EF0978 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 63E1E9841B28CB2100EF0978 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 63E1E9861B28CB2100EF0978 /* FirstViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FirstViewController.h; sourceTree = ""; }; - 63E1E9871B28CB2100EF0978 /* FirstViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FirstViewController.m; sourceTree = ""; }; + 63E1E9861B28CB2100EF0978 /* SelectUserViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SelectUserViewController.h; sourceTree = ""; }; + 63E1E9871B28CB2100EF0978 /* SelectUserViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SelectUserViewController.m; sourceTree = ""; }; 63E1E9891B28CB2100EF0978 /* SecondViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecondViewController.h; sourceTree = ""; }; 63E1E98A1B28CB2100EF0978 /* SecondViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecondViewController.m; sourceTree = ""; }; 63E1E98D1B28CB2100EF0978 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; @@ -85,8 +85,8 @@ 63E1E97E1B28CB2100EF0978 /* AuthSample */ = { isa = PBXGroup; children = ( - 63E1E9861B28CB2100EF0978 /* FirstViewController.h */, - 63E1E9871B28CB2100EF0978 /* FirstViewController.m */, + 63E1E9861B28CB2100EF0978 /* SelectUserViewController.h */, + 63E1E9871B28CB2100EF0978 /* SelectUserViewController.m */, 63E1E9891B28CB2100EF0978 /* SecondViewController.h */, 63E1E98A1B28CB2100EF0978 /* SecondViewController.m */, 63F5DE471B28F5C100CDD07E /* GoogleService-Info.plist */, @@ -216,7 +216,7 @@ files = ( 63E1E98B1B28CB2100EF0978 /* SecondViewController.m in Sources */, 63E1E9851B28CB2100EF0978 /* AppDelegate.m in Sources */, - 63E1E9881B28CB2100EF0978 /* FirstViewController.m in Sources */, + 63E1E9881B28CB2100EF0978 /* SelectUserViewController.m in Sources */, 63E1E9821B28CB2100EF0978 /* main.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/objective-c/auth_sample/Misc/AppDelegate.m b/objective-c/auth_sample/Misc/AppDelegate.m index a38e366..798d342 100644 --- a/objective-c/auth_sample/Misc/AppDelegate.m +++ b/objective-c/auth_sample/Misc/AppDelegate.m @@ -33,5 +33,29 @@ #import "AppDelegate.h" +#import + @implementation AppDelegate + +// As instructed in https://developers.google.com/identity/sign-in/ios/sign-in +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + NSError* configureError; + [GGLContext.sharedInstance configureWithError: &configureError]; + NSAssert(!configureError, @"Error configuring Google services: %@", configureError); + + return YES; +} + +// As instructed in https://developers.google.com/identity/sign-in/ios/sign-in +- (BOOL)application:(UIApplication *)application + openURL:(NSURL *)url + sourceApplication:(NSString *)sourceApplication + annotation:(id)annotation { + // This will properly handle the URL that the application receives at the end of the + // authentication process. + return [GIDSignIn.sharedInstance handleURL:url + sourceApplication:sourceApplication + annotation:annotation]; +} + @end diff --git a/objective-c/auth_sample/Misc/Base.lproj/Main.storyboard b/objective-c/auth_sample/Misc/Base.lproj/Main.storyboard index 5258761..761e7bf 100644 --- a/objective-c/auth_sample/Misc/Base.lproj/Main.storyboard +++ b/objective-c/auth_sample/Misc/Base.lproj/Main.storyboard @@ -1,13 +1,13 @@ - + - + - + - + @@ -16,29 +16,75 @@ - + + - + - + + + + + + + @@ -47,7 +93,7 @@ - + diff --git a/objective-c/auth_sample/FirstViewController.h b/objective-c/auth_sample/SelectUserViewController.h similarity index 81% rename from objective-c/auth_sample/FirstViewController.h rename to objective-c/auth_sample/SelectUserViewController.h index 9630f4d..eb3c2cf 100644 --- a/objective-c/auth_sample/FirstViewController.h +++ b/objective-c/auth_sample/SelectUserViewController.h @@ -31,8 +31,12 @@ * */ +#import #import -@interface FirstViewController : UIViewController - +@interface SelectUserViewController : UIViewController +@property(weak, nonatomic) IBOutlet GIDSignInButton *signInButton; +@property(weak, nonatomic) IBOutlet UIButton *signOutButton; +@property(weak, nonatomic) IBOutlet UILabel *mainLabel; +@property(weak, nonatomic) IBOutlet UILabel *subLabel; @end diff --git a/objective-c/auth_sample/FirstViewController.m b/objective-c/auth_sample/SelectUserViewController.m similarity index 58% rename from objective-c/auth_sample/FirstViewController.m rename to objective-c/auth_sample/SelectUserViewController.m index 1237c42..5e03056 100644 --- a/objective-c/auth_sample/FirstViewController.m +++ b/objective-c/auth_sample/SelectUserViewController.m @@ -31,13 +31,46 @@ * */ -#import "FirstViewController.h" +#import "SelectUserViewController.h" -@implementation FirstViewController +@implementation SelectUserViewController - (void)viewDidLoad { [super viewDidLoad]; - // Do any additional setup after loading the view, typically from a nib. + + self.signOutButton.layer.cornerRadius = 5; + self.signOutButton.hidden = YES; + + // As instructed in https://developers.google.com/identity/sign-in/ios/sign-in + GIDSignIn.sharedInstance.delegate = self; + GIDSignIn.sharedInstance.uiDelegate = self; + + [GIDSignIn.sharedInstance signInSilently]; +} + +- (void)signIn:(GIDSignIn *)signIn +didSignInForUser:(GIDGoogleUser *)user + withError:(NSError *)error { + if (error) { + // The user probably cancelled the sign-in flow. + return; + } + + self.mainLabel.text = [NSString stringWithFormat:@"User: %@", user.profile.email]; + NSString *scopes = [user.accessibleScopes componentsJoinedByString:@", "]; + scopes = scopes.length ? scopes : @"(none)"; + self.subLabel.text = [NSString stringWithFormat:@"Scopes: %@", scopes]; + + self.signInButton.hidden = YES; + self.signOutButton.hidden = NO; +} + +- (IBAction)didTapSignOut { + [GIDSignIn.sharedInstance signOut]; + self.mainLabel.text = @"Please sign in."; + self.subLabel.text = @""; + self.signInButton.hidden = NO; + self.signOutButton.hidden = YES; } @end From 3600977997c6f1b5e9bbdde7513872c276f040eb Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Thu, 11 Jun 2015 13:10:38 -0700 Subject: [PATCH 09/15] Request test scope --- objective-c/auth_sample/SecondViewController.h | 3 ++- objective-c/auth_sample/SecondViewController.m | 4 ++++ .../auth_sample/SelectUserViewController.m | 16 +++++++++++++--- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/objective-c/auth_sample/SecondViewController.h b/objective-c/auth_sample/SecondViewController.h index 06a3ca0..3e5ccf9 100644 --- a/objective-c/auth_sample/SecondViewController.h +++ b/objective-c/auth_sample/SecondViewController.h @@ -33,6 +33,7 @@ #import -@interface SecondViewController : UIViewController +extern NSString * const kTestScope; +@interface SecondViewController : UIViewController @end diff --git a/objective-c/auth_sample/SecondViewController.m b/objective-c/auth_sample/SecondViewController.m index aa9e5b6..d5ba19a 100644 --- a/objective-c/auth_sample/SecondViewController.m +++ b/objective-c/auth_sample/SecondViewController.m @@ -33,6 +33,10 @@ #import "SecondViewController.h" +#import + +NSString * const kTestScope = @"https://www.googleapis.com/auth/xapi.zoo"; + @implementation SecondViewController - (void)viewDidLoad { diff --git a/objective-c/auth_sample/SelectUserViewController.m b/objective-c/auth_sample/SelectUserViewController.m index 5e03056..e54e9f8 100644 --- a/objective-c/auth_sample/SelectUserViewController.m +++ b/objective-c/auth_sample/SelectUserViewController.m @@ -33,6 +33,8 @@ #import "SelectUserViewController.h" +#import "SecondViewController.h" + @implementation SelectUserViewController - (void)viewDidLoad { @@ -42,10 +44,16 @@ self.signOutButton.hidden = YES; // As instructed in https://developers.google.com/identity/sign-in/ios/sign-in - GIDSignIn.sharedInstance.delegate = self; - GIDSignIn.sharedInstance.uiDelegate = self; + GIDSignIn *signIn = GIDSignIn.sharedInstance; + signIn.delegate = self; + signIn.uiDelegate = self; - [GIDSignIn.sharedInstance signInSilently]; + // As instructed in https://developers.google.com/identity/sign-in/ios/additional-scopes + if (![signIn.scopes containsObject:kTestScope]) { + signIn.scopes = [signIn.scopes arrayByAddingObject:kTestScope]; + } + + [signIn signInSilently]; } - (void)signIn:(GIDSignIn *)signIn @@ -67,8 +75,10 @@ didSignInForUser:(GIDGoogleUser *)user - (IBAction)didTapSignOut { [GIDSignIn.sharedInstance signOut]; + self.mainLabel.text = @"Please sign in."; self.subLabel.text = @""; + self.signInButton.hidden = NO; self.signOutButton.hidden = YES; } From 64428acf977dfe761cd1348c4486a6a2a6bfcb8e Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Thu, 11 Jun 2015 15:21:55 -0700 Subject: [PATCH 10/15] Add MakeRPCViewController with authenticated RPC --- .../AuthSample.xcodeproj/project.pbxproj | 12 +-- ...ewController.h => MakeRPCViewController.h} | 3 +- .../auth_sample/MakeRPCViewController.m | 89 +++++++++++++++++++ .../Misc/Base.lproj/Main.storyboard | 27 +++--- .../auth_sample/SecondViewController.m | 47 ---------- .../auth_sample/SelectUserViewController.m | 2 +- 6 files changed, 110 insertions(+), 70 deletions(-) rename objective-c/auth_sample/{SecondViewController.h => MakeRPCViewController.h} (93%) create mode 100644 objective-c/auth_sample/MakeRPCViewController.m delete mode 100644 objective-c/auth_sample/SecondViewController.m diff --git a/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj b/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj index dd4778e..1e983ca 100644 --- a/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj +++ b/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj @@ -10,7 +10,7 @@ 63E1E9821B28CB2100EF0978 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E9811B28CB2100EF0978 /* main.m */; }; 63E1E9851B28CB2100EF0978 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E9841B28CB2100EF0978 /* AppDelegate.m */; }; 63E1E9881B28CB2100EF0978 /* SelectUserViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E9871B28CB2100EF0978 /* SelectUserViewController.m */; }; - 63E1E98B1B28CB2100EF0978 /* SecondViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E98A1B28CB2100EF0978 /* SecondViewController.m */; }; + 63E1E98B1B28CB2100EF0978 /* MakeRPCViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E1E98A1B28CB2100EF0978 /* MakeRPCViewController.m */; }; 63E1E98E1B28CB2100EF0978 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 63E1E98C1B28CB2100EF0978 /* Main.storyboard */; }; 63E1E9901B28CB2100EF0978 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 63E1E98F1B28CB2100EF0978 /* Images.xcassets */; }; 63F5DE481B28F5C100CDD07E /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 63F5DE471B28F5C100CDD07E /* GoogleService-Info.plist */; }; @@ -25,8 +25,8 @@ 63E1E9841B28CB2100EF0978 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 63E1E9861B28CB2100EF0978 /* SelectUserViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SelectUserViewController.h; sourceTree = ""; }; 63E1E9871B28CB2100EF0978 /* SelectUserViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SelectUserViewController.m; sourceTree = ""; }; - 63E1E9891B28CB2100EF0978 /* SecondViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecondViewController.h; sourceTree = ""; }; - 63E1E98A1B28CB2100EF0978 /* SecondViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecondViewController.m; sourceTree = ""; }; + 63E1E9891B28CB2100EF0978 /* MakeRPCViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MakeRPCViewController.h; sourceTree = ""; }; + 63E1E98A1B28CB2100EF0978 /* MakeRPCViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MakeRPCViewController.m; sourceTree = ""; }; 63E1E98D1B28CB2100EF0978 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 63E1E98F1B28CB2100EF0978 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 63F5DE471B28F5C100CDD07E /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; @@ -87,8 +87,8 @@ children = ( 63E1E9861B28CB2100EF0978 /* SelectUserViewController.h */, 63E1E9871B28CB2100EF0978 /* SelectUserViewController.m */, - 63E1E9891B28CB2100EF0978 /* SecondViewController.h */, - 63E1E98A1B28CB2100EF0978 /* SecondViewController.m */, + 63E1E9891B28CB2100EF0978 /* MakeRPCViewController.h */, + 63E1E98A1B28CB2100EF0978 /* MakeRPCViewController.m */, 63F5DE471B28F5C100CDD07E /* GoogleService-Info.plist */, 63E1E97F1B28CB2100EF0978 /* Supporting Files */, ); @@ -214,7 +214,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 63E1E98B1B28CB2100EF0978 /* SecondViewController.m in Sources */, + 63E1E98B1B28CB2100EF0978 /* MakeRPCViewController.m in Sources */, 63E1E9851B28CB2100EF0978 /* AppDelegate.m in Sources */, 63E1E9881B28CB2100EF0978 /* SelectUserViewController.m in Sources */, 63E1E9821B28CB2100EF0978 /* main.m in Sources */, diff --git a/objective-c/auth_sample/SecondViewController.h b/objective-c/auth_sample/MakeRPCViewController.h similarity index 93% rename from objective-c/auth_sample/SecondViewController.h rename to objective-c/auth_sample/MakeRPCViewController.h index 3e5ccf9..c75a8b3 100644 --- a/objective-c/auth_sample/SecondViewController.h +++ b/objective-c/auth_sample/MakeRPCViewController.h @@ -35,5 +35,6 @@ extern NSString * const kTestScope; -@interface SecondViewController : UIViewController +@interface MakeRPCViewController : UIViewController +@property(weak, nonatomic) IBOutlet UILabel *mainLabel; @end diff --git a/objective-c/auth_sample/MakeRPCViewController.m b/objective-c/auth_sample/MakeRPCViewController.m new file mode 100644 index 0000000..410ae7d --- /dev/null +++ b/objective-c/auth_sample/MakeRPCViewController.m @@ -0,0 +1,89 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import "MakeRPCViewController.h" + +#import +#import +#import +#include + +NSString * const kTestScope = @"https://www.googleapis.com/auth/xapi.zoo"; + +static NSString * const kTestHostAddress = @"grpc-test.sandbox.google.com"; + +@implementation MakeRPCViewController + +- (void)viewWillAppear:(BOOL)animated { + + // Create a service client and a proto request as usual. + AUTHTestService *client = [[AUTHTestService alloc] initWithHost:kTestHostAddress]; + + AUTHRequest *request = [AUTHRequest message]; + request.fillUsername = YES; + request.fillOauthScope = YES; + + // Create a not-yet-started RPC. We want to set the request headers on this object before starting + // it. + __block ProtoRPC *call = + [client RPCToUnaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { + if (response) { + // This test server responds with the email and scope of the access token it receives. + self.mainLabel.text = [NSString stringWithFormat:@"Used scope: %@ on behalf of user %@", + response.oauthScope, response.username]; + + } else if (error.code == GRPC_STATUS_UNAUTHENTICATED) { + // Authentication error. OAuth2 specifies we'll receive a challenge header. + NSString *challengeHeader = call.responseMetadata[@"www-authenticate"][0] ?: @""; + self.mainLabel.text = + [@"Invalid credentials. Server challenge:\n" stringByAppendingString:challengeHeader]; + + } else { + // Any other error. + self.mainLabel.text = [NSString stringWithFormat:@"Unexpected RPC error %li: %@", + (long)error.code, error.localizedDescription]; + } + }]; + + // Set the access token to be used. + NSString *accessToken = GIDSignIn.sharedInstance.currentUser.authentication.accessToken; + call.requestMetadata = [NSMutableDictionary dictionaryWithDictionary: + @{@"Authorization": [@"Bearer " stringByAppendingString:accessToken]}]; + + // Start the RPC. + [call start]; + + self.mainLabel.text = @"Waiting for RPC to complete..."; +} + +@end diff --git a/objective-c/auth_sample/Misc/Base.lproj/Main.storyboard b/objective-c/auth_sample/Misc/Base.lproj/Main.storyboard index 761e7bf..fb29c12 100644 --- a/objective-c/auth_sample/Misc/Base.lproj/Main.storyboard +++ b/objective-c/auth_sample/Misc/Base.lproj/Main.storyboard @@ -2,6 +2,7 @@ + @@ -90,10 +91,10 @@ - + - + @@ -102,29 +103,25 @@ - - - - + + - + + + + diff --git a/objective-c/auth_sample/SecondViewController.m b/objective-c/auth_sample/SecondViewController.m deleted file mode 100644 index d5ba19a..0000000 --- a/objective-c/auth_sample/SecondViewController.m +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#import "SecondViewController.h" - -#import - -NSString * const kTestScope = @"https://www.googleapis.com/auth/xapi.zoo"; - -@implementation SecondViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - // Do any additional setup after loading the view, typically from a nib. -} - -@end diff --git a/objective-c/auth_sample/SelectUserViewController.m b/objective-c/auth_sample/SelectUserViewController.m index e54e9f8..954c531 100644 --- a/objective-c/auth_sample/SelectUserViewController.m +++ b/objective-c/auth_sample/SelectUserViewController.m @@ -33,7 +33,7 @@ #import "SelectUserViewController.h" -#import "SecondViewController.h" +#import "MakeRPCViewController.h" @implementation SelectUserViewController From 98cbb3f1982fddafcff9d2b2ac364be8f7ccb46e Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 12 Jun 2015 12:38:16 -0700 Subject: [PATCH 11/15] Move OAuth2 plist into Misc folder --- objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj | 2 +- objective-c/auth_sample/{ => Misc}/GoogleService-Info.plist | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename objective-c/auth_sample/{ => Misc}/GoogleService-Info.plist (100%) diff --git a/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj b/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj index 1e983ca..51a39c5 100644 --- a/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj +++ b/objective-c/auth_sample/AuthSample.xcodeproj/project.pbxproj @@ -89,7 +89,6 @@ 63E1E9871B28CB2100EF0978 /* SelectUserViewController.m */, 63E1E9891B28CB2100EF0978 /* MakeRPCViewController.h */, 63E1E98A1B28CB2100EF0978 /* MakeRPCViewController.m */, - 63F5DE471B28F5C100CDD07E /* GoogleService-Info.plist */, 63E1E97F1B28CB2100EF0978 /* Supporting Files */, ); name = AuthSample; @@ -99,6 +98,7 @@ isa = PBXGroup; children = ( 63E1E98C1B28CB2100EF0978 /* Main.storyboard */, + 63F5DE471B28F5C100CDD07E /* GoogleService-Info.plist */, 63E1E98F1B28CB2100EF0978 /* Images.xcassets */, 63E1E9801B28CB2100EF0978 /* Info.plist */, 63E1E9831B28CB2100EF0978 /* AppDelegate.h */, diff --git a/objective-c/auth_sample/GoogleService-Info.plist b/objective-c/auth_sample/Misc/GoogleService-Info.plist similarity index 100% rename from objective-c/auth_sample/GoogleService-Info.plist rename to objective-c/auth_sample/Misc/GoogleService-Info.plist From 3508c9a5b85e41b4a7c9a68e10a6838108232170 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Tue, 16 Jun 2015 22:21:48 -0700 Subject: [PATCH 12/15] Add README for the auth example --- objective-c/auth_sample/README.md | 174 ++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 objective-c/auth_sample/README.md diff --git a/objective-c/auth_sample/README.md b/objective-c/auth_sample/README.md new file mode 100644 index 0000000..0681232 --- /dev/null +++ b/objective-c/auth_sample/README.md @@ -0,0 +1,174 @@ +#OAuth2 on gRPC: Objective-C + +This example application demostrates how to use OAuth2 on gRPC to make authenticated API calls on +behalf of a user. By walking through it you'll learn how to use the Objective-C gRPC API to: + +- Initialize and configure a remote call object before the RPC is started. +- Set request metadata elements on a call, which are semantically equivalent to HTTP request +headers. +- Read response metadata from a call, which is equivalent to HTTP response headers and trailers. + +It assumes you know the basics on how to make gRPC API calls using the Objective-C client library, +as shown in the [Hello World](https://github.com/grpc/grpc-common/tree/master/objective-c/helloworld) +or [Route Guide](https://github.com/grpc/grpc-common/tree/master/objective-c/route_guide) tutorials, +and familiarity with OAuth2 concepts like _access token_. + +- [Example code and setup](#setup) +- [Try it out!](#try) +- [Create an RPC object and start it later](#rpc-object) +- [Set request metadata of a call: Authorization header with an access token](#request-metadata) +- [Get response metadata of a call: Auth challenge header](#response-metadata) + + +## Example code and setup + +The example code for our tutorial is in [grpc/grpc-common/objective-c/auth_sample](https://github.com/grpc/grpc-common/tree/master/objective-c/auth_sample). +To download the example, clone the `grpc-common` repository by running the following command: +```shell +$ git clone https://github.com/grpc/grpc-common.git +``` + +Then change your current directory to `grpc-common/objective-c/auth_sample`: +```shell +$ cd grpc-common/objective-c/auth_sample +``` + +Our example is a simple application with two views. The first one lets a user sign in and out using +the OAuth2 flow of Google's [iOS SignIn library](https://developers.google.com/identity/sign-in/ios/). +(Google's library is used in this example because the test gRPC service we are going to call expects +Google account credentials, but neither gRPC nor the Objective-C client library is tied to any +specific OAuth2 provider). The second view makes a gRPC request to the test server, using the +access token obtained by the first view. + +Note: OAuth2 libraries need the application to register and obtain an ID from the identity provider +(in the case of this example app, Google). The app's XCode project is configured using that ID, so +you shouldn't copy this project as is for your own app: It would result in your app being identified +in the consent screen as "gRPC-AuthSample", and not having access to real Google services. Instead, +configure your XCode project following the [instructions here](https://developers.google.com/identity/sign-in/ios/). + +As with the other examples, you also should have [Cocoapods](https://cocoapods.org/#install) +installed, as well as the relevant tools to generate the client library code. You can obtain the +latter by following [these setup instructions](https://github.com/grpc/homebrew-grpc). + + + +## Try it out! + +To try the sample app, first have Cocoapods generate and install the client library for our .proto +files: + +```shell +$ pod install +``` + +(This might have to compile OpenSSL, which takes around 15 minutes if Cocoapods doesn't have it yet +on your computer's cache). + +Finally, open the XCode workspace created by Cocoapods, and run the app. + +The first view, `SelectUserViewController.h/m`, asks you to sign in with your Google account, and to +give the "gRPC-AuthSample" app the following permissions: + +- View your email address. +- View your basic profile info. +- "Test scope for access to the Zoo service". + +This last permission, corresponding to the scope `https://www.googleapis.com/auth/xapi.zoo` doesn't +grant any real capability: It's only used for testing. You can log out at any moment. + +The second view, `MakeRPCViewController.h/m`, makes a gRPC request to a test server at +https://grpc-test.sandbox.google.com, sending the access token along with the request. The test +service simply validates the token and writes in its response which user it belongs to, and which +scopes it gives access to. (The client application already knows those two values; it's a way to +verify that everything went as expected). + +The next sections guide you step-by-step through how the gRPC call in `MakeRPCViewController` is +performed. + + +## Create an RPC object and start it later + +The other basic tutorials show how to invoke an RPC by calling an asynchronous method in a generated +client object. This shows how to initialize an object that represents the RPC, and configure it +before starting the network request. + +Assume you have a proto service definition like this: + +```protobuf +option objc_class_prefix = "AUTH"; + +service TestService { + rpc UnaryCall(Request) returns (Response); +} +``` + +A `unaryCallWithRequest:handler:` method is generated, with which you're already familiar, is +generated for the `AUTHTestService` class: + +```objective-c +[client unaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { + ... +}]; +``` + +And a second `RPCToUnaryCallWithRequest:handler:` method is generated, which returns a +not-yet-started RPC object: + +```objective-c +#import + +ProtoRPC *call = + [client RPCToUnaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { + ... + }]; +``` + +The RPC represented by this object can be started at any later time like this: + +```objective-c +[call start]; +``` + + +## Set request metadata of a call: Authorization header with an access token + +The `ProtoRPC` class has a `requestMetadata` property defined like this: + +```objective-c +@property(nonatomic, readwrite) NSMutableDictionary *requestMetadata; +``` + +Setting it to a dictionary of metadata keys and values will have them sent on the wire when the call +is started. + +```objective-c +call.requestMetadata = [NSMutableDictionary dictionaryWithDictionary: + @{@"My-Header": @"Value for this header", + @"Another-Header": @"Its value"}]; +``` + +If you have an access token, OAuth2 specifies it is to be sent in this format: + +```objective-c +@{@"Authorization": [@"Bearer " stringByAppendingString:accessToken]} +``` + + +## Get response metadata of a call: Auth challenge header + +Analogously to the request metadata, the `ProtoRPC` class has a `responseMetadata` property defined +this way: + +```objective-c +@property(atomic, readonly) NSDictionary *responseMetadata; +``` + +Because gRPC metadata keys can be repeated, the values of the `responseMetadata` dictionary are +always `NSArray`s. Thus, to access OAuth2's authentication challenge header you write: + +```objective-c +call.responseMetadata[@"www-authenticate"][0] +``` + +Note that, as gRPC metadata elements are mapped to HTTP/2 headers (or trailers), the keys of the +response metadata are always ASCII strings in lowercase. From 777fee23d8ae78d01d8f2fce47c6aa566d6e4887 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Tue, 16 Jun 2015 11:03:20 -0700 Subject: [PATCH 13/15] Add Objective-C sections to the common auth README --- grpc-auth-support.md | 56 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/grpc-auth-support.md b/grpc-auth-support.md index 9b97203..597f443 100644 --- a/grpc-auth-support.md +++ b/grpc-auth-support.md @@ -114,6 +114,22 @@ var channel = new Channel("localhost:50051", credentials); var client = new Greeter.GreeterClient(channel); ``` +###SSL/TLS for server authentication and encryption (Objective-C) + +The default for Objective-C is to use SSL/TLS, as that's the most common use case when accessing +remote APIs. + +```objective-c +// Base case - With server authentication SSL/TLS +HLWGreeter *client = [[HLWGreeter alloc] initWithHost:@"localhost:50051"]; +// Same as using @"https://localhost:50051". +... + +// No encryption +HLWGreeter *client = [[HLWGreeter alloc] initWithHost:@"http://localhost:50051"]; +// Specifying the HTTP scheme explicitly forces no encryption. +``` + ###Authenticating with Google (Ruby) ```ruby # Base case - No encryption/authorization @@ -174,3 +190,43 @@ if (authorization.IsCreateScopedRequired) var client = new Greeter.GreeterClient(channel, new StubConfiguration(OAuth2InterceptorFactory.Create(credential))); ``` + +###Authenticating with Google (Objective-C) + +This example uses the [Google iOS Sign-In library](https://developers.google.com/identity/sign-in/ios/), +but it's easily extrapolated to any other OAuth2 library. + +```objective-c +// Base case - No authentication +[client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) { + ... +}]; + +... + +// Authenticating with Google + +// When signing the user in, ask her for the relevant scopes. +GIDSignIn.sharedInstance.scopes = @[@"https://www.googleapis.com/auth/grpc-testing"]; + +... + +#import + +// Create a not-yet-started RPC. We want to set the request headers on this object before starting +// it. +ProtoRPC *call = + [client RPCToSayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) { + ... + }]; + +// Set the access token to be used. +NSString *accessToken = GIDSignIn.sharedInstance.currentUser.authentication.accessToken; +call.requestMetadata = [NSMutableDictionary dictionaryWithDictionary: + @{@"Authorization": [@"Bearer " stringByAppendingString:accessToken]}]; + +// Start the RPC. +[call start]; +``` + +You can see a working example app, with a more detailed explanation, [here](https://github.com/grpc/grpc-common/tree/master/objective-c/auth_sample). From 1f0d49bb6e91571cb2a56f3bed2be76a3ea3ec92 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Wed, 8 Jul 2015 16:44:55 -0700 Subject: [PATCH 14/15] Fixes per the review. --- objective-c/auth_sample/README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/objective-c/auth_sample/README.md b/objective-c/auth_sample/README.md index 0681232..b677686 100644 --- a/objective-c/auth_sample/README.md +++ b/objective-c/auth_sample/README.md @@ -11,7 +11,7 @@ headers. It assumes you know the basics on how to make gRPC API calls using the Objective-C client library, as shown in the [Hello World](https://github.com/grpc/grpc-common/tree/master/objective-c/helloworld) or [Route Guide](https://github.com/grpc/grpc-common/tree/master/objective-c/route_guide) tutorials, -and familiarity with OAuth2 concepts like _access token_. +and are familiar with OAuth2 concepts like _access token_. - [Example code and setup](#setup) - [Try it out!](#try) @@ -42,9 +42,9 @@ access token obtained by the first view. Note: OAuth2 libraries need the application to register and obtain an ID from the identity provider (in the case of this example app, Google). The app's XCode project is configured using that ID, so -you shouldn't copy this project as is for your own app: It would result in your app being identified -in the consent screen as "gRPC-AuthSample", and not having access to real Google services. Instead, -configure your XCode project following the [instructions here](https://developers.google.com/identity/sign-in/ios/). +you shouldn't copy this project "as is" for your own app: it would result in your app being +identified in the consent screen as "gRPC-AuthSample", and not having access to real Google +services. Instead, configure your own XCode project following the [instructions here](https://developers.google.com/identity/sign-in/ios/). As with the other examples, you also should have [Cocoapods](https://cocoapods.org/#install) installed, as well as the relevant tools to generate the client library code. You can obtain the @@ -74,7 +74,7 @@ give the "gRPC-AuthSample" app the following permissions: - "Test scope for access to the Zoo service". This last permission, corresponding to the scope `https://www.googleapis.com/auth/xapi.zoo` doesn't -grant any real capability: It's only used for testing. You can log out at any moment. +grant any real capability: it's only used for testing. You can log out at any time. The second view, `MakeRPCViewController.h/m`, makes a gRPC request to a test server at https://grpc-test.sandbox.google.com, sending the access token along with the request. The test @@ -102,8 +102,8 @@ service TestService { } ``` -A `unaryCallWithRequest:handler:` method is generated, with which you're already familiar, is -generated for the `AUTHTestService` class: +A `unaryCallWithRequest:handler:` method, with which you're already familiar, is generated for the +`AUTHTestService` class: ```objective-c [client unaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { @@ -111,7 +111,7 @@ generated for the `AUTHTestService` class: }]; ``` -And a second `RPCToUnaryCallWithRequest:handler:` method is generated, which returns a +In addition, an `RPCToUnaryCallWithRequest:handler:` method is generated, which returns a not-yet-started RPC object: ```objective-c @@ -156,8 +156,8 @@ If you have an access token, OAuth2 specifies it is to be sent in this format: ## Get response metadata of a call: Auth challenge header -Analogously to the request metadata, the `ProtoRPC` class has a `responseMetadata` property defined -this way: +The `ProtoRPC` class also has a `responseMetadata` property, analogous to the request metadata we +just looked at. It's defined like this: ```objective-c @property(atomic, readonly) NSDictionary *responseMetadata; From 71e4c9679fa556d24f390adb3fc89f8675f3ec53 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Thu, 9 Jul 2015 10:10:15 -0700 Subject: [PATCH 15/15] Explain a bit more what metadata is. --- objective-c/auth_sample/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/objective-c/auth_sample/README.md b/objective-c/auth_sample/README.md index b677686..335e29f 100644 --- a/objective-c/auth_sample/README.md +++ b/objective-c/auth_sample/README.md @@ -139,7 +139,8 @@ The `ProtoRPC` class has a `requestMetadata` property defined like this: ``` Setting it to a dictionary of metadata keys and values will have them sent on the wire when the call -is started. +is started. gRPC metadata are pieces of information about the call sent by the client to the server +(and vice versa). They take the form of key-value pairs and are essentially opaque to gRPC itself. ```objective-c call.requestMetadata = [NSMutableDictionary dictionaryWithDictionary: