ソースを参照

Resolve hard dependency of GameKit (#2355)

Chuan Ren 7 年 前
コミット
a2e13d5b1c

+ 16 - 1
Firebase/Auth/Source/AuthProviders/GameCenter/FIRGameCenterAuthProvider.m

@@ -31,7 +31,22 @@
 }
 
 + (void)getCredentialWithCompletion:(FIRGameCenterCredentialCallback)completion {
-  __weak GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
+  /**
+   Linking GameKit.framework without using it on macOS results in App Store rejection.
+   Thus we don't link GameKit.framework to our SDK directly. `optionalLocalPlayer` is used for
+   checking whether the APP that consuming our SDK has linked GameKit.framework. If not, a
+   `GameKitNotLinkedError` will be raised.
+   **/
+  GKLocalPlayer *optionalLocalPlayer = [[NSClassFromString(@"GKLocalPlayer") alloc] init];
+
+  if (!optionalLocalPlayer) {
+    if (completion) {
+      completion(nil, [FIRAuthErrorUtils gameKitNotLinkedError]);
+    }
+    return;
+  }
+
+  __weak GKLocalPlayer *localPlayer = [[optionalLocalPlayer class] localPlayer];
   if (!localPlayer.isAuthenticated) {
     if (completion) {
       completion(nil, [FIRAuthErrorUtils localPlayerNotAuthenticatedError]);

+ 6 - 0
Firebase/Auth/Source/FIRAuthErrorUtils.h

@@ -451,6 +451,12 @@ NS_ASSUME_NONNULL_BEGIN
  */
 + (NSError *)localPlayerNotAuthenticatedError;
 
+/** @fn gameKitNotLinkedError
+   @brief Constructs an @c NSError with the @c FIRAuthErrorCodeGameKitNotLinked code.
+   @return The NSError instance associated with the given FIRAuthError.
+ */
++ (NSError *)gameKitNotLinkedError;
+
 /** @fn notificationNotForwardedError
     @brief Constructs an @c NSError with the @c FIRAuthErrorCodeNotificationNotForwarded code.
     @return The NSError instance associated with the given FIRAuthError.

+ 15 - 1
Firebase/Auth/Source/FIRAuthErrorUtils.m

@@ -312,11 +312,17 @@ static NSString *const kFIRAuthErrorMessageInvalidVerificationID =
     @"The verification ID used to create the phone auth credential is invalid.";
 
 /** @var kFIRAuthErrorMessageLocalPlayerNotAuthenticated
- @brief Message for @c FIRAuthErrorCodeLocalPlayerNotAuthenticated error code.
+    @brief Message for @c FIRAuthErrorCodeLocalPlayerNotAuthenticated error code.
  */
 static NSString *const kFIRAuthErrorMessageLocalPlayerNotAuthenticated =
     @"The local player is not authenticated. Please log the local player in to Game Center.";
 
+/** @var kFIRAuthErrorMessageGameKitNotLinked
+    @brief Message for @c kFIRAuthErrorMessageGameKitNotLinked error code.
+ */
+static NSString *const kFIRAuthErrorMessageGameKitNotLinked =
+    @"The GameKit framework is not linked. Please turn on the Game Center capability.";
+
 /** @var kFIRAuthErrorMessageSessionExpired
     @brief Message for @c FIRAuthErrorCodeSessionExpired error code.
  */
@@ -556,6 +562,8 @@ static NSString *FIRAuthErrorDescription(FIRAuthErrorCode code) {
       return kFIRAuthErrorMessageMalformedJWT;
     case FIRAuthErrorCodeLocalPlayerNotAuthenticated:
       return kFIRAuthErrorMessageLocalPlayerNotAuthenticated;
+    case FIRAuthErrorCodeGameKitNotLinked:
+      return kFIRAuthErrorMessageGameKitNotLinked;
   }
 }
 
@@ -683,6 +691,8 @@ static NSString *const FIRAuthErrorCodeString(FIRAuthErrorCode code) {
       return @"ERROR_MALFORMED_JWT";
     case FIRAuthErrorCodeLocalPlayerNotAuthenticated:
       return @"ERROR_LOCAL_PLAYER_NOT_AUTHENTICATED";
+    case FIRAuthErrorCodeGameKitNotLinked:
+      return @"ERROR_GAME_KIT_NOT_LINKED";
   }
 }
 
@@ -1000,6 +1010,10 @@ static NSString *const FIRAuthErrorCodeString(FIRAuthErrorCode code) {
   return [self errorWithCode:FIRAuthInternalErrorCodeLocalPlayerNotAuthenticated];
 }
 
++ (NSError *)gameKitNotLinkedError {
+  return [self errorWithCode:FIRAuthInternalErrorCodeGameKitNotLinked];
+}
+
 + (NSError *)notificationNotForwardedError {
   return [self errorWithCode:FIRAuthInternalErrorCodeNotificationNotForwarded];
 }

+ 5 - 0
Firebase/Auth/Source/FIRAuthInternalErrors.h

@@ -375,6 +375,11 @@ typedef NS_ENUM(NSInteger, FIRAuthInternalErrorCode) {
   FIRAuthInternalErrorCodeLocalPlayerNotAuthenticated =
       FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeLocalPlayerNotAuthenticated,
 
+  /** Indicates that the Game Center local player was not authenticated.
+   */
+  FIRAuthInternalErrorCodeGameKitNotLinked =
+      FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeGameKitNotLinked,
+
   /** Indicates that a non-null user was expected as an argmument to the operation but a null
         user was provided.
    */

+ 4 - 0
Firebase/Auth/Source/Public/FIRAuthErrors.h

@@ -313,6 +313,10 @@ typedef NS_ENUM(NSInteger, FIRAuthErrorCode) {
      */
     FIRAuthErrorCodeInvalidDynamicLinkDomain = 17074,
 
+    /** Indicates that the GameKit framework is not linked prior to attempting Game Center signin.
+     */
+    FIRAuthErrorCodeGameKitNotLinked = 17076,
+
     /** Indicates an error occurred while attempting to access the keychain.
      */
     FIRAuthErrorCodeKeychainError = 17995,