teachers-assistant

[RADIOACTIVE] oh boy did i make bad apps back in the day
git clone git://git.figbert.com/teachers-assistant.git
Log | Files | Refs

commit 32ae7a8db13b56c79333e6611baf200650655ccb
parent 94e86d17562f6a48dceac1f0686992aabae112fa
Author: Naomi Welner <naomi@Naomis-MacBook-Air.local>
Date:   Wed, 13 Mar 2019 17:50:09 -0700

Adding existing files

Diffstat:
M.DS_Store | 0
MPodfile | 2--
MPodfile.lock | 90+------------------------------------------------------------------------------
DPods/Firebase/CoreOnly/Sources/Firebase.h | 113-------------------------------------------------------------------------------
DPods/Firebase/CoreOnly/Sources/module.modulemap | 5-----
DPods/Firebase/README.md | 90-------------------------------------------------------------------------------
DPods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector | 0
DPods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/Modules/module.modulemap | 9---------
DPods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/FirebaseAnalytics | 0
DPods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h | 62--------------------------------------------------------------
DPods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics.h | 119-------------------------------------------------------------------------------
DPods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIREventNames.h | 407-------------------------------------------------------------------------------
DPods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRParameterNames.h | 532-------------------------------------------------------------------------------
DPods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h | 17-----------------
DPods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h | 5-----
DPods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Modules/module.modulemap | 10----------
DPods/FirebaseAnalytics/Frameworks/FirebaseCoreDiagnostics.framework/FirebaseCoreDiagnostics | 0
DPods/FirebaseAnalytics/Frameworks/FirebaseCoreDiagnostics.framework/Modules/module.modulemap | 6------
DPods/FirebaseCore/Firebase/Core/FIRAnalyticsConfiguration.m | 69---------------------------------------------------------------------
DPods/FirebaseCore/Firebase/Core/FIRApp.m | 784-------------------------------------------------------------------------------
DPods/FirebaseCore/Firebase/Core/FIRAppAssociationRegistration.m | 47-----------------------------------------------
DPods/FirebaseCore/Firebase/Core/FIRBundleUtil.m | 57---------------------------------------------------------
DPods/FirebaseCore/Firebase/Core/FIRComponent.m | 65-----------------------------------------------------------------
DPods/FirebaseCore/Firebase/Core/FIRComponentContainer.m | 176-------------------------------------------------------------------------------
DPods/FirebaseCore/Firebase/Core/FIRComponentType.m | 28----------------------------
DPods/FirebaseCore/Firebase/Core/FIRConfiguration.m | 44--------------------------------------------
DPods/FirebaseCore/Firebase/Core/FIRDependency.m | 44--------------------------------------------
DPods/FirebaseCore/Firebase/Core/FIRErrors.m | 29-----------------------------
DPods/FirebaseCore/Firebase/Core/FIRLogger.m | 171-------------------------------------------------------------------------------
DPods/FirebaseCore/Firebase/Core/FIROptions.m | 443-------------------------------------------------------------------------------
DPods/FirebaseCore/Firebase/Core/FIRVersion.m | 33---------------------------------
DPods/FirebaseCore/Firebase/Core/Private/FIRAnalyticsConfiguration+Internal.h | 49-------------------------------------------------
DPods/FirebaseCore/Firebase/Core/Private/FIRAppAssociationRegistration.h | 49-------------------------------------------------
DPods/FirebaseCore/Firebase/Core/Private/FIRAppInternal.h | 182-------------------------------------------------------------------------------
DPods/FirebaseCore/Firebase/Core/Private/FIRBundleUtil.h | 52----------------------------------------------------
DPods/FirebaseCore/Firebase/Core/Private/FIRComponent.h | 91-------------------------------------------------------------------------------
DPods/FirebaseCore/Firebase/Core/Private/FIRComponentContainer.h | 44--------------------------------------------
DPods/FirebaseCore/Firebase/Core/Private/FIRComponentContainerInternal.h | 43-------------------------------------------
DPods/FirebaseCore/Firebase/Core/Private/FIRComponentType.h | 34----------------------------------
DPods/FirebaseCore/Firebase/Core/Private/FIRDependency.h | 45---------------------------------------------
DPods/FirebaseCore/Firebase/Core/Private/FIRErrorCode.h | 55-------------------------------------------------------
DPods/FirebaseCore/Firebase/Core/Private/FIRErrors.h | 33---------------------------------
DPods/FirebaseCore/Firebase/Core/Private/FIRLibrary.h | 44--------------------------------------------
DPods/FirebaseCore/Firebase/Core/Private/FIRLogger.h | 159-------------------------------------------------------------------------------
DPods/FirebaseCore/Firebase/Core/Private/FIROptionsInternal.h | 114-------------------------------------------------------------------------------
DPods/FirebaseCore/Firebase/Core/Private/FIRVersion.h | 23-----------------------
DPods/FirebaseCore/Firebase/Core/Public/FIRAnalyticsConfiguration.h | 55-------------------------------------------------------
DPods/FirebaseCore/Firebase/Core/Public/FIRApp.h | 127-------------------------------------------------------------------------------
DPods/FirebaseCore/Firebase/Core/Public/FIRConfiguration.h | 50--------------------------------------------------
DPods/FirebaseCore/Firebase/Core/Public/FIRLoggerLevel.h | 38--------------------------------------
DPods/FirebaseCore/Firebase/Core/Public/FIROptions.h | 116-------------------------------------------------------------------------------
DPods/FirebaseCore/Firebase/Core/Public/FirebaseCore.h | 21---------------------
DPods/FirebaseCore/LICENSE | 202-------------------------------------------------------------------------------
DPods/FirebaseCore/README.md | 197-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRIMessageCode.h | 155-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID+Private.h | 55-------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID+Private.m | 46----------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID+Testing.h | 48------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID.m | 1217-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAPNSInfo.h | 64----------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAPNSInfo.m | 79-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthKeyChain.h | 98-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthKeyChain.m | 219-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthService.h | 91-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthService.m | 302------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDBackupExcludedPlist.h | 89-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDBackupExcludedPlist.m | 200-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences+Internal.h | 64----------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences+Internal.m | 112-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences.h | 63---------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences.m | 97-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences_Private.h | 27---------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinService.h | 81-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinService.m | 223-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinStore.h | 108-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinStore.m | 239-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDConstants.h | 63---------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDConstants.m | 46----------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDDefines.h | 70----------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPair.h | 78------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPair.m | 73-------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairStore.h | 85-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairStore.m | 526-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairUtilities.h | 36------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairUtilities.m | 84-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeychain.h | 76----------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeychain.m | 175-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDLogger.h | 66------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDLogger.m | 92-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDStore.h | 183-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDStore.m | 232-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDStringEncoding.h | 66------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDStringEncoding.m | 202-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenDeleteOperation.h | 31-------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenDeleteOperation.m | 120-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenFetchOperation.h | 29-----------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenFetchOperation.m | 200-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenInfo.h | 82-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenInfo.m | 188-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenManager.h | 149-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenManager.m | 341-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation+Private.h | 67-------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation.h | 73-------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation.m | 243-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenStore.h | 106-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenStore.m | 137-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDURLQueryItem.h | 39---------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDURLQueryItem.m | 55-------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDUtilities.h | 85-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDUtilities.m | 194-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDVersionUtilities.h | 35-----------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDVersionUtilities.m | 91-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/NSError+FIRInstanceID.h | 70----------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/NSError+FIRInstanceID.m | 44--------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/Public/FIRInstanceID.h | 320-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/Firebase/InstanceID/Public/FirebaseInstanceID.h | 17-----------------
DPods/FirebaseInstanceID/LICENSE | 202-------------------------------------------------------------------------------
DPods/FirebaseInstanceID/README.md | 197-------------------------------------------------------------------------------
DPods/GTMSessionFetcher/LICENSE | 202-------------------------------------------------------------------------------
DPods/GTMSessionFetcher/README.md | 23-----------------------
DPods/GTMSessionFetcher/Source/GTMGatherInputStream.h | 52----------------------------------------------------
DPods/GTMSessionFetcher/Source/GTMGatherInputStream.m | 185-------------------------------------------------------------------------------
DPods/GTMSessionFetcher/Source/GTMMIMEDocument.h | 148-------------------------------------------------------------------------------
DPods/GTMSessionFetcher/Source/GTMMIMEDocument.m | 631-------------------------------------------------------------------------------
DPods/GTMSessionFetcher/Source/GTMReadMonitorInputStream.h | 49-------------------------------------------------
DPods/GTMSessionFetcher/Source/GTMReadMonitorInputStream.m | 190-------------------------------------------------------------------------------
DPods/GTMSessionFetcher/Source/GTMSessionFetcher.h | 1305-------------------------------------------------------------------------------
DPods/GTMSessionFetcher/Source/GTMSessionFetcher.m | 4579-------------------------------------------------------------------------------
DPods/GTMSessionFetcher/Source/GTMSessionFetcherLogging.h | 112-------------------------------------------------------------------------------
DPods/GTMSessionFetcher/Source/GTMSessionFetcherLogging.m | 982-------------------------------------------------------------------------------
DPods/GTMSessionFetcher/Source/GTMSessionFetcherService.h | 193-------------------------------------------------------------------------------
DPods/GTMSessionFetcher/Source/GTMSessionFetcherService.m | 1365-------------------------------------------------------------------------------
DPods/GTMSessionFetcher/Source/GTMSessionUploadFetcher.h | 166-------------------------------------------------------------------------------
DPods/GTMSessionFetcher/Source/GTMSessionUploadFetcher.m | 1954-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/LICENSE | 202-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/README.md | 48------------------------------------------------
DPods/GoogleAPIClientForREST/Source/GTLRDefines.h | 109-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/GeneratedServices/Sheets/GTLRSheets.h | 13-------------
DPods/GoogleAPIClientForREST/Source/GeneratedServices/Sheets/GTLRSheetsObjects.h | 9245-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/GeneratedServices/Sheets/GTLRSheetsObjects.m | 2856-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/GeneratedServices/Sheets/GTLRSheetsQuery.h | 1078-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/GeneratedServices/Sheets/GTLRSheetsQuery.m | 497-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/GeneratedServices/Sheets/GTLRSheetsService.h | 103-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/GeneratedServices/Sheets/GTLRSheetsService.m | 39---------------------------------------
DPods/GoogleAPIClientForREST/Source/Objects/GTLRBatchQuery.h | 85-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Objects/GTLRBatchQuery.m | 179-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Objects/GTLRBatchResult.h | 78------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Objects/GTLRBatchResult.m | 168-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Objects/GTLRDateTime.h | 115-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Objects/GTLRDateTime.m | 373-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Objects/GTLRDuration.h | 83-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Objects/GTLRDuration.m | 222-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Objects/GTLRErrorObject.h | 116-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Objects/GTLRErrorObject.m | 140-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Objects/GTLRObject.h | 317-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Objects/GTLRObject.m | 760-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Objects/GTLRQuery.h | 253-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Objects/GTLRQuery.m | 313-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Objects/GTLRRuntimeCommon.h | 73-------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Objects/GTLRRuntimeCommon.m | 1060-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Objects/GTLRService.h | 879-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Objects/GTLRService.m | 2883-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Objects/GTLRUploadParameters.h | 124-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Objects/GTLRUploadParameters.m | 119-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Utilities/GTLRBase64.h | 29-----------------------------
DPods/GoogleAPIClientForREST/Source/Utilities/GTLRBase64.m | 143-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Utilities/GTLRFramework.h | 34----------------------------------
DPods/GoogleAPIClientForREST/Source/Utilities/GTLRFramework.m | 44--------------------------------------------
DPods/GoogleAPIClientForREST/Source/Utilities/GTLRURITemplate.h | 48------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Utilities/GTLRURITemplate.m | 511-------------------------------------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Utilities/GTLRUtilities.h | 52----------------------------------------------------
DPods/GoogleAPIClientForREST/Source/Utilities/GTLRUtilities.m | 117-------------------------------------------------------------------------------
DPods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.framework/GoogleAppMeasurement | 0
DPods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.framework/Modules/module.modulemap | 9---------
DPods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/GULAppDelegateSwizzler.m | 718-------------------------------------------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Internal/GULAppDelegateSwizzler_Private.h | 64----------------------------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Private/GULAppDelegateSwizzler.h | 63---------------------------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/Common/GULLoggerCodes.h | 36------------------------------------
DPods/GoogleUtilities/GoogleUtilities/Environment/third_party/GULAppEnvironmentUtil.h | 43-------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/Environment/third_party/GULAppEnvironmentUtil.m | 250-------------------------------------------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/Logger/GULLogger.m | 209-------------------------------------------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/Logger/Private/GULLogger.h | 159-------------------------------------------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/Logger/Public/GULLoggerLevel.h | 35-----------------------------------
DPods/GoogleUtilities/GoogleUtilities/MethodSwizzler/GULSwizzler.m | 185-------------------------------------------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/MethodSwizzler/Private/GULOriginalIMPConvenienceMacros.h | 207-------------------------------------------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/MethodSwizzler/Private/GULSwizzler.h | 91-------------------------------------------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/NSData+zlib/GULNSData+zlib.h | 49-------------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/NSData+zlib/GULNSData+zlib.m | 207-------------------------------------------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/Network/GULMutableDictionary.m | 97-------------------------------------------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/Network/GULNetwork.m | 389-------------------------------------------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/Network/GULNetworkConstants.m | 40----------------------------------------
DPods/GoogleUtilities/GoogleUtilities/Network/GULNetworkURLSession.m | 740-------------------------------------------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/Network/Private/GULMutableDictionary.h | 46----------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/Network/Private/GULNetwork.h | 87-------------------------------------------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/Network/Private/GULNetworkConstants.h | 79-------------------------------------------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/Network/Private/GULNetworkLoggerProtocol.h | 51---------------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/Network/Private/GULNetworkMessageCode.h | 45---------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/Network/Private/GULNetworkURLSession.h | 62--------------------------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/Reachability/GULReachabilityChecker+Internal.h | 47-----------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/Reachability/GULReachabilityChecker.m | 240-------------------------------------------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/Reachability/Private/GULReachabilityChecker.h | 77-----------------------------------------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/Reachability/Private/GULReachabilityMessageCode.h | 27---------------------------
DPods/GoogleUtilities/GoogleUtilities/UserDefaults/GULUserDefaults.m | 235-------------------------------------------------------------------------------
DPods/GoogleUtilities/GoogleUtilities/UserDefaults/Private/GULUserDefaults.h | 110-------------------------------------------------------------------------------
DPods/GoogleUtilities/LICENSE | 202-------------------------------------------------------------------------------
DPods/GoogleUtilities/README.md | 193-------------------------------------------------------------------------------
DPods/Headers/Private/Firebase/Firebase.h | 2--
DPods/Headers/Public/Firebase/Firebase.h | 2--
MPods/Manifest.lock | 90+------------------------------------------------------------------------------
MPods/Pods.xcodeproj/project.pbxproj | 2603++++---------------------------------------------------------------------------
DPods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/Firebase.xcscheme | 60------------------------------------------------------------
DPods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/FirebaseAnalytics.xcscheme | 60------------------------------------------------------------
DPods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/FirebaseCore.xcscheme | 60------------------------------------------------------------
DPods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/FirebaseInstanceID.xcscheme | 60------------------------------------------------------------
DPods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/GTMSessionFetcher.xcscheme | 60------------------------------------------------------------
DPods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/GoogleAPIClientForREST.xcscheme | 60------------------------------------------------------------
DPods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/GoogleAppMeasurement.xcscheme | 60------------------------------------------------------------
DPods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/GoogleUtilities.xcscheme | 60------------------------------------------------------------
MPods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/Pods-TeachersAssistant.xcscheme | 4++--
DPods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/nanopb.xcscheme | 60------------------------------------------------------------
MPods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/xcschememanagement.plist | 67++-----------------------------------------------------------------
DPods/Target Support Files/Firebase/Firebase.xcconfig | 10----------
DPods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics.xcconfig | 10----------
DPods/Target Support Files/FirebaseCore/FirebaseCore-Info.plist | 26--------------------------
DPods/Target Support Files/FirebaseCore/FirebaseCore-dummy.m | 5-----
DPods/Target Support Files/FirebaseCore/FirebaseCore-umbrella.h | 22----------------------
DPods/Target Support Files/FirebaseCore/FirebaseCore.modulemap | 6------
DPods/Target Support Files/FirebaseCore/FirebaseCore.xcconfig | 11-----------
DPods/Target Support Files/FirebaseInstanceID/FirebaseInstanceID-Info.plist | 26--------------------------
DPods/Target Support Files/FirebaseInstanceID/FirebaseInstanceID-dummy.m | 5-----
DPods/Target Support Files/FirebaseInstanceID/FirebaseInstanceID-umbrella.h | 18------------------
DPods/Target Support Files/FirebaseInstanceID/FirebaseInstanceID.modulemap | 6------
DPods/Target Support Files/FirebaseInstanceID/FirebaseInstanceID.xcconfig | 10----------
DPods/Target Support Files/GTMSessionFetcher/GTMSessionFetcher-Info.plist | 26--------------------------
DPods/Target Support Files/GTMSessionFetcher/GTMSessionFetcher-dummy.m | 5-----
DPods/Target Support Files/GTMSessionFetcher/GTMSessionFetcher-prefix.pch | 12------------
DPods/Target Support Files/GTMSessionFetcher/GTMSessionFetcher-umbrella.h | 23-----------------------
DPods/Target Support Files/GTMSessionFetcher/GTMSessionFetcher.modulemap | 6------
DPods/Target Support Files/GTMSessionFetcher/GTMSessionFetcher.xcconfig | 9---------
DPods/Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST-Info.plist | 26--------------------------
DPods/Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST-dummy.m | 5-----
DPods/Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST-prefix.pch | 12------------
DPods/Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST-umbrella.h | 35-----------------------------------
DPods/Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST.modulemap | 6------
DPods/Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST.xcconfig | 9---------
DPods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement.xcconfig | 10----------
DPods/Target Support Files/GoogleUtilities/GoogleUtilities-Info.plist | 26--------------------------
DPods/Target Support Files/GoogleUtilities/GoogleUtilities-dummy.m | 5-----
DPods/Target Support Files/GoogleUtilities/GoogleUtilities-prefix.pch | 12------------
DPods/Target Support Files/GoogleUtilities/GoogleUtilities-umbrella.h | 19-------------------
DPods/Target Support Files/GoogleUtilities/GoogleUtilities.modulemap | 6------
DPods/Target Support Files/GoogleUtilities/GoogleUtilities.xcconfig | 9---------
MPods/Target Support Files/Pods-TeachersAssistant/Pods-TeachersAssistant-acknowledgements.markdown | 1066-------------------------------------------------------------------------------
MPods/Target Support Files/Pods-TeachersAssistant/Pods-TeachersAssistant-acknowledgements.plist | 1120-------------------------------------------------------------------------------
MPods/Target Support Files/Pods-TeachersAssistant/Pods-TeachersAssistant.debug.xcconfig | 5+----
MPods/Target Support Files/Pods-TeachersAssistant/Pods-TeachersAssistant.release.xcconfig | 5+----
MPods/Target Support Files/Pods-TeachersAssistantTests/Pods-TeachersAssistantTests.debug.xcconfig | 5+----
MPods/Target Support Files/Pods-TeachersAssistantTests/Pods-TeachersAssistantTests.release.xcconfig | 5+----
DPods/Target Support Files/nanopb/nanopb-Info.plist | 26--------------------------
DPods/Target Support Files/nanopb/nanopb-dummy.m | 5-----
DPods/Target Support Files/nanopb/nanopb-prefix.pch | 12------------
DPods/Target Support Files/nanopb/nanopb-umbrella.h | 26--------------------------
DPods/Target Support Files/nanopb/nanopb.modulemap | 6------
DPods/Target Support Files/nanopb/nanopb.xcconfig | 8--------
DPods/nanopb/LICENSE.txt | 20--------------------
DPods/nanopb/README.md | 71-----------------------------------------------------------------------
DPods/nanopb/pb.h | 593-------------------------------------------------------------------------------
DPods/nanopb/pb_common.c | 97-------------------------------------------------------------------------------
DPods/nanopb/pb_common.h | 42------------------------------------------
DPods/nanopb/pb_decode.c | 1508-------------------------------------------------------------------------------
DPods/nanopb/pb_decode.h | 175-------------------------------------------------------------------------------
DPods/nanopb/pb_encode.c | 869-------------------------------------------------------------------------------
DPods/nanopb/pb_encode.h | 170-------------------------------------------------------------------------------
MTeachers' Assistant/AppDelegate.swift | 1-
DTeachers' Assistant/GoogleService-Info.plist | 40----------------------------------------
MTeachersAssistant.xcodeproj/project.pbxproj | 29-----------------------------
MTeachersAssistant.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/xcschememanagement.plist | 2+-
MTeachersAssistant.xcworkspace/xcuserdata/naomi.xcuserdatad/UserInterfaceState.xcuserstate | 0
278 files changed, 138 insertions(+), 64453 deletions(-)

diff --git a/.DS_Store b/.DS_Store Binary files differ. diff --git a/Podfile b/Podfile @@ -4,8 +4,6 @@ platform :ios, '9.0' target 'TeachersAssistant' do # Comment the next line if you're not using Swift and don't want to use dynamic frameworks use_frameworks! - pod 'Firebase/Core' - pod 'GoogleAPIClientForREST/Sheets' target 'TeachersAssistantTests' do inherit! :search_paths diff --git a/Podfile.lock b/Podfile.lock @@ -1,91 +1,3 @@ -PODS: - - Firebase/Core (5.18.0): - - Firebase/CoreOnly - - FirebaseAnalytics (= 5.7.0) - - Firebase/CoreOnly (5.18.0): - - FirebaseCore (= 5.3.1) - - FirebaseAnalytics (5.7.0): - - FirebaseCore (~> 5.3) - - FirebaseInstanceID (~> 3.6) - - GoogleAppMeasurement (= 5.7.0) - - GoogleUtilities/AppDelegateSwizzler (~> 5.2) - - GoogleUtilities/MethodSwizzler (~> 5.2) - - GoogleUtilities/Network (~> 5.2) - - "GoogleUtilities/NSData+zlib (~> 5.2)" - - nanopb (~> 0.3) - - FirebaseCore (5.3.1): - - GoogleUtilities/Logger (~> 5.2) - - FirebaseInstanceID (3.7.0): - - FirebaseCore (~> 5.2) - - GoogleUtilities/Environment (~> 5.2) - - GoogleUtilities/UserDefaults (~> 5.2) - - GoogleAPIClientForREST/Core (1.3.8): - - GTMSessionFetcher (>= 1.1.7) - - GoogleAPIClientForREST/Sheets (1.3.8): - - GoogleAPIClientForREST/Core - - GTMSessionFetcher (>= 1.1.7) - - GoogleAppMeasurement (5.7.0): - - GoogleUtilities/AppDelegateSwizzler (~> 5.2) - - GoogleUtilities/MethodSwizzler (~> 5.2) - - GoogleUtilities/Network (~> 5.2) - - "GoogleUtilities/NSData+zlib (~> 5.2)" - - nanopb (~> 0.3) - - GoogleUtilities/AppDelegateSwizzler (5.3.7): - - GoogleUtilities/Environment - - GoogleUtilities/Logger - - GoogleUtilities/Network - - GoogleUtilities/Environment (5.3.7) - - GoogleUtilities/Logger (5.3.7): - - GoogleUtilities/Environment - - GoogleUtilities/MethodSwizzler (5.3.7): - - GoogleUtilities/Logger - - GoogleUtilities/Network (5.3.7): - - GoogleUtilities/Logger - - "GoogleUtilities/NSData+zlib" - - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (5.3.7)" - - GoogleUtilities/Reachability (5.3.7): - - GoogleUtilities/Logger - - GoogleUtilities/UserDefaults (5.3.7): - - GoogleUtilities/Logger - - GTMSessionFetcher (1.2.1): - - GTMSessionFetcher/Full (= 1.2.1) - - GTMSessionFetcher/Core (1.2.1) - - GTMSessionFetcher/Full (1.2.1): - - GTMSessionFetcher/Core (= 1.2.1) - - nanopb (0.3.901): - - nanopb/decode (= 0.3.901) - - nanopb/encode (= 0.3.901) - - nanopb/decode (0.3.901) - - nanopb/encode (0.3.901) - -DEPENDENCIES: - - Firebase/Core - - GoogleAPIClientForREST/Sheets - -SPEC REPOS: - https://github.com/cocoapods/specs.git: - - Firebase - - FirebaseAnalytics - - FirebaseCore - - FirebaseInstanceID - - GoogleAPIClientForREST - - GoogleAppMeasurement - - GoogleUtilities - - GTMSessionFetcher - - nanopb - -SPEC CHECKSUMS: - Firebase: 02f3281965c075426141a0ce1277e9de6649cab9 - FirebaseAnalytics: 23851fe602c872130a2c5c55040b302120346cc2 - FirebaseCore: 52f851b30e11360f1e67cf04b1edfebf0a47a2d3 - FirebaseInstanceID: bd6fc5a258884e206fd5c474ebe4f5b00e21770e - GoogleAPIClientForREST: 5447a194eae517986cafe6421a5330b80b820591 - GoogleAppMeasurement: 6cf307834da065863f9faf4c0de0a936d81dd832 - GoogleUtilities: 111a012f4c3a29c9e7c954c082fafd6ee3c999c0 - GTMSessionFetcher: 32aeca0aa144acea523e1c8e053089dec2cb98ca - nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 - -PODFILE CHECKSUM: 4852c02225a8d343844dd5ce2a4039dcb525ad3c +PODFILE CHECKSUM: 63ac3d21ea92db5b9ad2b6028ed0e73c7741657d COCOAPODS: 1.6.1 diff --git a/Pods/Firebase/CoreOnly/Sources/Firebase.h b/Pods/Firebase/CoreOnly/Sources/Firebase.h @@ -1,113 +0,0 @@ -#import <FirebaseCore/FirebaseCore.h> - -#if !defined(__has_include) - #error "Firebase.h won't import anything if your compiler doesn't support __has_include. Please \ - import the headers individually." -#else - #if __has_include(<FirebaseAnalytics/FirebaseAnalytics.h>) - #import <FirebaseAnalytics/FirebaseAnalytics.h> - #else - #ifndef FIREBASE_ANALYTICS_SUPPRESS_WARNING - #warning "FirebaseAnalytics.framework is not included in your target. Please add \ -`Firebase/Core` to your Podfile or add FirebaseAnalytics.framework to your project to ensure \ -Firebase services work as intended." - #endif // #ifndef FIREBASE_ANALYTICS_SUPPRESS_WARNING - #endif - - #if __has_include(<FirebaseAuth/FirebaseAuth.h>) - #import <FirebaseAuth/FirebaseAuth.h> - #endif - - #if __has_include(<FirebaseCrash/FirebaseCrash.h>) - #import <FirebaseCrash/FirebaseCrash.h> - #endif - - #if __has_include(<FirebaseDatabase/FirebaseDatabase.h>) - #import <FirebaseDatabase/FirebaseDatabase.h> - #endif - - #if __has_include(<FirebaseDynamicLinks/FirebaseDynamicLinks.h>) - #import <FirebaseDynamicLinks/FirebaseDynamicLinks.h> - #endif - - #if __has_include(<FirebaseFirestore/FirebaseFirestore.h>) - #import <FirebaseFirestore/FirebaseFirestore.h> - #endif - - #if __has_include(<FirebaseFunctions/FirebaseFunctions.h>) - #import <FirebaseFunctions/FirebaseFunctions.h> - #endif - - #if __has_include(<FirebaseInAppMessaging/FirebaseInAppMessaging.h>) - #import <FirebaseInAppMessaging/FirebaseInAppMessaging.h> - #endif - - #if __has_include(<FirebaseInstanceID/FirebaseInstanceID.h>) - #import <FirebaseInstanceID/FirebaseInstanceID.h> - #endif - - #if __has_include(<FirebaseInvites/FirebaseInvites.h>) - #import <FirebaseInvites/FirebaseInvites.h> - #endif - - #if __has_include(<FirebaseMessaging/FirebaseMessaging.h>) - #import <FirebaseMessaging/FirebaseMessaging.h> - #endif - - #if __has_include(<FirebaseMLModelInterpreter/FirebaseMLModelInterpreter.h>) - #import <FirebaseMLModelInterpreter/FirebaseMLModelInterpreter.h> - #endif - - #if __has_include(<FirebaseMLNLLanguageID/FirebaseMLNLLanguageID.h>) - #import <FirebaseMLNLLanguageID/FirebaseMLNLLanguageID.h> - #endif - - #if __has_include(<FirebaseMLNaturalLanguage/FirebaseMLNaturalLanguage.h>) - #import <FirebaseMLNaturalLanguage/FirebaseMLNaturalLanguage.h> - #endif - - #if __has_include(<FirebaseMLVision/FirebaseMLVision.h>) - #import <FirebaseMLVision/FirebaseMLVision.h> - #endif - - #if __has_include(<FirebaseMLVisionBarcodeModel/FirebaseMLVisionBarcodeModel.h>) - #import <FirebaseMLVisionBarcodeModel/FirebaseMLVisionBarcodeModel.h> - #endif - - #if __has_include(<FirebaseMLVisionFaceModel/FirebaseMLVisionFaceModel.h>) - #import <FirebaseMLVisionFaceModel/FirebaseMLVisionFaceModel.h> - #endif - - #if __has_include(<FirebaseMLVisionLabelModel/FirebaseMLVisionLabelModel.h>) - #import <FirebaseMLVisionLabelModel/FirebaseMLVisionLabelModel.h> - #endif - - #if __has_include(<FirebaseMLVisionTextModel/FirebaseMLVisionTextModel.h>) - #import <FirebaseMLVisionTextModel/FirebaseMLVisionTextModel.h> - #endif - - #if __has_include(<FirebasePerformance/FirebasePerformance.h>) - #import <FirebasePerformance/FirebasePerformance.h> - #endif - - #if __has_include(<FirebaseRemoteConfig/FirebaseRemoteConfig.h>) - #import <FirebaseRemoteConfig/FirebaseRemoteConfig.h> - #endif - - #if __has_include(<FirebaseStorage/FirebaseStorage.h>) - #import <FirebaseStorage/FirebaseStorage.h> - #endif - - #if __has_include(<GoogleMobileAds/GoogleMobileAds.h>) - #import <GoogleMobileAds/GoogleMobileAds.h> - #endif - - #if __has_include(<Fabric/Fabric.h>) - #import <Fabric/Fabric.h> - #endif - - #if __has_include(<Crashlytics/Crashlytics.h>) - #import <Crashlytics/Crashlytics.h> - #endif - -#endif // defined(__has_include) diff --git a/Pods/Firebase/CoreOnly/Sources/module.modulemap b/Pods/Firebase/CoreOnly/Sources/module.modulemap @@ -1,4 +0,0 @@ -module Firebase { - export * - header "Firebase.h" -} -\ No newline at end of file diff --git a/Pods/Firebase/README.md b/Pods/Firebase/README.md @@ -1,90 +0,0 @@ -# Firebase APIs for iOS - -Simplify your iOS development, grow your user base, and monetize more -effectively with Firebase services. - -Much more information can be found at [https://firebase.google.com](https://firebase.google.com). - -## Install a Firebase SDK using CocoaPods - -Firebase distributes several iOS specific APIs and SDKs via CocoaPods. -You can install the CocoaPods tool on OS X by running the following command from -the terminal. Detailed information is available in the [Getting Started -guide](https://guides.cocoapods.org/using/getting-started.html#getting-started). - -``` -$ sudo gem install cocoapods -``` - -## Try out an SDK - -You can try any of the SDKs with `pod try`. Run the following command and select -the SDK you are interested in when prompted: - -``` -$ pod try Firebase -``` - -Note that some SDKs may require credentials. More information is available in -the SDK-specific documentation at [https://firebase.google.com/docs/](https://firebase.google.com/docs/). - -## Add a Firebase SDK to your iOS app - -CocoaPods is used to install and manage dependencies in existing Xcode projects. - -1. Create an Xcode project, and save it to your local machine. -2. Create a file named `Podfile` in your project directory. This file defines - your project's dependencies, and is commonly referred to as a Podspec. -3. Open `Podfile`, and add your dependencies. A simple Podspec is shown here: - - ``` - platform :ios, '8.0' - pod 'Firebase' - ``` - -4. Save the file. - -5. Open a terminal and `cd` to the directory containing the Podfile. - - ``` - $ cd <path-to-project>/project/ - ``` - -6. Run the `pod install` command. This will install the SDKs specified in the - Podspec, along with any dependencies they may have. - - ``` - $ pod install - ``` - -7. Open your app's `.xcworkspace` file to launch Xcode. Use this file for all - development on your app. - -8. You can also install other Firebase SDKs by adding the subspecs in the - Podfile. - - ``` - pod 'Firebase/AdMob' - pod 'Firebase/Analytics' - pod 'Firebase/Auth' - pod 'Firebase/Database' - pod 'Firebase/DynamicLinks' - pod 'Firebase/Firestore' - pod 'Firebase/Functions' - pod 'Firebase/InAppMessaging' - pod 'Firebase/InAppMessagingDisplay' - pod 'Firebase/Messaging' - pod 'Firebase/MLCommon' - pod 'Firebase/MLModelInterpreter' - pod 'Firebase/MLNLLanguageID' - pod 'Firebase/MLNLSmartReply' - pod 'Firebase/MLNaturalLanguage' - pod 'Firebase/MLVision' - pod 'Firebase/MLVisionBarcodeModel' - pod 'Firebase/MLVisionFaceModel' - pod 'Firebase/MLVisionLabelModel' - pod 'Firebase/MLVisionTextModel' - pod 'Firebase/Performance' - pod 'Firebase/RemoteConfig' - pod 'Firebase/Storage' - ``` diff --git a/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector b/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector Binary files differ. diff --git a/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/Modules/module.modulemap b/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/Modules/module.modulemap @@ -1,9 +0,0 @@ -framework module FIRAnalyticsConnector { - export * - module * { export *} - link "sqlite3" - link "z" - link framework "Security" - link framework "StoreKit" - link framework "SystemConfiguration" - link framework "UIKit"} diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/FirebaseAnalytics b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/FirebaseAnalytics Binary files differ. diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h @@ -1,62 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "FIRAnalytics.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - * Provides App Delegate handlers to be used in your App Delegate. - * - * To save time integrating Firebase Analytics in an application, Firebase Analytics does not - * require delegation implementation from the AppDelegate. Instead this is automatically done by - * Firebase Analytics. Should you choose instead to delegate manually, you can turn off the App - * Delegate Proxy by adding FirebaseAppDelegateProxyEnabled into your app's Info.plist and setting - * it to NO, and adding the methods in this category to corresponding delegation handlers. - * - * To handle Universal Links, you must return YES in - * [UIApplicationDelegate application:didFinishLaunchingWithOptions:]. - */ -@interface FIRAnalytics (AppDelegate) - -/** - * Handles events related to a URL session that are waiting to be processed. - * - * For optimal use of Firebase Analytics, call this method from the - * [UIApplicationDelegate application:handleEventsForBackgroundURLSession:completionHandler] - * method of the app delegate in your app. - * - * @param identifier The identifier of the URL session requiring attention. - * @param completionHandler The completion handler to call when you finish processing the events. - * Calling this completion handler lets the system know that your app's user interface is - * updated and a new snapshot can be taken. - */ -+ (void)handleEventsForBackgroundURLSession:(NSString *)identifier - completionHandler:(nullable void (^)(void))completionHandler; - -/** - * Handles the event when the app is launched by a URL. - * - * Call this method from [UIApplicationDelegate application:openURL:options:] &#40;on iOS 9.0 and - * above&#41;, or [UIApplicationDelegate application:openURL:sourceApplication:annotation:] &#40;on - * iOS 8.x and below&#41; in your app. - * - * @param url The URL resource to open. This resource can be a network resource or a file. - */ -+ (void)handleOpenURL:(NSURL *)url; - -/** - * Handles the event when the app receives data associated with user activity that includes a - * Universal Link (on iOS 9.0 and above). - * - * Call this method from [UIApplication continueUserActivity:restorationHandler:] in your app - * delegate (on iOS 9.0 and above). - * - * @param userActivity The activity object containing the data associated with the task the user - * was performing. - */ -+ (void)handleUserActivity:(id)userActivity; - -@end - -NS_ASSUME_NONNULL_END - diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics.h @@ -1,119 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "FIREventNames.h" -#import "FIRParameterNames.h" -#import "FIRUserPropertyNames.h" - -NS_ASSUME_NONNULL_BEGIN - -/// The top level Firebase Analytics singleton that provides methods for logging events and setting -/// user properties. See <a href="http://goo.gl/gz8SLz">the developer guides</a> for general -/// information on using Firebase Analytics in your apps. -NS_SWIFT_NAME(Analytics) -@interface FIRAnalytics : NSObject - -/// Logs an app event. The event can have up to 25 parameters. Events with the same name must have -/// the same parameters. Up to 500 event names are supported. Using predefined events and/or -/// parameters is recommended for optimal reporting. -/// -/// The following event names are reserved and cannot be used: -/// <ul> -/// <li>ad_activeview</li> -/// <li>ad_click</li> -/// <li>ad_exposure</li> -/// <li>ad_impression</li> -/// <li>ad_query</li> -/// <li>adunit_exposure</li> -/// <li>app_clear_data</li> -/// <li>app_remove</li> -/// <li>app_update</li> -/// <li>error</li> -/// <li>first_open</li> -/// <li>in_app_purchase</li> -/// <li>notification_dismiss</li> -/// <li>notification_foreground</li> -/// <li>notification_open</li> -/// <li>notification_receive</li> -/// <li>os_update</li> -/// <li>screen_view</li> -/// <li>session_start</li> -/// <li>user_engagement</li> -/// </ul> -/// -/// @param name The name of the event. Should contain 1 to 40 alphanumeric characters or -/// underscores. The name must start with an alphabetic character. Some event names are -/// reserved. See FIREventNames.h for the list of reserved event names. The "firebase_", -/// "google_", and "ga_" prefixes are reserved and should not be used. Note that event names are -/// case-sensitive and that logging two events whose names differ only in case will result in -/// two distinct events. -/// @param parameters The dictionary of event parameters. Passing nil indicates that the event has -/// no parameters. Parameter names can be up to 40 characters long and must start with an -/// alphabetic character and contain only alphanumeric characters and underscores. Only NSString -/// and NSNumber (signed 64-bit integer and 64-bit floating-point number) parameter types are -/// supported. NSString parameter values can be up to 100 characters long. The "firebase_", -/// "google_", and "ga_" prefixes are reserved and should not be used for parameter names. -+ (void)logEventWithName:(NSString *)name - parameters:(nullable NSDictionary<NSString *, id> *)parameters - NS_SWIFT_NAME(logEvent(_:parameters:)); - -/// Sets a user property to a given value. Up to 25 user property names are supported. Once set, -/// user property values persist throughout the app lifecycle and across sessions. -/// -/// The following user property names are reserved and cannot be used: -/// <ul> -/// <li>first_open_time</li> -/// <li>last_deep_link_referrer</li> -/// <li>user_id</li> -/// </ul> -/// -/// @param value The value of the user property. Values can be up to 36 characters long. Setting the -/// value to nil removes the user property. -/// @param name The name of the user property to set. Should contain 1 to 24 alphanumeric characters -/// or underscores and must start with an alphabetic character. The "firebase_", "google_", and -/// "ga_" prefixes are reserved and should not be used for user property names. -+ (void)setUserPropertyString:(nullable NSString *)value forName:(NSString *)name - NS_SWIFT_NAME(setUserProperty(_:forName:)); - -/// Sets the user ID property. This feature must be used in accordance with -/// <a href="https://www.google.com/policies/privacy">Google's Privacy Policy</a> -/// -/// @param userID The user ID to ascribe to the user of this app on this device, which must be -/// non-empty and no more than 256 characters long. Setting userID to nil removes the user ID. -+ (void)setUserID:(nullable NSString *)userID; - -/// Sets the current screen name, which specifies the current visual context in your app. This helps -/// identify the areas in your app where users spend their time and how they interact with your app. -/// Must be called on the main thread. -/// -/// Note that screen reporting is enabled automatically and records the class name of the current -/// UIViewController for you without requiring you to call this method. If you implement -/// viewDidAppear in your UIViewController but do not call [super viewDidAppear:], that screen class -/// will not be automatically tracked. The class name can optionally be overridden by calling this -/// method in the viewDidAppear callback of your UIViewController and specifying the -/// screenClassOverride parameter. setScreenName:screenClass: must be called after -/// [super viewDidAppear:]. -/// -/// If your app does not use a distinct UIViewController for each screen, you should call this -/// method and specify a distinct screenName each time a new screen is presented to the user. -/// -/// The screen name and screen class remain in effect until the current UIViewController changes or -/// a new call to setScreenName:screenClass: is made. -/// -/// @param screenName The name of the current screen. Should contain 1 to 100 characters. Set to nil -/// to clear the current screen name. -/// @param screenClassOverride The name of the screen class. Should contain 1 to 100 characters. By -/// default this is the class name of the current UIViewController. Set to nil to revert to the -/// default class name. -+ (void)setScreenName:(nullable NSString *)screenName - screenClass:(nullable NSString *)screenClassOverride; - -/// The unique ID for this instance of the application. -+ (NSString *)appInstanceID; - -/// Clears all analytics data for this instance from the device and resets the app instance ID. -/// FIRAnalyticsConfiguration values will be reset to the default values. -+ (void)resetAnalyticsData; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIREventNames.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIREventNames.h @@ -1,407 +0,0 @@ -/// @file FIREventNames.h -/// -/// Predefined event names. -/// -/// An Event is an important occurrence in your app that you want to measure. You can report up to -/// 500 different types of Events per app and you can associate up to 25 unique parameters with each -/// Event type. Some common events are suggested below, but you may also choose to specify custom -/// Event types that are associated with your specific app. Each event type is identified by a -/// unique name. Event names can be up to 40 characters long, may only contain alphanumeric -/// characters and underscores ("_"), and must start with an alphabetic character. The "firebase_", -/// "google_", and "ga_" prefixes are reserved and should not be used. - -#import <Foundation/Foundation.h> - -/// Add Payment Info event. This event signifies that a user has submitted their payment information -/// to your app. -static NSString *const kFIREventAddPaymentInfo NS_SWIFT_NAME(AnalyticsEventAddPaymentInfo) = - @"add_payment_info"; - -/// E-Commerce Add To Cart event. This event signifies that an item was added to a cart for -/// purchase. Add this event to a funnel with kFIREventEcommercePurchase to gauge the effectiveness -/// of your checkout process. Note: If you supply the @c kFIRParameterValue parameter, you must -/// also supply the @c kFIRParameterCurrency parameter so that revenue metrics can be computed -/// accurately. Params: -/// -/// <ul> -/// <li>@c kFIRParameterQuantity (signed 64-bit integer as NSNumber)</li> -/// <li>@c kFIRParameterItemID (NSString)</li> -/// <li>@c kFIRParameterItemName (NSString)</li> -/// <li>@c kFIRParameterItemCategory (NSString)</li> -/// <li>@c kFIRParameterItemLocationID (NSString) (optional)</li> -/// <li>@c kFIRParameterPrice (double as NSNumber) (optional)</li> -/// <li>@c kFIRParameterCurrency (NSString) (optional)</li> -/// <li>@c kFIRParameterValue (double as NSNumber) (optional)</li> -/// <li>@c kFIRParameterOrigin (NSString) (optional)</li> -/// <li>@c kFIRParameterDestination (NSString) (optional)</li> -/// <li>@c kFIRParameterStartDate (NSString) (optional)</li> -/// <li>@c kFIRParameterEndDate (NSString) (optional)</li> -/// </ul> -static NSString *const kFIREventAddToCart NS_SWIFT_NAME(AnalyticsEventAddToCart) = @"add_to_cart"; - -/// E-Commerce Add To Wishlist event. This event signifies that an item was added to a wishlist. -/// Use this event to identify popular gift items in your app. Note: If you supply the -/// @c kFIRParameterValue parameter, you must also supply the @c kFIRParameterCurrency -/// parameter so that revenue metrics can be computed accurately. Params: -/// -/// <ul> -/// <li>@c kFIRParameterQuantity (signed 64-bit integer as NSNumber)</li> -/// <li>@c kFIRParameterItemID (NSString)</li> -/// <li>@c kFIRParameterItemName (NSString)</li> -/// <li>@c kFIRParameterItemCategory (NSString)</li> -/// <li>@c kFIRParameterItemLocationID (NSString) (optional)</li> -/// <li>@c kFIRParameterPrice (double as NSNumber) (optional)</li> -/// <li>@c kFIRParameterCurrency (NSString) (optional)</li> -/// <li>@c kFIRParameterValue (double as NSNumber) (optional)</li> -/// </ul> -static NSString *const kFIREventAddToWishlist NS_SWIFT_NAME(AnalyticsEventAddToWishlist) = - @"add_to_wishlist"; - -/// App Open event. By logging this event when an App becomes active, developers can understand how -/// often users leave and return during the course of a Session. Although Sessions are automatically -/// reported, this event can provide further clarification around the continuous engagement of -/// app-users. -static NSString *const kFIREventAppOpen NS_SWIFT_NAME(AnalyticsEventAppOpen) = @"app_open"; - -/// E-Commerce Begin Checkout event. This event signifies that a user has begun the process of -/// checking out. Add this event to a funnel with your kFIREventEcommercePurchase event to gauge the -/// effectiveness of your checkout process. Note: If you supply the @c kFIRParameterValue -/// parameter, you must also supply the @c kFIRParameterCurrency parameter so that revenue -/// metrics can be computed accurately. Params: -/// -/// <ul> -/// <li>@c kFIRParameterValue (double as NSNumber) (optional)</li> -/// <li>@c kFIRParameterCurrency (NSString) (optional)</li> -/// <li>@c kFIRParameterTransactionID (NSString) (optional)</li> -/// <li>@c kFIRParameterStartDate (NSString) (optional)</li> -/// <li>@c kFIRParameterEndDate (NSString) (optional)</li> -/// <li>@c kFIRParameterNumberOfNights (signed 64-bit integer as NSNumber) (optional) for -/// hotel bookings</li> -/// <li>@c kFIRParameterNumberOfRooms (signed 64-bit integer as NSNumber) (optional) for -/// hotel bookings</li> -/// <li>@c kFIRParameterNumberOfPassengers (signed 64-bit integer as NSNumber) (optional) -/// for travel bookings</li> -/// <li>@c kFIRParameterOrigin (NSString) (optional)</li> -/// <li>@c kFIRParameterDestination (NSString) (optional)</li> -/// <li>@c kFIRParameterTravelClass (NSString) (optional) for travel bookings</li> -/// </ul> -static NSString *const kFIREventBeginCheckout NS_SWIFT_NAME(AnalyticsEventBeginCheckout) = - @"begin_checkout"; - -/// Campaign Detail event. Log this event to supply the referral details of a re-engagement -/// campaign. Note: you must supply at least one of the required parameters kFIRParameterSource, -/// kFIRParameterMedium or kFIRParameterCampaign. Params: -/// -/// <ul> -/// <li>@c kFIRParameterSource (NSString)</li> -/// <li>@c kFIRParameterMedium (NSString)</li> -/// <li>@c kFIRParameterCampaign (NSString)</li> -/// <li>@c kFIRParameterTerm (NSString) (optional)</li> -/// <li>@c kFIRParameterContent (NSString) (optional)</li> -/// <li>@c kFIRParameterAdNetworkClickID (NSString) (optional)</li> -/// <li>@c kFIRParameterCP1 (NSString) (optional)</li> -/// </ul> -static NSString *const kFIREventCampaignDetails NS_SWIFT_NAME(AnalyticsEventCampaignDetails) = - @"campaign_details"; - -/// Checkout progress. Params: -/// -/// <ul> -/// <li>@c kFIRParameterCheckoutStep (unsigned 64-bit integer as NSNumber)</li> -/// <li>@c kFIRParameterCheckoutOption (NSString) (optional)</li> -/// </ul> -static NSString *const kFIREventCheckoutProgress NS_SWIFT_NAME(AnalyticsEventCheckoutProgress) = - @"checkout_progress"; - -/// Earn Virtual Currency event. This event tracks the awarding of virtual currency in your app. Log -/// this along with @c kFIREventSpendVirtualCurrency to better understand your virtual economy. -/// Params: -/// -/// <ul> -/// <li>@c kFIRParameterVirtualCurrencyName (NSString)</li> -/// <li>@c kFIRParameterValue (signed 64-bit integer or double as NSNumber)</li> -/// </ul> -static NSString *const kFIREventEarnVirtualCurrency - NS_SWIFT_NAME(AnalyticsEventEarnVirtualCurrency) = @"earn_virtual_currency"; - -/// E-Commerce Purchase event. This event signifies that an item was purchased by a user. Note: -/// This is different from the in-app purchase event, which is reported automatically for App -/// Store-based apps. Note: If you supply the @c kFIRParameterValue parameter, you must also -/// supply the @c kFIRParameterCurrency parameter so that revenue metrics can be computed -/// accurately. Params: -/// -/// <ul> -/// <li>@c kFIRParameterCurrency (NSString) (optional)</li> -/// <li>@c kFIRParameterValue (double as NSNumber) (optional)</li> -/// <li>@c kFIRParameterTransactionID (NSString) (optional)</li> -/// <li>@c kFIRParameterTax (double as NSNumber) (optional)</li> -/// <li>@c kFIRParameterShipping (double as NSNumber) (optional)</li> -/// <li>@c kFIRParameterCoupon (NSString) (optional)</li> -/// <li>@c kFIRParameterLocation (NSString) (optional)</li> -/// <li>@c kFIRParameterStartDate (NSString) (optional)</li> -/// <li>@c kFIRParameterEndDate (NSString) (optional)</li> -/// <li>@c kFIRParameterNumberOfNights (signed 64-bit integer as NSNumber) (optional) for -/// hotel bookings</li> -/// <li>@c kFIRParameterNumberOfRooms (signed 64-bit integer as NSNumber) (optional) for -/// hotel bookings</li> -/// <li>@c kFIRParameterNumberOfPassengers (signed 64-bit integer as NSNumber) (optional) -/// for travel bookings</li> -/// <li>@c kFIRParameterOrigin (NSString) (optional)</li> -/// <li>@c kFIRParameterDestination (NSString) (optional)</li> -/// <li>@c kFIRParameterTravelClass (NSString) (optional) for travel bookings</li> -/// </ul> -static NSString *const kFIREventEcommercePurchase NS_SWIFT_NAME(AnalyticsEventEcommercePurchase) = - @"ecommerce_purchase"; - -/// Generate Lead event. Log this event when a lead has been generated in the app to understand the -/// efficacy of your install and re-engagement campaigns. Note: If you supply the -/// @c kFIRParameterValue parameter, you must also supply the @c kFIRParameterCurrency -/// parameter so that revenue metrics can be computed accurately. Params: -/// -/// <ul> -/// <li>@c kFIRParameterCurrency (NSString) (optional)</li> -/// <li>@c kFIRParameterValue (double as NSNumber) (optional)</li> -/// </ul> -static NSString *const kFIREventGenerateLead NS_SWIFT_NAME(AnalyticsEventGenerateLead) = - @"generate_lead"; - -/// Join Group event. Log this event when a user joins a group such as a guild, team or family. Use -/// this event to analyze how popular certain groups or social features are in your app. Params: -/// -/// <ul> -/// <li>@c kFIRParameterGroupID (NSString)</li> -/// </ul> -static NSString *const kFIREventJoinGroup NS_SWIFT_NAME(AnalyticsEventJoinGroup) = @"join_group"; - -/// Level Up event. This event signifies that a player has leveled up in your gaming app. It can -/// help you gauge the level distribution of your userbase and help you identify certain levels that -/// are difficult to pass. Params: -/// -/// <ul> -/// <li>@c kFIRParameterLevel (signed 64-bit integer as NSNumber)</li> -/// <li>@c kFIRParameterCharacter (NSString) (optional)</li> -/// </ul> -static NSString *const kFIREventLevelUp NS_SWIFT_NAME(AnalyticsEventLevelUp) = @"level_up"; - -/// Login event. Apps with a login feature can report this event to signify that a user has logged -/// in. -static NSString *const kFIREventLogin NS_SWIFT_NAME(AnalyticsEventLogin) = @"login"; - -/// Post Score event. Log this event when the user posts a score in your gaming app. This event can -/// help you understand how users are actually performing in your game and it can help you correlate -/// high scores with certain audiences or behaviors. Params: -/// -/// <ul> -/// <li>@c kFIRParameterScore (signed 64-bit integer as NSNumber)</li> -/// <li>@c kFIRParameterLevel (signed 64-bit integer as NSNumber) (optional)</li> -/// <li>@c kFIRParameterCharacter (NSString) (optional)</li> -/// </ul> -static NSString *const kFIREventPostScore NS_SWIFT_NAME(AnalyticsEventPostScore) = @"post_score"; - -/// Present Offer event. This event signifies that the app has presented a purchase offer to a user. -/// Add this event to a funnel with the kFIREventAddToCart and kFIREventEcommercePurchase to gauge -/// your conversion process. Note: If you supply the @c kFIRParameterValue parameter, you must -/// also supply the @c kFIRParameterCurrency parameter so that revenue metrics can be computed -/// accurately. Params: -/// -/// <ul> -/// <li>@c kFIRParameterQuantity (signed 64-bit integer as NSNumber)</li> -/// <li>@c kFIRParameterItemID (NSString)</li> -/// <li>@c kFIRParameterItemName (NSString)</li> -/// <li>@c kFIRParameterItemCategory (NSString)</li> -/// <li>@c kFIRParameterItemLocationID (NSString) (optional)</li> -/// <li>@c kFIRParameterPrice (double as NSNumber) (optional)</li> -/// <li>@c kFIRParameterCurrency (NSString) (optional)</li> -/// <li>@c kFIRParameterValue (double as NSNumber) (optional)</li> -/// </ul> -static NSString *const kFIREventPresentOffer NS_SWIFT_NAME(AnalyticsEventPresentOffer) = - @"present_offer"; - -/// E-Commerce Purchase Refund event. This event signifies that an item purchase was refunded. -/// Note: If you supply the @c kFIRParameterValue parameter, you must also supply the -/// @c kFIRParameterCurrency parameter so that revenue metrics can be computed accurately. -/// Params: -/// -/// <ul> -/// <li>@c kFIRParameterCurrency (NSString) (optional)</li> -/// <li>@c kFIRParameterValue (double as NSNumber) (optional)</li> -/// <li>@c kFIRParameterTransactionID (NSString) (optional)</li> -/// </ul> -static NSString *const kFIREventPurchaseRefund NS_SWIFT_NAME(AnalyticsEventPurchaseRefund) = - @"purchase_refund"; - -/// Remove from cart event. Params: -/// -/// <ul> -/// <li>@c kFIRParameterQuantity (signed 64-bit integer as NSNumber)</li> -/// <li>@c kFIRParameterItemID (NSString)</li> -/// <li>@c kFIRParameterItemName (NSString)</li> -/// <li>@c kFIRParameterItemCategory (NSString)</li> -/// <li>@c kFIRParameterItemLocationID (NSString) (optional)</li> -/// <li>@c kFIRParameterPrice (double as NSNumber) (optional)</li> -/// <li>@c kFIRParameterCurrency (NSString) (optional)</li> -/// <li>@c kFIRParameterValue (double as NSNumber) (optional)</li> -/// <li>@c kFIRParameterOrigin (NSString) (optional)</li> -/// <li>@c kFIRParameterDestination (NSString) (optional)</li> -/// <li>@c kFIRParameterStartDate (NSString) (optional)</li> -/// <li>@c kFIRParameterEndDate (NSString) (optional)</li> -/// </ul> -static NSString *const kFIREventRemoveFromCart NS_SWIFT_NAME(AnalyticsEventRemoveFromCart) = - @"remove_from_cart"; - -/// Search event. Apps that support search features can use this event to contextualize search -/// operations by supplying the appropriate, corresponding parameters. This event can help you -/// identify the most popular content in your app. Params: -/// -/// <ul> -/// <li>@c kFIRParameterSearchTerm (NSString)</li> -/// <li>@c kFIRParameterStartDate (NSString) (optional)</li> -/// <li>@c kFIRParameterEndDate (NSString) (optional)</li> -/// <li>@c kFIRParameterNumberOfNights (signed 64-bit integer as NSNumber) (optional) for -/// hotel bookings</li> -/// <li>@c kFIRParameterNumberOfRooms (signed 64-bit integer as NSNumber) (optional) for -/// hotel bookings</li> -/// <li>@c kFIRParameterNumberOfPassengers (signed 64-bit integer as NSNumber) (optional) -/// for travel bookings</li> -/// <li>@c kFIRParameterOrigin (NSString) (optional)</li> -/// <li>@c kFIRParameterDestination (NSString) (optional)</li> -/// <li>@c kFIRParameterTravelClass (NSString) (optional) for travel bookings</li> -/// </ul> -static NSString *const kFIREventSearch NS_SWIFT_NAME(AnalyticsEventSearch) = @"search"; - -/// Select Content event. This general purpose event signifies that a user has selected some content -/// of a certain type in an app. The content can be any object in your app. This event can help you -/// identify popular content and categories of content in your app. Params: -/// -/// <ul> -/// <li>@c kFIRParameterContentType (NSString)</li> -/// <li>@c kFIRParameterItemID (NSString)</li> -/// </ul> -static NSString *const kFIREventSelectContent NS_SWIFT_NAME(AnalyticsEventSelectContent) = - @"select_content"; - -/// Set checkout option. Params: -/// -/// <ul> -/// <li>@c kFIRParameterCheckoutStep (unsigned 64-bit integer as NSNumber)</li> -/// <li>@c kFIRParameterCheckoutOption (NSString)</li> -/// </ul> -static NSString *const kFIREventSetCheckoutOption NS_SWIFT_NAME(AnalyticsEventSetCheckoutOption) = - @"set_checkout_option"; - -/// Share event. Apps with social features can log the Share event to identify the most viral -/// content. Params: -/// -/// <ul> -/// <li>@c kFIRParameterContentType (NSString)</li> -/// <li>@c kFIRParameterItemID (NSString)</li> -/// </ul> -static NSString *const kFIREventShare NS_SWIFT_NAME(AnalyticsEventShare) = @"share"; - -/// Sign Up event. This event indicates that a user has signed up for an account in your app. The -/// parameter signifies the method by which the user signed up. Use this event to understand the -/// different behaviors between logged in and logged out users. Params: -/// -/// <ul> -/// <li>@c kFIRParameterSignUpMethod (NSString)</li> -/// </ul> -static NSString *const kFIREventSignUp NS_SWIFT_NAME(AnalyticsEventSignUp) = @"sign_up"; - -/// Spend Virtual Currency event. This event tracks the sale of virtual goods in your app and can -/// help you identify which virtual goods are the most popular objects of purchase. Params: -/// -/// <ul> -/// <li>@c kFIRParameterItemName (NSString)</li> -/// <li>@c kFIRParameterVirtualCurrencyName (NSString)</li> -/// <li>@c kFIRParameterValue (signed 64-bit integer or double as NSNumber)</li> -/// </ul> -static NSString *const kFIREventSpendVirtualCurrency - NS_SWIFT_NAME(AnalyticsEventSpendVirtualCurrency) = @"spend_virtual_currency"; - -/// Tutorial Begin event. This event signifies the start of the on-boarding process in your app. Use -/// this in a funnel with kFIREventTutorialComplete to understand how many users complete this -/// process and move on to the full app experience. -static NSString *const kFIREventTutorialBegin NS_SWIFT_NAME(AnalyticsEventTutorialBegin) = - @"tutorial_begin"; - -/// Tutorial End event. Use this event to signify the user's completion of your app's on-boarding -/// process. Add this to a funnel with kFIREventTutorialBegin to gauge the completion rate of your -/// on-boarding process. -static NSString *const kFIREventTutorialComplete NS_SWIFT_NAME(AnalyticsEventTutorialComplete) = - @"tutorial_complete"; - -/// Unlock Achievement event. Log this event when the user has unlocked an achievement in your -/// game. Since achievements generally represent the breadth of a gaming experience, this event can -/// help you understand how many users are experiencing all that your game has to offer. Params: -/// -/// <ul> -/// <li>@c kFIRParameterAchievementID (NSString)</li> -/// </ul> -static NSString *const kFIREventUnlockAchievement NS_SWIFT_NAME(AnalyticsEventUnlockAchievement) = - @"unlock_achievement"; - -/// View Item event. This event signifies that some content was shown to the user. This content may -/// be a product, a webpage or just a simple image or text. Use the appropriate parameters to -/// contextualize the event. Use this event to discover the most popular items viewed in your app. -/// Note: If you supply the @c kFIRParameterValue parameter, you must also supply the -/// @c kFIRParameterCurrency parameter so that revenue metrics can be computed accurately. -/// Params: -/// -/// <ul> -/// <li>@c kFIRParameterItemID (NSString)</li> -/// <li>@c kFIRParameterItemName (NSString)</li> -/// <li>@c kFIRParameterItemCategory (NSString)</li> -/// <li>@c kFIRParameterItemLocationID (NSString) (optional)</li> -/// <li>@c kFIRParameterPrice (double as NSNumber) (optional)</li> -/// <li>@c kFIRParameterQuantity (signed 64-bit integer as NSNumber) (optional)</li> -/// <li>@c kFIRParameterCurrency (NSString) (optional)</li> -/// <li>@c kFIRParameterValue (double as NSNumber) (optional)</li> -/// <li>@c kFIRParameterStartDate (NSString) (optional)</li> -/// <li>@c kFIRParameterEndDate (NSString) (optional)</li> -/// <li>@c kFIRParameterFlightNumber (NSString) (optional) for travel bookings</li> -/// <li>@c kFIRParameterNumberOfPassengers (signed 64-bit integer as NSNumber) (optional) -/// for travel bookings</li> -/// <li>@c kFIRParameterNumberOfNights (signed 64-bit integer as NSNumber) (optional) for -/// travel bookings</li> -/// <li>@c kFIRParameterNumberOfRooms (signed 64-bit integer as NSNumber) (optional) for -/// travel bookings</li> -/// <li>@c kFIRParameterOrigin (NSString) (optional)</li> -/// <li>@c kFIRParameterDestination (NSString) (optional)</li> -/// <li>@c kFIRParameterSearchTerm (NSString) (optional) for travel bookings</li> -/// <li>@c kFIRParameterTravelClass (NSString) (optional) for travel bookings</li> -/// </ul> -static NSString *const kFIREventViewItem NS_SWIFT_NAME(AnalyticsEventViewItem) = @"view_item"; - -/// View Item List event. Log this event when the user has been presented with a list of items of a -/// certain category. Params: -/// -/// <ul> -/// <li>@c kFIRParameterItemCategory (NSString)</li> -/// </ul> -static NSString *const kFIREventViewItemList NS_SWIFT_NAME(AnalyticsEventViewItemList) = - @"view_item_list"; - -/// View Search Results event. Log this event when the user has been presented with the results of a -/// search. Params: -/// -/// <ul> -/// <li>@c kFIRParameterSearchTerm (NSString)</li> -/// </ul> -static NSString *const kFIREventViewSearchResults NS_SWIFT_NAME(AnalyticsEventViewSearchResults) = - @"view_search_results"; - -/// Level Start event. Log this event when the user starts a new level. Params: -/// -/// <ul> -/// <li>@c kFIRParameterLevelName (NSString)</li> -/// </ul> -static NSString *const kFIREventLevelStart NS_SWIFT_NAME(AnalyticsEventLevelStart) = - @"level_start"; - -/// Level End event. Log this event when the user finishes a level. Params: -/// -/// <ul> -/// <li>@c kFIRParameterLevelName (NSString)</li> -/// <li>@c kFIRParameterSuccess (NSString)</li> -/// </ul> -static NSString *const kFIREventLevelEnd NS_SWIFT_NAME(AnalyticsEventLevelEnd) = @"level_end"; diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRParameterNames.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRParameterNames.h @@ -1,532 +0,0 @@ -/// @file FIRParameterNames.h -/// -/// Predefined event parameter names. -/// -/// Params supply information that contextualize Events. You can associate up to 25 unique Params -/// with each Event type. Some Params are suggested below for certain common Events, but you are -/// not limited to these. You may supply extra Params for suggested Events or custom Params for -/// Custom events. Param names can be up to 40 characters long, may only contain alphanumeric -/// characters and underscores ("_"), and must start with an alphabetic character. Param values can -/// be up to 100 characters long. The "firebase_", "google_", and "ga_" prefixes are reserved and -/// should not be used. - -#import <Foundation/Foundation.h> - -/// Game achievement ID (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterAchievementID : @"10_matches_won", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterAchievementID NS_SWIFT_NAME(AnalyticsParameterAchievementID) = - @"achievement_id"; - -/// Ad Network Click ID (NSString). Used for network-specific click IDs which vary in format. -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterAdNetworkClickID : @"1234567", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterAdNetworkClickID - NS_SWIFT_NAME(AnalyticsParameterAdNetworkClickID) = @"aclid"; - -/// The store or affiliation from which this transaction occurred (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterAffiliation : @"Google Store", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterAffiliation NS_SWIFT_NAME(AnalyticsParameterAffiliation) = - @"affiliation"; - -/// The individual campaign name, slogan, promo code, etc. Some networks have pre-defined macro to -/// capture campaign information, otherwise can be populated by developer. Highly Recommended -/// (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterCampaign : @"winter_promotion", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterCampaign NS_SWIFT_NAME(AnalyticsParameterCampaign) = - @"campaign"; - -/// Character used in game (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterCharacter : @"beat_boss", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterCharacter NS_SWIFT_NAME(AnalyticsParameterCharacter) = - @"character"; - -/// The checkout step (1..N) (unsigned 64-bit integer as NSNumber). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterCheckoutStep : @"1", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterCheckoutStep NS_SWIFT_NAME(AnalyticsParameterCheckoutStep) = - @"checkout_step"; - -/// Some option on a step in an ecommerce flow (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterCheckoutOption : @"Visa", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterCheckoutOption - NS_SWIFT_NAME(AnalyticsParameterCheckoutOption) = @"checkout_option"; - -/// Campaign content (NSString). -static NSString *const kFIRParameterContent NS_SWIFT_NAME(AnalyticsParameterContent) = @"content"; - -/// Type of content selected (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterContentType : @"news article", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterContentType NS_SWIFT_NAME(AnalyticsParameterContentType) = - @"content_type"; - -/// Coupon code for a purchasable item (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterCoupon : @"zz123", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterCoupon NS_SWIFT_NAME(AnalyticsParameterCoupon) = @"coupon"; - -/// Campaign custom parameter (NSString). Used as a method of capturing custom data in a campaign. -/// Use varies by network. -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterCP1 : @"custom_data", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterCP1 NS_SWIFT_NAME(AnalyticsParameterCP1) = @"cp1"; - -/// The name of a creative used in a promotional spot (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterCreativeName : @"Summer Sale", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterCreativeName NS_SWIFT_NAME(AnalyticsParameterCreativeName) = - @"creative_name"; - -/// The name of a creative slot (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterCreativeSlot : @"summer_banner2", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterCreativeSlot NS_SWIFT_NAME(AnalyticsParameterCreativeSlot) = - @"creative_slot"; - -/// Purchase currency in 3-letter <a href="http://en.wikipedia.org/wiki/ISO_4217#Active_codes"> -/// ISO_4217</a> format (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterCurrency : @"USD", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterCurrency NS_SWIFT_NAME(AnalyticsParameterCurrency) = - @"currency"; - -/// Flight or Travel destination (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterDestination : @"Mountain View, CA", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterDestination NS_SWIFT_NAME(AnalyticsParameterDestination) = - @"destination"; - -/// The arrival date, check-out date or rental end date for the item. This should be in -/// YYYY-MM-DD format (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterEndDate : @"2015-09-14", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterEndDate NS_SWIFT_NAME(AnalyticsParameterEndDate) = @"end_date"; - -/// Flight number for travel events (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterFlightNumber : @"ZZ800", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterFlightNumber NS_SWIFT_NAME(AnalyticsParameterFlightNumber) = - @"flight_number"; - -/// Group/clan/guild ID (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterGroupID : @"g1", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterGroupID NS_SWIFT_NAME(AnalyticsParameterGroupID) = @"group_id"; - -/// Index of an item in a list (signed 64-bit integer as NSNumber). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterIndex : @(1), -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterIndex NS_SWIFT_NAME(AnalyticsParameterIndex) = @"index"; - -/// Item brand (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterItemBrand : @"Google", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterItemBrand NS_SWIFT_NAME(AnalyticsParameterItemBrand) = - @"item_brand"; - -/// Item category (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterItemCategory : @"t-shirts", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterItemCategory NS_SWIFT_NAME(AnalyticsParameterItemCategory) = - @"item_category"; - -/// Item ID (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterItemID : @"p7654", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterItemID NS_SWIFT_NAME(AnalyticsParameterItemID) = @"item_id"; - -/// The Google <a href="https://developers.google.com/places/place-id">Place ID</a> (NSString) that -/// corresponds to the associated item. Alternatively, you can supply your own custom Location ID. -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterItemLocationID : @"ChIJiyj437sx3YAR9kUWC8QkLzQ", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterItemLocationID - NS_SWIFT_NAME(AnalyticsParameterItemLocationID) = @"item_location_id"; - -/// Item name (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterItemName : @"abc", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterItemName NS_SWIFT_NAME(AnalyticsParameterItemName) = - @"item_name"; - -/// The list in which the item was presented to the user (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterItemList : @"Search Results", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterItemList NS_SWIFT_NAME(AnalyticsParameterItemList) = - @"item_list"; - -/// Item variant (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterItemVariant : @"Red", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterItemVariant NS_SWIFT_NAME(AnalyticsParameterItemVariant) = - @"item_variant"; - -/// Level in game (signed 64-bit integer as NSNumber). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterLevel : @(42), -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterLevel NS_SWIFT_NAME(AnalyticsParameterLevel) = @"level"; - -/// Location (NSString). The Google <a href="https://developers.google.com/places/place-id">Place ID -/// </a> that corresponds to the associated event. Alternatively, you can supply your own custom -/// Location ID. -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterLocation : @"ChIJiyj437sx3YAR9kUWC8QkLzQ", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterLocation NS_SWIFT_NAME(AnalyticsParameterLocation) = - @"location"; - -/// The advertising or marketing medium, for example: cpc, banner, email, push. Highly recommended -/// (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterMedium : @"email", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterMedium NS_SWIFT_NAME(AnalyticsParameterMedium) = @"medium"; - -/// Number of nights staying at hotel (signed 64-bit integer as NSNumber). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterNumberOfNights : @(3), -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterNumberOfNights - NS_SWIFT_NAME(AnalyticsParameterNumberOfNights) = @"number_of_nights"; - -/// Number of passengers traveling (signed 64-bit integer as NSNumber). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterNumberOfPassengers : @(11), -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterNumberOfPassengers - NS_SWIFT_NAME(AnalyticsParameterNumberOfPassengers) = @"number_of_passengers"; - -/// Number of rooms for travel events (signed 64-bit integer as NSNumber). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterNumberOfRooms : @(2), -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterNumberOfRooms NS_SWIFT_NAME(AnalyticsParameterNumberOfRooms) = - @"number_of_rooms"; - -/// Flight or Travel origin (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterOrigin : @"Mountain View, CA", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterOrigin NS_SWIFT_NAME(AnalyticsParameterOrigin) = @"origin"; - -/// Purchase price (double as NSNumber). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterPrice : @(1.0), -/// kFIRParameterCurrency : @"USD", // e.g. $1.00 USD -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterPrice NS_SWIFT_NAME(AnalyticsParameterPrice) = @"price"; - -/// Purchase quantity (signed 64-bit integer as NSNumber). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterQuantity : @(1), -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterQuantity NS_SWIFT_NAME(AnalyticsParameterQuantity) = - @"quantity"; - -/// Score in game (signed 64-bit integer as NSNumber). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterScore : @(4200), -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterScore NS_SWIFT_NAME(AnalyticsParameterScore) = @"score"; - -/// The search string/keywords used (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterSearchTerm : @"periodic table", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterSearchTerm NS_SWIFT_NAME(AnalyticsParameterSearchTerm) = - @"search_term"; - -/// Shipping cost (double as NSNumber). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterShipping : @(9.50), -/// kFIRParameterCurrency : @"USD", // e.g. $9.50 USD -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterShipping NS_SWIFT_NAME(AnalyticsParameterShipping) = - @"shipping"; - -/// Sign up method (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterSignUpMethod : @"google", -/// // ... -/// }; -/// </pre> -/// -/// <b>This constant has been deprecated. Use Method constant instead.</b> -static NSString *const kFIRParameterSignUpMethod NS_SWIFT_NAME(AnalyticsParameterSignUpMethod) = - @"sign_up_method"; - -/// A particular approach used in an operation; for example, "facebook" or "email" in the context -/// of a sign_up or login event. (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterMethod : @"google", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterMethod NS_SWIFT_NAME(AnalyticsParameterMethod) = @"method"; - -/// The origin of your traffic, such as an Ad network (for example, google) or partner (urban -/// airship). Identify the advertiser, site, publication, etc. that is sending traffic to your -/// property. Highly recommended (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterSource : @"InMobi", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterSource NS_SWIFT_NAME(AnalyticsParameterSource) = @"source"; - -/// The departure date, check-in date or rental start date for the item. This should be in -/// YYYY-MM-DD format (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterStartDate : @"2015-09-14", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterStartDate NS_SWIFT_NAME(AnalyticsParameterStartDate) = - @"start_date"; - -/// Tax amount (double as NSNumber). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterTax : @(1.0), -/// kFIRParameterCurrency : @"USD", // e.g. $1.00 USD -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterTax NS_SWIFT_NAME(AnalyticsParameterTax) = @"tax"; - -/// If you're manually tagging keyword campaigns, you should use utm_term to specify the keyword -/// (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterTerm : @"game", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterTerm NS_SWIFT_NAME(AnalyticsParameterTerm) = @"term"; - -/// A single ID for a ecommerce group transaction (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterTransactionID : @"ab7236dd9823", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterTransactionID NS_SWIFT_NAME(AnalyticsParameterTransactionID) = - @"transaction_id"; - -/// Travel class (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterTravelClass : @"business", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterTravelClass NS_SWIFT_NAME(AnalyticsParameterTravelClass) = - @"travel_class"; - -/// A context-specific numeric value which is accumulated automatically for each event type. This is -/// a general purpose parameter that is useful for accumulating a key metric that pertains to an -/// event. Examples include revenue, distance, time and points. Value should be specified as signed -/// 64-bit integer or double as NSNumber. Notes: Values for pre-defined currency-related events -/// (such as @c kFIREventAddToCart) should be supplied using double as NSNumber and must be -/// accompanied by a @c kFIRParameterCurrency parameter. The valid range of accumulated values is -/// [-9,223,372,036,854.77, 9,223,372,036,854.77]. Supplying a non-numeric value, omitting the -/// corresponding @c kFIRParameterCurrency parameter, or supplying an invalid -/// <a href="https://goo.gl/qqX3J2">currency code</a> for conversion events will cause that -/// conversion to be omitted from reporting. -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterValue : @(3.99), -/// kFIRParameterCurrency : @"USD", // e.g. $3.99 USD -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterValue NS_SWIFT_NAME(AnalyticsParameterValue) = @"value"; - -/// Name of virtual currency type (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterVirtualCurrencyName : @"virtual_currency_name", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterVirtualCurrencyName - NS_SWIFT_NAME(AnalyticsParameterVirtualCurrencyName) = @"virtual_currency_name"; - -/// The name of a level in a game (NSString). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterLevelName : @"room_1", -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterLevelName NS_SWIFT_NAME(AnalyticsParameterLevelName) = - @"level_name"; - -/// The result of an operation. Specify 1 to indicate success and 0 to indicate failure (unsigned -/// integer as NSNumber). -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterSuccess : @(1), -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterSuccess NS_SWIFT_NAME(AnalyticsParameterSuccess) = @"success"; - -/// Indicates that the associated event should either extend the current session -/// or start a new session if no session was active when the event was logged. -/// Specify YES to extend the current session or to start a new session; any -/// other value will not extend or start a session. -/// <pre> -/// NSDictionary *params = @{ -/// kFIRParameterExtendSession : @YES, -/// // ... -/// }; -/// </pre> -static NSString *const kFIRParameterExtendSession NS_SWIFT_NAME(AnalyticsParameterExtendSession) = - @"extend_session"; diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h @@ -1,17 +0,0 @@ -/// @file FIRUserPropertyNames.h -/// -/// Predefined user property names. -/// -/// A UserProperty is an attribute that describes the app-user. By supplying UserProperties, you can -/// later analyze different behaviors of various segments of your userbase. You may supply up to 25 -/// unique UserProperties per app, and you can use the name and value of your choosing for each one. -/// UserProperty names can be up to 24 characters long, may only contain alphanumeric characters and -/// underscores ("_"), and must start with an alphabetic character. UserProperty values can be up to -/// 36 characters long. The "firebase_", "google_", and "ga_" prefixes are reserved and should not -/// be used. - -#import <Foundation/Foundation.h> - -/// The method used to sign in. For example, "google", "facebook" or "twitter". -static NSString *const kFIRUserPropertySignUpMethod - NS_SWIFT_NAME(AnalyticsUserPropertySignUpMethod) = @"sign_up_method"; diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h @@ -1,5 +0,0 @@ -#import "FIRAnalytics+AppDelegate.h" -#import "FIRAnalytics.h" -#import "FIREventNames.h" -#import "FIRParameterNames.h" -#import "FIRUserPropertyNames.h" diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Modules/module.modulemap b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Modules/module.modulemap @@ -1,10 +0,0 @@ -framework module FirebaseAnalytics { - umbrella header "FirebaseAnalytics.h" - export * - module * { export *} - link "sqlite3" - link "z" - link framework "Security" - link framework "StoreKit" - link framework "SystemConfiguration" - link framework "UIKit"} diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseCoreDiagnostics.framework/FirebaseCoreDiagnostics b/Pods/FirebaseAnalytics/Frameworks/FirebaseCoreDiagnostics.framework/FirebaseCoreDiagnostics Binary files differ. diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseCoreDiagnostics.framework/Modules/module.modulemap b/Pods/FirebaseAnalytics/Frameworks/FirebaseCoreDiagnostics.framework/Modules/module.modulemap @@ -1,6 +0,0 @@ -framework module FirebaseCoreDiagnostics { - export * - module * { export *} - link "z" - link framework "Security" - link framework "SystemConfiguration"} diff --git a/Pods/FirebaseCore/Firebase/Core/FIRAnalyticsConfiguration.m b/Pods/FirebaseCore/Firebase/Core/FIRAnalyticsConfiguration.m @@ -1,69 +0,0 @@ -// Copyright 2017 Google -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#import "FIRAnalyticsConfiguration.h" - -#import "Private/FIRAnalyticsConfiguration+Internal.h" - -@implementation FIRAnalyticsConfiguration - -+ (FIRAnalyticsConfiguration *)sharedInstance { - static FIRAnalyticsConfiguration *sharedInstance = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - sharedInstance = [[FIRAnalyticsConfiguration alloc] init]; - }); - return sharedInstance; -} - -- (void)postNotificationName:(NSString *)name value:(id)value { - if (!name.length || !value) { - return; - } - [[NSNotificationCenter defaultCenter] postNotificationName:name - object:self - userInfo:@{name : value}]; -} - -- (void)setMinimumSessionInterval:(NSTimeInterval)minimumSessionInterval { - [self postNotificationName:kFIRAnalyticsConfigurationSetMinimumSessionIntervalNotification - value:@(minimumSessionInterval)]; -} - -- (void)setSessionTimeoutInterval:(NSTimeInterval)sessionTimeoutInterval { - [self postNotificationName:kFIRAnalyticsConfigurationSetSessionTimeoutIntervalNotification - value:@(sessionTimeoutInterval)]; -} - -- (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled { - [self setAnalyticsCollectionEnabled:analyticsCollectionEnabled persistSetting:YES]; -} - -- (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled - persistSetting:(BOOL)shouldPersist { - // Persist the measurementEnabledState. Use FIRAnalyticsEnabledState values instead of YES/NO. - FIRAnalyticsEnabledState analyticsEnabledState = - analyticsCollectionEnabled ? kFIRAnalyticsEnabledStateSetYes : kFIRAnalyticsEnabledStateSetNo; - if (shouldPersist) { - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - [userDefaults setObject:@(analyticsEnabledState) - forKey:kFIRAPersistedConfigMeasurementEnabledStateKey]; - [userDefaults synchronize]; - } - - [self postNotificationName:kFIRAnalyticsConfigurationSetEnabledNotification - value:@(analyticsCollectionEnabled)]; -} - -@end diff --git a/Pods/FirebaseCore/Firebase/Core/FIRApp.m b/Pods/FirebaseCore/Firebase/Core/FIRApp.m @@ -1,784 +0,0 @@ -// Copyright 2017 Google -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include <sys/utsname.h> - -#import "FIRApp.h" -#import "FIRConfiguration.h" -#import "Private/FIRAnalyticsConfiguration+Internal.h" -#import "Private/FIRAppInternal.h" -#import "Private/FIRBundleUtil.h" -#import "Private/FIRComponentContainerInternal.h" -#import "Private/FIRLibrary.h" -#import "Private/FIRLogger.h" -#import "Private/FIROptionsInternal.h" - -NSString *const kFIRServiceAdMob = @"AdMob"; -NSString *const kFIRServiceAuth = @"Auth"; -NSString *const kFIRServiceAuthUI = @"AuthUI"; -NSString *const kFIRServiceCrash = @"Crash"; -NSString *const kFIRServiceDatabase = @"Database"; -NSString *const kFIRServiceDynamicLinks = @"DynamicLinks"; -NSString *const kFIRServiceFirestore = @"Firestore"; -NSString *const kFIRServiceFunctions = @"Functions"; -NSString *const kFIRServiceInstanceID = @"InstanceID"; -NSString *const kFIRServiceInvites = @"Invites"; -NSString *const kFIRServiceMessaging = @"Messaging"; -NSString *const kFIRServiceMeasurement = @"Measurement"; -NSString *const kFIRServicePerformance = @"Performance"; -NSString *const kFIRServiceRemoteConfig = @"RemoteConfig"; -NSString *const kFIRServiceStorage = @"Storage"; -NSString *const kGGLServiceAnalytics = @"Analytics"; -NSString *const kGGLServiceSignIn = @"SignIn"; - -NSString *const kFIRDefaultAppName = @"__FIRAPP_DEFAULT"; -NSString *const kFIRAppReadyToConfigureSDKNotification = @"FIRAppReadyToConfigureSDKNotification"; -NSString *const kFIRAppDeleteNotification = @"FIRAppDeleteNotification"; -NSString *const kFIRAppIsDefaultAppKey = @"FIRAppIsDefaultAppKey"; -NSString *const kFIRAppNameKey = @"FIRAppNameKey"; -NSString *const kFIRGoogleAppIDKey = @"FIRGoogleAppIDKey"; - -NSString *const kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat = - @"/google/firebase/global_data_collection_enabled:%@"; -NSString *const kFIRGlobalAppDataCollectionEnabledPlistKey = - @"FirebaseDataCollectionDefaultEnabled"; - -NSString *const kFIRAppDiagnosticsNotification = @"FIRAppDiagnosticsNotification"; - -NSString *const kFIRAppDiagnosticsConfigurationTypeKey = @"ConfigType"; -NSString *const kFIRAppDiagnosticsErrorKey = @"Error"; -NSString *const kFIRAppDiagnosticsFIRAppKey = @"FIRApp"; -NSString *const kFIRAppDiagnosticsSDKNameKey = @"SDKName"; -NSString *const kFIRAppDiagnosticsSDKVersionKey = @"SDKVersion"; - -// Auth internal notification notification and key. -NSString *const FIRAuthStateDidChangeInternalNotification = - @"FIRAuthStateDidChangeInternalNotification"; -NSString *const FIRAuthStateDidChangeInternalNotificationAppKey = - @"FIRAuthStateDidChangeInternalNotificationAppKey"; -NSString *const FIRAuthStateDidChangeInternalNotificationTokenKey = - @"FIRAuthStateDidChangeInternalNotificationTokenKey"; -NSString *const FIRAuthStateDidChangeInternalNotificationUIDKey = - @"FIRAuthStateDidChangeInternalNotificationUIDKey"; - -/** - * The URL to download plist files. - */ -static NSString *const kPlistURL = @"https://console.firebase.google.com/"; - -/** - * An array of all classes that registered as `FIRCoreConfigurable` in order to receive lifecycle - * events from Core. - */ -static NSMutableArray<Class<FIRLibrary>> *sRegisteredAsConfigurable; - -@interface FIRApp () - -#ifdef DEBUG -@property(nonatomic) BOOL alreadyOutputDataCollectionFlag; -#endif // DEBUG - -@end - -@implementation FIRApp - -// This is necessary since our custom getter prevents `_options` from being created. -@synthesize options = _options; - -static NSMutableDictionary *sAllApps; -static FIRApp *sDefaultApp; -static NSMutableDictionary *sLibraryVersions; - -+ (void)configure { - FIROptions *options = [FIROptions defaultOptions]; - if (!options) { - // Read the Info.plist to see if the flag is set. At this point we can't check any user defaults - // since the app isn't configured at all, so only rely on the Info.plist value. - NSNumber *collectionEnabledPlistValue = [[self class] readDataCollectionSwitchFromPlist]; - if (collectionEnabledPlistValue == nil || [collectionEnabledPlistValue boolValue]) { - [[NSNotificationCenter defaultCenter] - postNotificationName:kFIRAppDiagnosticsNotification - object:nil - userInfo:@{ - kFIRAppDiagnosticsConfigurationTypeKey : @(FIRConfigTypeCore), - kFIRAppDiagnosticsErrorKey : [FIRApp errorForMissingOptions] - }]; - } - - [NSException raise:kFirebaseCoreErrorDomain - format:@"`[FIRApp configure];` (`FirebaseApp.configure()` in Swift) could not find " - @"a valid GoogleService-Info.plist in your project. Please download one " - @"from %@.", - kPlistURL]; - } - [FIRApp configureWithOptions:options]; -#if TARGET_OS_OSX || TARGET_OS_TV - FIRLogNotice(kFIRLoggerCore, @"I-COR000028", - @"tvOS and macOS SDK support is not part of the official Firebase product. " - @"Instead they are community supported. Details at " - @"https://github.com/firebase/firebase-ios-sdk/blob/master/README.md."); -#endif -} - -+ (void)configureWithOptions:(FIROptions *)options { - if (!options) { - [NSException raise:kFirebaseCoreErrorDomain - format:@"Options is nil. Please pass a valid options."]; - } - [FIRApp configureWithName:kFIRDefaultAppName options:options]; -} - -+ (void)configureWithName:(NSString *)name options:(FIROptions *)options { - if (!name || !options) { - [NSException raise:kFirebaseCoreErrorDomain format:@"Neither name nor options can be nil."]; - } - if (name.length == 0) { - [NSException raise:kFirebaseCoreErrorDomain format:@"Name cannot be empty."]; - } - - if ([name isEqualToString:kFIRDefaultAppName]) { - if (sDefaultApp) { - [NSException raise:kFirebaseCoreErrorDomain - format:@"Default app has already been configured."]; - } - - FIRLogDebug(kFIRLoggerCore, @"I-COR000001", @"Configuring the default app."); - } else { - // Validate the app name and ensure it hasn't been configured already. - for (NSUInteger charIndex = 0; charIndex < name.length; charIndex++) { - char character = [name characterAtIndex:charIndex]; - if (!((character >= 'a' && character <= 'z') || (character >= 'A' && character <= 'Z') || - (character >= '0' && character <= '9') || character == '_' || character == '-')) { - [NSException raise:kFirebaseCoreErrorDomain - format:@"App name should only contain Letters, " - @"Numbers, Underscores, and Dashes."]; - } - } - - if (sAllApps && sAllApps[name]) { - [NSException raise:kFirebaseCoreErrorDomain - format:@"App named %@ has already been configured.", name]; - } - - FIRLogDebug(kFIRLoggerCore, @"I-COR000002", @"Configuring app named %@", name); - } - - @synchronized(self) { - FIRApp *app = [[FIRApp alloc] initInstanceWithName:name options:options]; - if (app.isDefaultApp) { - sDefaultApp = app; - } - - [FIRApp addAppToAppDictionary:app]; - [FIRApp sendNotificationsToSDKs:app]; - } -} - -+ (FIRApp *)defaultApp { - if (sDefaultApp) { - return sDefaultApp; - } - FIRLogError(kFIRLoggerCore, @"I-COR000003", - @"The default Firebase app has not yet been " - @"configured. Add `[FIRApp configure];` (`FirebaseApp.configure()` in Swift) to your " - @"application initialization. Read more: https://goo.gl/ctyzm8."); - return nil; -} - -+ (FIRApp *)appNamed:(NSString *)name { - @synchronized(self) { - if (sAllApps) { - FIRApp *app = sAllApps[name]; - if (app) { - return app; - } - } - FIRLogError(kFIRLoggerCore, @"I-COR000004", @"App with name %@ does not exist.", name); - return nil; - } -} - -+ (NSDictionary *)allApps { - @synchronized(self) { - if (!sAllApps) { - FIRLogError(kFIRLoggerCore, @"I-COR000005", @"No app has been configured yet."); - } - NSDictionary *dict = [NSDictionary dictionaryWithDictionary:sAllApps]; - return dict; - } -} - -// Public only for tests -+ (void)resetApps { - sDefaultApp = nil; - [sAllApps removeAllObjects]; - sAllApps = nil; - [sLibraryVersions removeAllObjects]; - sLibraryVersions = nil; -} - -- (void)deleteApp:(FIRAppVoidBoolCallback)completion { - @synchronized([self class]) { - if (sAllApps && sAllApps[self.name]) { - FIRLogDebug(kFIRLoggerCore, @"I-COR000006", @"Deleting app named %@", self.name); - - // Remove all cached instances from the container before deleting the app. - [self.container removeAllCachedInstances]; - - [sAllApps removeObjectForKey:self.name]; - [self clearDataCollectionSwitchFromUserDefaults]; - if ([self.name isEqualToString:kFIRDefaultAppName]) { - sDefaultApp = nil; - } - NSDictionary *appInfoDict = @{kFIRAppNameKey : self.name}; - [[NSNotificationCenter defaultCenter] postNotificationName:kFIRAppDeleteNotification - object:[self class] - userInfo:appInfoDict]; - completion(YES); - } else { - FIRLogError(kFIRLoggerCore, @"I-COR000007", @"App does not exist."); - completion(NO); - } - } -} - -+ (void)addAppToAppDictionary:(FIRApp *)app { - if (!sAllApps) { - sAllApps = [NSMutableDictionary dictionary]; - } - if ([app configureCore]) { - sAllApps[app.name] = app; - } else { - [NSException raise:kFirebaseCoreErrorDomain - format:@"Configuration fails. It may be caused by an invalid GOOGLE_APP_ID in " - @"GoogleService-Info.plist or set in the customized options."]; - } -} - -- (instancetype)initInstanceWithName:(NSString *)name options:(FIROptions *)options { - self = [super init]; - if (self) { - _name = [name copy]; - _options = [options copy]; - _options.editingLocked = YES; - _isDefaultApp = [name isEqualToString:kFIRDefaultAppName]; - _container = [[FIRComponentContainer alloc] initWithApp:self]; - } - return self; -} - -- (BOOL)configureCore { - [self checkExpectedBundleID]; - if (![self isAppIDValid]) { - if (_options.usingOptionsFromDefaultPlist && [self isDataCollectionDefaultEnabled]) { - [[NSNotificationCenter defaultCenter] - postNotificationName:kFIRAppDiagnosticsNotification - object:nil - userInfo:@{ - kFIRAppDiagnosticsConfigurationTypeKey : @(FIRConfigTypeCore), - kFIRAppDiagnosticsErrorKey : [FIRApp errorForInvalidAppID], - }]; - } - return NO; - } - - if ([self isDataCollectionDefaultEnabled]) { - [[NSNotificationCenter defaultCenter] - postNotificationName:kFIRAppDiagnosticsNotification - object:nil - userInfo:@{ - kFIRAppDiagnosticsConfigurationTypeKey : @(FIRConfigTypeCore), - kFIRAppDiagnosticsFIRAppKey : self - }]; - } - -#if TARGET_OS_IOS - // Initialize the Analytics once there is a valid options under default app. Analytics should - // always initialize first by itself before the other SDKs. - if ([self.name isEqualToString:kFIRDefaultAppName]) { - Class firAnalyticsClass = NSClassFromString(@"FIRAnalytics"); - if (!firAnalyticsClass) { - FIRLogWarning(kFIRLoggerCore, @"I-COR000022", - @"Firebase Analytics is not available. To add it, include Firebase/Core in the " - @"Podfile or add FirebaseAnalytics.framework to the Link Build Phase"); - } else { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wundeclared-selector" - SEL startWithConfigurationSelector = @selector(startWithConfiguration:options:); -#pragma clang diagnostic pop - if ([firAnalyticsClass respondsToSelector:startWithConfigurationSelector]) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warc-performSelector-leaks" - [firAnalyticsClass performSelector:startWithConfigurationSelector - withObject:[FIRConfiguration sharedInstance].analyticsConfiguration - withObject:_options]; -#pragma clang diagnostic pop - } - } - } -#endif - - return YES; -} - -- (FIROptions *)options { - return [_options copy]; -} - -- (void)setDataCollectionDefaultEnabled:(BOOL)dataCollectionDefaultEnabled { -#ifdef DEBUG - FIRLogDebug(kFIRLoggerCore, @"I-COR000034", @"Explicitly %@ data collection flag.", - dataCollectionDefaultEnabled ? @"enabled" : @"disabled"); - self.alreadyOutputDataCollectionFlag = YES; -#endif // DEBUG - - NSString *key = - [NSString stringWithFormat:kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat, self.name]; - [[NSUserDefaults standardUserDefaults] setBool:dataCollectionDefaultEnabled forKey:key]; - - // Core also controls the FirebaseAnalytics flag, so check if the Analytics flags are set - // within FIROptions and change the Analytics value if necessary. Analytics only works with the - // default app, so return if this isn't the default app. - if (!self.isDefaultApp) { - return; - } - - // Check if the Analytics flag is explicitly set. If so, no further actions are necessary. - if ([self.options isAnalyticsCollectionExpicitlySet]) { - return; - } - - // The Analytics flag has not been explicitly set, so update with the value being set. - [[FIRAnalyticsConfiguration sharedInstance] - setAnalyticsCollectionEnabled:dataCollectionDefaultEnabled - persistSetting:NO]; -} - -- (BOOL)isDataCollectionDefaultEnabled { - // Check if it's been manually set before in code, and use that as the higher priority value. - NSNumber *defaultsObject = [[self class] readDataCollectionSwitchFromUserDefaultsForApp:self]; - if (defaultsObject != nil) { -#ifdef DEBUG - if (!self.alreadyOutputDataCollectionFlag) { - FIRLogDebug(kFIRLoggerCore, @"I-COR000031", @"Data Collection flag is %@ in user defaults.", - [defaultsObject boolValue] ? @"enabled" : @"disabled"); - self.alreadyOutputDataCollectionFlag = YES; - } -#endif // DEBUG - return [defaultsObject boolValue]; - } - - // Read the Info.plist to see if the flag is set. If it's not set, it should default to `YES`. - // As per the implementation of `readDataCollectionSwitchFromPlist`, it's a cached value and has - // no performance impact calling multiple times. - NSNumber *collectionEnabledPlistValue = [[self class] readDataCollectionSwitchFromPlist]; - if (collectionEnabledPlistValue != nil) { -#ifdef DEBUG - if (!self.alreadyOutputDataCollectionFlag) { - FIRLogDebug(kFIRLoggerCore, @"I-COR000032", @"Data Collection flag is %@ in plist.", - [collectionEnabledPlistValue boolValue] ? @"enabled" : @"disabled"); - self.alreadyOutputDataCollectionFlag = YES; - } -#endif // DEBUG - return [collectionEnabledPlistValue boolValue]; - } - -#ifdef DEBUG - if (!self.alreadyOutputDataCollectionFlag) { - FIRLogDebug(kFIRLoggerCore, @"I-COR000033", @"Data Collection flag is not set."); - self.alreadyOutputDataCollectionFlag = YES; - } -#endif // DEBUG - return YES; -} - -#pragma mark - private - -+ (void)sendNotificationsToSDKs:(FIRApp *)app { - // TODO: Remove this notification once all SDKs are registered with `FIRCoreConfigurable`. - NSNumber *isDefaultApp = [NSNumber numberWithBool:app.isDefaultApp]; - NSDictionary *appInfoDict = @{ - kFIRAppNameKey : app.name, - kFIRAppIsDefaultAppKey : isDefaultApp, - kFIRGoogleAppIDKey : app.options.googleAppID - }; - [[NSNotificationCenter defaultCenter] postNotificationName:kFIRAppReadyToConfigureSDKNotification - object:self - userInfo:appInfoDict]; - - // This is the new way of sending information to SDKs. - // TODO: Do we want this on a background thread, maybe? - for (Class<FIRLibrary> library in sRegisteredAsConfigurable) { - [library configureWithApp:app]; - } -} - -+ (NSError *)errorForMissingOptions { - NSDictionary *errorDict = @{ - NSLocalizedDescriptionKey : - @"Unable to parse GoogleService-Info.plist in order to configure services.", - NSLocalizedRecoverySuggestionErrorKey : - @"Check formatting and location of GoogleService-Info.plist." - }; - return [NSError errorWithDomain:kFirebaseCoreErrorDomain - code:FIRErrorCodeInvalidPlistFile - userInfo:errorDict]; -} - -+ (NSError *)errorForSubspecConfigurationFailureWithDomain:(NSString *)domain - errorCode:(FIRErrorCode)code - service:(NSString *)service - reason:(NSString *)reason { - NSString *description = - [NSString stringWithFormat:@"Configuration failed for service %@.", service]; - NSDictionary *errorDict = - @{NSLocalizedDescriptionKey : description, NSLocalizedFailureReasonErrorKey : reason}; - return [NSError errorWithDomain:domain code:code userInfo:errorDict]; -} - -+ (NSError *)errorForInvalidAppID { - NSDictionary *errorDict = @{ - NSLocalizedDescriptionKey : @"Unable to validate Google App ID", - NSLocalizedRecoverySuggestionErrorKey : - @"Check formatting and location of GoogleService-Info.plist or GoogleAppID set in the " - @"customized options." - }; - return [NSError errorWithDomain:kFirebaseCoreErrorDomain - code:FIRErrorCodeInvalidAppID - userInfo:errorDict]; -} - -+ (BOOL)isDefaultAppConfigured { - return (sDefaultApp != nil); -} - -+ (void)registerLibrary:(nonnull NSString *)name withVersion:(nonnull NSString *)version { - // Create the set of characters which aren't allowed, only if this feature is used. - NSMutableCharacterSet *allowedSet = [NSMutableCharacterSet alphanumericCharacterSet]; - [allowedSet addCharactersInString:@"-_."]; - NSCharacterSet *disallowedSet = [allowedSet invertedSet]; - // Make sure the library name and version strings do not contain unexpected characters, and - // add the name/version pair to the dictionary. - if ([name rangeOfCharacterFromSet:disallowedSet].location == NSNotFound && - [version rangeOfCharacterFromSet:disallowedSet].location == NSNotFound) { - if (!sLibraryVersions) { - sLibraryVersions = [[NSMutableDictionary alloc] init]; - } - sLibraryVersions[name] = version; - } else { - FIRLogError(kFIRLoggerCore, @"I-COR000027", - @"The library name (%@) or version number (%@) contain invalid characters. " - @"Only alphanumeric, dash, underscore and period characters are allowed.", - name, version); - } -} - -+ (void)registerInternalLibrary:(nonnull Class<FIRLibrary>)library - withName:(nonnull NSString *)name - withVersion:(nonnull NSString *)version { - // This is called at +load time, keep the work to a minimum. - - // Ensure the class given conforms to the proper protocol. - if (![(Class)library conformsToProtocol:@protocol(FIRLibrary)] || - ![(Class)library respondsToSelector:@selector(componentsToRegister)]) { - [NSException raise:NSInvalidArgumentException - format:@"Class %@ attempted to register components, but it does not conform to " - @"`FIRLibrary or provide a `componentsToRegister:` method.", - library]; - } - - [FIRComponentContainer registerAsComponentRegistrant:library]; - if ([(Class)library respondsToSelector:@selector(configureWithApp:)]) { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - sRegisteredAsConfigurable = [[NSMutableArray alloc] init]; - }); - [sRegisteredAsConfigurable addObject:library]; - } - [self registerLibrary:name withVersion:version]; -} - -+ (NSString *)firebaseUserAgent { - NSMutableArray<NSString *> *libraries = - [[NSMutableArray<NSString *> alloc] initWithCapacity:sLibraryVersions.count]; - for (NSString *libraryName in sLibraryVersions) { - [libraries - addObject:[NSString stringWithFormat:@"%@/%@", libraryName, sLibraryVersions[libraryName]]]; - } - [libraries sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; - return [libraries componentsJoinedByString:@" "]; -} - -- (void)checkExpectedBundleID { - NSArray *bundles = [FIRBundleUtil relevantBundles]; - NSString *expectedBundleID = [self expectedBundleID]; - // The checking is only done when the bundle ID is provided in the serviceInfo dictionary for - // backward compatibility. - if (expectedBundleID != nil && ![FIRBundleUtil hasBundleIdentifier:expectedBundleID - inBundles:bundles]) { - FIRLogError(kFIRLoggerCore, @"I-COR000008", - @"The project's Bundle ID is inconsistent with " - @"either the Bundle ID in '%@.%@', or the Bundle ID in the options if you are " - @"using a customized options. To ensure that everything can be configured " - @"correctly, you may need to make the Bundle IDs consistent. To continue with this " - @"plist file, you may change your app's bundle identifier to '%@'. Or you can " - @"download a new configuration file that matches your bundle identifier from %@ " - @"and replace the current one.", - kServiceInfoFileName, kServiceInfoFileType, expectedBundleID, kPlistURL); - } -} - -#pragma mark - private - App ID Validation - -/** - * Validates the format and fingerprint of the app ID contained in GOOGLE_APP_ID in the plist file. - * This is the main method for validating app ID. - * - * @return YES if the app ID fulfills the expected format and fingerprint, NO otherwise. - */ -- (BOOL)isAppIDValid { - NSString *appID = _options.googleAppID; - BOOL isValid = [FIRApp validateAppID:appID]; - if (!isValid) { - NSString *expectedBundleID = [self expectedBundleID]; - FIRLogError(kFIRLoggerCore, @"I-COR000009", - @"The GOOGLE_APP_ID either in the plist file " - @"'%@.%@' or the one set in the customized options is invalid. If you are using " - @"the plist file, use the iOS version of bundle identifier to download the file, " - @"and do not manually edit the GOOGLE_APP_ID. You may change your app's bundle " - @"identifier to '%@'. Or you can download a new configuration file that matches " - @"your bundle identifier from %@ and replace the current one.", - kServiceInfoFileName, kServiceInfoFileType, expectedBundleID, kPlistURL); - }; - return isValid; -} - -+ (BOOL)validateAppID:(NSString *)appID { - // Failing validation only occurs when we are sure we are looking at a V2 app ID and it does not - // have a valid fingerprint, otherwise we just warn about the potential issue. - if (!appID.length) { - return NO; - } - - // All app IDs must start with at least "<version number>:". - NSString *const versionPattern = @"^\\d+:"; - NSRegularExpression *versionRegex = - [NSRegularExpression regularExpressionWithPattern:versionPattern options:0 error:NULL]; - if (!versionRegex) { - return NO; - } - - NSRange appIDRange = NSMakeRange(0, appID.length); - NSArray *versionMatches = [versionRegex matchesInString:appID options:0 range:appIDRange]; - if (versionMatches.count != 1) { - return NO; - } - - NSRange versionRange = [(NSTextCheckingResult *)versionMatches.firstObject range]; - NSString *appIDVersion = [appID substringWithRange:versionRange]; - NSArray *knownVersions = @[ @"1:" ]; - if (![knownVersions containsObject:appIDVersion]) { - // Permit unknown yet properly formatted app ID versions. - return YES; - } - - if (![FIRApp validateAppIDFormat:appID withVersion:appIDVersion]) { - return NO; - } - - if (![FIRApp validateAppIDFingerprint:appID withVersion:appIDVersion]) { - return NO; - } - - return YES; -} - -+ (NSString *)actualBundleID { - return [[NSBundle mainBundle] bundleIdentifier]; -} - -/** - * Validates that the format of the app ID string is what is expected based on the supplied version. - * The version must end in ":". - * - * For v1 app ids the format is expected to be - * '<version #>:<project number>:ios:<fingerprint of bundle id>'. - * - * This method does not verify that the contents of the app id are correct, just that they fulfill - * the expected format. - * - * @param appID Contents of GOOGLE_APP_ID from the plist file. - * @param version Indicates what version of the app id format this string should be. - * @return YES if provided string fufills the expected format, NO otherwise. - */ -+ (BOOL)validateAppIDFormat:(NSString *)appID withVersion:(NSString *)version { - if (!appID.length || !version.length) { - return NO; - } - - if (![version hasSuffix:@":"]) { - return NO; - } - - if (![appID hasPrefix:version]) { - return NO; - } - - NSString *const pattern = @"^\\d+:ios:[a-f0-9]+$"; - NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern - options:0 - error:NULL]; - if (!regex) { - return NO; - } - - NSRange localRange = NSMakeRange(version.length, appID.length - version.length); - NSUInteger numberOfMatches = [regex numberOfMatchesInString:appID options:0 range:localRange]; - if (numberOfMatches != 1) { - return NO; - } - return YES; -} - -/** - * Validates that the fingerprint of the app ID string is what is expected based on the supplied - * version. The version must end in ":". - * - * Note that the v1 hash algorithm is not permitted on the client and cannot be fully validated. - * - * @param appID Contents of GOOGLE_APP_ID from the plist file. - * @param version Indicates what version of the app id format this string should be. - * @return YES if provided string fufills the expected fingerprint and the version is known, NO - * otherwise. - */ -+ (BOOL)validateAppIDFingerprint:(NSString *)appID withVersion:(NSString *)version { - if (!appID.length || !version.length) { - return NO; - } - - if (![version hasSuffix:@":"]) { - return NO; - } - - if (![appID hasPrefix:version]) { - return NO; - } - - // Extract the supplied fingerprint from the supplied app ID. - // This assumes the app ID format is the same for all known versions below. If the app ID format - // changes in future versions, the tokenizing of the app ID format will need to take into account - // the version of the app ID. - NSArray *components = [appID componentsSeparatedByString:@":"]; - if (components.count != 4) { - return NO; - } - - NSString *suppliedFingerprintString = components[3]; - if (!suppliedFingerprintString.length) { - return NO; - } - - uint64_t suppliedFingerprint; - NSScanner *scanner = [NSScanner scannerWithString:suppliedFingerprintString]; - if (![scanner scanHexLongLong:&suppliedFingerprint]) { - return NO; - } - - if ([version isEqual:@"1:"]) { - // The v1 hash algorithm is not permitted on the client so the actual hash cannot be validated. - return YES; - } - - // Unknown version. - return NO; -} - -- (NSString *)expectedBundleID { - return _options.bundleID; -} - -// end App ID validation - -#pragma mark - Reading From Plist & User Defaults - -/** - * Clears the data collection switch from the standard NSUserDefaults for easier testing and - * readability. - */ -- (void)clearDataCollectionSwitchFromUserDefaults { - NSString *key = - [NSString stringWithFormat:kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat, self.name]; - [[NSUserDefaults standardUserDefaults] removeObjectForKey:key]; -} - -/** - * Reads the data collection switch from the standard NSUserDefaults for easier testing and - * readability. - */ -+ (nullable NSNumber *)readDataCollectionSwitchFromUserDefaultsForApp:(FIRApp *)app { - // Read the object in user defaults, and only return if it's an NSNumber. - NSString *key = - [NSString stringWithFormat:kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat, app.name]; - id collectionEnabledDefaultsObject = [[NSUserDefaults standardUserDefaults] objectForKey:key]; - if ([collectionEnabledDefaultsObject isKindOfClass:[NSNumber class]]) { - return collectionEnabledDefaultsObject; - } - - return nil; -} - -/** - * Reads the data collection switch from the Info.plist for easier testing and readability. Will - * only read once from the plist and return the cached value. - */ -+ (nullable NSNumber *)readDataCollectionSwitchFromPlist { - static NSNumber *collectionEnabledPlistObject; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - // Read the data from the `Info.plist`, only assign it if it's there and an NSNumber. - id plistValue = [[NSBundle mainBundle] - objectForInfoDictionaryKey:kFIRGlobalAppDataCollectionEnabledPlistKey]; - if (plistValue && [plistValue isKindOfClass:[NSNumber class]]) { - collectionEnabledPlistObject = (NSNumber *)plistValue; - } - }); - - return collectionEnabledPlistObject; -} - -#pragma mark - Sending Logs - -- (void)sendLogsWithServiceName:(NSString *)serviceName - version:(NSString *)version - error:(NSError *)error { - // If the user has manually turned off data collection, return and don't send logs. - if (![self isDataCollectionDefaultEnabled]) { - return; - } - - NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] initWithDictionary:@{ - kFIRAppDiagnosticsConfigurationTypeKey : @(FIRConfigTypeSDK), - kFIRAppDiagnosticsSDKNameKey : serviceName, - kFIRAppDiagnosticsSDKVersionKey : version, - kFIRAppDiagnosticsFIRAppKey : self - }]; - if (error) { - userInfo[kFIRAppDiagnosticsErrorKey] = error; - } - [[NSNotificationCenter defaultCenter] postNotificationName:kFIRAppDiagnosticsNotification - object:nil - userInfo:userInfo]; -} - -@end diff --git a/Pods/FirebaseCore/Firebase/Core/FIRAppAssociationRegistration.m b/Pods/FirebaseCore/Firebase/Core/FIRAppAssociationRegistration.m @@ -1,47 +0,0 @@ -// Copyright 2017 Google -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#import "Private/FIRAppAssociationRegistration.h" - -#import <objc/runtime.h> - -@implementation FIRAppAssociationRegistration - -+ (nullable id)registeredObjectWithHost:(id)host - key:(NSString *)key - creationBlock:(id _Nullable (^)(void))creationBlock { - @synchronized(self) { - SEL dictKey = @selector(registeredObjectWithHost:key:creationBlock:); - NSMutableDictionary<NSString *, id> *objectsByKey = objc_getAssociatedObject(host, dictKey); - if (!objectsByKey) { - objectsByKey = [[NSMutableDictionary alloc] init]; - objc_setAssociatedObject(host, dictKey, objectsByKey, OBJC_ASSOCIATION_RETAIN_NONATOMIC); - } - id obj = objectsByKey[key]; - NSValue *creationBlockBeingCalled = [NSValue valueWithPointer:dictKey]; - if (obj) { - if ([creationBlockBeingCalled isEqual:obj]) { - [NSException raise:@"Reentering registeredObjectWithHost:key:creationBlock: not allowed" - format:@"host: %@ key: %@", host, key]; - } - return obj; - } - objectsByKey[key] = creationBlockBeingCalled; - obj = creationBlock(); - objectsByKey[key] = obj; - return obj; - } -} - -@end diff --git a/Pods/FirebaseCore/Firebase/Core/FIRBundleUtil.m b/Pods/FirebaseCore/Firebase/Core/FIRBundleUtil.m @@ -1,57 +0,0 @@ -// Copyright 2017 Google -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#import "Private/FIRBundleUtil.h" - -@implementation FIRBundleUtil - -+ (NSArray *)relevantBundles { - return @[ [NSBundle mainBundle], [NSBundle bundleForClass:[self class]] ]; -} - -+ (NSString *)optionsDictionaryPathWithResourceName:(NSString *)resourceName - andFileType:(NSString *)fileType - inBundles:(NSArray *)bundles { - // Loop through all bundles to find the config dict. - for (NSBundle *bundle in bundles) { - NSString *path = [bundle pathForResource:resourceName ofType:fileType]; - // Use the first one we find. - if (path) { - return path; - } - } - return nil; -} - -+ (NSArray *)relevantURLSchemes { - NSMutableArray *result = [[NSMutableArray alloc] init]; - for (NSBundle *bundle in [[self class] relevantBundles]) { - NSArray *urlTypes = [bundle objectForInfoDictionaryKey:@"CFBundleURLTypes"]; - for (NSDictionary *urlType in urlTypes) { - [result addObjectsFromArray:urlType[@"CFBundleURLSchemes"]]; - } - } - return result; -} - -+ (BOOL)hasBundleIdentifier:(NSString *)bundleIdentifier inBundles:(NSArray *)bundles { - for (NSBundle *bundle in bundles) { - if ([bundle.bundleIdentifier isEqualToString:bundleIdentifier]) { - return YES; - } - } - return NO; -} - -@end diff --git a/Pods/FirebaseCore/Firebase/Core/FIRComponent.m b/Pods/FirebaseCore/Firebase/Core/FIRComponent.m @@ -1,65 +0,0 @@ -/* - * Copyright 2018 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "Private/FIRComponent.h" - -#import "Private/FIRComponentContainer.h" -#import "Private/FIRDependency.h" - -@interface FIRComponent () - -- (instancetype)initWithProtocol:(Protocol *)protocol - instantiationTiming:(FIRInstantiationTiming)instantiationTiming - dependencies:(NSArray<FIRDependency *> *)dependencies - creationBlock:(FIRComponentCreationBlock)creationBlock; - -@end - -@implementation FIRComponent - -+ (instancetype)componentWithProtocol:(Protocol *)protocol - creationBlock:(FIRComponentCreationBlock)creationBlock { - return [[FIRComponent alloc] initWithProtocol:protocol - instantiationTiming:FIRInstantiationTimingLazy - dependencies:@[] - creationBlock:creationBlock]; -} - -+ (instancetype)componentWithProtocol:(Protocol *)protocol - instantiationTiming:(FIRInstantiationTiming)instantiationTiming - dependencies:(NSArray<FIRDependency *> *)dependencies - creationBlock:(FIRComponentCreationBlock)creationBlock { - return [[FIRComponent alloc] initWithProtocol:protocol - instantiationTiming:instantiationTiming - dependencies:dependencies - creationBlock:creationBlock]; -} - -- (instancetype)initWithProtocol:(Protocol *)protocol - instantiationTiming:(FIRInstantiationTiming)instantiationTiming - dependencies:(NSArray<FIRDependency *> *)dependencies - creationBlock:(FIRComponentCreationBlock)creationBlock { - self = [super init]; - if (self) { - _protocol = protocol; - _instantiationTiming = instantiationTiming; - _dependencies = [dependencies copy]; - _creationBlock = creationBlock; - } - return self; -} - -@end diff --git a/Pods/FirebaseCore/Firebase/Core/FIRComponentContainer.m b/Pods/FirebaseCore/Firebase/Core/FIRComponentContainer.m @@ -1,176 +0,0 @@ -/* - * Copyright 2018 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "Private/FIRComponentContainer.h" - -#import "Private/FIRAppInternal.h" -#import "Private/FIRComponent.h" -#import "Private/FIRLibrary.h" -#import "Private/FIRLogger.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface FIRComponentContainer () - -/// The dictionary of components that are registered for a particular app. The key is an NSString -/// of the protocol. -@property(nonatomic, strong) NSMutableDictionary<NSString *, FIRComponentCreationBlock> *components; - -/// Cached instances of components that requested to be cached. -@property(nonatomic, strong) NSMutableDictionary<NSString *, id> *cachedInstances; - -@end - -@implementation FIRComponentContainer - -// Collection of all classes that register to provide components. -static NSMutableSet<Class> *sFIRComponentRegistrants; - -#pragma mark - Public Registration - -+ (void)registerAsComponentRegistrant:(Class<FIRLibrary>)klass { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - sFIRComponentRegistrants = [[NSMutableSet<Class> alloc] init]; - }); - - [self registerAsComponentRegistrant:klass inSet:sFIRComponentRegistrants]; -} - -+ (void)registerAsComponentRegistrant:(Class<FIRLibrary>)klass - inSet:(NSMutableSet<Class> *)allRegistrants { - [allRegistrants addObject:klass]; -} - -#pragma mark - Internal Initialization - -- (instancetype)initWithApp:(FIRApp *)app { - return [self initWithApp:app registrants:sFIRComponentRegistrants]; -} - -- (instancetype)initWithApp:(FIRApp *)app registrants:(NSMutableSet<Class> *)allRegistrants { - self = [super init]; - if (self) { - _app = app; - _cachedInstances = [NSMutableDictionary<NSString *, id> dictionary]; - _components = [NSMutableDictionary<NSString *, FIRComponentCreationBlock> dictionary]; - - [self populateComponentsFromRegisteredClasses:allRegistrants forApp:app]; - } - return self; -} - -- (void)populateComponentsFromRegisteredClasses:(NSSet<Class> *)classes forApp:(FIRApp *)app { - // Loop through the verified component registrants and populate the components array. - for (Class<FIRLibrary> klass in classes) { - // Loop through all the components being registered and store them as appropriate. - // Classes which do not provide functionality should use a dummy FIRComponentRegistrant - // protocol. - for (FIRComponent *component in [klass componentsToRegister]) { - // Check if the component has been registered before, and error out if so. - NSString *protocolName = NSStringFromProtocol(component.protocol); - if (self.components[protocolName]) { - FIRLogError(kFIRLoggerCore, @"I-COR000029", - @"Attempted to register protocol %@, but it already has an implementation.", - protocolName); - continue; - } - - // Store the creation block for later usage. - self.components[protocolName] = component.creationBlock; - - // Instantiate the - BOOL shouldInstantiateEager = - (component.instantiationTiming == FIRInstantiationTimingAlwaysEager); - BOOL shouldInstantiateDefaultEager = - (component.instantiationTiming == FIRInstantiationTimingEagerInDefaultApp && - [app isDefaultApp]); - if (shouldInstantiateEager || shouldInstantiateDefaultEager) { - [self instantiateInstanceForProtocol:component.protocol withBlock:component.creationBlock]; - } - } - } -} - -#pragma mark - Instance Creation - -/// Instantiate an instance of a class that conforms to the specified protocol. -/// This will: -/// - Call the block to create an instance if possible, -/// - Validate that the instance returned conforms to the protocol it claims to, -/// - Cache the instance if the block requests it -- (nullable id)instantiateInstanceForProtocol:(Protocol *)protocol - withBlock:(FIRComponentCreationBlock)creationBlock { - if (!creationBlock) { - return nil; - } - - // Create an instance using the creation block. - BOOL shouldCache = NO; - id instance = creationBlock(self, &shouldCache); - if (!instance) { - return nil; - } - - // An instance was created, validate that it conforms to the protocol it claims to. - NSString *protocolName = NSStringFromProtocol(protocol); - if (![instance conformsToProtocol:protocol]) { - FIRLogError(kFIRLoggerCore, @"I-COR000030", - @"An instance conforming to %@ was requested, but the instance provided does not " - @"conform to the protocol", - protocolName); - } - - // The instance is ready to be returned, but check if it should be cached first before returning. - if (shouldCache) { - self.cachedInstances[protocolName] = instance; - } - - return instance; -} - -#pragma mark - Internal Retrieval - -- (nullable id)instanceForProtocol:(Protocol *)protocol { - // Check if there is a cached instance, and return it if so. - NSString *protocolName = NSStringFromProtocol(protocol); - id cachedInstance = self.cachedInstances[protocolName]; - if (cachedInstance) { - return cachedInstance; - } - - // Use the creation block to instantiate an instance and return it. - FIRComponentCreationBlock creationBlock = self.components[protocolName]; - return [self instantiateInstanceForProtocol:protocol withBlock:creationBlock]; -} - -#pragma mark - Lifecycle - -- (void)removeAllCachedInstances { - // Loop through the cache and notify each instance that is a maintainer to clean up after itself. - for (id instance in self.cachedInstances.allValues) { - if ([instance conformsToProtocol:@protocol(FIRComponentLifecycleMaintainer)] && - [instance respondsToSelector:@selector(appWillBeDeleted:)]) { - [instance appWillBeDeleted:self.app]; - } - } - - [self.cachedInstances removeAllObjects]; -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/Firebase/Core/FIRComponentType.m b/Pods/FirebaseCore/Firebase/Core/FIRComponentType.m @@ -1,28 +0,0 @@ -/* - * Copyright 2018 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "Private/FIRComponentType.h" - -#import "Private/FIRComponentContainerInternal.h" - -@implementation FIRComponentType - -+ (id)instanceForProtocol:(Protocol *)protocol inContainer:(FIRComponentContainer *)container { - // Forward the call to the container. - return [container instanceForProtocol:protocol]; -} - -@end diff --git a/Pods/FirebaseCore/Firebase/Core/FIRConfiguration.m b/Pods/FirebaseCore/Firebase/Core/FIRConfiguration.m @@ -1,44 +0,0 @@ -// Copyright 2017 Google -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#import "FIRConfiguration.h" - -extern void FIRSetLoggerLevel(FIRLoggerLevel loggerLevel); - -@implementation FIRConfiguration - -+ (instancetype)sharedInstance { - static FIRConfiguration *sharedInstance = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - sharedInstance = [[FIRConfiguration alloc] init]; - }); - return sharedInstance; -} - -- (instancetype)init { - self = [super init]; - if (self) { - _analyticsConfiguration = [FIRAnalyticsConfiguration sharedInstance]; - } - return self; -} - -- (void)setLoggerLevel:(FIRLoggerLevel)loggerLevel { - NSAssert(loggerLevel <= FIRLoggerLevelMax && loggerLevel >= FIRLoggerLevelMin, - @"Invalid logger level, %ld", (long)loggerLevel); - FIRSetLoggerLevel(loggerLevel); -} - -@end diff --git a/Pods/FirebaseCore/Firebase/Core/FIRDependency.m b/Pods/FirebaseCore/Firebase/Core/FIRDependency.m @@ -1,44 +0,0 @@ -/* - * Copyright 2018 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "Private/FIRDependency.h" - -@interface FIRDependency () - -- (instancetype)initWithProtocol:(Protocol *)protocol isRequired:(BOOL)required; - -@end - -@implementation FIRDependency - -+ (instancetype)dependencyWithProtocol:(Protocol *)protocol { - return [[self alloc] initWithProtocol:protocol isRequired:YES]; -} - -+ (instancetype)dependencyWithProtocol:(Protocol *)protocol isRequired:(BOOL)required { - return [[self alloc] initWithProtocol:protocol isRequired:required]; -} - -- (instancetype)initWithProtocol:(Protocol *)protocol isRequired:(BOOL)required { - self = [super init]; - if (self) { - _protocol = protocol; - _isRequired = required; - } - return self; -} - -@end diff --git a/Pods/FirebaseCore/Firebase/Core/FIRErrors.m b/Pods/FirebaseCore/Firebase/Core/FIRErrors.m @@ -1,29 +0,0 @@ -// Copyright 2017 Google -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#import "Private/FIRErrors.h" - -NSString *const kFirebaseErrorDomain = @"com.firebase"; -NSString *const kFirebaseAdMobErrorDomain = @"com.firebase.admob"; -NSString *const kFirebaseAppInviteErrorDomain = @"com.firebase.appinvite"; -NSString *const kFirebaseAuthErrorDomain = @"com.firebase.auth"; -NSString *const kFirebaseCloudMessagingErrorDomain = @"com.firebase.cloudmessaging"; -NSString *const kFirebaseConfigErrorDomain = @"com.firebase.config"; -NSString *const kFirebaseCoreErrorDomain = @"com.firebase.core"; -NSString *const kFirebaseCrashReportingErrorDomain = @"com.firebase.crashreporting"; -NSString *const kFirebaseDatabaseErrorDomain = @"com.firebase.database"; -NSString *const kFirebaseDurableDeepLinkErrorDomain = @"com.firebase.durabledeeplink"; -NSString *const kFirebaseInstanceIDErrorDomain = @"com.firebase.instanceid"; -NSString *const kFirebasePerfErrorDomain = @"com.firebase.perf"; -NSString *const kFirebaseStorageErrorDomain = @"com.firebase.storage"; diff --git a/Pods/FirebaseCore/Firebase/Core/FIRLogger.m b/Pods/FirebaseCore/Firebase/Core/FIRLogger.m @@ -1,171 +0,0 @@ -// Copyright 2017 Google -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#import "Private/FIRLogger.h" - -#import <FirebaseCore/FIRLoggerLevel.h> -#import <GoogleUtilities/GULAppEnvironmentUtil.h> -#import <GoogleUtilities/GULLogger.h> - -#import "Private/FIRVersion.h" - -FIRLoggerService kFIRLoggerABTesting = @"[Firebase/ABTesting]"; -FIRLoggerService kFIRLoggerAdMob = @"[Firebase/AdMob]"; -FIRLoggerService kFIRLoggerAnalytics = @"[Firebase/Analytics]"; -FIRLoggerService kFIRLoggerAuth = @"[Firebase/Auth]"; -FIRLoggerService kFIRLoggerCore = @"[Firebase/Core]"; -FIRLoggerService kFIRLoggerCrash = @"[Firebase/Crash]"; -FIRLoggerService kFIRLoggerDatabase = @"[Firebase/Database]"; -FIRLoggerService kFIRLoggerDynamicLinks = @"[Firebase/DynamicLinks]"; -FIRLoggerService kFIRLoggerFirestore = @"[Firebase/Firestore]"; -FIRLoggerService kFIRLoggerInstanceID = @"[Firebase/InstanceID]"; -FIRLoggerService kFIRLoggerInvites = @"[Firebase/Invites]"; -FIRLoggerService kFIRLoggerMLKit = @"[Firebase/MLKit]"; -FIRLoggerService kFIRLoggerMessaging = @"[Firebase/Messaging]"; -FIRLoggerService kFIRLoggerPerf = @"[Firebase/Performance]"; -FIRLoggerService kFIRLoggerRemoteConfig = @"[Firebase/RemoteConfig]"; -FIRLoggerService kFIRLoggerStorage = @"[Firebase/Storage]"; -FIRLoggerService kFIRLoggerSwizzler = @"[FirebaseSwizzlingUtilities]"; - -/// Arguments passed on launch. -NSString *const kFIRDisableDebugModeApplicationArgument = @"-FIRDebugDisabled"; -NSString *const kFIREnableDebugModeApplicationArgument = @"-FIRDebugEnabled"; -NSString *const kFIRLoggerForceSDTERRApplicationArgument = @"-FIRLoggerForceSTDERR"; - -/// Key for the debug mode bit in NSUserDefaults. -NSString *const kFIRPersistedDebugModeKey = @"/google/firebase/debug_mode"; - -/// NSUserDefaults that should be used to store and read variables. If nil, `standardUserDefaults` -/// will be used. -static NSUserDefaults *sFIRLoggerUserDefaults; - -static dispatch_once_t sFIRLoggerOnceToken; - -// The sFIRAnalyticsDebugMode flag is here to support the -FIRDebugEnabled/-FIRDebugDisabled -// flags used by Analytics. Users who use those flags expect Analytics to log verbosely, -// while the rest of Firebase logs at the default level. This flag is introduced to support -// that behavior. -static BOOL sFIRAnalyticsDebugMode; - -#ifdef DEBUG -/// The regex pattern for the message code. -static NSString *const kMessageCodePattern = @"^I-[A-Z]{3}[0-9]{6}$"; -static NSRegularExpression *sMessageCodeRegex; -#endif - -void FIRLoggerInitializeASL() { - dispatch_once(&sFIRLoggerOnceToken, ^{ - // Register Firebase Version with GULLogger. - GULLoggerRegisterVersion(FIRVersionString); - - // Override the aslOptions to ASL_OPT_STDERR if the override argument is passed in. - NSArray *arguments = [NSProcessInfo processInfo].arguments; - BOOL overrideSTDERR = [arguments containsObject:kFIRLoggerForceSDTERRApplicationArgument]; - - // Use the standard NSUserDefaults if it hasn't been explicitly set. - if (sFIRLoggerUserDefaults == nil) { - sFIRLoggerUserDefaults = [NSUserDefaults standardUserDefaults]; - } - - BOOL forceDebugMode = NO; - BOOL debugMode = [sFIRLoggerUserDefaults boolForKey:kFIRPersistedDebugModeKey]; - if ([arguments containsObject:kFIRDisableDebugModeApplicationArgument]) { // Default mode - [sFIRLoggerUserDefaults removeObjectForKey:kFIRPersistedDebugModeKey]; - } else if ([arguments containsObject:kFIREnableDebugModeApplicationArgument] || - debugMode) { // Debug mode - [sFIRLoggerUserDefaults setBool:YES forKey:kFIRPersistedDebugModeKey]; - forceDebugMode = YES; - } - GULLoggerInitializeASL(); - if (overrideSTDERR) { - GULLoggerEnableSTDERR(); - } - if (forceDebugMode) { - GULLoggerForceDebug(); - } - }); -} - -__attribute__((no_sanitize("thread"))) void FIRSetAnalyticsDebugMode(BOOL analyticsDebugMode) { - sFIRAnalyticsDebugMode = analyticsDebugMode; -} - -void FIRSetLoggerLevel(FIRLoggerLevel loggerLevel) { - FIRLoggerInitializeASL(); - GULSetLoggerLevel((GULLoggerLevel)loggerLevel); -} - -/** - * Check if the level is high enough to be loggable. - * - * Analytics can override the log level with an intentional race condition. - * Add the attribute to get a clean thread sanitizer run. - */ -__attribute__((no_sanitize("thread"))) BOOL FIRIsLoggableLevel(FIRLoggerLevel loggerLevel, - BOOL analyticsComponent) { - FIRLoggerInitializeASL(); - if (sFIRAnalyticsDebugMode && analyticsComponent) { - return YES; - } - return GULIsLoggableLevel((GULLoggerLevel)loggerLevel); -} - -void FIRLogBasic(FIRLoggerLevel level, - FIRLoggerService service, - NSString *messageCode, - NSString *message, - va_list args_ptr) { - FIRLoggerInitializeASL(); - GULLogBasic((GULLoggerLevel)level, service, - sFIRAnalyticsDebugMode && [kFIRLoggerAnalytics isEqualToString:service], messageCode, - message, args_ptr); -} - -/** - * Generates the logging functions using macros. - * - * Calling FIRLogError(kFIRLoggerCore, @"I-COR000001", @"Configure %@ failed.", @"blah") shows: - * yyyy-mm-dd hh:mm:ss.SSS sender[PID] <Error> [Firebase/Core][I-COR000001] Configure blah failed. - * Calling FIRLogDebug(kFIRLoggerCore, @"I-COR000001", @"Configure succeed.") shows: - * yyyy-mm-dd hh:mm:ss.SSS sender[PID] <Debug> [Firebase/Core][I-COR000001] Configure succeed. - */ -#define FIR_LOGGING_FUNCTION(level) \ - void FIRLog##level(FIRLoggerService service, NSString *messageCode, NSString *message, ...) { \ - va_list args_ptr; \ - va_start(args_ptr, message); \ - FIRLogBasic(FIRLoggerLevel##level, service, messageCode, message, args_ptr); \ - va_end(args_ptr); \ - } - -FIR_LOGGING_FUNCTION(Error) -FIR_LOGGING_FUNCTION(Warning) -FIR_LOGGING_FUNCTION(Notice) -FIR_LOGGING_FUNCTION(Info) -FIR_LOGGING_FUNCTION(Debug) - -#undef FIR_MAKE_LOGGER - -#pragma mark - FIRLoggerWrapper - -@implementation FIRLoggerWrapper - -+ (void)logWithLevel:(FIRLoggerLevel)level - withService:(FIRLoggerService)service - withCode:(NSString *)messageCode - withMessage:(NSString *)message - withArgs:(va_list)args { - FIRLogBasic(level, service, messageCode, message, args); -} - -@end diff --git a/Pods/FirebaseCore/Firebase/Core/FIROptions.m b/Pods/FirebaseCore/Firebase/Core/FIROptions.m @@ -1,443 +0,0 @@ -// Copyright 2017 Google -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#import "Private/FIRAppInternal.h" -#import "Private/FIRBundleUtil.h" -#import "Private/FIRErrors.h" -#import "Private/FIRLogger.h" -#import "Private/FIROptionsInternal.h" - -// Keys for the strings in the plist file. -NSString *const kFIRAPIKey = @"API_KEY"; -NSString *const kFIRTrackingID = @"TRACKING_ID"; -NSString *const kFIRGoogleAppID = @"GOOGLE_APP_ID"; -NSString *const kFIRClientID = @"CLIENT_ID"; -NSString *const kFIRGCMSenderID = @"GCM_SENDER_ID"; -NSString *const kFIRAndroidClientID = @"ANDROID_CLIENT_ID"; -NSString *const kFIRDatabaseURL = @"DATABASE_URL"; -NSString *const kFIRStorageBucket = @"STORAGE_BUCKET"; -// The key to locate the expected bundle identifier in the plist file. -NSString *const kFIRBundleID = @"BUNDLE_ID"; -// The key to locate the project identifier in the plist file. -NSString *const kFIRProjectID = @"PROJECT_ID"; - -NSString *const kFIRIsMeasurementEnabled = @"IS_MEASUREMENT_ENABLED"; -NSString *const kFIRIsAnalyticsCollectionEnabled = @"FIREBASE_ANALYTICS_COLLECTION_ENABLED"; -NSString *const kFIRIsAnalyticsCollectionDeactivated = @"FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED"; - -NSString *const kFIRIsAnalyticsEnabled = @"IS_ANALYTICS_ENABLED"; -NSString *const kFIRIsSignInEnabled = @"IS_SIGNIN_ENABLED"; - -// Library version ID. -NSString *const kFIRLibraryVersionID = @"5" // Major version (one or more digits) - @"03" // Minor version (exactly 2 digits) - @"01" // Build number (exactly 2 digits) - @"000"; // Fixed "000" -// Plist file name. -NSString *const kServiceInfoFileName = @"GoogleService-Info"; -// Plist file type. -NSString *const kServiceInfoFileType = @"plist"; - -// Exception raised from attempting to modify a FIROptions after it's been copied to a FIRApp. -NSString *const kFIRExceptionBadModification = - @"Attempted to modify options after it's set on FIRApp. Please modify all properties before " - @"initializing FIRApp."; - -@interface FIROptions () - -/** - * This property maintains the actual configuration key-value pairs. - */ -@property(nonatomic, readwrite) NSMutableDictionary *optionsDictionary; - -/** - * Calls `analyticsOptionsDictionaryWithInfoDictionary:` using [NSBundle mainBundle].infoDictionary. - * It combines analytics options from both the infoDictionary and the GoogleService-Info.plist. - * Values which are present in the main plist override values from the GoogleService-Info.plist. - */ -@property(nonatomic, readonly) NSDictionary *analyticsOptionsDictionary; - -/** - * Combination of analytics options from both the infoDictionary and the GoogleService-Info.plist. - * Values which are present in the infoDictionary override values from the GoogleService-Info.plist. - */ -- (NSDictionary *)analyticsOptionsDictionaryWithInfoDictionary:(NSDictionary *)infoDictionary; - -/** - * Throw exception if editing is locked when attempting to modify an option. - */ -- (void)checkEditingLocked; - -@end - -@implementation FIROptions { - /// Backing variable for self.analyticsOptionsDictionary. - NSDictionary *_analyticsOptionsDictionary; -} - -static FIROptions *sDefaultOptions = nil; -static NSDictionary *sDefaultOptionsDictionary = nil; - -#pragma mark - Public only for internal class methods - -+ (FIROptions *)defaultOptions { - if (sDefaultOptions != nil) { - return sDefaultOptions; - } - - NSDictionary *defaultOptionsDictionary = [self defaultOptionsDictionary]; - if (defaultOptionsDictionary == nil) { - return nil; - } - - sDefaultOptions = [[FIROptions alloc] initInternalWithOptionsDictionary:defaultOptionsDictionary]; - return sDefaultOptions; -} - -#pragma mark - Private class methods - -+ (void)initialize { - // Report FirebaseCore version for useragent string - NSRange major = NSMakeRange(0, 1); - NSRange minor = NSMakeRange(1, 2); - NSRange patch = NSMakeRange(3, 2); - [FIRApp - registerLibrary:@"fire-ios" - withVersion:[NSString stringWithFormat:@"%@.%d.%d", - [kFIRLibraryVersionID substringWithRange:major], - [[kFIRLibraryVersionID substringWithRange:minor] - intValue], - [[kFIRLibraryVersionID substringWithRange:patch] - intValue]]]; - NSDictionary<NSString *, id> *info = [[NSBundle mainBundle] infoDictionary]; - NSString *xcodeVersion = info[@"DTXcodeBuild"]; - NSString *sdkVersion = info[@"DTSDKBuild"]; - if (xcodeVersion) { - [FIRApp registerLibrary:@"xcode" withVersion:xcodeVersion]; - } - if (sdkVersion) { - [FIRApp registerLibrary:@"apple-sdk" withVersion:sdkVersion]; - } -} - -+ (NSDictionary *)defaultOptionsDictionary { - if (sDefaultOptionsDictionary != nil) { - return sDefaultOptionsDictionary; - } - NSString *plistFilePath = [FIROptions plistFilePathWithName:kServiceInfoFileName]; - if (plistFilePath == nil) { - return nil; - } - sDefaultOptionsDictionary = [NSDictionary dictionaryWithContentsOfFile:plistFilePath]; - if (sDefaultOptionsDictionary == nil) { - FIRLogError(kFIRLoggerCore, @"I-COR000011", - @"The configuration file is not a dictionary: " - @"'%@.%@'.", - kServiceInfoFileName, kServiceInfoFileType); - } - return sDefaultOptionsDictionary; -} - -// Returns the path of the plist file with a given file name. -+ (NSString *)plistFilePathWithName:(NSString *)fileName { - NSArray *bundles = [FIRBundleUtil relevantBundles]; - NSString *plistFilePath = - [FIRBundleUtil optionsDictionaryPathWithResourceName:fileName - andFileType:kServiceInfoFileType - inBundles:bundles]; - if (plistFilePath == nil) { - FIRLogError(kFIRLoggerCore, @"I-COR000012", @"Could not locate configuration file: '%@.%@'.", - fileName, kServiceInfoFileType); - } - return plistFilePath; -} - -+ (void)resetDefaultOptions { - sDefaultOptions = nil; - sDefaultOptionsDictionary = nil; -} - -#pragma mark - Private instance methods - -- (instancetype)initInternalWithOptionsDictionary:(NSDictionary *)optionsDictionary { - self = [super init]; - if (self) { - _optionsDictionary = [optionsDictionary mutableCopy]; - _usingOptionsFromDefaultPlist = YES; - } - return self; -} - -- (id)copyWithZone:(NSZone *)zone { - FIROptions *newOptions = [[[self class] allocWithZone:zone] init]; - if (newOptions) { - newOptions.optionsDictionary = self.optionsDictionary; - newOptions.deepLinkURLScheme = self.deepLinkURLScheme; - newOptions.editingLocked = self.isEditingLocked; - newOptions.usingOptionsFromDefaultPlist = self.usingOptionsFromDefaultPlist; - } - return newOptions; -} - -#pragma mark - Public instance methods - -- (instancetype)initWithContentsOfFile:(NSString *)plistPath { - self = [super init]; - if (self) { - if (plistPath == nil) { - FIRLogError(kFIRLoggerCore, @"I-COR000013", @"The plist file path is nil."); - return nil; - } - _optionsDictionary = [[NSDictionary dictionaryWithContentsOfFile:plistPath] mutableCopy]; - if (_optionsDictionary == nil) { - FIRLogError(kFIRLoggerCore, @"I-COR000014", - @"The configuration file at %@ does not exist or " - @"is not a well-formed plist file.", - plistPath); - return nil; - } - // TODO: Do we want to validate the dictionary here? It says we do that already in - // the public header. - } - return self; -} - -- (instancetype)initWithGoogleAppID:(NSString *)googleAppID GCMSenderID:(NSString *)GCMSenderID { - self = [super init]; - if (self) { - NSMutableDictionary *mutableOptionsDict = [NSMutableDictionary dictionary]; - [mutableOptionsDict setValue:googleAppID forKey:kFIRGoogleAppID]; - [mutableOptionsDict setValue:GCMSenderID forKey:kFIRGCMSenderID]; - [mutableOptionsDict setValue:[[NSBundle mainBundle] bundleIdentifier] forKey:kFIRBundleID]; - self.optionsDictionary = mutableOptionsDict; - } - return self; -} - -- (NSString *)APIKey { - return self.optionsDictionary[kFIRAPIKey]; -} - -- (void)checkEditingLocked { - if (self.isEditingLocked) { - [NSException raise:kFirebaseCoreErrorDomain format:kFIRExceptionBadModification]; - } -} - -- (void)setAPIKey:(NSString *)APIKey { - [self checkEditingLocked]; - _optionsDictionary[kFIRAPIKey] = [APIKey copy]; -} - -- (NSString *)clientID { - return self.optionsDictionary[kFIRClientID]; -} - -- (void)setClientID:(NSString *)clientID { - [self checkEditingLocked]; - _optionsDictionary[kFIRClientID] = [clientID copy]; -} - -- (NSString *)trackingID { - return self.optionsDictionary[kFIRTrackingID]; -} - -- (void)setTrackingID:(NSString *)trackingID { - [self checkEditingLocked]; - _optionsDictionary[kFIRTrackingID] = [trackingID copy]; -} - -- (NSString *)GCMSenderID { - return self.optionsDictionary[kFIRGCMSenderID]; -} - -- (void)setGCMSenderID:(NSString *)GCMSenderID { - [self checkEditingLocked]; - _optionsDictionary[kFIRGCMSenderID] = [GCMSenderID copy]; -} - -- (NSString *)projectID { - return self.optionsDictionary[kFIRProjectID]; -} - -- (void)setProjectID:(NSString *)projectID { - [self checkEditingLocked]; - _optionsDictionary[kFIRProjectID] = [projectID copy]; -} - -- (NSString *)androidClientID { - return self.optionsDictionary[kFIRAndroidClientID]; -} - -- (void)setAndroidClientID:(NSString *)androidClientID { - [self checkEditingLocked]; - _optionsDictionary[kFIRAndroidClientID] = [androidClientID copy]; -} - -- (NSString *)googleAppID { - return self.optionsDictionary[kFIRGoogleAppID]; -} - -- (void)setGoogleAppID:(NSString *)googleAppID { - [self checkEditingLocked]; - _optionsDictionary[kFIRGoogleAppID] = [googleAppID copy]; -} - -- (NSString *)libraryVersionID { - return kFIRLibraryVersionID; -} - -- (void)setLibraryVersionID:(NSString *)libraryVersionID { - _optionsDictionary[kFIRLibraryVersionID] = [libraryVersionID copy]; -} - -- (NSString *)databaseURL { - return self.optionsDictionary[kFIRDatabaseURL]; -} - -- (void)setDatabaseURL:(NSString *)databaseURL { - [self checkEditingLocked]; - - _optionsDictionary[kFIRDatabaseURL] = [databaseURL copy]; -} - -- (NSString *)storageBucket { - return self.optionsDictionary[kFIRStorageBucket]; -} - -- (void)setStorageBucket:(NSString *)storageBucket { - [self checkEditingLocked]; - _optionsDictionary[kFIRStorageBucket] = [storageBucket copy]; -} - -- (void)setDeepLinkURLScheme:(NSString *)deepLinkURLScheme { - [self checkEditingLocked]; - _deepLinkURLScheme = [deepLinkURLScheme copy]; -} - -- (NSString *)bundleID { - return self.optionsDictionary[kFIRBundleID]; -} - -- (void)setBundleID:(NSString *)bundleID { - [self checkEditingLocked]; - _optionsDictionary[kFIRBundleID] = [bundleID copy]; -} - -#pragma mark - Internal instance methods - -- (NSDictionary *)analyticsOptionsDictionaryWithInfoDictionary:(NSDictionary *)infoDictionary { - if (_analyticsOptionsDictionary == nil) { - NSMutableDictionary *tempAnalyticsOptions = [[NSMutableDictionary alloc] init]; - NSArray *measurementKeys = @[ - kFIRIsMeasurementEnabled, kFIRIsAnalyticsCollectionEnabled, - kFIRIsAnalyticsCollectionDeactivated - ]; - for (NSString *key in measurementKeys) { - id value = infoDictionary[key] ?: self.optionsDictionary[key] ?: nil; - if (!value) { - continue; - } - tempAnalyticsOptions[key] = value; - } - _analyticsOptionsDictionary = tempAnalyticsOptions; - } - return _analyticsOptionsDictionary; -} - -- (NSDictionary *)analyticsOptionsDictionary { - return [self analyticsOptionsDictionaryWithInfoDictionary:[NSBundle mainBundle].infoDictionary]; -} - -/** - * Whether or not Measurement was enabled. Measurement is enabled unless explicitly disabled in - * GoogleService-Info.plist. This uses the old plist flag IS_MEASUREMENT_ENABLED, which should still - * be supported. - */ -- (BOOL)isMeasurementEnabled { - if (self.isAnalyticsCollectionDeactivated) { - return NO; - } - NSNumber *value = self.analyticsOptionsDictionary[kFIRIsMeasurementEnabled]; - if (value == nil) { - // TODO: This could probably be cleaned up since FIROptions shouldn't know about FIRApp or have - // to check if it's the default app. The FIROptions instance can't be modified after - // `+configure` is called, so it's not a good place to copy it either in case the flag is - // changed at runtime. - - // If no values are set for Analytics, fall back to the global collection switch in FIRApp. - // Analytics only supports the default FIRApp, so check that first. - if (![FIRApp isDefaultAppConfigured]) { - return NO; - } - - // Fall back to the default app's collection switch when the key is not in the dictionary. - return [FIRApp defaultApp].isDataCollectionDefaultEnabled; - } - return [value boolValue]; -} - -- (BOOL)isAnalyticsCollectionExpicitlySet { - // If it's de-activated, it classifies as explicity set. If not, it's not a good enough indication - // that the developer wants FirebaseAnalytics enabled so continue checking. - if (self.isAnalyticsCollectionDeactivated) { - return YES; - } - - // Check if the current Analytics flag is set. - id collectionEnabledObject = self.analyticsOptionsDictionary[kFIRIsAnalyticsCollectionEnabled]; - if (collectionEnabledObject && [collectionEnabledObject isKindOfClass:[NSNumber class]]) { - // It doesn't matter what the value is, it's explicitly set. - return YES; - } - - // Check if the old measurement flag is set. - id measurementEnabledObject = self.analyticsOptionsDictionary[kFIRIsMeasurementEnabled]; - if (measurementEnabledObject && [measurementEnabledObject isKindOfClass:[NSNumber class]]) { - // It doesn't matter what the value is, it's explicitly set. - return YES; - } - - // No flags are set to explicitly enable or disable FirebaseAnalytics. - return NO; -} - -- (BOOL)isAnalyticsCollectionEnabled { - if (self.isAnalyticsCollectionDeactivated) { - return NO; - } - NSNumber *value = self.analyticsOptionsDictionary[kFIRIsAnalyticsCollectionEnabled]; - if (value == nil) { - return self.isMeasurementEnabled; // Fall back to older plist flag. - } - return [value boolValue]; -} - -- (BOOL)isAnalyticsCollectionDeactivated { - NSNumber *value = self.analyticsOptionsDictionary[kFIRIsAnalyticsCollectionDeactivated]; - if (value == nil) { - return NO; // Analytics Collection is not deactivated when the key is not in the dictionary. - } - return [value boolValue]; -} - -- (BOOL)isAnalyticsEnabled { - return [self.optionsDictionary[kFIRIsAnalyticsEnabled] boolValue]; -} - -- (BOOL)isSignInEnabled { - return [self.optionsDictionary[kFIRIsSignInEnabled] boolValue]; -} - -@end diff --git a/Pods/FirebaseCore/Firebase/Core/FIRVersion.m b/Pods/FirebaseCore/Firebase/Core/FIRVersion.m @@ -1,33 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef Firebase_VERSION -#error "Firebase_VERSION is not defined: add -DFirebase_VERSION=... to the build invocation" -#endif - -#ifndef FIRCore_VERSION -#error "FIRCore_VERSION is not defined: add -DFIRCore_VERSION=... to the build invocation" -#endif - -// The following two macros supply the incantation so that the C -// preprocessor does not try to parse the version as a floating -// point number. See -// https://www.guyrutenberg.com/2008/12/20/expanding-macros-into-string-constants-in-c/ -#define STR(x) STR_EXPAND(x) -#define STR_EXPAND(x) #x - -const char *const FIRVersionString = (const char *const)STR(Firebase_VERSION); -const char *const FIRCoreVersionString = (const char *const)STR(FIRCore_VERSION); diff --git a/Pods/FirebaseCore/Firebase/Core/Private/FIRAnalyticsConfiguration+Internal.h b/Pods/FirebaseCore/Firebase/Core/Private/FIRAnalyticsConfiguration+Internal.h @@ -1,49 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRAnalyticsConfiguration.h" - -/// Values stored in analyticsEnabledState. Never alter these constants since they must match with -/// values persisted to disk. -typedef NS_ENUM(int64_t, FIRAnalyticsEnabledState) { - // 0 is the default value for keys not found stored in persisted config, so it cannot represent - // kFIRAnalyticsEnabledStateSetNo. It must represent kFIRAnalyticsEnabledStateNotSet. - kFIRAnalyticsEnabledStateNotSet = 0, - kFIRAnalyticsEnabledStateSetYes = 1, - kFIRAnalyticsEnabledStateSetNo = 2, -}; - -/// The user defaults key for the persisted measurementEnabledState value. FIRAPersistedConfig reads -/// measurementEnabledState using this same key. -static NSString *const kFIRAPersistedConfigMeasurementEnabledStateKey = - @"/google/measurement/measurement_enabled_state"; - -static NSString *const kFIRAnalyticsConfigurationSetEnabledNotification = - @"FIRAnalyticsConfigurationSetEnabledNotification"; -static NSString *const kFIRAnalyticsConfigurationSetMinimumSessionIntervalNotification = - @"FIRAnalyticsConfigurationSetMinimumSessionIntervalNotification"; -static NSString *const kFIRAnalyticsConfigurationSetSessionTimeoutIntervalNotification = - @"FIRAnalyticsConfigurationSetSessionTimeoutIntervalNotification"; - -@interface FIRAnalyticsConfiguration (Internal) - -/// Sets whether analytics collection is enabled for this app on this device, and a flag to persist -/// the value or not. The setting should not be persisted if being set by the global data collection -/// flag. -- (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled - persistSetting:(BOOL)shouldPersist; - -@end diff --git a/Pods/FirebaseCore/Firebase/Core/Private/FIRAppAssociationRegistration.h b/Pods/FirebaseCore/Firebase/Core/Private/FIRAppAssociationRegistration.h @@ -1,49 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -NS_ASSUME_NONNULL_BEGIN - -// TODO: Remove this once Auth moves over to Core's instance registration system. -/** @class FIRAppAssociationRegistration - @brief Manages object associations as a singleton-dependent: At most one object is - registered for any given host/key pair, and the object shall be created on-the-fly when - asked for. - */ -@interface FIRAppAssociationRegistration<ObjectType> : NSObject - -/** @fn registeredObjectWithHost:key:creationBlock: - @brief Retrieves the registered object with a particular host and key. - @param host The host object. - @param key The key to specify the registered object on the host. - @param creationBlock The block to return the object to be registered if not already. - The block is executed immediately before this method returns if it is executed at all. - It can also be executed multiple times across different method invocations if previous - execution of the block returns @c nil. - @return The registered object for the host/key pair, or @c nil if no object is registered - and @c creationBlock returns @c nil. - @remarks The method is thread-safe but non-reentrant in the sense that attempting to call this - method again within the @c creationBlock with the same host/key pair raises an exception. - The registered object is retained by the host. - */ -+ (nullable ObjectType)registeredObjectWithHost:(id)host - key:(NSString *)key - creationBlock:(ObjectType _Nullable (^)(void))creationBlock; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/Firebase/Core/Private/FIRAppInternal.h b/Pods/FirebaseCore/Firebase/Core/Private/FIRAppInternal.h @@ -1,182 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRApp.h" -#import "FIRErrors.h" - -@class FIRComponentContainer; -@protocol FIRLibrary; - -/** - * The internal interface to FIRApp. This is meant for first-party integrators, who need to receive - * FIRApp notifications, log info about the success or failure of their configuration, and access - * other internal functionality of FIRApp. - * - * TODO(b/28296561): Restructure this header. - */ -NS_ASSUME_NONNULL_BEGIN - -typedef NS_ENUM(NSInteger, FIRConfigType) { - FIRConfigTypeCore = 1, - FIRConfigTypeSDK = 2, -}; - -/** - * Names of services provided by Firebase. - */ -extern NSString *const kFIRServiceAdMob; -extern NSString *const kFIRServiceAuth; -extern NSString *const kFIRServiceAuthUI; -extern NSString *const kFIRServiceCrash; -extern NSString *const kFIRServiceDatabase; -extern NSString *const kFIRServiceDynamicLinks; -extern NSString *const kFIRServiceInstanceID; -extern NSString *const kFIRServiceInvites; -extern NSString *const kFIRServiceMessaging; -extern NSString *const kFIRServiceMeasurement; -extern NSString *const kFIRServiceRemoteConfig; -extern NSString *const kFIRServiceStorage; - -/** - * Names of services provided by the Google pod, but logged by the Firebase pod. - */ -extern NSString *const kGGLServiceAnalytics; -extern NSString *const kGGLServiceSignIn; - -extern NSString *const kFIRDefaultAppName; -extern NSString *const kFIRAppReadyToConfigureSDKNotification; -extern NSString *const kFIRAppDeleteNotification; -extern NSString *const kFIRAppIsDefaultAppKey; -extern NSString *const kFIRAppNameKey; -extern NSString *const kFIRGoogleAppIDKey; - -/** - * The format string for the User Defaults key used for storing the data collection enabled flag. - * This includes formatting to append the Firebase App's name. - */ -extern NSString *const kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat; - -/** - * The plist key used for storing the data collection enabled flag. - */ -extern NSString *const kFIRGlobalAppDataCollectionEnabledPlistKey; - -/** - * A notification fired containing diagnostic information when SDK errors occur. - */ -extern NSString *const kFIRAppDiagnosticsNotification; - -/** @var FIRAuthStateDidChangeInternalNotification - @brief The name of the @c NSNotificationCenter notification which is posted when the auth state - changes (e.g. a new token has been produced, a user logs in or out). The object parameter of - the notification is a dictionary possibly containing the key: - @c FIRAuthStateDidChangeInternalNotificationTokenKey (the new access token.) If it does not - contain this key it indicates a sign-out event took place. - */ -extern NSString *const FIRAuthStateDidChangeInternalNotification; - -/** @var FIRAuthStateDidChangeInternalNotificationTokenKey - @brief A key present in the dictionary object parameter of the - @c FIRAuthStateDidChangeInternalNotification notification. The value associated with this - key will contain the new access token. - */ -extern NSString *const FIRAuthStateDidChangeInternalNotificationTokenKey; - -/** @var FIRAuthStateDidChangeInternalNotificationAppKey - @brief A key present in the dictionary object parameter of the - @c FIRAuthStateDidChangeInternalNotification notification. The value associated with this - key will contain the FIRApp associated with the auth instance. - */ -extern NSString *const FIRAuthStateDidChangeInternalNotificationAppKey; - -/** @var FIRAuthStateDidChangeInternalNotificationUIDKey - @brief A key present in the dictionary object parameter of the - @c FIRAuthStateDidChangeInternalNotification notification. The value associated with this - key will contain the new user's UID (or nil if there is no longer a user signed in). - */ -extern NSString *const FIRAuthStateDidChangeInternalNotificationUIDKey; - -@interface FIRApp () - -/** - * A flag indicating if this is the default app (has the default app name). - */ -@property(nonatomic, readonly) BOOL isDefaultApp; - -/* - * The container of interop SDKs for this app. - */ -@property(nonatomic) FIRComponentContainer *container; - -/** - * Creates an error for failing to configure a subspec service. This method is called by each - * FIRApp notification listener. - */ -+ (NSError *)errorForSubspecConfigurationFailureWithDomain:(NSString *)domain - errorCode:(FIRErrorCode)code - service:(NSString *)service - reason:(NSString *)reason; -/** - * Checks if the default app is configured without trying to configure it. - */ -+ (BOOL)isDefaultAppConfigured; - -/** - * Registers a given third-party library with the given version number to be reported for - * analytics. - * - * @param name Name of the library. - * @param version Version of the library. - */ -+ (void)registerLibrary:(nonnull NSString *)name withVersion:(nonnull NSString *)version; - -/** - * Registers a given internal library with the given version number to be reported for - * analytics. - * - * @param library Optional parameter for component registration. - * @param name Name of the library. - * @param version Version of the library. - */ -+ (void)registerInternalLibrary:(nonnull Class<FIRLibrary>)library - withName:(nonnull NSString *)name - withVersion:(nonnull NSString *)version; - -/** - * A concatenated string representing all the third-party libraries and version numbers. - */ -+ (NSString *)firebaseUserAgent; - -/** - * Used by each SDK to send logs about SDK configuration status to Clearcut. - */ -- (void)sendLogsWithServiceName:(NSString *)serviceName - version:(NSString *)version - error:(NSError *)error; - -/** - * Can be used by the unit tests in eack SDK to reset FIRApp. This method is thread unsafe. - */ -+ (void)resetApps; - -/** - * Can be used by the unit tests in each SDK to set customized options. - */ -- (instancetype)initInstanceWithName:(NSString *)name options:(FIROptions *)options; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/Firebase/Core/Private/FIRBundleUtil.h b/Pods/FirebaseCore/Firebase/Core/Private/FIRBundleUtil.h @@ -1,52 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -/** - * This class provides utilities for accessing resources in bundles. - */ -@interface FIRBundleUtil : NSObject - -/** - * Finds all relevant bundles, starting with [NSBundle mainBundle]. - */ -+ (NSArray *)relevantBundles; - -/** - * Reads the options dictionary from one of the provided bundles. - * - * @param resourceName The resource name, e.g. @"GoogleService-Info". - * @param fileType The file type (extension), e.g. @"plist". - * @param bundles The bundles to expect, in priority order. See also - * +[FIRBundleUtil relevantBundles]. - */ -+ (NSString *)optionsDictionaryPathWithResourceName:(NSString *)resourceName - andFileType:(NSString *)fileType - inBundles:(NSArray *)bundles; - -/** - * Finds URL schemes defined in all relevant bundles, starting with those from - * [NSBundle mainBundle]. - */ -+ (NSArray *)relevantURLSchemes; - -/** - * Checks if the bundle identifier exists in the given bundles. - */ -+ (BOOL)hasBundleIdentifier:(NSString *)bundleIdentifier inBundles:(NSArray *)bundles; - -@end diff --git a/Pods/FirebaseCore/Firebase/Core/Private/FIRComponent.h b/Pods/FirebaseCore/Firebase/Core/Private/FIRComponent.h @@ -1,91 +0,0 @@ -/* - * Copyright 2018 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -@class FIRApp; -@class FIRComponentContainer; - -NS_ASSUME_NONNULL_BEGIN - -/// Provides a system to clean up cached instances returned from the component system. -NS_SWIFT_NAME(ComponentLifecycleMaintainer) -@protocol FIRComponentLifecycleMaintainer -/// The associated app will be deleted, clean up any resources as they are about to be deallocated. -- (void)appWillBeDeleted:(FIRApp *)app; -@end - -typedef _Nullable id (^FIRComponentCreationBlock)(FIRComponentContainer *container, - BOOL *isCacheable) - NS_SWIFT_NAME(ComponentCreationBlock); - -@class FIRDependency; - -/// Describes the timing of instantiation. Note: new components should default to lazy unless there -/// is a strong reason to be eager. -typedef NS_ENUM(NSInteger, FIRInstantiationTiming) { - FIRInstantiationTimingLazy, - FIRInstantiationTimingAlwaysEager, - FIRInstantiationTimingEagerInDefaultApp -} NS_SWIFT_NAME(InstantiationTiming); - -/// A component that can be used from other Firebase SDKs. -NS_SWIFT_NAME(Component) -@interface FIRComponent : NSObject - -/// The protocol describing functionality provided from the Component. -@property(nonatomic, strong, readonly) Protocol *protocol; - -/// The timing of instantiation. -@property(nonatomic, readonly) FIRInstantiationTiming instantiationTiming; - -/// An array of dependencies for the component. -@property(nonatomic, copy, readonly) NSArray<FIRDependency *> *dependencies; - -/// A block to instantiate an instance of the component with the appropriate dependencies. -@property(nonatomic, copy, readonly) FIRComponentCreationBlock creationBlock; - -// There's an issue with long NS_SWIFT_NAMES that causes compilation to fail, disable clang-format -// for the next two methods. -// clang-format off - -/// Creates a component with no dependencies that will be lazily initialized. -+ (instancetype)componentWithProtocol:(Protocol *)protocol - creationBlock:(FIRComponentCreationBlock)creationBlock -NS_SWIFT_NAME(init(_:creationBlock:)); - -/// Creates a component to be registered with the component container. -/// -/// @param protocol - The protocol describing functionality provided by the component. -/// @param instantiationTiming - When the component should be initialized. Use .lazy unless there's -/// a good reason to be instantiated earlier. -/// @param dependencies - Any dependencies the `implementingClass` has, optional or required. -/// @param creationBlock - A block to instantiate the component with a container, and if -/// @return A component that can be registered with the component container. -+ (instancetype)componentWithProtocol:(Protocol *)protocol - instantiationTiming:(FIRInstantiationTiming)instantiationTiming - dependencies:(NSArray<FIRDependency *> *)dependencies - creationBlock:(FIRComponentCreationBlock)creationBlock -NS_SWIFT_NAME(init(_:instantiationTiming:dependencies:creationBlock:)); - -// clang-format on - -/// Unavailable. -- (instancetype)init NS_UNAVAILABLE; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentContainer.h b/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentContainer.h @@ -1,44 +0,0 @@ -/* - * Copyright 2018 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#import <Foundation/Foundation.h> - -#import "FIRComponentType.h" -#import "FIRLibrary.h" - -NS_ASSUME_NONNULL_BEGIN - -/// A type-safe macro to retrieve a component from a container. This should be used to retrieve -/// components instead of using the container directly. -#define FIR_COMPONENT(type, container) \ - [FIRComponentType<id<type>> instanceForProtocol:@protocol(type) inContainer:container] - -@class FIRApp; - -/// A container that holds different components that are registered via the -/// `registerAsComponentRegistrant:` call. These classes should conform to `FIRComponentRegistrant` -/// in order to properly register components for Core. -NS_SWIFT_NAME(FirebaseComponentContainer) -@interface FIRComponentContainer : NSObject - -/// A weak reference to the app that an instance of the container belongs to. -@property(nonatomic, weak, readonly) FIRApp *app; - -/// Unavailable. Use the `container` property on `FIRApp`. -- (instancetype)init NS_UNAVAILABLE; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentContainerInternal.h b/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentContainerInternal.h @@ -1,43 +0,0 @@ -/* - * Copyright 2018 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#import <Foundation/Foundation.h> - -#import "FIRComponent.h" -#import "FIRComponentContainer.h" - -@class FIRApp; - -NS_ASSUME_NONNULL_BEGIN - -@interface FIRComponentContainer (Private) - -/// Initializes a contain for a given app. This should only be called by the app itself. -- (instancetype)initWithApp:(FIRApp *)app; - -/// Retrieves an instance that conforms to the specified protocol. This will return `nil` if the -/// protocol wasn't registered, or if the instance couldn't instantiate for the provided app. -- (nullable id)instanceForProtocol:(Protocol *)protocol NS_SWIFT_NAME(instance(for:)); - -/// Remove all of the cached instances stored and allow them to clean up after themselves. -- (void)removeAllCachedInstances; - -/// Register a class to provide components for the interoperability system. The class should conform -/// to `FIRComponentRegistrant` and provide an array of `FIRComponent` objects. -+ (void)registerAsComponentRegistrant:(Class<FIRLibrary>)klass; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentType.h b/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentType.h @@ -1,34 +0,0 @@ -/* - * Copyright 2018 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -@class FIRComponentContainer; - -NS_ASSUME_NONNULL_BEGIN - -/// Do not use directly. A placeholder type in order to provide a macro that will warn users of -/// mis-matched protocols. -NS_SWIFT_NAME(ComponentType) -@interface FIRComponentType<__covariant T> : NSObject - -/// Do not use directly. A factory method to retrieve an instance that provides a specific -/// functionality. -+ (T)instanceForProtocol:(Protocol *)protocol inContainer:(FIRComponentContainer *)container; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/Firebase/Core/Private/FIRDependency.h b/Pods/FirebaseCore/Firebase/Core/Private/FIRDependency.h @@ -1,45 +0,0 @@ -/* - * Copyright 2018 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -NS_ASSUME_NONNULL_BEGIN - -/// A dependency on a specific protocol's functionality. -NS_SWIFT_NAME(Dependency) -@interface FIRDependency : NSObject - -/// The protocol describing functionality being depended on. -@property(nonatomic, strong, readonly) Protocol *protocol; - -/// A flag to specify if the dependency is required or not. -@property(nonatomic, readonly) BOOL isRequired; - -/// Initializes a dependency that is required. Calls `initWithProtocol:isRequired` with `YES` for -/// the required parameter. -/// Creates a required dependency on the specified protocol's functionality. -+ (instancetype)dependencyWithProtocol:(Protocol *)protocol; - -/// Creates a dependency on the specified protocol's functionality and specify if it's required for -/// the class's functionality. -+ (instancetype)dependencyWithProtocol:(Protocol *)protocol isRequired:(BOOL)required; - -/// Use `dependencyWithProtocol:isRequired:` instead. -- (instancetype)init NS_UNAVAILABLE; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/Firebase/Core/Private/FIRErrorCode.h b/Pods/FirebaseCore/Firebase/Core/Private/FIRErrorCode.h @@ -1,55 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** Error codes in Firebase error domain. */ -typedef NS_ENUM(NSInteger, FIRErrorCode) { - /** - * Unknown error. - */ - FIRErrorCodeUnknown = 0, - /** - * Loading data from the GoogleService-Info.plist file failed. This is a fatal error and should - * not be ignored. Further calls to the API will fail and/or possibly cause crashes. - */ - FIRErrorCodeInvalidPlistFile = -100, - - /** - * Validating the Google App ID format failed. - */ - FIRErrorCodeInvalidAppID = -101, - - /** - * Error code for failing to configure a specific service. - */ - FIRErrorCodeAdMobFailed = -110, - FIRErrorCodeAppInviteFailed = -112, - FIRErrorCodeCloudMessagingFailed = -113, - FIRErrorCodeConfigFailed = -114, - FIRErrorCodeDatabaseFailed = -115, - FIRErrorCodeCrashReportingFailed = -118, - FIRErrorCodeDurableDeepLinkFailed = -119, - FIRErrorCodeAuthFailed = -120, - FIRErrorCodeInstanceIDFailed = -121, - FIRErrorCodeStorageFailed = -123, - - /** - * Error codes returned by Dynamic Links - */ - FIRErrorCodeDynamicLinksStrongMatchNotAvailable = -124, - FIRErrorCodeDynamicLinksManualRetrievalNotEnabled = -125, - FIRErrorCodeDynamicLinksPendingLinkOnlyAvailableAtFirstLaunch = -126, - FIRErrorCodeDynamicLinksPendingLinkRetrievalAlreadyRunning = -127, -}; diff --git a/Pods/FirebaseCore/Firebase/Core/Private/FIRErrors.h b/Pods/FirebaseCore/Firebase/Core/Private/FIRErrors.h @@ -1,33 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -#include "FIRErrorCode.h" - -extern NSString *const kFirebaseErrorDomain; -extern NSString *const kFirebaseAdMobErrorDomain; -extern NSString *const kFirebaseAppInviteErrorDomain; -extern NSString *const kFirebaseAuthErrorDomain; -extern NSString *const kFirebaseCloudMessagingErrorDomain; -extern NSString *const kFirebaseConfigErrorDomain; -extern NSString *const kFirebaseCoreErrorDomain; -extern NSString *const kFirebaseCrashReportingErrorDomain; -extern NSString *const kFirebaseDatabaseErrorDomain; -extern NSString *const kFirebaseDurableDeepLinkErrorDomain; -extern NSString *const kFirebaseInstanceIDErrorDomain; -extern NSString *const kFirebasePerfErrorDomain; -extern NSString *const kFirebaseStorageErrorDomain; diff --git a/Pods/FirebaseCore/Firebase/Core/Private/FIRLibrary.h b/Pods/FirebaseCore/Firebase/Core/Private/FIRLibrary.h @@ -1,44 +0,0 @@ -/* - * Copyright 2018 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FIRLibrary_h -#define FIRLibrary_h - -#import <Foundation/Foundation.h> -#import "FIRComponent.h" - -@class FIRApp; - -NS_ASSUME_NONNULL_BEGIN - -/// Provide an interface to register a library for userAgent logging and availability to others. -NS_SWIFT_NAME(Library) -@protocol FIRLibrary - -/// Returns one or more FIRComponents that will be registered in -/// FIRApp and participate in dependency resolution and injection. -+ (NSArray<FIRComponent *> *)componentsToRegister; - -@optional -/// Implement this method if the library needs notifications for lifecycle events. This method is -/// called when the developer calls `FirebaseApp.configure()`. -+ (void)configureWithApp:(FIRApp *)app; - -@end - -NS_ASSUME_NONNULL_END - -#endif /* FIRLibrary_h */ diff --git a/Pods/FirebaseCore/Firebase/Core/Private/FIRLogger.h b/Pods/FirebaseCore/Firebase/Core/Private/FIRLogger.h @@ -1,159 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -#import "FIRLoggerLevel.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - * The Firebase services used in Firebase logger. - */ -typedef NSString *const FIRLoggerService; - -extern FIRLoggerService kFIRLoggerABTesting; -extern FIRLoggerService kFIRLoggerAdMob; -extern FIRLoggerService kFIRLoggerAnalytics; -extern FIRLoggerService kFIRLoggerAuth; -extern FIRLoggerService kFIRLoggerCore; -extern FIRLoggerService kFIRLoggerCrash; -extern FIRLoggerService kFIRLoggerDatabase; -extern FIRLoggerService kFIRLoggerDynamicLinks; -extern FIRLoggerService kFIRLoggerFirestore; -extern FIRLoggerService kFIRLoggerInstanceID; -extern FIRLoggerService kFIRLoggerInvites; -extern FIRLoggerService kFIRLoggerMLKit; -extern FIRLoggerService kFIRLoggerMessaging; -extern FIRLoggerService kFIRLoggerPerf; -extern FIRLoggerService kFIRLoggerRemoteConfig; -extern FIRLoggerService kFIRLoggerStorage; -extern FIRLoggerService kFIRLoggerSwizzler; - -/** - * The key used to store the logger's error count. - */ -extern NSString *const kFIRLoggerErrorCountKey; - -/** - * The key used to store the logger's warning count. - */ -extern NSString *const kFIRLoggerWarningCountKey; - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -/** - * Enables or disables Analytics debug mode. - * If set to YES, the logging level for Analytics will be set to FIRLoggerLevelDebug. - * Enabling the debug mode has no effect if the app is running from App Store. - * (required) analytics debug mode flag. - */ -void FIRSetAnalyticsDebugMode(BOOL analyticsDebugMode); - -/** - * Changes the default logging level of FIRLoggerLevelNotice to a user-specified level. - * The default level cannot be set above FIRLoggerLevelNotice if the app is running from App Store. - * (required) log level (one of the FIRLoggerLevel enum values). - */ -void FIRSetLoggerLevel(FIRLoggerLevel loggerLevel); - -/** - * Checks if the specified logger level is loggable given the current settings. - * (required) log level (one of the FIRLoggerLevel enum values). - * (required) whether or not this function is called from the Analytics component. - */ -BOOL FIRIsLoggableLevel(FIRLoggerLevel loggerLevel, BOOL analyticsComponent); - -/** - * Logs a message to the Xcode console and the device log. If running from AppStore, will - * not log any messages with a level higher than FIRLoggerLevelNotice to avoid log spamming. - * (required) log level (one of the FIRLoggerLevel enum values). - * (required) service name of type FIRLoggerService. - * (required) message code starting with "I-" which means iOS, followed by a capitalized - * three-character service identifier and a six digit integer message ID that is unique - * within the service. - * An example of the message code is @"I-COR000001". - * (required) message string which can be a format string. - * (optional) variable arguments list obtained from calling va_start, used when message is a format - * string. - */ -extern void FIRLogBasic(FIRLoggerLevel level, - FIRLoggerService service, - NSString *messageCode, - NSString *message, -// On 64-bit simulators, va_list is not a pointer, so cannot be marked nullable -// See: http://stackoverflow.com/q/29095469 -#if __LP64__ && TARGET_OS_SIMULATOR || TARGET_OS_OSX - va_list args_ptr -#else - va_list _Nullable args_ptr -#endif -); - -/** - * The following functions accept the following parameters in order: - * (required) service name of type FIRLoggerService. - * (required) message code starting from "I-" which means iOS, followed by a capitalized - * three-character service identifier and a six digit integer message ID that is unique - * within the service. - * An example of the message code is @"I-COR000001". - * See go/firebase-log-proposal for details. - * (required) message string which can be a format string. - * (optional) the list of arguments to substitute into the format string. - * Example usage: - * FIRLogError(kFIRLoggerCore, @"I-COR000001", @"Configuration of %@ failed.", app.name); - */ -extern void FIRLogError(FIRLoggerService service, NSString *messageCode, NSString *message, ...) - NS_FORMAT_FUNCTION(3, 4); -extern void FIRLogWarning(FIRLoggerService service, NSString *messageCode, NSString *message, ...) - NS_FORMAT_FUNCTION(3, 4); -extern void FIRLogNotice(FIRLoggerService service, NSString *messageCode, NSString *message, ...) - NS_FORMAT_FUNCTION(3, 4); -extern void FIRLogInfo(FIRLoggerService service, NSString *messageCode, NSString *message, ...) - NS_FORMAT_FUNCTION(3, 4); -extern void FIRLogDebug(FIRLoggerService service, NSString *messageCode, NSString *message, ...) - NS_FORMAT_FUNCTION(3, 4); - -#ifdef __cplusplus -} // extern "C" -#endif // __cplusplus - -@interface FIRLoggerWrapper : NSObject - -/** - * Objective-C wrapper for FIRLogBasic to allow weak linking to FIRLogger - * (required) log level (one of the FIRLoggerLevel enum values). - * (required) service name of type FIRLoggerService. - * (required) message code starting with "I-" which means iOS, followed by a capitalized - * three-character service identifier and a six digit integer message ID that is unique - * within the service. - * An example of the message code is @"I-COR000001". - * (required) message string which can be a format string. - * (optional) variable arguments list obtained from calling va_start, used when message is a format - * string. - */ - -+ (void)logWithLevel:(FIRLoggerLevel)level - withService:(FIRLoggerService)service - withCode:(NSString *)messageCode - withMessage:(NSString *)message - withArgs:(va_list)args; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/Firebase/Core/Private/FIROptionsInternal.h b/Pods/FirebaseCore/Firebase/Core/Private/FIROptionsInternal.h @@ -1,114 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIROptions.h" - -/** - * Keys for the strings in the plist file. - */ -extern NSString *const kFIRAPIKey; -extern NSString *const kFIRTrackingID; -extern NSString *const kFIRGoogleAppID; -extern NSString *const kFIRClientID; -extern NSString *const kFIRGCMSenderID; -extern NSString *const kFIRAndroidClientID; -extern NSString *const kFIRDatabaseURL; -extern NSString *const kFIRStorageBucket; -extern NSString *const kFIRBundleID; -extern NSString *const kFIRProjectID; - -/** - * Keys for the plist file name - */ -extern NSString *const kServiceInfoFileName; - -extern NSString *const kServiceInfoFileType; - -/** - * This header file exposes the initialization of FIROptions to internal use. - */ -@interface FIROptions () - -/** - * resetDefaultOptions and initInternalWithOptionsDictionary: are exposed only for unit tests. - */ -+ (void)resetDefaultOptions; - -/** - * Initializes the options with dictionary. The above strings are the keys of the dictionary. - * This is the designated initializer. - */ -- (instancetype)initInternalWithOptionsDictionary:(NSDictionary *)serviceInfoDictionary; - -/** - * defaultOptions and defaultOptionsDictionary are exposed in order to be used in FIRApp and - * other first party services. - */ -+ (FIROptions *)defaultOptions; - -+ (NSDictionary *)defaultOptionsDictionary; - -/** - * Indicates whether or not Analytics collection was explicitly enabled via a plist flag or at - * runtime. - */ -@property(nonatomic, readonly) BOOL isAnalyticsCollectionExpicitlySet; - -/** - * Whether or not Analytics Collection was enabled. Analytics Collection is enabled unless - * explicitly disabled in GoogleService-Info.plist. - */ -@property(nonatomic, readonly) BOOL isAnalyticsCollectionEnabled; - -/** - * Whether or not Analytics Collection was completely disabled. If YES, then - * isAnalyticsCollectionEnabled will be NO. - */ -@property(nonatomic, readonly) BOOL isAnalyticsCollectionDeactivated; - -/** - * The version ID of the client library, e.g. @"1100000". - */ -@property(nonatomic, readonly, copy) NSString *libraryVersionID; - -/** - * The flag indicating whether this object was constructed with the values in the default plist - * file. - */ -@property(nonatomic) BOOL usingOptionsFromDefaultPlist; - -/** - * Whether or not Measurement was enabled. Measurement is enabled unless explicitly disabled in - * GoogleService-Info.plist. - */ -@property(nonatomic, readonly) BOOL isMeasurementEnabled; - -/** - * Whether or not Analytics was enabled in the developer console. - */ -@property(nonatomic, readonly) BOOL isAnalyticsEnabled; - -/** - * Whether or not SignIn was enabled in the developer console. - */ -@property(nonatomic, readonly) BOOL isSignInEnabled; - -/** - * Whether or not editing is locked. This should occur after FIROptions has been set on a FIRApp. - */ -@property(nonatomic, getter=isEditingLocked) BOOL editingLocked; - -@end diff --git a/Pods/FirebaseCore/Firebase/Core/Private/FIRVersion.h b/Pods/FirebaseCore/Firebase/Core/Private/FIRVersion.h @@ -1,23 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -/** The version of the Firebase SDK. */ -FOUNDATION_EXPORT const char *const FIRVersionString; - -/** The version of the FirebaseCore Component. */ -FOUNDATION_EXPORT const char *const FIRCoreVersionString; diff --git a/Pods/FirebaseCore/Firebase/Core/Public/FIRAnalyticsConfiguration.h b/Pods/FirebaseCore/Firebase/Core/Public/FIRAnalyticsConfiguration.h @@ -1,55 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -NS_ASSUME_NONNULL_BEGIN - -/** - * This class provides configuration fields for Firebase Analytics. - */ -NS_SWIFT_NAME(AnalyticsConfiguration) -@interface FIRAnalyticsConfiguration : NSObject - -/** - * Returns the shared instance of FIRAnalyticsConfiguration. - */ -+ (FIRAnalyticsConfiguration *)sharedInstance NS_SWIFT_NAME(shared()); - -/** - * Deprecated. - * Sets the minimum engagement time in seconds required to start a new session. The default value - * is 10 seconds. - */ -- (void)setMinimumSessionInterval:(NSTimeInterval)minimumSessionInterval - DEPRECATED_MSG_ATTRIBUTE( - "Sessions are started immediately. More information at https://bit.ly/2FU46av"); - -/** - * Sets the interval of inactivity in seconds that terminates the current session. The default - * value is 1800 seconds (30 minutes). - */ -- (void)setSessionTimeoutInterval:(NSTimeInterval)sessionTimeoutInterval; - -/** - * Sets whether analytics collection is enabled for this app on this device. This setting is - * persisted across app sessions. By default it is enabled. - */ -- (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/Firebase/Core/Public/FIRApp.h b/Pods/FirebaseCore/Firebase/Core/Public/FIRApp.h @@ -1,127 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -@class FIROptions; - -NS_ASSUME_NONNULL_BEGIN - -/** A block that takes a BOOL and has no return value. */ -typedef void (^FIRAppVoidBoolCallback)(BOOL success) NS_SWIFT_NAME(FirebaseAppVoidBoolCallback); - -/** - * The entry point of Firebase SDKs. - * - * Initialize and configure FIRApp using +[FIRApp configure] - * or other customized ways as shown below. - * - * The logging system has two modes: default mode and debug mode. In default mode, only logs with - * log level Notice, Warning and Error will be sent to device. In debug mode, all logs will be sent - * to device. The log levels that Firebase uses are consistent with the ASL log levels. - * - * Enable debug mode by passing the -FIRDebugEnabled argument to the application. You can add this - * argument in the application's Xcode scheme. When debug mode is enabled via -FIRDebugEnabled, - * further executions of the application will also be in debug mode. In order to return to default - * mode, you must explicitly disable the debug mode with the application argument -FIRDebugDisabled. - * - * It is also possible to change the default logging level in code by calling setLoggerLevel: on - * the FIRConfiguration interface. - */ -NS_SWIFT_NAME(FirebaseApp) -@interface FIRApp : NSObject - -/** - * Configures a default Firebase app. Raises an exception if any configuration step fails. The - * default app is named "__FIRAPP_DEFAULT". This method should be called after the app is launched - * and before using Firebase services. This method is thread safe and contains synchronous file I/O - * (reading GoogleService-Info.plist from disk). - */ -+ (void)configure; - -/** - * Configures the default Firebase app with the provided options. The default app is named - * "__FIRAPP_DEFAULT". Raises an exception if any configuration step fails. This method is thread - * safe. - * - * @param options The Firebase application options used to configure the service. - */ -+ (void)configureWithOptions:(FIROptions *)options NS_SWIFT_NAME(configure(options:)); - -/** - * Configures a Firebase app with the given name and options. Raises an exception if any - * configuration step fails. This method is thread safe. - * - * @param name The application's name given by the developer. The name should should only contain - Letters, Numbers and Underscore. - * @param options The Firebase application options used to configure the services. - */ -// clang-format off -+ (void)configureWithName:(NSString *)name - options:(FIROptions *)options NS_SWIFT_NAME(configure(name:options:)); -// clang-format on - -/** - * Returns the default app, or nil if the default app does not exist. - */ -+ (nullable FIRApp *)defaultApp NS_SWIFT_NAME(app()); - -/** - * Returns a previously created FIRApp instance with the given name, or nil if no such app exists. - * This method is thread safe. - */ -+ (nullable FIRApp *)appNamed:(NSString *)name NS_SWIFT_NAME(app(name:)); - -/** - * Returns the set of all extant FIRApp instances, or nil if there are no FIRApp instances. This - * method is thread safe. - */ -@property(class, readonly, nullable) NSDictionary<NSString *, FIRApp *> *allApps; - -/** - * Cleans up the current FIRApp, freeing associated data and returning its name to the pool for - * future use. This method is thread safe. - */ -- (void)deleteApp:(FIRAppVoidBoolCallback)completion; - -/** - * FIRApp instances should not be initialized directly. Call +[FIRApp configure], - * +[FIRApp configureWithOptions:], or +[FIRApp configureWithNames:options:] directly. - */ -- (instancetype)init NS_UNAVAILABLE; - -/** - * Gets the name of this app. - */ -@property(nonatomic, copy, readonly) NSString *name; - -/** - * Gets a copy of the options for this app. These are non-modifiable. - */ -@property(nonatomic, copy, readonly) FIROptions *options; - -/** - * Gets or sets whether automatic data collection is enabled for all products. Defaults to `YES` - * unless `FirebaseDataCollectionDefaultEnabled` is set to `NO` in your app's Info.plist. This value - * is persisted across runs of the app so that it can be set once when users have consented to - * collection. - */ -@property(nonatomic, readwrite, getter=isDataCollectionDefaultEnabled) - BOOL dataCollectionDefaultEnabled; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/Firebase/Core/Public/FIRConfiguration.h b/Pods/FirebaseCore/Firebase/Core/Public/FIRConfiguration.h @@ -1,50 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -#import "FIRAnalyticsConfiguration.h" -#import "FIRLoggerLevel.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - * This interface provides global level properties that the developer can tweak, and the singleton - * of the Firebase Analytics configuration class. - */ -NS_SWIFT_NAME(FirebaseConfiguration) -@interface FIRConfiguration : NSObject - -/** Returns the shared configuration object. */ -@property(class, nonatomic, readonly) FIRConfiguration *sharedInstance NS_SWIFT_NAME(shared); - -/** The configuration class for Firebase Analytics. */ -@property(nonatomic, readwrite) FIRAnalyticsConfiguration *analyticsConfiguration; - -/** - * Sets the logging level for internal Firebase logging. Firebase will only log messages - * that are logged at or below loggerLevel. The messages are logged both to the Xcode - * console and to the device's log. Note that if an app is running from AppStore, it will - * never log above FIRLoggerLevelNotice even if loggerLevel is set to a higher (more verbose) - * setting. - * - * @param loggerLevel The maximum logging level. The default level is set to FIRLoggerLevelNotice. - */ -- (void)setLoggerLevel:(FIRLoggerLevel)loggerLevel; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/Firebase/Core/Public/FIRLoggerLevel.h b/Pods/FirebaseCore/Firebase/Core/Public/FIRLoggerLevel.h @@ -1,38 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// Note that importing GULLoggerLevel.h will lead to a non-modular header -// import error. - -/** - * The log levels used by internal logging. - */ -typedef NS_ENUM(NSInteger, FIRLoggerLevel) { - /** Error level, matches ASL_LEVEL_ERR. */ - FIRLoggerLevelError = 3, - /** Warning level, matches ASL_LEVEL_WARNING. */ - FIRLoggerLevelWarning = 4, - /** Notice level, matches ASL_LEVEL_NOTICE. */ - FIRLoggerLevelNotice = 5, - /** Info level, matches ASL_LEVEL_INFO. */ - FIRLoggerLevelInfo = 6, - /** Debug level, matches ASL_LEVEL_DEBUG. */ - FIRLoggerLevelDebug = 7, - /** Minimum log level. */ - FIRLoggerLevelMin = FIRLoggerLevelError, - /** Maximum log level. */ - FIRLoggerLevelMax = FIRLoggerLevelDebug -} NS_SWIFT_NAME(FirebaseLoggerLevel); diff --git a/Pods/FirebaseCore/Firebase/Core/Public/FIROptions.h b/Pods/FirebaseCore/Firebase/Core/Public/FIROptions.h @@ -1,116 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -NS_ASSUME_NONNULL_BEGIN - -/** - * This class provides constant fields of Google APIs. - */ -NS_SWIFT_NAME(FirebaseOptions) -@interface FIROptions : NSObject <NSCopying> - -/** - * Returns the default options. The first time this is called it synchronously reads - * GoogleService-Info.plist from disk. - */ -+ (nullable FIROptions *)defaultOptions NS_SWIFT_NAME(defaultOptions()); - -/** - * An iOS API key used for authenticating requests from your app, e.g. - * @"AIzaSyDdVgKwhZl0sTTTLZ7iTmt1r3N2cJLnaDk", used to identify your app to Google servers. - */ -@property(nonatomic, copy, nullable) NSString *APIKey NS_SWIFT_NAME(apiKey); - -/** - * The bundle ID for the application. Defaults to `[[NSBundle mainBundle] bundleID]` when not set - * manually or in a plist. - */ -@property(nonatomic, copy) NSString *bundleID; - -/** - * The OAuth2 client ID for iOS application used to authenticate Google users, for example - * @"12345.apps.googleusercontent.com", used for signing in with Google. - */ -@property(nonatomic, copy, nullable) NSString *clientID; - -/** - * The tracking ID for Google Analytics, e.g. @"UA-12345678-1", used to configure Google Analytics. - */ -@property(nonatomic, copy, nullable) NSString *trackingID; - -/** - * The Project Number from the Google Developer's console, for example @"012345678901", used to - * configure Google Cloud Messaging. - */ -@property(nonatomic, copy) NSString *GCMSenderID NS_SWIFT_NAME(gcmSenderID); - -/** - * The Project ID from the Firebase console, for example @"abc-xyz-123". - */ -@property(nonatomic, copy, nullable) NSString *projectID; - -/** - * The Android client ID used in Google AppInvite when an iOS app has its Android version, for - * example @"12345.apps.googleusercontent.com". - */ -@property(nonatomic, copy, nullable) NSString *androidClientID; - -/** - * The Google App ID that is used to uniquely identify an instance of an app. - */ -@property(nonatomic, copy) NSString *googleAppID; - -/** - * The database root URL, e.g. @"http://abc-xyz-123.firebaseio.com". - */ -@property(nonatomic, copy, nullable) NSString *databaseURL; - -/** - * The URL scheme used to set up Durable Deep Link service. - */ -@property(nonatomic, copy, nullable) NSString *deepLinkURLScheme; - -/** - * The Google Cloud Storage bucket name, e.g. @"abc-xyz-123.storage.firebase.com". - */ -@property(nonatomic, copy, nullable) NSString *storageBucket; - -/** - * Initializes a customized instance of FIROptions from the file at the given plist file path. This - * will read the file synchronously from disk. - * For example, - * NSString *filePath = - * [[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist"]; - * FIROptions *options = [[FIROptions alloc] initWithContentsOfFile:filePath]; - * Returns nil if the plist file does not exist or is invalid. - */ -- (nullable instancetype)initWithContentsOfFile:(NSString *)plistPath; - -/** - * Initializes a customized instance of FIROptions with required fields. Use the mutable properties - * to modify fields for configuring specific services. - */ -// clang-format off -- (instancetype)initWithGoogleAppID:(NSString *)googleAppID - GCMSenderID:(NSString *)GCMSenderID - NS_SWIFT_NAME(init(googleAppID:gcmSenderID:)); -// clang-format on - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/Firebase/Core/Public/FirebaseCore.h b/Pods/FirebaseCore/Firebase/Core/Public/FirebaseCore.h @@ -1,21 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRAnalyticsConfiguration.h" -#import "FIRApp.h" -#import "FIRConfiguration.h" -#import "FIRLoggerLevel.h" -#import "FIROptions.h" diff --git a/Pods/FirebaseCore/LICENSE b/Pods/FirebaseCore/LICENSE @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Pods/FirebaseCore/README.md b/Pods/FirebaseCore/README.md @@ -1,197 +0,0 @@ -# Firebase iOS Open Source Development [![Build Status](https://travis-ci.org/firebase/firebase-ios-sdk.svg?branch=master)](https://travis-ci.org/firebase/firebase-ios-sdk) - -This repository contains a subset of the Firebase iOS SDK source. It currently -includes FirebaseCore, FirebaseAuth, FirebaseDatabase, FirebaseFirestore, -FirebaseFunctions, FirebaseInstanceID, FirebaseInAppMessaging, -FirebaseInAppMessagingDisplay, FirebaseMessaging and FirebaseStorage. - -The repository also includes GoogleUtilities source. The -[GoogleUtilities](GoogleUtilities/README.md) pod is -a set of utilities used by Firebase and other Google products. - -Firebase is an app development platform with tools to help you build, grow and -monetize your app. More information about Firebase can be found at -[https://firebase.google.com](https://firebase.google.com). - -## Installation - -See the three subsections for details about three different installation methods. -1. [Standard pod install](README.md#standard-pod-install) -1. [Installing from the GitHub repo](README.md#installing-from-github) -1. [Experimental Carthage](README.md#carthage-ios-only) - -### Standard pod install - -Go to -[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup). - -### Installing from GitHub - -For releases starting with 5.0.0, the source for each release is also deployed -to CocoaPods master and available via standard -[CocoaPods Podfile syntax](https://guides.cocoapods.org/syntax/podfile.html#pod). - -These instructions can be used to access the Firebase repo at other branches, -tags, or commits. - -#### Background - -See -[the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod) -for instructions and options about overriding pod source locations. - -#### Accessing Firebase Source Snapshots - -All of the official releases are tagged in this repo and available via CocoaPods. To access a local -source snapshot or unreleased branch, use Podfile directives like the following: - -To access FirebaseFirestore via a branch: -``` -pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' -pod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' -``` - -To access FirebaseMessaging via a checked out version of the firebase-ios-sdk repo do: - -``` -pod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk' -pod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk' -``` - -### Carthage (iOS only) - -Instructions for the experimental Carthage distribution are at -[Carthage](Carthage.md). - -### Rome - -Instructions for installing binary frameworks via -[Rome](https://github.com/CocoaPods/Rome) are at [Rome](Rome.md). - -## Development - -Follow the subsequent instructions to develop, debug, unit test, run integration -tests, and try out reference samples: - -``` -$ git clone git@github.com:firebase/firebase-ios-sdk.git -$ cd firebase-ios-sdk/Example -$ pod update -$ open Firebase.xcworkspace -``` - -Firestore and Functions have self contained Xcode projects. See -[Firestore/README.md](Firestore/README.md) and -[Functions/README.md](Functions/README.md). - -### Code Formatting - -To ensure that the code is formatted consistently, run the script -[./scripts/style.sh](https://github.com/firebase/firebase-ios-sdk/blob/master/scripts/style.sh) -before creating a PR. - -Travis will verify that any code changes are done in a style compliant way. Install -`clang-format` and `swiftformat`. -This command will get the right `clang-format` version: - -`brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/773cb75d360b58f32048f5964038d09825a507c8/Formula/clang-format.rb` - -### Running Unit Tests - -Select a scheme and press Command-u to build a component and run its unit tests. - -### Running Sample Apps -In order to run the sample apps and integration tests, you'll need valid -`GoogleService-Info.plist` files for those samples. The Firebase Xcode project contains dummy plist -files without real values, but can be replaced with real plist files. To get your own -`GoogleService-Info.plist` files: - -1. Go to the [Firebase Console](https://console.firebase.google.com/) -2. Create a new Firebase project, if you don't already have one -3. For each sample app you want to test, create a new Firebase app with the sample app's bundle -identifier (e.g. `com.google.Database-Example`) -4. Download the resulting `GoogleService-Info.plist` and replace the appropriate dummy plist file -(e.g. in [Example/Database/App/](Example/Database/App/)); - -Some sample apps like Firebase Messaging ([Example/Messaging/App](Example/Messaging/App)) require -special Apple capabilities, and you will have to change the sample app to use a unique bundle -identifier that you can control in your own Apple Developer account. - -## Specific Component Instructions -See the sections below for any special instructions for those components. - -### Firebase Auth - -If you're doing specific Firebase Auth development, see -[the Auth Sample README](Example/Auth/README.md) for instructions about -building and running the FirebaseAuth pod along with various samples and tests. - -### Firebase Database - -To run the Database Integration tests, make your database authentication rules -[public](https://firebase.google.com/docs/database/security/quickstart). - -### Firebase Storage - -To run the Storage Integration tests, follow the instructions in -[FIRStorageIntegrationTests.m](Example/Storage/Tests/Integration/FIRStorageIntegrationTests.m). - -#### Push Notifications - -Push notifications can only be delivered to specially provisioned App IDs in the developer portal. -In order to actually test receiving push notifications, you will need to: - -1. Change the bundle identifier of the sample app to something you own in your Apple Developer -account, and enable that App ID for push notifications. -2. You'll also need to -[upload your APNs Provider Authentication Key or certificate to the Firebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs) -at **Project Settings > Cloud Messaging > [Your Firebase App]**. -3. Ensure your iOS device is added to your Apple Developer portal as a test device. - -#### iOS Simulator - -The iOS Simulator cannot register for remote notifications, and will not receive push notifications. -In order to receive push notifications, you'll have to follow the steps above and run the app on a -physical device. - -## Community Supported Efforts - -We've seen an amazing amount of interest and contributions to improve the Firebase SDKs, and we are -very grateful! We'd like to empower as many developers as we can to be able to use Firebase and -participate in the Firebase community. - -### macOS and tvOS -FirebaseAuth, FirebaseCore, FirebaseDatabase and FirebaseStorage now compile, run unit tests, and -work on macOS and tvOS, thanks to contributions from the community. There are a few tweaks needed, -like ensuring iOS-only, macOS-only, or tvOS-only code is correctly guarded with checks for -`TARGET_OS_IOS`, `TARGET_OS_OSX` and `TARGET_OS_TV`. - -For tvOS, checkout the [Sample](Example/tvOSSample). - -Keep in mind that macOS and tvOS are not officially supported by Firebase, and this repository is -actively developed primarily for iOS. While we can catch basic unit test issues with Travis, there -may be some changes where the SDK no longer works as expected on macOS or tvOS. If you encounter -this, please [file an issue](https://github.com/firebase/firebase-ios-sdk/issues). - -For installation instructions, see [above](README.md#accessing-firebase-source-snapshots). - -Note that the Firebase pod is not available for macOS and tvOS. Install a selection of the -`FirebaseAuth`, `FirebaseCore`, `FirebaseDatabase` and `FirebaseStorage` CocoaPods. - -## Roadmap - -See [Roadmap](ROADMAP.md) for more about the Firebase iOS SDK Open Source -plans and directions. - -## Contributing - -See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase -iOS SDK. - -## License - -The contents of this repository is licensed under the -[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). - -Your use of Firebase is governed by the -[Terms of Service for Firebase Services](https://firebase.google.com/terms/). diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRIMessageCode.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRIMessageCode.h @@ -1,155 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -// The format of the debug code will show in the log as: e.g. -// for code 1000, it will show as I-IID001000. -typedef NS_ENUM(NSInteger, FIRInstanceIDMessageCode) { - // DO NOT USE 2000, 2002. - kFIRInstanceIDMessageCodeFIRApp000 = 1000, // I-IID001000 - kFIRInstanceIDMessageCodeFIRApp001 = 1001, - kFIRInstanceIDMessageCodeFIRApp002 = 1002, - kFIRInstanceIDMessageCodeInternal001 = 2001, - kFIRInstanceIDMessageCodeInternal002 = 2002, - // FIRInstanceID.m - // DO NOT USE 4000. - kFIRInstanceIDMessageCodeInstanceID000 = 3000, - kFIRInstanceIDMessageCodeInstanceID001 = 3001, - kFIRInstanceIDMessageCodeInstanceID002 = 3002, - kFIRInstanceIDMessageCodeInstanceID003 = 3003, - kFIRInstanceIDMessageCodeInstanceID004 = 3004, - kFIRInstanceIDMessageCodeInstanceID005 = 3005, - kFIRInstanceIDMessageCodeInstanceID006 = 3006, - kFIRInstanceIDMessageCodeInstanceID007 = 3007, - kFIRInstanceIDMessageCodeInstanceID008 = 3008, - kFIRInstanceIDMessageCodeInstanceID009 = 3009, - kFIRInstanceIDMessageCodeInstanceID010 = 3010, - kFIRInstanceIDMessageCodeInstanceID011 = 3011, - kFIRInstanceIDMessageCodeInstanceID012 = 3012, - kFIRInstanceIDMessageCodeInstanceID013 = 3013, - kFIRInstanceIDMessageCodeInstanceID014 = 3014, - kFIRInstanceIDMessageCodeInstanceID015 = 3015, - kFIRInstanceIDMessageCodeRefetchingTokenForAPNS = 3016, - // FIRInstanceIDAuthService.m - kFIRInstanceIDMessageCodeAuthService000 = 5000, - kFIRInstanceIDMessageCodeAuthService001 = 5001, - kFIRInstanceIDMessageCodeAuthService002 = 5002, - kFIRInstanceIDMessageCodeAuthService003 = 5003, - kFIRInstanceIDMessageCodeAuthService004 = 5004, - kFIRInstanceIDMessageCodeAuthServiceCheckinInProgress = 5004, - - // FIRInstanceIDBackupExcludedPlist.m - kFIRInstanceIDMessageCodeBackupExcludedPlist000 = 6000, - kFIRInstanceIDMessageCodeBackupExcludedPlist001 = 6001, - kFIRInstanceIDMessageCodeBackupExcludedPlist002 = 6002, - kFIRInstanceIDMessageCodeBackupExcludedPlistInvalidPlistEnum = 6003, - // FIRInstanceIDCheckinService.m - kFIRInstanceIDMessageCodeService000 = 7000, - kFIRInstanceIDMessageCodeService001 = 7001, - kFIRInstanceIDMessageCodeService002 = 7002, - kFIRInstanceIDMessageCodeService003 = 7003, - kFIRInstanceIDMessageCodeService004 = 7004, - kFIRInstanceIDMessageCodeService005 = 7005, - kFIRInstanceIDMessageCodeService006 = 7006, - // FIRInstanceIDCheckinStore.m - // DO NOT USE 8002, 8004 - 8008 - kFIRInstanceIDMessageCodeCheckinStore000 = 8000, - kFIRInstanceIDMessageCodeCheckinStore001 = 8001, - kFIRInstanceIDMessageCodeCheckinStore003 = 8003, - // FIRInstanceIDKeyPair.m - // DO NOT USE 9001, 9003 - kFIRInstanceIDMessageCodeKeyPair000 = 9000, - kFIRInstanceIDMessageCodeKeyPair002 = 9002, - kFIRInstanceIDMessageCodeKeyPairMigrationError = 9004, - kFIRInstanceIDMessageCodeKeyPairMigrationSuccess = 9005, - // FIRInstanceIDKeyPairStore.m - kFIRInstanceIDMessageCodeKeyPairStore000 = 10000, - kFIRInstanceIDMessageCodeKeyPairStore001 = 10001, - kFIRInstanceIDMessageCodeKeyPairStore002 = 10002, - kFIRInstanceIDMessageCodeKeyPairStore003 = 10003, - kFIRInstanceIDMessageCodeKeyPairStore004 = 10004, - kFIRInstanceIDMessageCodeKeyPairStore005 = 10005, - kFIRInstanceIDMessageCodeKeyPairStore006 = 10006, - kFIRInstanceIDMessageCodeKeyPairStore007 = 10007, - kFIRInstanceIDMessageCodeKeyPairStore008 = 10008, - kFIRInstanceIDMessageCodeKeyPairStoreCouldNotLoadKeyPair = 10009, - // FIRInstanceIDKeyPairUtilities.m - kFIRInstanceIDMessageCodeKeyPairUtilities000 = 11000, - kFIRInstanceIDMessageCodeKeyPairUtilities001 = 11001, - kFIRInstanceIDMessageCodeKeyPairUtilitiesFirstConcatenateParamNil = 11002, - - // DO NOT USE 12000 - 12014 - - // FIRInstanceIDStore.m - // DO NOT USE 13004, 13005, 13007, 13008, 13010, 13011, 13013, 13014 - kFIRInstanceIDMessageCodeStore000 = 13000, - kFIRInstanceIDMessageCodeStore001 = 13001, - kFIRInstanceIDMessageCodeStore002 = 13002, - kFIRInstanceIDMessageCodeStore003 = 13003, - kFIRInstanceIDMessageCodeStore006 = 13006, - kFIRInstanceIDMessageCodeStore009 = 13009, - kFIRInstanceIDMessageCodeStore012 = 13012, - // FIRInstanceIDTokenManager.m - // DO NOT USE 14002, 14005 - kFIRInstanceIDMessageCodeTokenManager000 = 14000, - kFIRInstanceIDMessageCodeTokenManager001 = 14001, - kFIRInstanceIDMessageCodeTokenManager003 = 14003, - kFIRInstanceIDMessageCodeTokenManager004 = 14004, - kFIRInstanceIDMessageCodeTokenManagerErrorDeletingFCMTokensOnAppReset = 14006, - kFIRInstanceIDMessageCodeTokenManagerDeletedFCMTokensOnAppReset = 14007, - kFIRInstanceIDMessageCodeTokenManagerSavedAppVersion = 14008, - kFIRInstanceIDMessageCodeTokenManagerErrorInvalidatingAllTokens = 14009, - kFIRInstanceIDMessageCodeTokenManagerAPNSChanged = 14010, - kFIRInstanceIDMessageCodeTokenManagerAPNSChangedTokenInvalidated = 14011, - kFIRInstanceIDMessageCodeTokenManagerInvalidateStaleToken = 14012, - // FIRInstanceIDTokenStore.m - // DO NOT USE 15002 - 15013 - kFIRInstanceIDMessageCodeTokenStore000 = 15000, - kFIRInstanceIDMessageCodeTokenStore001 = 15001, - kFIRInstanceIDMessageCodeTokenStoreExceptionUnarchivingTokenInfo = 15015, - - // DO NOT USE 16000, 18004 - - // FIRInstanceIDUtilities.m - kFIRInstanceIDMessageCodeUtilitiesMissingBundleIdentifier = 18000, - kFIRInstanceIDMessageCodeUtilitiesAppEnvironmentUtilNotAvailable = 18001, - kFIRInstanceIDMessageCodeUtilitiesCannotGetHardwareModel = 18002, - kFIRInstanceIDMessageCodeUtilitiesCannotGetSystemVersion = 18003, - // FIRInstanceIDTokenOperation.m - kFIRInstanceIDMessageCodeTokenOperationFailedToSignParams = 19000, - // FIRInstanceIDTokenFetchOperation.m - // DO NOT USE 20004, 20005 - kFIRInstanceIDMessageCodeTokenFetchOperationFetchRequest = 20000, - kFIRInstanceIDMessageCodeTokenFetchOperationRequestError = 20001, - kFIRInstanceIDMessageCodeTokenFetchOperationBadResponse = 20002, - kFIRInstanceIDMessageCodeTokenFetchOperationBadTokenStructure = 20003, - // FIRInstanceIDTokenDeleteOperation.m - kFIRInstanceIDMessageCodeTokenDeleteOperationFetchRequest = 21000, - kFIRInstanceIDMessageCodeTokenDeleteOperationRequestError = 21001, - kFIRInstanceIDMessageCodeTokenDeleteOperationBadResponse = 21002, - // FIRInstanceIDTokenInfo.m - kFIRInstanceIDMessageCodeTokenInfoBadAPNSInfo = 22000, - kFIRInstanceIDMessageCodeTokenInfoFirebaseAppIDChanged = 22001, - kFIRInstanceIDMessageCodeTokenInfoLocaleChanged = 22002, - // FIRInstanceIDKeychain.m - kFIRInstanceIDKeychainReadItemError = 23000, - kFIRInstanceIDKeychainAddItemError = 23001, - kFIRInstanceIDKeychainDeleteItemError = 23002, - kFIRInstanceIDKeychainCreateKeyPairError = 23003, - kFIRInstanceIDKeychainUpdateItemError = 23004, - -}; diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID+Private.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID+Private.h @@ -1,55 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceID.h" - -#import "FIRInstanceIDCheckinService.h" - -/** - * Internal API used by other Firebase SDK teams, including Messaging, Analytics and Remote config. - */ -@interface FIRInstanceID (Private) - -/** - * Return the cached checkin preferences on the disk. This is used internally only by Messaging. - * - * @return The cached checkin preferences on the client. - */ -- (nullable FIRInstanceIDCheckinPreferences *)cachedCheckinPreferences; - -/** - * Fetches checkin info for the app. If the app has valid cached checkin preferences - * they are returned instead of making a network request. - * - * @param handler The completion handler to invoke once the request has completed. - */ -- (void)fetchCheckinInfoWithHandler:(nullable FIRInstanceIDDeviceCheckinCompletion)handler; - -/** - * Get the InstanceID for the app. If an ID was created before and cached - * successfully we will return that ID. If no cached ID exists we create - * a new ID, cache it and return that. - * - * This is a blocking call and should not really be called on the main thread. - * - * @param error The error object that represents the error while trying to - * retrieve the instance id. - * - * @return The InstanceID for the app. - */ -- (nullable NSString *)appInstanceID:(NSError *_Nullable *_Nullable)error; - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID+Private.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID+Private.m @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceID+Private.h" - -#import "FIRInstanceIDAuthService.h" -#import "FIRInstanceIDKeyPairStore.h" -#import "FIRInstanceIDTokenManager.h" - -@interface FIRInstanceID () - -@property(nonatomic, readonly, strong) FIRInstanceIDTokenManager *tokenManager; -@property(nonatomic, readonly, strong) FIRInstanceIDKeyPairStore *keyPairStore; - -@end - -@implementation FIRInstanceID (Private) - -- (FIRInstanceIDCheckinPreferences *)cachedCheckinPreferences { - return [self.tokenManager.authService checkinPreferences]; -} - -// This method just wraps our pre-configured auth service to make the request. -// This method is only needed by first-party users, like Remote Config. -- (void)fetchCheckinInfoWithHandler:(FIRInstanceIDDeviceCheckinCompletion)handler { - [self.tokenManager.authService fetchCheckinInfoWithHandler:handler]; -} - -- (NSString *)appInstanceID:(NSError **)error { - return [self.keyPairStore appIdentityWithError:error]; -} - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID+Testing.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID+Testing.h @@ -1,48 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceID+Private.h" -#import "FIRInstanceID.h" -#import "FIRInstanceIDKeyPairStore.h" -#import "FIRInstanceIDTokenManager.h" - -@interface FIRInstanceID (Testing) - -@property(nonatomic, readwrite, strong) FIRInstanceIDTokenManager *tokenManager; -@property(nonatomic, readwrite, strong) FIRInstanceIDKeyPairStore *keyPairStore; -@property(nonatomic, readwrite, copy) NSString *fcmSenderID; - -/** - * Private initializer. - */ -- (instancetype)initPrivately; - -/** - * Actually makes InstanceID instantiate both the IID and Token-related subsystems. - */ -- (void)start; - -/** - * Without checking any caches etc, always attempts to fetch the default token (unless a fetch - * is already in progress. - */ -- (void)fetchDefaultToken; - -+ (int64_t)maxRetryCountForDefaultToken; -+ (int64_t)minIntervalForDefaultTokenRetry; -+ (int64_t)maxRetryIntervalForDefaultTokenInSeconds; - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID.m @@ -1,1217 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceID.h" - -#import <FirebaseCore/FIRAppInternal.h> -#import <FirebaseCore/FIRComponent.h> -#import <FirebaseCore/FIRComponentContainer.h> -#import <FirebaseCore/FIRLibrary.h> -#import <FirebaseCore/FIROptions.h> -#import <GoogleUtilities/GULAppEnvironmentUtil.h> -#import "FIRInstanceID+Private.h" -#import "FIRInstanceIDAuthService.h" -#import "FIRInstanceIDConstants.h" -#import "FIRInstanceIDDefines.h" -#import "FIRInstanceIDKeyPairStore.h" -#import "FIRInstanceIDLogger.h" -#import "FIRInstanceIDStore.h" -#import "FIRInstanceIDTokenInfo.h" -#import "FIRInstanceIDTokenManager.h" -#import "FIRInstanceIDUtilities.h" -#import "FIRInstanceIDVersionUtilities.h" -#import "NSError+FIRInstanceID.h" - -// Public constants -NSString *const kFIRInstanceIDScopeFirebaseMessaging = @"fcm"; - -#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 -const NSNotificationName kFIRInstanceIDTokenRefreshNotification = - @"com.firebase.iid.notif.refresh-token"; -#else -NSString *const kFIRInstanceIDTokenRefreshNotification = @"com.firebase.iid.notif.refresh-token"; -#endif // defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 - -NSString *const kFIRInstanceIDInvalidNilHandlerError = @"Invalid nil handler."; - -// Private constants -int64_t const kMaxRetryIntervalForDefaultTokenInSeconds = 20 * 60; // 20 minutes -int64_t const kMinRetryIntervalForDefaultTokenInSeconds = 10; // 10 seconds -// we retry only a max 5 times. -// TODO(chliangGoogle): If we still fail we should listen for the network change notification -// since GCM would have started Reachability. We only start retrying after we see a configuration -// change. -NSInteger const kMaxRetryCountForDefaultToken = 5; - -static NSString *const kEntitlementsAPSEnvironmentKey = @"Entitlements.aps-environment"; -static NSString *const kAPSEnvironmentDevelopmentValue = @"development"; -/// FIRMessaging selector that returns the current FIRMessaging auto init -/// enabled flag. -static NSString *const kFIRInstanceIDFCMSelectorAutoInitEnabled = @"isAutoInitEnabled"; -static NSString *const kFIRInstanceIDFCMSelectorInstance = @"messaging"; - -static NSString *const kFIRInstanceIDAPNSTokenType = @"APNSTokenType"; -static NSString *const kFIRIIDAppReadyToConfigureSDKNotification = - @"FIRAppReadyToConfigureSDKNotification"; -static NSString *const kFIRIIDAppNameKey = @"FIRAppNameKey"; -static NSString *const kFIRIIDErrorDomain = @"com.firebase.instanceid"; -static NSString *const kFIRIIDServiceInstanceID = @"InstanceID"; - -// This should be the same value as FIRErrorCodeInstanceIDFailed, which we can't import directly -static NSInteger const kFIRIIDErrorCodeInstanceIDFailed = -121; - -typedef void (^FIRInstanceIDKeyPairHandler)(FIRInstanceIDKeyPair *keyPair, NSError *error); - -/** - * The APNS token type for the app. If the token type is set to `UNKNOWN` - * InstanceID will implicitly try to figure out what the actual token type - * is from the provisioning profile. - * This must match FIRMessagingAPNSTokenType in FIRMessaging.h - */ -typedef NS_ENUM(NSInteger, FIRInstanceIDAPNSTokenType) { - /// Unknown token type. - FIRInstanceIDAPNSTokenTypeUnknown, - /// Sandbox token type. - FIRInstanceIDAPNSTokenTypeSandbox, - /// Production token type. - FIRInstanceIDAPNSTokenTypeProd, -} NS_SWIFT_NAME(InstanceIDAPNSTokenType); - -@interface FIRInstanceIDResult () -@property(nonatomic, readwrite, copy) NSString *instanceID; -@property(nonatomic, readwrite, copy) NSString *token; -@end - -@interface FIRInstanceID () - -// FIRApp configuration objects. -@property(nonatomic, readwrite, copy) NSString *fcmSenderID; -@property(nonatomic, readwrite, copy) NSString *firebaseAppID; - -// Raw APNS token data -@property(nonatomic, readwrite, strong) NSData *apnsTokenData; - -@property(nonatomic, readwrite) FIRInstanceIDAPNSTokenType apnsTokenType; -// String-based, internal representation of APNS token -@property(nonatomic, readwrite, copy) NSString *APNSTupleString; -// Token fetched from the server automatically for the default app. -@property(nonatomic, readwrite, copy) NSString *defaultFCMToken; - -@property(nonatomic, readwrite, strong) FIRInstanceIDTokenManager *tokenManager; -@property(nonatomic, readwrite, strong) FIRInstanceIDKeyPairStore *keyPairStore; - -// backoff and retry for default token -@property(atomic, readwrite, assign) BOOL isFetchingDefaultToken; -@property(atomic, readwrite, assign) BOOL isDefaultTokenFetchScheduled; -@property(nonatomic, readwrite, assign) NSInteger retryCountForDefaultToken; - -@end - -// InstanceID doesn't provide any functionality to other components, -// so it provides a private, empty protocol that it conforms to and use it for registration. - -@protocol FIRInstanceIDInstanceProvider -@end - -@interface FIRInstanceID () <FIRInstanceIDInstanceProvider, FIRLibrary> -@end - -@implementation FIRInstanceIDResult -- (id)copyWithZone:(NSZone *)zone { - FIRInstanceIDResult *result = [[[self class] allocWithZone:zone] init]; - result.instanceID = self.instanceID; - result.token = self.token; - return result; -} -@end - -@implementation FIRInstanceID - -// File static to support InstanceID tests that call [FIRInstanceID instanceID] after -// [FIRInstanceID instanceIDForTests]. -static FIRInstanceID *gInstanceID; - -+ (instancetype)instanceID { - // If the static instance was created, return it. This should only be set in tests and we should - // eventually use proper dependency injection for a better test structure. - if (gInstanceID != nil) { - return gInstanceID; - } - FIRApp *defaultApp = [FIRApp defaultApp]; // Missing configure will be logged here. - FIRInstanceID *instanceID = - (FIRInstanceID *)FIR_COMPONENT(FIRInstanceIDInstanceProvider, defaultApp.container); - return instanceID; -} - -- (instancetype)initPrivately { - self = [super init]; - if (self != nil) { - // Use automatic detection of sandbox, unless otherwise set by developer - _apnsTokenType = FIRInstanceIDAPNSTokenTypeUnknown; - } - return self; -} - -+ (FIRInstanceID *)instanceIDForTests { - gInstanceID = [[FIRInstanceID alloc] initPrivately]; - [gInstanceID start]; - return gInstanceID; -} - -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - -- (void)stopAllRequests { - [self.tokenManager stopAllTokenOperations]; -} - -#pragma mark - Tokens - -- (NSString *)token { - if (!self.fcmSenderID.length) { - return nil; - } - - NSString *cachedToken = [self cachedTokenIfAvailable]; - - if (cachedToken) { - return cachedToken; - } else { - // If we've never had a cached default token, we should fetch one because unrelatedly, - // this request will help us determine whether the locally-generated Instance ID keypair is not - // unique, and therefore generate a new one. - [self fetchDefaultToken]; - return nil; - } -} - -- (void)instanceIDWithHandler:(FIRInstanceIDResultHandler)handler { - FIRInstanceID_WEAKIFY(self); - [self getIDWithHandler:^(NSString *identity, NSError *error) { - FIRInstanceID_STRONGIFY(self); - // This is in main queue already - if (error) { - if (handler) { - handler(nil, error); - } - return; - } - FIRInstanceIDResult *result = [[FIRInstanceIDResult alloc] init]; - result.instanceID = identity; - NSString *cachedToken = [self cachedTokenIfAvailable]; - if (cachedToken) { - if (handler) { - result.token = cachedToken; - handler(result, nil); - } - // If no handler, simply return since client has generated iid and token. - return; - } - - // Now get token - FIRInstanceIDTokenHandler tokenHandler = ^void(NSString *token, NSError *error) { - if (error) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID007, - @"Failed to retrieve the default FCM token after %ld retries", - (long)self.retryCountForDefaultToken); - if (handler) { - // If token fetching fails, result should be nil with error returned. - handler(nil, error); - } - return; - } - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeInstanceID008, @"Got default token %@", - token); - NSString *previousFCMToken = self.defaultFCMToken; - self.defaultFCMToken = token; - - // Only notify of token refresh if we have a new valid token that's different than before - if (self.defaultFCMToken.length && ![self.defaultFCMToken isEqualToString:previousFCMToken]) { - NSNotification *tokenRefreshNotification = - [NSNotification notificationWithName:kFIRInstanceIDTokenRefreshNotification - object:[self.defaultFCMToken copy]]; - [[NSNotificationQueue defaultQueue] enqueueNotification:tokenRefreshNotification - postingStyle:NSPostASAP]; - } - - if (handler) { - result.token = token; - handler(result, nil); - } - }; - - [self defaultTokenWithHandler:tokenHandler]; - }]; -} - -- (NSString *)cachedTokenIfAvailable { - FIRInstanceIDTokenInfo *cachedTokenInfo = - [self.tokenManager cachedTokenInfoWithAuthorizedEntity:self.fcmSenderID - scope:kFIRInstanceIDDefaultTokenScope]; - return cachedTokenInfo.token; -} - -- (void)setDefaultFCMToken:(NSString *)defaultFCMToken { - if (_defaultFCMToken && defaultFCMToken && [defaultFCMToken isEqualToString:_defaultFCMToken]) { - return; - } - - _defaultFCMToken = defaultFCMToken; - - // Sending this notification out will ensure that FIRMessaging has the updated - // default FCM token. - NSNotification *internalDefaultTokenNotification = - [NSNotification notificationWithName:kFIRInstanceIDDefaultGCMTokenNotification - object:_defaultFCMToken]; - [[NSNotificationQueue defaultQueue] enqueueNotification:internalDefaultTokenNotification - postingStyle:NSPostASAP]; -} - -- (void)tokenWithAuthorizedEntity:(NSString *)authorizedEntity - scope:(NSString *)scope - options:(NSDictionary *)options - handler:(FIRInstanceIDTokenHandler)handler { - _FIRInstanceIDDevAssert(handler != nil && [authorizedEntity length] && [scope length], - @"Invalid authorizedEntity or scope to new token"); - if (!handler) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID000, - kFIRInstanceIDInvalidNilHandlerError); - return; - } - - NSMutableDictionary *tokenOptions = [NSMutableDictionary dictionary]; - if (options.count) { - [tokenOptions addEntriesFromDictionary:options]; - } - - NSString *APNSKey = kFIRInstanceIDTokenOptionsAPNSKey; - NSString *serverTypeKey = kFIRInstanceIDTokenOptionsAPNSIsSandboxKey; - - if (tokenOptions[APNSKey] != nil && tokenOptions[serverTypeKey] == nil) { - // APNS key was given, but server type is missing. Supply the server type with automatic - // checking. This can happen when the token is requested from FCM, which does not include a - // server type during its request. - tokenOptions[serverTypeKey] = @([self isSandboxApp]); - } - - // comparing enums to ints directly throws a warning - FIRInstanceIDErrorCode noError = INT_MAX; - FIRInstanceIDErrorCode errorCode = noError; - if (FIRInstanceIDIsValidGCMScope(scope) && !tokenOptions[APNSKey]) { - errorCode = kFIRInstanceIDErrorCodeMissingAPNSToken; - } else if (FIRInstanceIDIsValidGCMScope(scope) && - ![tokenOptions[APNSKey] isKindOfClass:[NSData class]]) { - errorCode = kFIRInstanceIDErrorCodeInvalidRequest; - } else if (![authorizedEntity length]) { - errorCode = kFIRInstanceIDErrorCodeInvalidAuthorizedEntity; - } else if (![scope length]) { - errorCode = kFIRInstanceIDErrorCodeInvalidScope; - } else if (!self.keyPairStore) { - errorCode = kFIRInstanceIDErrorCodeInvalidStart; - } - - FIRInstanceIDTokenHandler newHandler = ^(NSString *token, NSError *error) { - dispatch_async(dispatch_get_main_queue(), ^{ - handler(token, error); - }); - }; - - if (errorCode != noError) { - newHandler(nil, [NSError errorWithFIRInstanceIDErrorCode:errorCode]); - return; - } - - // TODO(chliangGoogle): Add some validation logic that the APNs token data and sandbox value are - // supplied in the valid format (NSData and BOOL, respectively). - - // Add internal options - if (self.firebaseAppID) { - tokenOptions[kFIRInstanceIDTokenOptionsFirebaseAppIDKey] = self.firebaseAppID; - } - - FIRInstanceID_WEAKIFY(self); - FIRInstanceIDAuthService *authService = self.tokenManager.authService; - [authService - fetchCheckinInfoWithHandler:^(FIRInstanceIDCheckinPreferences *preferences, NSError *error) { - FIRInstanceID_STRONGIFY(self); - if (error) { - newHandler(nil, error); - return; - } - - // Only use the token in the cache if the APNSInfo matches what the request's options has. - // It's possible for the request to be with a newer APNs device token, which should be - // honored. - FIRInstanceIDTokenInfo *cachedTokenInfo = - [self.tokenManager cachedTokenInfoWithAuthorizedEntity:authorizedEntity scope:scope]; - if (cachedTokenInfo) { - // Ensure that the cached token matches APNs data before returning it. - FIRInstanceIDAPNSInfo *optionsAPNSInfo = - [[FIRInstanceIDAPNSInfo alloc] initWithTokenOptionsDictionary:tokenOptions]; - // If either the APNs info is missing in both, or if they are an exact match, then we can - // use this cached token. - if ((!cachedTokenInfo.APNSInfo && !optionsAPNSInfo) || - [cachedTokenInfo.APNSInfo isEqualToAPNSInfo:optionsAPNSInfo]) { - newHandler(cachedTokenInfo.token, nil); - return; - } - } - - FIRInstanceID_WEAKIFY(self); - [self asyncLoadKeyPairWithHandler:^(FIRInstanceIDKeyPair *keyPair, NSError *error) { - FIRInstanceID_STRONGIFY(self); - - if (error) { - NSError *newError = - [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeInvalidKeyPair]; - newHandler(nil, newError); - - } else { - [self.tokenManager fetchNewTokenWithAuthorizedEntity:[authorizedEntity copy] - scope:[scope copy] - keyPair:keyPair - options:tokenOptions - handler:newHandler]; - } - }]; - }]; -} - -- (void)deleteTokenWithAuthorizedEntity:(NSString *)authorizedEntity - scope:(NSString *)scope - handler:(FIRInstanceIDDeleteTokenHandler)handler { - _FIRInstanceIDDevAssert(handler != nil && [authorizedEntity length] && [scope length], - @"Invalid authorizedEntity or scope to delete token"); - - if (!handler) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID001, - kFIRInstanceIDInvalidNilHandlerError); - } - - // comparing enums to ints directly throws a warning - FIRInstanceIDErrorCode noError = INT_MAX; - FIRInstanceIDErrorCode errorCode = noError; - - if (![authorizedEntity length]) { - errorCode = kFIRInstanceIDErrorCodeInvalidAuthorizedEntity; - } else if (![scope length]) { - errorCode = kFIRInstanceIDErrorCodeInvalidScope; - } else if (!self.keyPairStore) { - errorCode = kFIRInstanceIDErrorCodeInvalidStart; - } - - FIRInstanceIDDeleteTokenHandler newHandler = ^(NSError *error) { - // If a default token is deleted successfully, reset the defaultFCMToken too. - if (!error && [authorizedEntity isEqualToString:self.fcmSenderID] && - [scope isEqualToString:kFIRInstanceIDDefaultTokenScope]) { - self.defaultFCMToken = nil; - } - dispatch_async(dispatch_get_main_queue(), ^{ - handler(error); - }); - }; - - if (errorCode != noError) { - newHandler([NSError errorWithFIRInstanceIDErrorCode:errorCode]); - return; - } - - FIRInstanceID_WEAKIFY(self); - FIRInstanceIDAuthService *authService = self.tokenManager.authService; - [authService - fetchCheckinInfoWithHandler:^(FIRInstanceIDCheckinPreferences *preferences, NSError *error) { - FIRInstanceID_STRONGIFY(self); - if (error) { - newHandler(error); - return; - } - - FIRInstanceID_WEAKIFY(self); - [self asyncLoadKeyPairWithHandler:^(FIRInstanceIDKeyPair *keyPair, NSError *error) { - FIRInstanceID_STRONGIFY(self); - if (error) { - NSError *newError = - [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeInvalidKeyPair]; - newHandler(newError); - - } else { - [self.tokenManager deleteTokenWithAuthorizedEntity:authorizedEntity - scope:scope - keyPair:keyPair - handler:newHandler]; - } - }]; - }]; -} - -- (void)asyncLoadKeyPairWithHandler:(FIRInstanceIDKeyPairHandler)handler { - FIRInstanceID_WEAKIFY(self); - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - FIRInstanceID_STRONGIFY(self); - - NSError *error = nil; - FIRInstanceIDKeyPair *keyPair = [self.keyPairStore loadKeyPairWithError:&error]; - dispatch_async(dispatch_get_main_queue(), ^{ - if (error) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeInstanceID002, - @"Failed to retreieve keyPair %@", error); - if (handler) { - handler(nil, error); - } - } else if (!keyPair && !error) { - if (handler) { - handler(nil, - [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeInvalidKeyPair]); - } - } else { - if (handler) { - handler(keyPair, nil); - } - } - }); - }); -} - -#pragma mark - Identity - -- (void)getIDWithHandler:(FIRInstanceIDHandler)handler { - _FIRInstanceIDDevAssert(handler, @"Invalid nil handler to getIdentity"); - - if (!handler) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID003, - kFIRInstanceIDInvalidNilHandlerError); - return; - } - - void (^callHandlerOnMainThread)(NSString *, NSError *) = ^(NSString *identity, NSError *error) { - dispatch_async(dispatch_get_main_queue(), ^{ - handler(identity, error); - }); - }; - - if (!self.keyPairStore) { - NSError *error = [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeInvalidStart]; - callHandlerOnMainThread(nil, error); - return; - } - - FIRInstanceID_WEAKIFY(self); - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - FIRInstanceID_STRONGIFY(self); - NSError *error; - NSString *appIdentity = [self.keyPairStore appIdentityWithError:&error]; - // When getID is explicitly called, trigger getToken to make sure token always exists. - // This is to avoid ID conflict (ID is not checked for conflict until we generate a token) - if (appIdentity) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - [self token]; -#pragma clang diagnostic pop - } - callHandlerOnMainThread(appIdentity, error); - }); -} - -- (void)deleteIDWithHandler:(FIRInstanceIDDeleteHandler)handler { - _FIRInstanceIDDevAssert(handler, @"Invalid nil handler to delete Identity"); - - if (!handler) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID004, - kFIRInstanceIDInvalidNilHandlerError); - return; - } - - void (^callHandlerOnMainThread)(NSError *) = ^(NSError *error) { - if ([NSThread isMainThread]) { - handler(error); - return; - } - dispatch_async(dispatch_get_main_queue(), ^{ - handler(error); - }); - }; - - if (!self.keyPairStore) { - FIRInstanceIDErrorCode error = kFIRInstanceIDErrorCodeInvalidStart; - callHandlerOnMainThread([NSError errorWithFIRInstanceIDErrorCode:error]); - return; - } - - FIRInstanceID_WEAKIFY(self); - void (^deleteTokensHandler)(NSError *) = ^void(NSError *error) { - FIRInstanceID_STRONGIFY(self); - if (error) { - callHandlerOnMainThread(error); - return; - } - [self deleteIdentityWithHandler:^(NSError *error) { - callHandlerOnMainThread(error); - }]; - }; - - [self asyncLoadKeyPairWithHandler:^(FIRInstanceIDKeyPair *keyPair, NSError *error) { - FIRInstanceID_STRONGIFY(self); - if (error) { - NSError *newError = - [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeInvalidKeyPair]; - callHandlerOnMainThread(newError); - } else { - [self.tokenManager deleteAllTokensWithKeyPair:keyPair handler:deleteTokensHandler]; - } - }]; -} - -- (void)notifyIdentityReset { - [self deleteIdentityWithHandler:nil]; -} - -// Delete all the local cache checkin, IID and token. -- (void)deleteIdentityWithHandler:(FIRInstanceIDDeleteHandler)handler { - // Delete tokens. - [self.tokenManager deleteAllTokensLocallyWithHandler:^(NSError *deleteTokenError) { - // Reset FCM token. - self.defaultFCMToken = nil; - if (deleteTokenError) { - if (handler) { - handler(deleteTokenError); - } - return; - } - - // Delete Instance ID. - [self.keyPairStore - deleteSavedKeyPairWithSubtype:kFIRInstanceIDKeyPairSubType - handler:^(NSError *error) { - NSError *deletePlistError; - [self.keyPairStore - removeKeyPairCreationTimePlistWithError:&deletePlistError]; - if (error || deletePlistError) { - if (handler) { - // Prefer to use the delete Instance ID error. - error = [NSError - errorWithFIRInstanceIDErrorCode: - kFIRInstanceIDErrorCodeUnknown - userInfo:@{ - NSUnderlyingErrorKey : error - ? error - : deletePlistError - }]; - handler(error); - } - return; - } - // Delete checkin. - [self.tokenManager.authService - resetCheckinWithHandler:^(NSError *error) { - if (error) { - if (handler) { - handler(error); - } - return; - } - // Only request new token if FCM auto initialization is - // enabled. - if ([self isFCMAutoInitEnabled]) { - // Deletion succeeds! Requesting new checkin, IID and token. - // TODO(chliangGoogle) see if dispatch_after is necessary - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, - (int64_t)(0.5 * NSEC_PER_SEC)), - dispatch_get_main_queue(), ^{ - [self fetchDefaultToken]; - }); - } - if (handler) { - handler(nil); - } - }]; - }]; - }]; -} - -#pragma mark - Config - -+ (void)load { - [FIRApp registerInternalLibrary:(Class<FIRLibrary>)self - withName:@"fire-iid" - withVersion:FIRInstanceIDCurrentLibraryVersion()]; -} - -+ (nonnull NSArray<FIRComponent *> *)componentsToRegister { - FIRComponentCreationBlock creationBlock = - ^id _Nullable(FIRComponentContainer *container, BOOL *isCacheable) { - // Ensure it's cached so it returns the same instance every time instanceID is called. - *isCacheable = YES; - FIRInstanceID *instanceID = [[FIRInstanceID alloc] initPrivately]; - [instanceID start]; - return instanceID; - }; - FIRComponent *instanceIDProvider = - [FIRComponent componentWithProtocol:@protocol(FIRInstanceIDInstanceProvider) - instantiationTiming:FIRInstantiationTimingLazy - dependencies:@[] - creationBlock:creationBlock]; - return @[ instanceIDProvider ]; -} - -+ (void)configureWithApp:(FIRApp *)app { - if (!app.isDefaultApp) { - // Only configure for the default FIRApp. - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeFIRApp002, - @"Firebase Instance ID only works with the default app."); - return; - } - [[FIRInstanceID instanceID] configureInstanceIDWithOptions:app.options app:app]; -} - -- (void)configureInstanceIDWithOptions:(FIROptions *)options app:(FIRApp *)firApp { - NSString *GCMSenderID = options.GCMSenderID; - if (!GCMSenderID.length) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeFIRApp000, - @"Firebase not set up correctly, nil or empty senderID."); - [FIRInstanceID exitWithReason:@"GCM_SENDER_ID must not be nil or empty." forFirebaseApp:firApp]; - return; - } - - self.fcmSenderID = GCMSenderID; - self.firebaseAppID = firApp.options.googleAppID; - - // FCM generates a FCM token during app start for sending push notification to device. - // This is not needed for app extension. - if (![GULAppEnvironmentUtil isAppExtension]) { - [self didCompleteConfigure]; - } -} - -+ (NSError *)configureErrorWithReason:(nonnull NSString *)reason { - NSString *description = - [NSString stringWithFormat:@"Configuration failed for service %@.", kFIRIIDServiceInstanceID]; - if (!reason.length) { - reason = @"Unknown reason"; - } - - NSDictionary *userInfo = - @{NSLocalizedDescriptionKey : description, NSLocalizedFailureReasonErrorKey : reason}; - - return [NSError errorWithDomain:kFIRIIDErrorDomain - code:kFIRIIDErrorCodeInstanceIDFailed - userInfo:userInfo]; -} - -// If the firebaseApp is available we should send logs for the error through it before -// raising an exception. -+ (void)exitWithReason:(nonnull NSString *)reason forFirebaseApp:(FIRApp *)firebaseApp { - [firebaseApp sendLogsWithServiceName:kFIRIIDServiceInstanceID - version:FIRInstanceIDCurrentLibraryVersion() - error:[self configureErrorWithReason:reason]]; - - [NSException raise:kFIRIIDErrorDomain - format:@"Could not configure Firebase InstanceID. %@", reason]; -} - -// This is used to start any operations when we receive FirebaseSDK setup notification -// from FIRCore. -- (void)didCompleteConfigure { - NSString *cachedToken = [self cachedTokenIfAvailable]; - // When there is a cached token, do the token refresh. - if (cachedToken) { - // Clean up expired tokens by checking the token refresh policy. - if ([self.tokenManager checkForTokenRefreshPolicy]) { - // Default token is expired, fetch default token from server. - [self fetchDefaultToken]; - } - // Notify FCM with the default token. -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - self.defaultFCMToken = [self token]; -#pragma clang diagnostic pop - } else if ([self isFCMAutoInitEnabled]) { - // When there is no cached token, must check auto init is enabled. - // If it's disabled, don't initiate token generation/refresh. - // If no cache token and auto init is enabled, fetch a token from server. - [self fetchDefaultToken]; - // Notify FCM with the default token. -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - self.defaultFCMToken = [self token]; -#pragma clang diagnostic pop - } - // ONLY checkin when auto data collection is turned on. - if ([self isFCMAutoInitEnabled]) { - [self.tokenManager.authService scheduleCheckin:YES]; - } -} - -- (BOOL)isFCMAutoInitEnabled { - Class messagingClass = NSClassFromString(kFIRInstanceIDFCMSDKClassString); - // Firebase Messaging is not installed, auto init should be disabled since it's for FCM. - if (!messagingClass) { - return NO; - } - - // Messaging doesn't have the singleton method, auto init should be enabled since FCM exists. - SEL instanceSelector = NSSelectorFromString(kFIRInstanceIDFCMSelectorInstance); - if (![messagingClass respondsToSelector:instanceSelector]) { - return YES; - } - - // Get FIRMessaging shared instance. - IMP messagingInstanceIMP = [messagingClass methodForSelector:instanceSelector]; - id (*getMessagingInstance)(id, SEL) = (void *)messagingInstanceIMP; - id messagingInstance = getMessagingInstance(messagingClass, instanceSelector); - - // Messaging doesn't have the property, auto init should be enabled since FCM exists. - SEL autoInitSelector = NSSelectorFromString(kFIRInstanceIDFCMSelectorAutoInitEnabled); - if (![messagingInstance respondsToSelector:autoInitSelector]) { - return YES; - } - - // Get autoInitEnabled method. - IMP isAutoInitEnabledIMP = [messagingInstance methodForSelector:autoInitSelector]; - BOOL (*isAutoInitEnabled)(id, SEL) = (BOOL(*)(id, SEL))isAutoInitEnabledIMP; - - // Check FCM's isAutoInitEnabled property. - return isAutoInitEnabled(messagingInstance, autoInitSelector); -} - -// Actually makes InstanceID instantiate both the IID and Token-related subsystems. -- (void)start { - NSString *instanceIDSubDirectory = kFIRInstanceIDApplicationSupportSubDirectory; - if (![FIRInstanceIDStore hasApplicationSupportSubDirectory:instanceIDSubDirectory]) { - [FIRInstanceIDStore createApplicationSupportSubDirectory:instanceIDSubDirectory]; - } - - [self setupTokenManager]; - [self setupKeyPairManager]; - [self setupNotificationListeners]; -} - -// Creates the token manager, which is used for fetching, caching, and retrieving tokens. -- (void)setupTokenManager { - self.tokenManager = [[FIRInstanceIDTokenManager alloc] init]; -} - -// Creates a key pair manager, which stores the public/private keys needed to generate an -// application instance ID. -- (void)setupKeyPairManager { - self.keyPairStore = [[FIRInstanceIDKeyPairStore alloc] init]; - if ([self.keyPairStore invalidateKeyPairsIfNeeded]) { - // Reset tokens right away when keypair is deleted, otherwise async call can make first query - // of token happens before reset old tokens during app start. - // TODO(chliangGoogle): Delete all tokens on server too, using - // deleteAllTokensWithKeyPair:handler:. This requires actually retrieving the invalid keypair - // from Keychain, which is something that the key pair store does not currently do. - [self.tokenManager deleteAllTokensLocallyWithHandler:nil]; - } -} - -- (void)setupNotificationListeners { - // To prevent double notifications remove observer from all events during setup. - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - [center removeObserver:self]; - [center addObserver:self - selector:@selector(notifyIdentityReset) - name:kFIRInstanceIDIdentityInvalidatedNotification - object:nil]; - [center addObserver:self - selector:@selector(notifyAPNSTokenIsSet:) - name:kFIRInstanceIDAPNSTokenNotification - object:nil]; -} - -#pragma mark - Private Helpers -/// Maximum retry count to fetch the default token. -+ (int64_t)maxRetryCountForDefaultToken { - return kMaxRetryCountForDefaultToken; -} - -/// Minimum interval in seconds between retries to fetch the default token. -+ (int64_t)minIntervalForDefaultTokenRetry { - return kMinRetryIntervalForDefaultTokenInSeconds; -} - -/// Maximum retry interval between retries to fetch default token. -+ (int64_t)maxRetryIntervalForDefaultTokenInSeconds { - return kMaxRetryIntervalForDefaultTokenInSeconds; -} - -- (NSInteger)retryIntervalToFetchDefaultToken { - if (self.retryCountForDefaultToken >= [[self class] maxRetryCountForDefaultToken]) { - return (NSInteger)[[self class] maxRetryIntervalForDefaultTokenInSeconds]; - } - // exponential backoff with a fixed initial retry time - // 11s, 22s, 44s, 88s ... - int64_t minInterval = [[self class] minIntervalForDefaultTokenRetry]; - return (NSInteger)MIN( - (1 << self.retryCountForDefaultToken) + minInterval * self.retryCountForDefaultToken, - kMaxRetryIntervalForDefaultTokenInSeconds); -} - -- (void)fetchDefaultToken { - if (self.isFetchingDefaultToken) { - return; - } - - FIRInstanceID_WEAKIFY(self); - FIRInstanceIDTokenHandler handler = ^void(NSString *token, NSError *error) { - FIRInstanceID_STRONGIFY(self); - - if (error) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID007, - @"Failed to retrieve the default FCM token after %ld retries", - (long)self.retryCountForDefaultToken); - } else { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeInstanceID008, @"Got default token %@", - token); - NSString *previousFCMToken = self.defaultFCMToken; - self.defaultFCMToken = token; - - // Only notify of token refresh if we have a new valid token that's different than before - if (self.defaultFCMToken.length && ![self.defaultFCMToken isEqualToString:previousFCMToken]) { - NSNotification *tokenRefreshNotification = - [NSNotification notificationWithName:kFIRInstanceIDTokenRefreshNotification - object:[self.defaultFCMToken copy]]; - [[NSNotificationQueue defaultQueue] enqueueNotification:tokenRefreshNotification - postingStyle:NSPostASAP]; - } - } - }; - - // Get a "*" token using this APNS token. - [self defaultTokenWithHandler:handler]; -} - -- (void)defaultTokenWithHandler:(FIRInstanceIDTokenHandler)handler { - if (self.isFetchingDefaultToken || self.isDefaultTokenFetchScheduled) { - return; - } - NSDictionary *instanceIDOptions = @{}; - BOOL hasFirebaseMessaging = NSClassFromString(kFIRInstanceIDFCMSDKClassString) != nil; - if (hasFirebaseMessaging && self.apnsTokenData) { - BOOL isSandboxApp = (self.apnsTokenType == FIRInstanceIDAPNSTokenTypeSandbox); - if (self.apnsTokenType == FIRInstanceIDAPNSTokenTypeUnknown) { - isSandboxApp = [self isSandboxApp]; - } - instanceIDOptions = @{ - kFIRInstanceIDTokenOptionsAPNSKey : self.apnsTokenData, - kFIRInstanceIDTokenOptionsAPNSIsSandboxKey : @(isSandboxApp), - }; - } - - FIRInstanceID_WEAKIFY(self); - FIRInstanceIDTokenHandler newHandler = ^void(NSString *token, NSError *error) { - FIRInstanceID_STRONGIFY(self); - self.isFetchingDefaultToken = NO; - - if (error) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID009, - @"Failed to fetch default token %@", error); - - // This notification can be sent multiple times since we can't guarantee success at any point - // of time. - NSNotification *tokenFetchFailNotification = - [NSNotification notificationWithName:kFIRInstanceIDDefaultGCMTokenFailNotification - object:[error copy]]; - [[NSNotificationQueue defaultQueue] enqueueNotification:tokenFetchFailNotification - postingStyle:NSPostASAP]; - - self.retryCountForDefaultToken = (NSInteger)MIN(self.retryCountForDefaultToken + 1, - [[self class] maxRetryCountForDefaultToken]); - - // Do not retry beyond the maximum limit. - if (self.retryCountForDefaultToken < [[self class] maxRetryCountForDefaultToken]) { - NSInteger retryInterval = [self retryIntervalToFetchDefaultToken]; - FIRInstanceID_WEAKIFY(self); - self.isDefaultTokenFetchScheduled = YES; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(retryInterval * NSEC_PER_SEC)), - dispatch_get_main_queue(), ^{ - FIRInstanceID_STRONGIFY(self); - self.isDefaultTokenFetchScheduled = NO; - [self defaultTokenWithHandler:handler]; - }); - } else { - if (handler) { - handler(nil, error); - } - } - } else { - // If somebody updated IID with APNS token while our initial request did not have it - // set we need to update it on the server. - BOOL shouldNotifyHandler = YES; - NSData *deviceTokenInRequest = instanceIDOptions[kFIRInstanceIDTokenOptionsAPNSKey]; - BOOL isSandboxInRequest = - [instanceIDOptions[kFIRInstanceIDTokenOptionsAPNSIsSandboxKey] boolValue]; - // Note that APNSTupleStringInRequest will be nil if deviceTokenInRequest is nil - NSString *APNSTupleStringInRequest = FIRInstanceIDAPNSTupleStringForTokenAndServerType( - deviceTokenInRequest, isSandboxInRequest); - // If the APNs value either remained nil, or was the same non-nil value, the APNs value - // did not change. - BOOL APNSRemainedSameDuringFetch = - (self.APNSTupleString == nil && APNSTupleStringInRequest == nil) || - ([self.APNSTupleString isEqualToString:APNSTupleStringInRequest]); - if (!APNSRemainedSameDuringFetch && hasFirebaseMessaging) { - // APNs value did change mid-fetch, so the token should be re-fetched with the current APNs - // value. - self.isDefaultTokenFetchScheduled = YES; - // Wait to notify until we can modify this token with APNS (or receive a new token) - shouldNotifyHandler = NO; - FIRInstanceID_WEAKIFY(self); - dispatch_async(dispatch_get_main_queue(), ^{ - FIRInstanceID_STRONGIFY(self); - self.isDefaultTokenFetchScheduled = NO; - [self defaultTokenWithHandler:handler]; - }); - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeRefetchingTokenForAPNS, - @"Received APNS token while fetching default token. " - @"Refetching default token."); - } else { - FIRInstanceIDLoggerInfo(kFIRInstanceIDMessageCodeInstanceID010, - @"Successfully fetched default token."); - } - // Post the required notifications if somebody is waiting. - if (shouldNotifyHandler && handler) { - handler(token, nil); - } - } - }; - - self.isFetchingDefaultToken = YES; - [self tokenWithAuthorizedEntity:self.fcmSenderID - scope:kFIRInstanceIDDefaultTokenScope - options:instanceIDOptions - handler:newHandler]; -} - -#pragma mark - APNS Token -// This should only be triggered from FCM. -- (void)notifyAPNSTokenIsSet:(NSNotification *)notification { - NSData *token = notification.object; - if (!token || ![token isKindOfClass:[NSData class]]) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeInternal002, @"Invalid APNS token type %@", - NSStringFromClass([notification.object class])); - return; - } - NSInteger type = [notification.userInfo[kFIRInstanceIDAPNSTokenType] integerValue]; - - // The APNS token is being added, or has changed (rare) - if ([self.apnsTokenData isEqualToData:token]) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeInstanceID011, - @"Trying to reset APNS token to the same value. Will return"); - return; - } - // Use this token type for when we have to automatically fetch tokens in the future - self.apnsTokenType = type; - BOOL isSandboxApp = (type == FIRInstanceIDAPNSTokenTypeSandbox); - if (self.apnsTokenType == FIRInstanceIDAPNSTokenTypeUnknown) { - isSandboxApp = [self isSandboxApp]; - } - self.apnsTokenData = [token copy]; - self.APNSTupleString = FIRInstanceIDAPNSTupleStringForTokenAndServerType(token, isSandboxApp); - - // Pro-actively invalidate the default token, if the APNs change makes it - // invalid. Previously, we invalidated just before fetching the token. - NSArray<FIRInstanceIDTokenInfo *> *invalidatedTokens = - [self.tokenManager updateTokensToAPNSDeviceToken:self.apnsTokenData isSandbox:isSandboxApp]; - - // Re-fetch any invalidated tokens automatically, this time with the current APNs token, so that - // they are up-to-date. - if (invalidatedTokens.count > 0) { - FIRInstanceID_WEAKIFY(self); - [self asyncLoadKeyPairWithHandler:^(FIRInstanceIDKeyPair *keyPair, NSError *error) { - FIRInstanceID_STRONGIFY(self); - - NSMutableDictionary *tokenOptions = [@{ - kFIRInstanceIDTokenOptionsAPNSKey : self.apnsTokenData, - kFIRInstanceIDTokenOptionsAPNSIsSandboxKey : @(isSandboxApp) - } mutableCopy]; - if (self.firebaseAppID) { - tokenOptions[kFIRInstanceIDTokenOptionsFirebaseAppIDKey] = self.firebaseAppID; - } - - for (FIRInstanceIDTokenInfo *tokenInfo in invalidatedTokens) { - if ([tokenInfo.token isEqualToString:self.defaultFCMToken]) { - // We will perform a special fetch for the default FCM token, so that the delegate methods - // are called. For all others, we will do an internal re-fetch. - [self fetchDefaultToken]; - } else { - [self.tokenManager fetchNewTokenWithAuthorizedEntity:tokenInfo.authorizedEntity - scope:tokenInfo.scope - keyPair:keyPair - options:tokenOptions - handler:^(NSString *_Nullable token, - NSError *_Nullable error){ - - }]; - } - } - }]; - } -} - -- (BOOL)isSandboxApp { - static BOOL isSandboxApp = YES; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - isSandboxApp = ![self isProductionApp]; - }); - return isSandboxApp; -} - -- (BOOL)isProductionApp { - const BOOL defaultAppTypeProd = YES; - - NSError *error = nil; - - Class envClass = NSClassFromString(@"FIRAppEnvironmentUtil"); - SEL isSimulatorSelector = NSSelectorFromString(@"isSimulator"); - if ([envClass respondsToSelector:isSimulatorSelector]) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warc-performSelector-leaks" - if ([envClass performSelector:isSimulatorSelector]) { -#pragma clang diagnostic pop - [self logAPNSConfigurationError:@"Running InstanceID on a simulator doesn't have APNS. " - @"Use prod profile by default."]; - return defaultAppTypeProd; - } - } - - NSString *path = [[[NSBundle mainBundle] bundlePath] - stringByAppendingPathComponent:@"embedded.mobileprovision"]; - - // Apps distributed via AppStore or TestFlight use the Production APNS certificates. - SEL isFromAppStoreSelector = NSSelectorFromString(@"isFromAppStore"); - if ([envClass respondsToSelector:isFromAppStoreSelector]) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warc-performSelector-leaks" - if ([envClass performSelector:isFromAppStoreSelector]) { -#pragma clang diagnostic pop - return defaultAppTypeProd; - } - } - - SEL isAppStoreReceiptSandboxSelector = NSSelectorFromString(@"isAppStoreReceiptSandbox"); - if ([envClass respondsToSelector:isAppStoreReceiptSandboxSelector]) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warc-performSelector-leaks" - if ([envClass performSelector:isAppStoreReceiptSandboxSelector] && !path.length) { -#pragma clang diagnostic pop - // Distributed via TestFlight - return defaultAppTypeProd; - } - } - - NSMutableData *profileData = [NSMutableData dataWithContentsOfFile:path options:0 error:&error]; - - if (!profileData.length || error) { - NSString *errorString = - [NSString stringWithFormat:@"Error while reading embedded mobileprovision %@", error]; - [self logAPNSConfigurationError:errorString]; - return defaultAppTypeProd; - } - - // The "embedded.mobileprovision" sometimes contains characters with value 0, which signals the - // end of a c-string and halts the ASCII parser, or with value > 127, which violates strict 7-bit - // ASCII. Replace any 0s or invalid characters in the input. - uint8_t *profileBytes = (uint8_t *)profileData.bytes; - for (int i = 0; i < profileData.length; i++) { - uint8_t currentByte = profileBytes[i]; - if (!currentByte || currentByte > 127) { - profileBytes[i] = '.'; - } - } - - NSString *embeddedProfile = [[NSString alloc] initWithBytesNoCopy:profileBytes - length:profileData.length - encoding:NSASCIIStringEncoding - freeWhenDone:NO]; - - if (error || !embeddedProfile.length) { - NSString *errorString = - [NSString stringWithFormat:@"Error while reading embedded mobileprovision %@", error]; - [self logAPNSConfigurationError:errorString]; - return defaultAppTypeProd; - } - - NSScanner *scanner = [NSScanner scannerWithString:embeddedProfile]; - NSString *plistContents; - if ([scanner scanUpToString:@"<plist" intoString:nil]) { - if ([scanner scanUpToString:@"</plist>" intoString:&plistContents]) { - plistContents = [plistContents stringByAppendingString:@"</plist>"]; - } - } - - if (!plistContents.length) { - return defaultAppTypeProd; - } - - NSData *data = [plistContents dataUsingEncoding:NSUTF8StringEncoding]; - if (!data.length) { - [self logAPNSConfigurationError:@"Couldn't read plist fetched from embedded mobileprovision"]; - return defaultAppTypeProd; - } - - NSError *plistMapError; - id plistData = [NSPropertyListSerialization propertyListWithData:data - options:NSPropertyListImmutable - format:nil - error:&plistMapError]; - if (plistMapError || ![plistData isKindOfClass:[NSDictionary class]]) { - NSString *errorString = - [NSString stringWithFormat:@"Error while converting assumed plist to dict %@", - plistMapError.localizedDescription]; - [self logAPNSConfigurationError:errorString]; - return defaultAppTypeProd; - } - NSDictionary *plistMap = (NSDictionary *)plistData; - - if ([plistMap valueForKeyPath:@"ProvisionedDevices"]) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeInstanceID012, - @"Provisioning profile has specifically provisioned devices, " - @"most likely a Dev profile."); - } - - NSString *apsEnvironment = [plistMap valueForKeyPath:kEntitlementsAPSEnvironmentKey]; - NSString *debugString __unused = - [NSString stringWithFormat:@"APNS Environment in profile: %@", apsEnvironment]; - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeInstanceID013, @"%@", debugString); - - // No aps-environment in the profile. - if (!apsEnvironment.length) { - [self logAPNSConfigurationError:@"No aps-environment set. If testing on a device APNS is not " - @"correctly configured. Please recheck your provisioning " - @"profiles. If testing on a simulator this is fine since APNS " - @"doesn't work on the simulator."]; - return defaultAppTypeProd; - } - - if ([apsEnvironment isEqualToString:kAPSEnvironmentDevelopmentValue]) { - return NO; - } - - return defaultAppTypeProd; -} - -/// Log error messages only when Messaging exists in the pod. -- (void)logAPNSConfigurationError:(NSString *)errorString { - BOOL hasFirebaseMessaging = NSClassFromString(kFIRInstanceIDFCMSDKClassString) != nil; - if (hasFirebaseMessaging) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID014, @"%@", errorString); - } else { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeInstanceID015, @"%@", errorString); - } -} - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAPNSInfo.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAPNSInfo.h @@ -1,64 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -NS_ASSUME_NONNULL_BEGIN - -/** - * Represents an APNS device token and whether its environment is for sandbox. - * It can read from and write to an NSDictionary for simple serialization. - */ -@interface FIRInstanceIDAPNSInfo : NSObject <NSCoding> - -/// The APNs device token, provided by the OS to the application delegate -@property(nonatomic, readonly, strong) NSData *deviceToken; -/// Represents whether or not this is deviceToken is for the sandbox -/// environment, or production. -@property(nonatomic, readonly, getter=isSandbox) BOOL sandbox; - -/** - * Initializes the receiver with an APNs device token, and boolean - * representing whether that token is for the sandbox environment. - * - * @param deviceToken The APNs device token typically provided by the - * operating system. - * @param isSandbox YES if the APNs device token is for the sandbox - * environment, or NO if it is for production. - * @return An instance of FIRInstanceIDAPNSInfo. - */ -- (instancetype)initWithDeviceToken:(NSData *)deviceToken isSandbox:(BOOL)isSandbox; - -/** - * Initializes the receiver from a token options dictionary containing data - * within the `kFIRInstanceIDTokenOptionsAPNSKey` and - * `kFIRInstanceIDTokenOptionsAPNSIsSandboxKey` keys. The token should be an - * NSData blob, and the sandbox value should be an NSNumber - * representing a boolean value. - * - * @param dictionary A dictionary containing values under the keys - * `kFIRInstanceIDTokenOptionsAPNSKey` and - * `kFIRInstanceIDTokenOptionsAPNSIsSandboxKey`. - * @return An instance of FIRInstanceIDAPNSInfo, or nil if the - * dictionary data was invalid or missing. - */ -- (nullable instancetype)initWithTokenOptionsDictionary:(NSDictionary *)dictionary; - -- (BOOL)isEqualToAPNSInfo:(FIRInstanceIDAPNSInfo *)otherInfo; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAPNSInfo.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAPNSInfo.m @@ -1,79 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDAPNSInfo.h" - -#import "FIRInstanceIDConstants.h" - -/// The key used to find the APNs device token in an archive. -NSString *const kFIRInstanceIDAPNSInfoTokenKey = @"device_token"; -/// The key used to find the sandbox value in an archive. -NSString *const kFIRInstanceIDAPNSInfoSandboxKey = @"sandbox"; - -@implementation FIRInstanceIDAPNSInfo - -- (instancetype)initWithDeviceToken:(NSData *)deviceToken isSandbox:(BOOL)isSandbox { - self = [super init]; - if (self) { - _deviceToken = [deviceToken copy]; - _sandbox = isSandbox; - } - return self; -} - -- (instancetype)initWithTokenOptionsDictionary:(NSDictionary *)dictionary { - id deviceToken = dictionary[kFIRInstanceIDTokenOptionsAPNSKey]; - if (![deviceToken isKindOfClass:[NSData class]]) { - return nil; - } - - id isSandbox = dictionary[kFIRInstanceIDTokenOptionsAPNSIsSandboxKey]; - if (![isSandbox isKindOfClass:[NSNumber class]]) { - return nil; - } - self = [super init]; - if (self) { - _deviceToken = (NSData *)deviceToken; - _sandbox = ((NSNumber *)isSandbox).boolValue; - } - return self; -} - -#pragma mark - NSCoding - -- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { - id deviceToken = [aDecoder decodeObjectForKey:kFIRInstanceIDAPNSInfoTokenKey]; - if (![deviceToken isKindOfClass:[NSData class]]) { - return nil; - } - BOOL isSandbox = [aDecoder decodeBoolForKey:kFIRInstanceIDAPNSInfoSandboxKey]; - return [self initWithDeviceToken:(NSData *)deviceToken isSandbox:isSandbox]; -} - -- (void)encodeWithCoder:(NSCoder *)aCoder { - [aCoder encodeObject:self.deviceToken forKey:kFIRInstanceIDAPNSInfoTokenKey]; - [aCoder encodeBool:self.sandbox forKey:kFIRInstanceIDAPNSInfoSandboxKey]; -} - -- (BOOL)isEqualToAPNSInfo:(FIRInstanceIDAPNSInfo *)otherInfo { - if ([super isEqual:otherInfo]) { - return YES; - } - return ([self.deviceToken isEqualToData:otherInfo.deviceToken] && - self.isSandbox == otherInfo.isSandbox); -} - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthKeyChain.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthKeyChain.h @@ -1,98 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -extern NSString *__nonnull const kFIRInstanceIDKeychainWildcardIdentifier; - -NS_ASSUME_NONNULL_BEGIN - -/** - * Wrapper around storing FCM auth data in iOS keychain. - */ -@interface FIRInstanceIDAuthKeychain : NSObject - -/** - * Designated Initializer. Init a generic `SecClassGenericPassword` keychain with `identifier` - * as the `kSecAttrGeneric`. - * - * @param identifier The generic attribute to be used by the keychain. - * - * @return A Keychain object with `kSecAttrGeneric` attribute set to identifier. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier; - -/** - * Get keychain items matching the given service and account. The service and/or account - * can be a wildcard (`kFIRInstanceIDKeychainWildcardIdentifier`), which case the query - * will include all items matching any services and/or accounts. - * - * @param service The kSecAttrService used to save the password. Can be wildcard. - * @param account The kSecAttrAccount used to save the password. Can be wildcard. - * - * @return An array of |NSData|s matching the provided inputs. - */ -- (NSArray<NSData *> *)itemsMatchingService:(NSString *)service account:(NSString *)account; - -/** - * Get keychain item for a given service and account. - * - * @param service The kSecAttrService used to save the password. - * @param account The kSecAttrAccount used to save the password. - * - * @return A cached keychain item for a given account and service, or nil if it was not - * found or could not be retrieved. - */ -- (NSData *)dataForService:(NSString *)service account:(NSString *)account; - -/** - * Remove the cached items from the keychain matching the service, account and access group. - * In case the items do not exist, YES is returned but with a valid error object with code - * `errSecItemNotFound`. - * - * @param service The kSecAttrService used to save the password. - * @param account The kSecAttrAccount used to save the password. - * @param handler The callback handler which is invoked when the remove operation is complete, with - * an error if there is any. - */ -- (void)removeItemsMatchingService:(NSString *)service - account:(NSString *)account - handler:(nullable void (^)(NSError *error))handler; - -/** - * Set the data for a given service and account with a specific accessibility. If - * accessibility is NULL we use `kSecAttrAccessibleAlwaysThisDeviceOnly` which - * prevents backup and restore to iCloud, and works for app extension that can - * execute right after a device is restarted (and not unlocked). - * - * @param data The data to save. - * @param service The `kSecAttrService` used to save the password. - * @param accessibility The `kSecAttrAccessibility` used to save the password. If NULL - * set this to `kSecAttrAccessibleAlwaysThisDeviceOnly`. - * @param account The `kSecAttrAccount` used to save the password. - * @param handler The callback handler which is invoked when the add operation is complete, - * with an error if there is any. - * - */ -- (void)setData:(NSData *)data - forService:(NSString *)service - accessibility:(nullable CFTypeRef)accessibility - account:(NSString *)account - handler:(nullable void (^)(NSError *))handler; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthKeyChain.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthKeyChain.m @@ -1,219 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDAuthKeyChain.h" -#import "FIRInstanceIDKeychain.h" -#import "FIRInstanceIDLogger.h" - -/** - * The error type representing why we couldn't read data from the keychain. - */ -typedef NS_ENUM(int, FIRInstanceIDKeychainErrorType) { - kFIRInstanceIDKeychainErrorBadArguments = -1301, -}; - -NSString *const kFIRInstanceIDKeychainWildcardIdentifier = @"*"; - -@interface FIRInstanceIDAuthKeychain () - -@property(nonatomic, copy) NSString *generic; -// cachedKeychainData is keyed by service and account, the value is an array of NSData. -// It is used to cache the tokens per service, per account, as well as checkin data per service, -// per account inside the keychain. -@property(nonatomic, copy) - NSMutableDictionary<NSString *, NSMutableDictionary<NSString *, NSArray<NSData *> *> *> - *cachedKeychainData; - -@end - -@implementation FIRInstanceIDAuthKeychain - -- (instancetype)initWithIdentifier:(NSString *)identifier { - self = [super init]; - if (self) { - _generic = [identifier copy]; - _cachedKeychainData = [[NSMutableDictionary alloc] init]; - } - return self; -} - -+ (NSMutableDictionary *)keychainQueryForService:(NSString *)service - account:(NSString *)account - generic:(NSString *)generic { - NSDictionary *query = @{(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword}; - - NSMutableDictionary *finalQuery = [NSMutableDictionary dictionaryWithDictionary:query]; - if ([generic length] && ![kFIRInstanceIDKeychainWildcardIdentifier isEqualToString:generic]) { - finalQuery[(__bridge NSString *)kSecAttrGeneric] = generic; - } - if ([account length] && ![kFIRInstanceIDKeychainWildcardIdentifier isEqualToString:account]) { - finalQuery[(__bridge NSString *)kSecAttrAccount] = account; - } - if ([service length] && ![kFIRInstanceIDKeychainWildcardIdentifier isEqualToString:service]) { - finalQuery[(__bridge NSString *)kSecAttrService] = service; - } - return finalQuery; -} - -- (NSMutableDictionary *)keychainQueryForService:(NSString *)service account:(NSString *)account { - return [[self class] keychainQueryForService:service account:account generic:self.generic]; -} - -- (NSArray<NSData *> *)itemsMatchingService:(NSString *)service account:(NSString *)account { - // If query wildcard service, it asks for all the results, which always query from keychain. - if (![service isEqualToString:kFIRInstanceIDKeychainWildcardIdentifier] && - ![account isEqualToString:kFIRInstanceIDKeychainWildcardIdentifier] && - _cachedKeychainData[service][account]) { - // As long as service, account array exist, even it's empty, it means we've queried it before, - // returns the cache value. - return _cachedKeychainData[service][account]; - } - - NSMutableDictionary *keychainQuery = [self keychainQueryForService:service account:account]; - - NSMutableArray<NSData *> *results; - keychainQuery[(__bridge id)kSecReturnData] = (__bridge id)kCFBooleanTrue; - keychainQuery[(__bridge id)kSecReturnAttributes] = (__bridge id)kCFBooleanTrue; - keychainQuery[(__bridge id)kSecMatchLimit] = (__bridge id)kSecMatchLimitAll; - // FIRInstanceIDKeychain should only take a query and return a result, will handle the query here. - CFArrayRef passwordInfos = [[FIRInstanceIDKeychain sharedInstance] itemWithQuery:keychainQuery]; - - if (!passwordInfos) { - // Nothing was found, simply return from this sync block. - // Make sure to label the cache entry empty, signaling that we've queried this entry. - if ([service isEqualToString:kFIRInstanceIDKeychainWildcardIdentifier] || - [account isEqualToString:kFIRInstanceIDKeychainWildcardIdentifier]) { - // Do not update cache if it's wildcard query. - return @[]; - } else if (_cachedKeychainData[service]) { - [_cachedKeychainData[service] setObject:@[] forKey:account]; - } else { - [_cachedKeychainData setObject:[@{account : @[]} mutableCopy] forKey:service]; - } - return @[]; - } - NSInteger numPasswords = CFArrayGetCount(passwordInfos); - results = [[NSMutableArray alloc] init]; - if (0 < numPasswords) { - for (NSUInteger i = 0; i < numPasswords; i++) { - NSDictionary *passwordInfo = [((__bridge NSArray *)passwordInfos) objectAtIndex:i]; - if (passwordInfo[(__bridge id)kSecValueData]) { - [results addObject:passwordInfo[(__bridge id)kSecValueData]]; - } - } - } - if (passwordInfos != NULL) { - CFRelease(passwordInfos); - } - - // We query the keychain because it didn't exist in cache, now query is done, update the result in - // the cache. - if ([service isEqualToString:kFIRInstanceIDKeychainWildcardIdentifier] || - [account isEqualToString:kFIRInstanceIDKeychainWildcardIdentifier]) { - // Do not update cache if it's wildcard query. - return [results copy]; - } else if (_cachedKeychainData[service]) { - [_cachedKeychainData[service] setObject:[results copy] forKey:account]; - } else { - NSMutableDictionary *entry = [@{account : [results copy]} mutableCopy]; - [_cachedKeychainData setObject:entry forKey:service]; - } - return [results copy]; -} - -- (NSData *)dataForService:(NSString *)service account:(NSString *)account { - NSArray<NSData *> *items = [self itemsMatchingService:service account:account]; - // If items is nil or empty, nil will be returned. - return items.firstObject; -} - -- (void)removeItemsMatchingService:(NSString *)service - account:(NSString *)account - handler:(void (^)(NSError *error))handler { - if ([service isEqualToString:kFIRInstanceIDKeychainWildcardIdentifier]) { - // Delete all keychain items. - _cachedKeychainData = [[NSMutableDictionary alloc] init]; - } else if ([account isEqualToString:kFIRInstanceIDKeychainWildcardIdentifier]) { - // Delete all entries under service, - if (_cachedKeychainData[service]) { - _cachedKeychainData[service] = [[NSMutableDictionary alloc] init]; - } - } else if (_cachedKeychainData[service]) { - // We should keep the service/account entry instead of nil so we know - // it's "empty entry" instead of "not query from keychain yet". - [_cachedKeychainData[service] setObject:@[] forKey:account]; - } else { - [_cachedKeychainData setObject:[@{account : @[]} mutableCopy] forKey:service]; - } - NSMutableDictionary *keychainQuery = [self keychainQueryForService:service account:account]; - [[FIRInstanceIDKeychain sharedInstance] removeItemWithQuery:keychainQuery handler:handler]; -} - -- (void)setData:(NSData *)data - forService:(NSString *)service - accessibility:(CFTypeRef)accessibility - account:(NSString *)account - handler:(void (^)(NSError *))handler { - if ([service isEqualToString:kFIRInstanceIDKeychainWildcardIdentifier] || - [account isEqualToString:kFIRInstanceIDKeychainWildcardIdentifier]) { - if (handler) { - handler([NSError errorWithDomain:kFIRInstanceIDKeychainErrorDomain - code:kFIRInstanceIDKeychainErrorBadArguments - userInfo:nil]); - } - return; - } - [self removeItemsMatchingService:service - account:account - handler:^(NSError *error) { - if (error) { - if (handler) { - handler(error); - } - return; - } - if (data.length > 0) { - NSMutableDictionary *keychainQuery = - [self keychainQueryForService:service account:account]; - keychainQuery[(__bridge id)kSecValueData] = data; - - if (accessibility != NULL) { - keychainQuery[(__bridge id)kSecAttrAccessible] = - (__bridge id)accessibility; - } else { - // Defaults to No backup - keychainQuery[(__bridge id)kSecAttrAccessible] = - (__bridge id)kSecAttrAccessibleAlwaysThisDeviceOnly; - } - [[FIRInstanceIDKeychain sharedInstance] - addItemWithQuery:keychainQuery - handler:handler]; - } - }]; - // Set the cache value. This must happen after removeItemsMatchingService:account:handler was - // called, so the cache value was reset before setting a new value. - if (_cachedKeychainData[service]) { - if (_cachedKeychainData[service][account]) { - _cachedKeychainData[service][account] = @[ data ]; - } else { - [_cachedKeychainData[service] setObject:@[ data ] forKey:account]; - } - } else { - [_cachedKeychainData setObject:[@{account : @[ data ]} mutableCopy] forKey:service]; - } -} - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthService.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthService.h @@ -1,91 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> -#import "FIRInstanceIDCheckinService.h" - -@class FIRInstanceIDCheckinPreferences; -@class FIRInstanceIDStore; - -/** - * FIRInstanceIDAuthService is responsible for retrieving, caching, and supplying checkin info - * for the rest of Instance ID. A checkin can be scheduled, meaning that it will keep retrying the - * checkin request until it is successful. A checkin can also be requested directly, with a - * completion handler. - */ -@interface FIRInstanceIDAuthService : NSObject - -/** - * Used only for testing. In addition to taking a store (for locally caching the checkin info), it - * also takes a checkinService. - */ -- (instancetype)initWithCheckinService:(FIRInstanceIDCheckinService *)checkinService - store:(FIRInstanceIDStore *)store; - -/** - * Initializes the auth service given a store (which provides the local caching of checkin info). - * This initializer will create its own instance of FIRInstanceIDCheckinService. - */ -- (instancetype)initWithStore:(FIRInstanceIDStore *)store; - -#pragma mark - Checkin Service - -/** - * Checks if the current deviceID and secret are valid or not. - * - * @return YES if the checkin credentials are valid else NO. - */ -- (BOOL)hasValidCheckinInfo; - -/** - * Fetch checkin info from the server. This would usually refresh the existing - * checkin credentials for the current app. - * - * @param handler The completion handler to invoke once the checkin info has been - * refreshed. - */ -- (void)fetchCheckinInfoWithHandler:(FIRInstanceIDDeviceCheckinCompletion)handler; - -/** - * Schedule checkin. Will hit the network only if the currently loaded checkin - * preferences are stale. - * - * @param immediately YES if we want it to be scheduled immediately else NO. - */ -- (void)scheduleCheckin:(BOOL)immediately; - -/** - * Returns the checkin preferences currently loaded in memory. The Checkin preferences - * can be either valid or invalid. - * - * @return The checkin preferences loaded in memory. - */ -- (FIRInstanceIDCheckinPreferences *)checkinPreferences; - -/** - * Cancels any ongoing checkin fetch, if any. - */ -- (void)stopCheckinRequest; - -/** - * Resets the checkin information. - * - * @param handler The callback handler which is invoked when checkin reset is complete, - * with an error if there is any. - */ -- (void)resetCheckinWithHandler:(void (^)(NSError *error))handler; - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthService.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthService.m @@ -1,302 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDAuthService.h" - -#import "FIRInstanceIDCheckinPreferences+Internal.h" -#import "FIRInstanceIDCheckinPreferences.h" -#import "FIRInstanceIDCheckinPreferences_Private.h" -#import "FIRInstanceIDConstants.h" -#import "FIRInstanceIDDefines.h" -#import "FIRInstanceIDLogger.h" -#import "FIRInstanceIDStore.h" -#import "NSError+FIRInstanceID.h" - -// Max time interval between checkin retry in seconds. -static const int64_t kMaxCheckinRetryIntervalInSeconds = 1 << 5; - -@interface FIRInstanceIDAuthService () - -// Used to retrieve and cache the checkin info to disk and Keychain. -@property(nonatomic, readwrite, strong) FIRInstanceIDStore *store; -// Used to perform single checkin fetches. -@property(nonatomic, readwrite, strong) FIRInstanceIDCheckinService *checkinService; -// The current checkin info. It will be compared to what is retrieved to determine whether it is -// different than what is in the cache. -@property(nonatomic, readwrite, strong) FIRInstanceIDCheckinPreferences *checkinPreferences; - -// This array will track multiple handlers waiting for checkin to be performed. When a checkin -// request completes, all the handlers will be notified. -// Changes to the checkinHandlers array should happen in a thread-safe manner. -@property(nonatomic, readonly, strong) - NSMutableArray<FIRInstanceIDDeviceCheckinCompletion> *checkinHandlers; - -// This is set to true if there is a checkin request in-flight. -@property(atomic, readwrite, assign) BOOL isCheckinInProgress; -// This timer is used a perform checkin retries. It is cancellable. -@property(atomic, readwrite, strong) NSTimer *scheduledCheckinTimer; -// The number of times checkin has been retried during a scheduled checkin. -@property(atomic, readwrite, assign) int checkinRetryCount; - -@end - -@implementation FIRInstanceIDAuthService - -- (instancetype)initWithCheckinService:(FIRInstanceIDCheckinService *)checkinService - store:(FIRInstanceIDStore *)store { - self = [super init]; - if (self) { - _store = store; - _checkinPreferences = [_store cachedCheckinPreferences]; - _checkinService = checkinService; - _checkinHandlers = [NSMutableArray array]; - } - return self; -} - -- (void)dealloc { - [_scheduledCheckinTimer invalidate]; -} - -- (instancetype)initWithStore:(FIRInstanceIDStore *)store { - FIRInstanceIDCheckinService *checkinService = [[FIRInstanceIDCheckinService alloc] init]; - return [self initWithCheckinService:checkinService store:store]; -} - -#pragma mark - Schedule Checkin - -- (void)scheduleCheckin:(BOOL)immediately { - // Checkin is still valid, so a remote checkin is not required. - if ([self.checkinPreferences hasValidCheckinInfo]) { - return; - } - - // Checkin is already scheduled, so this (non-immediate) request can be ignored. - if (!immediately && [self.scheduledCheckinTimer isValid]) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeAuthService000, - @"Checkin sync already scheduled. Will not schedule."); - return; - } - - if (immediately) { - [self performScheduledCheckin]; - } else { - int64_t checkinRetryDuration = [self calculateNextCheckinRetryIntervalInSeconds]; - [self startCheckinTimerWithDuration:(NSTimeInterval)checkinRetryDuration]; - } -} - -- (void)startCheckinTimerWithDuration:(NSTimeInterval)timerDuration { - self.scheduledCheckinTimer = - [NSTimer scheduledTimerWithTimeInterval:timerDuration - target:self - selector:@selector(onScheduledCheckinTimerFired:) - userInfo:nil - repeats:NO]; - // Add some tolerance to the timer, to allow iOS to be more flexible with this timer - self.scheduledCheckinTimer.tolerance = 0.5; -} - -- (void)clearScheduledCheckinTimer { - [self.scheduledCheckinTimer invalidate]; - self.scheduledCheckinTimer = nil; -} - -- (void)onScheduledCheckinTimerFired:(NSTimer *)timer { - [self performScheduledCheckin]; -} - -- (void)performScheduledCheckin { - // No checkin scheduled as of now. - [self clearScheduledCheckinTimer]; - - // Checkin is still valid, so a remote checkin is not required. - if ([self.checkinPreferences hasValidCheckinInfo]) { - return; - } - - FIRInstanceID_WEAKIFY(self); - [self - fetchCheckinInfoWithHandler:^(FIRInstanceIDCheckinPreferences *preferences, NSError *error) { - FIRInstanceID_STRONGIFY(self); - self.checkinRetryCount++; - - if (error) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeAuthService001, @"Checkin error %@.", - error); - - dispatch_async(dispatch_get_main_queue(), ^{ - // Schedule another checkin - [self scheduleCheckin:NO]; - }); - - } else { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeAuthService002, @"Checkin success."); - } - }]; -} - -- (int64_t)calculateNextCheckinRetryIntervalInSeconds { - // persistent failures can lead to overflow prevent that. - if (self.checkinRetryCount >= 10) { - return kMaxCheckinRetryIntervalInSeconds; - } - return MIN(1 << self.checkinRetryCount, kMaxCheckinRetryIntervalInSeconds); -} - -#pragma mark - Checkin Service - -- (BOOL)hasValidCheckinInfo { - return [self.checkinPreferences hasValidCheckinInfo]; -} - -- (void)fetchCheckinInfoWithHandler:(nonnull FIRInstanceIDDeviceCheckinCompletion)handler { - // Perform any changes to self.checkinHandlers and _isCheckinInProgress in a thread-safe way. - @synchronized(self) { - [self.checkinHandlers addObject:handler]; - - if (_isCheckinInProgress) { - // Nothing more to do until our checkin request is done - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeAuthServiceCheckinInProgress, - @"Checkin is in progress\n"); - return; - } - } - - // Checkin is still valid, so a remote checkin is not required. - if ([self.checkinPreferences hasValidCheckinInfo]) { - [self notifyCheckinHandlersWithCheckin:self.checkinPreferences error:nil]; - return; - } - - @synchronized(self) { - _isCheckinInProgress = YES; - } - [self.checkinService - checkinWithExistingCheckin:self.checkinPreferences - completion:^(FIRInstanceIDCheckinPreferences *checkinPreferences, - NSError *error) { - @synchronized(self) { - self->_isCheckinInProgress = NO; - } - if (error) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeAuthService003, - @"Failed to checkin device %@", error); - [self notifyCheckinHandlersWithCheckin:nil error:error]; - return; - } - - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeAuthService004, - @"Successfully got checkin credentials"); - BOOL hasSameCachedPreferences = - [self cachedCheckinMatchesCheckin:checkinPreferences]; - checkinPreferences.hasPreCachedAuthCredentials = hasSameCachedPreferences; - - // Update to the most recent checkin preferences - self.checkinPreferences = checkinPreferences; - - // Save the checkin info to disk - // Keychain might not be accessible, so confirm that checkin preferences can - // be saved - [self.store - saveCheckinPreferences:checkinPreferences - handler:^(NSError *checkinSaveError) { - if (checkinSaveError && !hasSameCachedPreferences) { - // The checkin info was new, but it couldn't be - // written to the Keychain. Delete any stuff that was - // cached in memory. This doesn't delete any - // previously persisted preferences. - FIRInstanceIDLoggerError( - kFIRInstanceIDMessageCodeService004, - @"Unable to save checkin info, resetting " - @"checkin preferences " - "in memory."); - [checkinPreferences reset]; - [self - notifyCheckinHandlersWithCheckin:nil - error: - checkinSaveError]; - } else { - // The checkin is either new, or it was the same (and - // it couldn't be saved). Either way, report that the - // checkin preferences were received successfully. - [self notifyCheckinHandlersWithCheckin: - checkinPreferences - error:nil]; - if (!hasSameCachedPreferences) { - // Checkin is new. - // Notify any listeners that might be waiting for - // checkin to be fetched, such as Firebase - // Messaging (for its MCS connection). - dispatch_async(dispatch_get_main_queue(), ^{ - [[NSNotificationCenter defaultCenter] - postNotificationName: - kFIRInstanceIDCheckinFetchedNotification - object:nil]; - }); - } - } - }]; - }]; -} - -- (FIRInstanceIDCheckinPreferences *)checkinPreferences { - return _checkinPreferences; -} - -- (void)stopCheckinRequest { - [self.checkinService stopFetching]; -} - -- (void)resetCheckinWithHandler:(void (^)(NSError *error))handler { - [self.store removeCheckinPreferencesWithHandler:^(NSError *error) { - if (!error) { - self.checkinPreferences = nil; - } - if (handler) { - handler(error); - } - }]; -} - -#pragma mark - Private - -/** - * Goes through the current list of checkin handlers and fires them with the same checkin and/or - * error info. The checkin handlers will get cleared after. - */ -- (void)notifyCheckinHandlersWithCheckin:(nullable FIRInstanceIDCheckinPreferences *)checkin - error:(nullable NSError *)error { - @synchronized(self) { - for (FIRInstanceIDDeviceCheckinCompletion handler in self.checkinHandlers) { - handler(checkin, error); - } - [self.checkinHandlers removeAllObjects]; - } -} - -/** - * Given a |checkin|, it will compare it to the current checkinPreferences to see if the - * deviceID and secretToken are the same. - */ -- (BOOL)cachedCheckinMatchesCheckin:(FIRInstanceIDCheckinPreferences *)checkin { - if (self.checkinPreferences && checkin) { - return ([self.checkinPreferences.deviceID isEqualToString:checkin.deviceID] && - [self.checkinPreferences.secretToken isEqualToString:checkin.secretToken]); - } - return NO; -} -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDBackupExcludedPlist.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDBackupExcludedPlist.h @@ -1,89 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -@interface FIRInstanceIDBackupExcludedPlist : NSObject - -/** - * Caches the plist contents in memory so we don't hit the disk each time we want - * to query something in the plist. This is loaded lazily i.e. if you write to the - * plist the contents you want to write will be stored here if the write was - * successful. The other case where it is loaded is if you read the plist contents - * by calling `contentAsDictionary`. - * - * In case you write to the plist and then try to read the file using - * `contentAsDictionary` we would just return the cachedPlistContents since it would - * represent the disk contents. - */ -@property(nonatomic, readonly, strong) NSDictionary *cachedPlistContents; - -/** - * Init a backup excluded plist file. - * - * @param fileName The filename for the plist file. - * @param applicationSupportSubDirectory The subdirectory in Application Support to save the plist. - * - * @return Helper which allows to read write data to a backup excluded plist. - */ -- (instancetype)initWithFileName:(NSString *)fileName - applicationSupportSubDirectory:(NSString *)applicationSupportSubDirectory; - -/** - * Write dictionary data to the backup excluded plist file. If the file does not exist - * it would be created before writing to it. - * - * @param dict The data to be written to the plist. - * @param error The error object if any while writing the data. - * - * @return YES if the write was successful else NO. - */ -- (BOOL)writeDictionary:(NSDictionary *)dict error:(NSError **)error; - -/** - * Delete the backup excluded plist created with the above filename. - * - * @param error The error object if any while deleting the file. - * - * @return YES If the delete was successful else NO. - */ -- (BOOL)deleteFile:(NSError **)error; - -/** - * The contents of the plist file. We also store the contents of the file in-memory. - * If the in-memory contents are valid we return the in-memory contents else we read - * the file from disk. - * - * @return A dictionary object that contains the contents of the plist file if the file - * exists else nil. - */ -- (NSDictionary *)contentAsDictionary; - -/** - * Check if the plist exists on the disk or not. - * - * @return YES if the file exists on the disk else NO. - */ -- (BOOL)doesFileExist; - -/** - * Move the plist to Application Support subdirectory. If the plist is already in the correct - * subdirectory this will be a no-op. If the plist was never written to before this will remember - * to write this plist to the Application Support subfolder if it's written to in future. - */ -- (void)moveToApplicationSupportSubDirectory; - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDBackupExcludedPlist.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDBackupExcludedPlist.m @@ -1,200 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDBackupExcludedPlist.h" - -#import "FIRInstanceIDDefines.h" -#import "FIRInstanceIDLogger.h" - -typedef enum : NSUInteger { - FIRInstanceIDPlistDirectoryUnknown, - FIRInstanceIDPlistDirectoryDocuments, - FIRInstanceIDPlistDirectoryApplicationSupport, -} FIRInstanceIDPlistDirectory; - -@interface FIRInstanceIDBackupExcludedPlist () - -@property(nonatomic, readwrite, copy) NSString *fileName; -@property(nonatomic, readwrite, copy) NSString *applicationSupportSubDirectory; -@property(nonatomic, readwrite, assign) BOOL fileInApplicationSupport; - -@property(nonatomic, readwrite, strong) NSDictionary *cachedPlistContents; - -@end - -@implementation FIRInstanceIDBackupExcludedPlist - -- (instancetype)initWithFileName:(NSString *)fileName - applicationSupportSubDirectory:(NSString *)applicationSupportSubDirectory { - self = [super init]; - if (self) { - _fileName = [fileName copy]; - _applicationSupportSubDirectory = [applicationSupportSubDirectory copy]; - _fileInApplicationSupport = - [self moveToApplicationSupportSubDirectory:applicationSupportSubDirectory]; - } - return self; -} - -- (BOOL)writeDictionary:(NSDictionary *)dict error:(NSError **)error { - NSString *path = [self plistPathInDirectory:[self plistDirectory]]; - if (![dict writeToFile:path atomically:YES]) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeBackupExcludedPlist000, - @"Failed to write to %@.plist", self.fileName); - return NO; - } - - // Successfully wrote contents -- change the in-memory contents - self.cachedPlistContents = [dict copy]; - - _FIRInstanceIDDevAssert([[NSFileManager defaultManager] fileExistsAtPath:path], - @"Error writing data to non-backed up plist %@.plist", self.fileName); - - NSURL *URL = [NSURL fileURLWithPath:path]; - if (error) { - *error = nil; - } - - NSDictionary *preferences = [URL resourceValuesForKeys:@[ NSURLIsExcludedFromBackupKey ] - error:error]; - if ([preferences[NSURLIsExcludedFromBackupKey] boolValue]) { - return YES; - } - - BOOL success = [URL setResourceValue:@(YES) forKey:NSURLIsExcludedFromBackupKey error:error]; - if (!success) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeBackupExcludedPlist001, - @"Error excluding %@ from backup, %@", [URL lastPathComponent], - error ? *error : @""); - } - return success; -} - -- (BOOL)deleteFile:(NSError **)error { - BOOL success = YES; - NSString *path = [self plistPathInDirectory:[self plistDirectory]]; - if ([[NSFileManager defaultManager] fileExistsAtPath:path]) { - success = [[NSFileManager defaultManager] removeItemAtPath:path error:error]; - } - // remove the in-memory contents - self.cachedPlistContents = nil; - return success; -} - -- (NSDictionary *)contentAsDictionary { - if (!self.cachedPlistContents) { - NSString *path = [self plistPathInDirectory:[self plistDirectory]]; - if ([[NSFileManager defaultManager] fileExistsAtPath:path]) { - self.cachedPlistContents = [[NSDictionary alloc] initWithContentsOfFile:path]; - } - } - return self.cachedPlistContents; -} - -- (void)moveToApplicationSupportSubDirectory { - self.fileInApplicationSupport = - [self moveToApplicationSupportSubDirectory:self.applicationSupportSubDirectory]; -} - -- (BOOL)moveToApplicationSupportSubDirectory:(NSString *)subDirectoryName { - NSArray *directoryPaths = - NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); - NSString *applicationSupportDirPath = directoryPaths.lastObject; - NSArray *components = @[ applicationSupportDirPath, subDirectoryName ]; - NSString *subDirectoryPath = [NSString pathWithComponents:components]; - BOOL hasSubDirectory; - if (![[NSFileManager defaultManager] fileExistsAtPath:subDirectoryPath - isDirectory:&hasSubDirectory]) { - // Cannot move to non-existent directory - return NO; - } - - if ([self doesFileExistInDirectory:FIRInstanceIDPlistDirectoryDocuments]) { - NSString *oldPlistPath = [self plistPathInDirectory:FIRInstanceIDPlistDirectoryDocuments]; - NSString *newPlistPath = - [self plistPathInDirectory:FIRInstanceIDPlistDirectoryApplicationSupport]; - if ([self doesFileExistInDirectory:FIRInstanceIDPlistDirectoryApplicationSupport]) { - // File exists in both Documents and ApplicationSupport - return NO; - } - NSError *moveError; - if (![[NSFileManager defaultManager] moveItemAtPath:oldPlistPath - toPath:newPlistPath - error:&moveError]) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeBackupExcludedPlist002, - @"Failed to move file %@ from %@ to %@. Error: %@", self.fileName, - oldPlistPath, newPlistPath, moveError); - return NO; - } - } - // We moved the file if it existed, otherwise we didn't need to do anything - return YES; -} - -- (BOOL)doesFileExist { - return [self doesFileExistInDirectory:[self plistDirectory]]; -} - -#pragma mark - Private - -- (FIRInstanceIDPlistDirectory)plistDirectory { - if (self.fileInApplicationSupport) { - return FIRInstanceIDPlistDirectoryApplicationSupport; - } else { - return FIRInstanceIDPlistDirectoryDocuments; - }; -} - -- (NSString *)plistPathInDirectory:(FIRInstanceIDPlistDirectory)directory { - return [self pathWithName:self.fileName inDirectory:directory]; -} - -- (NSString *)pathWithName:(NSString *)plistName - inDirectory:(FIRInstanceIDPlistDirectory)directory { - NSArray *directoryPaths; - NSArray *components = @[]; - NSString *plistNameWithExtension = [NSString stringWithFormat:@"%@.plist", plistName]; - switch (directory) { - case FIRInstanceIDPlistDirectoryDocuments: - directoryPaths = - NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); - components = @[ directoryPaths.lastObject, plistNameWithExtension ]; - break; - - case FIRInstanceIDPlistDirectoryApplicationSupport: - directoryPaths = - NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); - components = @[ - directoryPaths.lastObject, self.applicationSupportSubDirectory, plistNameWithExtension - ]; - break; - - default: - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeBackupExcludedPlistInvalidPlistEnum, - @"Invalid plist directory type: %lu", (unsigned long)directory); - NSAssert(NO, @"Invalid plist directory type: %lu", (unsigned long)directory); - break; - } - - return [NSString pathWithComponents:components]; -} - -- (BOOL)doesFileExistInDirectory:(FIRInstanceIDPlistDirectory)directory { - NSString *path = [self plistPathInDirectory:directory]; - return [[NSFileManager defaultManager] fileExistsAtPath:path]; -} - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences+Internal.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences+Internal.h @@ -1,64 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDCheckinPreferences.h" - -@interface FIRInstanceIDCheckinPreferences (Internal) - -/** - * Parse the checkin auth credentials saved in the Keychain to initialize checkin - * preferences. - * - * @param keychainContent The checkin auth credentials saved in the Keychain. - * - * @return A valid checkin preferences object if the checkin auth credentials in the - * keychain can be parsed successfully else nil. - */ -+ (FIRInstanceIDCheckinPreferences *)preferencesFromKeychainContents:(NSString *)keychainContent; - -/** - * Default initializer for InstanceID checkin preferences. - * - * @param deviceID The deviceID for the app. - * @param secretToken The secret token the app uses to authenticate with the server. - * - * @return A checkin preferences object with given deviceID and secretToken. - */ -- (instancetype)initWithDeviceID:(NSString *)deviceID secretToken:(NSString *)secretToken; - -/** - * Update checkin preferences from the preferences dict persisted as a plist. The dict contains - * all the checkin preferences retrieved from the server except the deviceID and secret which - * are stored in the Keychain. - * - * @param checkinPlistContent The checkin preferences saved in a plist on the disk. - */ -- (void)updateWithCheckinPlistContents:(NSDictionary *)checkinPlistContent; - -/** - * Reset the current checkin preferences object. - */ -- (void)reset; - -/** - * The string that contains the checkin auth credentials i.e. deviceID and secret. This - * needs to be stored in the Keychain. - * - * @return The checkin auth credential string containing the deviceID and secret. - */ -- (NSString *)checkinKeychainContent; - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences+Internal.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences+Internal.m @@ -1,112 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDCheckinPreferences+Internal.h" - -#import "FIRInstanceIDCheckinService.h" -#import "FIRInstanceIDUtilities.h" - -static NSString *const kCheckinKeychainContentSeparatorString = @"|"; - -@interface FIRInstanceIDCheckinPreferences () - -@property(nonatomic, readwrite, copy) NSString *deviceID; -@property(nonatomic, readwrite, copy) NSString *secretToken; -@property(nonatomic, readwrite, copy) NSString *digest; -@property(nonatomic, readwrite, copy) NSString *versionInfo; -@property(nonatomic, readwrite, copy) NSString *deviceDataVersion; - -@property(nonatomic, readwrite, strong) NSMutableDictionary *gServicesData; -@property(nonatomic, readwrite, assign) int64_t lastCheckinTimestampMillis; - -@end - -@implementation FIRInstanceIDCheckinPreferences (Internal) - -+ (FIRInstanceIDCheckinPreferences *)preferencesFromKeychainContents:(NSString *)keychainContent { - NSString *deviceID = [self checkinDeviceIDFromKeychainContent:keychainContent]; - NSString *secret = [self checkinSecretFromKeychainContent:keychainContent]; - if ([deviceID length] && [secret length]) { - return [[FIRInstanceIDCheckinPreferences alloc] initWithDeviceID:deviceID secretToken:secret]; - } else { - return nil; - } -} - -- (instancetype)initWithDeviceID:(NSString *)deviceID secretToken:(NSString *)secretToken { - self = [super init]; - if (self) { - self.deviceID = [deviceID copy]; - self.secretToken = [secretToken copy]; - } - return self; -} - -- (void)reset { - self.deviceID = nil; - self.secretToken = nil; - self.digest = nil; - self.versionInfo = nil; - self.gServicesData = nil; - self.deviceDataVersion = nil; - self.lastCheckinTimestampMillis = 0; -} - -- (void)updateWithCheckinPlistContents:(NSDictionary *)checkinPlistContent { - for (NSString *key in checkinPlistContent) { - if ([kFIRInstanceIDDigestStringKey isEqualToString:key]) { - self.digest = [checkinPlistContent[key] copy]; - } else if ([kFIRInstanceIDVersionInfoStringKey isEqualToString:key]) { - self.versionInfo = [checkinPlistContent[key] copy]; - } else if ([kFIRInstanceIDLastCheckinTimeKey isEqualToString:key]) { - self.lastCheckinTimestampMillis = [checkinPlistContent[key] longLongValue]; - } else if ([kFIRInstanceIDGServicesDictionaryKey isEqualToString:key]) { - self.gServicesData = [checkinPlistContent[key] mutableCopy]; - } else if ([kFIRInstanceIDDeviceDataVersionKey isEqualToString:key]) { - self.deviceDataVersion = [checkinPlistContent[key] copy]; - } - // Otherwise we have some keys we don't care about - } -} - -- (NSString *)checkinKeychainContent { - if ([self.deviceID length] && [self.secretToken length]) { - return [NSString stringWithFormat:@"%@%@%@", self.deviceID, - kCheckinKeychainContentSeparatorString, self.secretToken]; - } else { - return nil; - } -} - -+ (NSString *)checkinDeviceIDFromKeychainContent:(NSString *)keychainContent { - return [self checkinKeychainContent:keychainContent forIndex:0]; -} - -+ (NSString *)checkinSecretFromKeychainContent:(NSString *)keychainContent { - return [self checkinKeychainContent:keychainContent forIndex:1]; -} - -+ (NSString *)checkinKeychainContent:(NSString *)keychainContent forIndex:(int)index { - NSArray *keychainComponents = - [keychainContent componentsSeparatedByString:kCheckinKeychainContentSeparatorString]; - if (index >= 0 && index < 2 && [keychainComponents count] == 2) { - return keychainComponents[index]; - } else { - return nil; - } -} - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences.h @@ -1,63 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -/** - * The preferences InstanceID loads from checkin server. The deviceID and secret that checkin - * provides is used to authenticate all future requests to the server. Besides the deviceID - * and secret the other information that checkin provides is stored in a plist on the device. - * The deviceID and secret are persisted in the device keychain. - */ -@interface FIRInstanceIDCheckinPreferences : NSObject - -/** - * DeviceID and secretToken are the checkin auth credentials and are stored in the Keychain. - */ -@property(nonatomic, readonly, copy) NSString *deviceID; -@property(nonatomic, readonly, copy) NSString *secretToken; - -/** - * All the other checkin preferences other than deviceID and secret are stored in a plist. - */ -@property(nonatomic, readonly, copy) NSString *deviceDataVersion; -@property(nonatomic, readonly, copy) NSString *digest; -@property(nonatomic, readonly, copy) NSString *versionInfo; -@property(nonatomic, readonly, strong) NSMutableDictionary *gServicesData; -@property(nonatomic, readonly, assign) int64_t lastCheckinTimestampMillis; - -/** - * The content retrieved from checkin server that should be persisted in a plist. This - * doesn't contain the deviceID and secret which are stored in the Keychain since they - * should be more private. - * - * @return The checkin preferences that should be persisted in a plist. - */ -- (NSDictionary *)checkinPlistContents; - -/** - * Return whether checkin info exists, valid or not. - */ -- (BOOL)hasCheckinInfo; - -/** - * Verify if checkin preferences are valid or not. - * - * @return YES if valid checkin preferences else NO. - */ -- (BOOL)hasValidCheckinInfo; - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences.m @@ -1,97 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDCheckinPreferences.h" - -#import <GoogleUtilities/GULUserDefaults.h> -#import "FIRInstanceIDCheckinService.h" -#import "FIRInstanceIDDefines.h" -#import "FIRInstanceIDUtilities.h" - -const NSTimeInterval kFIRInstanceIDDefaultCheckinInterval = 7 * 24 * 60 * 60; // 7 days. - -@interface FIRInstanceIDCheckinPreferences () - -@property(nonatomic, readwrite, copy) NSString *deviceID; -@property(nonatomic, readwrite, copy) NSString *secretToken; -@property(nonatomic, readwrite, copy) NSString *digest; -@property(nonatomic, readwrite, copy) NSString *versionInfo; -@property(nonatomic, readwrite, copy) NSString *deviceDataVersion; - -@property(nonatomic, readwrite, strong) NSMutableDictionary *gServicesData; -@property(nonatomic, readwrite, assign) int64_t lastCheckinTimestampMillis; - -// This flag indicates that we have already saved the above deviceID and secret -// to our keychain and hence we don't need to save again. This is helpful since -// on checkin refresh we can avoid writing to the Keychain which can sometimes -// be very buggy. For info check this https://forums.developer.apple.com/thread/4743 -@property(nonatomic, readwrite, assign) BOOL hasPreCachedAuthCredentials; - -@end - -@implementation FIRInstanceIDCheckinPreferences - -- (NSDictionary *)checkinPlistContents { - NSMutableDictionary *checkinPlistContents = [NSMutableDictionary dictionary]; - checkinPlistContents[kFIRInstanceIDDigestStringKey] = self.digest ?: @""; - checkinPlistContents[kFIRInstanceIDVersionInfoStringKey] = self.versionInfo ?: @""; - checkinPlistContents[kFIRInstanceIDDeviceDataVersionKey] = self.deviceDataVersion ?: @""; - checkinPlistContents[kFIRInstanceIDLastCheckinTimeKey] = @(self.lastCheckinTimestampMillis); - checkinPlistContents[kFIRInstanceIDGServicesDictionaryKey] = - [self.gServicesData count] ? self.gServicesData : @{}; - return checkinPlistContents; -} - -- (BOOL)hasCheckinInfo { - return (self.deviceID.length && self.secretToken.length); -} - -- (BOOL)hasValidCheckinInfo { - int64_t currentTimestampInMillis = FIRInstanceIDCurrentTimestampInMilliseconds(); - int64_t timeSinceLastCheckinInMillis = currentTimestampInMillis - self.lastCheckinTimestampMillis; - _FIRInstanceIDDevAssert(timeSinceLastCheckinInMillis >= 0, - @"FCM error: cannot have last checkin timestamp in future"); - BOOL hasCheckinInfo = [self hasCheckinInfo]; - NSString *lastLocale = - [[GULUserDefaults standardUserDefaults] stringForKey:kFIRInstanceIDUserDefaultsKeyLocale]; - // If it's app's first time open and checkin is already fetched and no locale information is - // stored, then checkin info is valid. We should not checkin again because locale is considered - // "changed". - if (hasCheckinInfo && !lastLocale) { - NSString *currentLocale = FIRInstanceIDCurrentLocale(); - [[GULUserDefaults standardUserDefaults] setObject:currentLocale - forKey:kFIRInstanceIDUserDefaultsKeyLocale]; - return YES; - } - - // If locale has changed, checkin info is no longer valid. - // Also update locale information if changed. (Only do it here not in token refresh) - if (FIRInstanceIDHasLocaleChanged()) { - NSString *currentLocale = FIRInstanceIDCurrentLocale(); - [[GULUserDefaults standardUserDefaults] setObject:currentLocale - forKey:kFIRInstanceIDUserDefaultsKeyLocale]; - return NO; - } - - return (hasCheckinInfo && - (timeSinceLastCheckinInMillis / 1000.0 < kFIRInstanceIDDefaultCheckinInterval)); -} - -- (void)setHasPreCachedAuthCredentials:(BOOL)hasPreCachedAuthCredentials { - _hasPreCachedAuthCredentials = hasPreCachedAuthCredentials; -} - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences_Private.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences_Private.h @@ -1,27 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDCheckinPreferences.h" - -/** Checkin refresh interval. **/ -FOUNDATION_EXPORT const NSTimeInterval kFIRInstanceIDDefaultCheckinInterval; - -@interface FIRInstanceIDCheckinPreferences () - -- (BOOL)hasPreCachedAuthCredentials; -- (void)setHasPreCachedAuthCredentials:(BOOL)hasPreCachedAuthCredentials; - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinService.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinService.h @@ -1,81 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -#import "FIRInstanceIDUtilities.h" - -NS_ASSUME_NONNULL_BEGIN - -// keys in Checkin preferences -FOUNDATION_EXPORT NSString *const kFIRInstanceIDDeviceAuthIdKey; -FOUNDATION_EXPORT NSString *const kFIRInstanceIDSecretTokenKey; -FOUNDATION_EXPORT NSString *const kFIRInstanceIDDigestStringKey; -FOUNDATION_EXPORT NSString *const kFIRInstanceIDLastCheckinTimeKey; -FOUNDATION_EXPORT NSString *const kFIRInstanceIDVersionInfoStringKey; -FOUNDATION_EXPORT NSString *const kFIRInstanceIDGServicesDictionaryKey; -FOUNDATION_EXPORT NSString *const kFIRInstanceIDDeviceDataVersionKey; - -@class FIRInstanceIDCheckinPreferences; - -/** - * @related FIRInstanceIDCheckinService - * - * The completion handler invoked once the fetch from Checkin server finishes. - * For successful fetches we returned checkin information by the checkin service - * and `nil` error, else we return the appropriate error object as reported by the - * Checkin Service. - * - * @param checkinPreferences The checkin preferences as fetched from the server. - * @param error The error object which fetching GServices data. - */ -typedef void (^FIRInstanceIDDeviceCheckinCompletion)( - FIRInstanceIDCheckinPreferences *_Nullable checkinPreferences, NSError *_Nullable error); - -/** - * Register the device with Checkin Service and get back the `authID`, `secret - * token` etc. for the client. Checkin results are cached in the - * `FIRInstanceIDCache` and periodically refreshed to prevent them from being stale. - * Each client needs to register with checkin before registering with InstanceID. - */ -@interface FIRInstanceIDCheckinService : NSObject - -/** - * Execute a device checkin request to obtain an deviceID, secret token, - * gService data. - * - * @param existingCheckin An existing checkin preference object, if available. - * @param completion Completion hander called on success or failure of device checkin. - */ -- (void)checkinWithExistingCheckin:(nullable FIRInstanceIDCheckinPreferences *)existingCheckin - completion:(FIRInstanceIDDeviceCheckinCompletion)completion; - -/** - * This would stop any request that the service made to the checkin backend and also - * release any callback handlers that it holds. - */ -- (void)stopFetching; - -/** - * Set test block for mock testing network requests. - * - * @param block The block to invoke as a mock response from the network. - */ -+ (void)setCheckinTestBlock:(nullable FIRInstanceIDURLRequestTestBlock)block; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinService.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinService.m @@ -1,223 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDCheckinService.h" - -#import "FIRInstanceIDCheckinPreferences+Internal.h" -#import "FIRInstanceIDCheckinPreferences_Private.h" -#import "FIRInstanceIDDefines.h" -#import "FIRInstanceIDLogger.h" -#import "FIRInstanceIDStore.h" -#import "FIRInstanceIDUtilities.h" -#import "NSError+FIRInstanceID.h" - -static NSString *const kDeviceCheckinURL = @"https://device-provisioning.googleapis.com/checkin"; - -// keys in Checkin preferences -NSString *const kFIRInstanceIDDeviceAuthIdKey = @"GMSInstanceIDDeviceAuthIdKey"; -NSString *const kFIRInstanceIDSecretTokenKey = @"GMSInstanceIDSecretTokenKey"; -NSString *const kFIRInstanceIDDigestStringKey = @"GMSInstanceIDDigestKey"; -NSString *const kFIRInstanceIDLastCheckinTimeKey = @"GMSInstanceIDLastCheckinTimestampKey"; -NSString *const kFIRInstanceIDVersionInfoStringKey = @"GMSInstanceIDVersionInfo"; -NSString *const kFIRInstanceIDGServicesDictionaryKey = @"GMSInstanceIDGServicesData"; -NSString *const kFIRInstanceIDDeviceDataVersionKey = @"GMSInstanceIDDeviceDataVersion"; - -static NSUInteger const kCheckinType = 2; // DeviceType IOS in l/w/a/_checkin.proto -static NSUInteger const kCheckinVersion = 2; -static NSUInteger const kFragment = 0; - -static FIRInstanceIDURLRequestTestBlock testBlock; - -@interface FIRInstanceIDCheckinService () - -@property(nonatomic, readwrite, strong) NSURLSession *session; - -@end - -@implementation FIRInstanceIDCheckinService -; - -- (instancetype)init { - self = [super init]; - if (self) { - // Create an URLSession once, even though checkin should happen about once a day - NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; - config.timeoutIntervalForResource = 60.0f; // 1 minute - config.allowsCellularAccess = YES; - _session = [NSURLSession sessionWithConfiguration:config]; - _session.sessionDescription = @"com.google.iid-checkin"; - } - return self; -} - -- (void)dealloc { - testBlock = nil; - [self.session invalidateAndCancel]; -} - -- (void)checkinWithExistingCheckin:(FIRInstanceIDCheckinPreferences *)existingCheckin - completion:(FIRInstanceIDDeviceCheckinCompletion)completion { - _FIRInstanceIDDevAssert(completion != nil, @"completion required"); - - NSURL *url = [NSURL URLWithString:kDeviceCheckinURL]; - NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; - [request setValue:@"application/json" forHTTPHeaderField:@"content-type"]; - NSDictionary *checkinParameters = [self checkinParametersWithExistingCheckin:existingCheckin]; - NSData *checkinData = [NSJSONSerialization dataWithJSONObject:checkinParameters - options:0 - error:nil]; - request.HTTPMethod = @"POST"; - request.HTTPBody = checkinData; - - void (^handler)(NSData *, NSURLResponse *, NSError *) = - ^(NSData *data, NSURLResponse *response, NSError *error) { - if (error) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeService000, - @"Device checkin HTTP fetch error. Error Code: %ld", - (long)error.code); - completion(nil, error); - return; - } - - NSError *serializationError; - NSDictionary *dataResponse = [NSJSONSerialization JSONObjectWithData:data - options:0 - error:&serializationError]; - if (serializationError) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeService001, - @"Error serializing json object. Error Code: %ld", - _FIRInstanceID_L(serializationError.code)); - completion(nil, serializationError); - return; - } - - NSString *deviceAuthID = [dataResponse[@"android_id"] stringValue]; - NSString *secretToken = [dataResponse[@"security_token"] stringValue]; - if ([deviceAuthID length] == 0) { - NSError *error = - [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeInvalidRequest]; - completion(nil, error); - return; - } - - int64_t lastCheckinTimestampMillis = [dataResponse[@"time_msec"] longLongValue]; - int64_t currentTimestampMillis = FIRInstanceIDCurrentTimestampInMilliseconds(); - // Somehow the server clock gets out of sync with the device clock. - // Reset the last checkin timestamp in case this happens. - if (lastCheckinTimestampMillis > currentTimestampMillis) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeService002, - @"Invalid last checkin timestamp in future."); - lastCheckinTimestampMillis = currentTimestampMillis; - } - - NSString *deviceDataVersionInfo = dataResponse[@"device_data_version_info"] ?: @""; - NSString *digest = dataResponse[@"digest"] ?: @""; - - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeService003, - @"Checkin successful with authId: %@, " - @"digest: %@, " - @"lastCheckinTimestamp: %lld", - deviceAuthID, digest, lastCheckinTimestampMillis); - - NSString *versionInfo = dataResponse[@"version_info"] ?: @""; - NSMutableDictionary *gservicesData = [NSMutableDictionary dictionary]; - - // Read gServices data. - NSArray *flatSettings = dataResponse[@"setting"]; - for (NSDictionary *dict in flatSettings) { - if (dict[@"name"] && dict[@"value"]) { - gservicesData[dict[@"name"]] = dict[@"value"]; - } else { - _FIRInstanceIDDevAssert(NO, @"Invalid setting in checkin response: (%@: %@)", - dict[@"name"], dict[@"value"]); - } - } - - FIRInstanceIDCheckinPreferences *checkinPreferences = - [[FIRInstanceIDCheckinPreferences alloc] initWithDeviceID:deviceAuthID - secretToken:secretToken]; - NSDictionary *preferences = @{ - kFIRInstanceIDDigestStringKey : digest, - kFIRInstanceIDVersionInfoStringKey : versionInfo, - kFIRInstanceIDLastCheckinTimeKey : @(lastCheckinTimestampMillis), - kFIRInstanceIDGServicesDictionaryKey : gservicesData, - kFIRInstanceIDDeviceDataVersionKey : deviceDataVersionInfo, - }; - [checkinPreferences updateWithCheckinPlistContents:preferences]; - completion(checkinPreferences, nil); - }; - // Test block - if (testBlock) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeService005, - @"Test block set, will not hit the server"); - testBlock(request, handler); - return; - } - - NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request completionHandler:handler]; - [task resume]; -} - -- (void)stopFetching { - [self.session invalidateAndCancel]; -} - -#pragma mark - Private - -- (NSDictionary *)checkinParametersWithExistingCheckin: - (nullable FIRInstanceIDCheckinPreferences *)checkinPreferences { - NSString *deviceModel = FIRInstanceIDDeviceModel(); - NSString *systemVersion = FIRInstanceIDOperatingSystemVersion(); - NSString *osVersion = [NSString stringWithFormat:@"IOS_%@", systemVersion]; - - // Get locale from GCM if GCM exists else use system API. - NSString *locale = FIRInstanceIDCurrentLocale(); - - NSInteger userNumber = 0; // Multi Profile may change this. - NSInteger userSerialNumber = 0; // Multi Profile may change this - - uint32_t loggingID = arc4random(); - NSString *timeZone = [NSTimeZone localTimeZone].name; - int64_t lastCheckingTimestampMillis = checkinPreferences.lastCheckinTimestampMillis; - - NSDictionary *checkinParameters = @{ - @"checkin" : @{ - @"iosbuild" : @{@"model" : deviceModel, @"os_version" : osVersion}, - @"type" : @(kCheckinType), - @"user_number" : @(userNumber), - @"last_checkin_msec" : @(lastCheckingTimestampMillis), - }, - @"fragment" : @(kFragment), - @"logging_id" : @(loggingID), - @"locale" : locale, - @"version" : @(kCheckinVersion), - @"digest" : checkinPreferences.digest ?: @"", - @"timezone" : timeZone, - @"user_serial_number" : @(userSerialNumber), - @"id" : @([checkinPreferences.deviceID longLongValue]), - @"security_token" : @([checkinPreferences.secretToken longLongValue]), - }; - - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeService006, @"Checkin parameters: %@", - checkinParameters); - return checkinParameters; -} - -+ (void)setCheckinTestBlock:(FIRInstanceIDURLRequestTestBlock)block { - testBlock = [block copy]; -} - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinStore.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinStore.h @@ -1,108 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -@class FIRInstanceIDAuthKeychain; -@class FIRInstanceIDBackupExcludedPlist; -@class FIRInstanceIDCheckinPreferences; - -// These values exposed for testing -extern NSString *const kFIRInstanceIDCheckinKeychainService; -extern NSString *const kFIRInstanceIDLegacyCheckinKeychainAccount; -extern NSString *const kFIRInstanceIDLegacyCheckinKeychainService; - -/** - * Checkin preferences backing store. - */ -@interface FIRInstanceIDCheckinStore : NSObject - -/** - * Designated Initializer. Initialize a checkin store with the given backup excluded - * plist filename. - * - * @param checkinFilename The backup excluded plist filename to persist checkin - * preferences. - * - * @param applicationSupportSubDirectory Sub-directory in Application support where we write - * InstanceID plist. - * - * @return Store to persist checkin preferences. - */ -- (instancetype)initWithCheckinPlistFileName:(NSString *)checkinFilename - applicationSupportSubDirectory:(NSString *)applicationSupportSubDirectory; - -/** - * Initialize a checkin store with the given backup excluded plist and keychain. - * - * @param plist The backup excluded plist to persist checkin preferences. - * @param keychain The keychain used to persist checkin auth preferences. - * - * @return Store to persist checkin preferences. - */ -- (instancetype)initWithCheckinPlist:(FIRInstanceIDBackupExcludedPlist *)plist - keychain:(FIRInstanceIDAuthKeychain *)keychain; - -/** - * Checks whether the backup excluded checkin preferences are present on the disk or not. - * - * @return YES if the backup excluded checkin plist exists on the disks else NO. - */ -- (BOOL)hasCheckinPlist; - -#pragma mark - Save - -/** - * Save the checkin preferences to backing store. - * - * @param preferences Checkin preferences to save. - * @param handler The callback handler which is invoked when the operation is complete, - * with an error if there is any. - */ -- (void)saveCheckinPreferences:(FIRInstanceIDCheckinPreferences *)preferences - handler:(void (^)(NSError *error))handler; - -#pragma mark - Delete - -/** - * Remove the cached checkin preferences. - * - * @param handler The callback handler which is invoked when the operation is complete, - * with an error if there is any. - */ -- (void)removeCheckinPreferencesWithHandler:(void (^)(NSError *error))handler; - -#pragma mark - Get - -/** - * Get the cached device secret. If we cannot access it for some reason we - * return the appropriate error object. - * - * @return The cached checkin preferences if present else nil. - */ -- (FIRInstanceIDCheckinPreferences *)cachedCheckinPreferences; - -/** - * Migrate the checkin item from old service/account to the new one. - * The new account is dynamic as it uses bundle ID. - * This is to ensure checkin is not shared across apps, but still the same - * if app has used GCM before. - * This call should only happen once. - * - */ -- (void)migrateCheckinItemIfNeeded; - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinStore.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinStore.m @@ -1,239 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDCheckinStore.h" - -#import "FIRInstanceIDAuthKeyChain.h" -#import "FIRInstanceIDBackupExcludedPlist.h" -#import "FIRInstanceIDCheckinPreferences+Internal.h" -#import "FIRInstanceIDCheckinPreferences_Private.h" -#import "FIRInstanceIDCheckinService.h" -#import "FIRInstanceIDLogger.h" -#import "FIRInstanceIDUtilities.h" -#import "FIRInstanceIDVersionUtilities.h" -#import "NSError+FIRInstanceID.h" - -static NSString *const kFIRInstanceIDCheckinKeychainGeneric = @"com.google.iid"; - -NSString *const kFIRInstanceIDCheckinKeychainService = @"com.google.iid.checkin"; -NSString *const kFIRInstanceIDLegacyCheckinKeychainAccount = @"com.google.iid.checkin-account"; -NSString *const kFIRInstanceIDLegacyCheckinKeychainService = @"com.google.iid.checkin-service"; - -// Checkin plist used to have the deviceID and secret stored in them and that's why they -// had 6 items in it. Since the deviceID and secret have been moved to the keychain -// there would only be 4 items. -static const NSInteger kOldCheckinPlistCount = 6; - -@interface FIRInstanceIDCheckinStore () - -@property(nonatomic, readwrite, strong) FIRInstanceIDBackupExcludedPlist *plist; -@property(nonatomic, readwrite, strong) FIRInstanceIDAuthKeychain *keychain; -// Checkin will store items under -// Keychain account: <app bundle id>, -// Keychain service: |kFIRInstanceIDCheckinKeychainService| -@property(nonatomic, readonly) NSString *bundleIdentifierForKeychainAccount; - -@end - -@implementation FIRInstanceIDCheckinStore - -- (instancetype)initWithCheckinPlistFileName:(NSString *)checkinFilename - applicationSupportSubDirectory:(NSString *)applicationSupportSubDirectory { - FIRInstanceIDBackupExcludedPlist *plist = - [[FIRInstanceIDBackupExcludedPlist alloc] initWithFileName:checkinFilename - applicationSupportSubDirectory:applicationSupportSubDirectory]; - - FIRInstanceIDAuthKeychain *keychain = - [[FIRInstanceIDAuthKeychain alloc] initWithIdentifier:kFIRInstanceIDCheckinKeychainGeneric]; - return [self initWithCheckinPlist:plist keychain:keychain]; -} - -- (instancetype)initWithCheckinPlist:(FIRInstanceIDBackupExcludedPlist *)plist - keychain:(FIRInstanceIDAuthKeychain *)keychain { - self = [super init]; - if (self) { - _plist = plist; - _keychain = keychain; - } - return self; -} - -- (BOOL)hasCheckinPlist { - return [self.plist doesFileExist]; -} - -- (NSString *)bundleIdentifierForKeychainAccount { - static NSString *bundleIdentifier; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - bundleIdentifier = FIRInstanceIDAppIdentifier(); - }); - return bundleIdentifier; -} - -- (void)saveCheckinPreferences:(FIRInstanceIDCheckinPreferences *)preferences - handler:(void (^)(NSError *error))handler { - NSDictionary *checkinPlistContents = [preferences checkinPlistContents]; - NSString *checkinKeychainContent = [preferences checkinKeychainContent]; - - if (![checkinKeychainContent length]) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeCheckinStore000, - @"Failed to get checkin keychain content from memory."); - if (handler) { - handler([NSError - errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeRegistrarFailedToCheckIn]); - } - return; - } - if (![checkinPlistContents count]) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeCheckinStore001, - @"Failed to get checkin plist contents from memory."); - if (handler) { - handler([NSError - errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeRegistrarFailedToCheckIn]); - } - return; - } - - // Save the deviceID and secret in the Keychain - __block BOOL shouldContinue = YES; - if (!preferences.hasPreCachedAuthCredentials) { - NSData *data = [checkinKeychainContent dataUsingEncoding:NSUTF8StringEncoding]; - [self.keychain setData:data - forService:kFIRInstanceIDCheckinKeychainService - accessibility:nil - account:self.bundleIdentifierForKeychainAccount - handler:^(NSError *error) { - if (error) { - if (handler) { - handler(error); - } - shouldContinue = NO; - return; - } - }]; - } - if (!shouldContinue) { - return; - } - - // Save all other checkin preferences in a plist - NSError *error; - if (![self.plist writeDictionary:checkinPlistContents error:&error]) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeCheckinStore003, - @"Failed to save checkin plist contents." - @"Will delete auth credentials"); - [self.keychain removeItemsMatchingService:kFIRInstanceIDCheckinKeychainService - account:self.bundleIdentifierForKeychainAccount - handler:nil]; - if (handler) { - handler(error); - } - return; - } - handler(nil); -} - -- (void)removeCheckinPreferencesWithHandler:(void (^)(NSError *error))handler { - // Remove deviceID and secret from Keychain - [self.keychain - removeItemsMatchingService:kFIRInstanceIDCheckinKeychainService - account:self.bundleIdentifierForKeychainAccount - handler:^(NSError *error) { - if (error) { - if (handler) { - handler(error); - } - return; - } - // Delete the checkin preferences plist - NSError *deletePlistError; - [self.plist deleteFile:&deletePlistError]; - - // Try to remove from old location as well because migration - // is no longer needed. Consider this is either a fresh install - // or an identity wipe. - [self.keychain - removeItemsMatchingService:kFIRInstanceIDLegacyCheckinKeychainService - account:kFIRInstanceIDLegacyCheckinKeychainAccount - handler:nil]; - handler(deletePlistError); - }]; -} - -- (FIRInstanceIDCheckinPreferences *)cachedCheckinPreferences { - // Query the keychain for deviceID and secret - NSData *item = [self.keychain dataForService:kFIRInstanceIDCheckinKeychainService - account:self.bundleIdentifierForKeychainAccount]; - - // Check info found in keychain - NSString *checkinKeychainContent = [[NSString alloc] initWithData:item - encoding:NSUTF8StringEncoding]; - FIRInstanceIDCheckinPreferences *checkinPreferences = - [FIRInstanceIDCheckinPreferences preferencesFromKeychainContents:checkinKeychainContent]; - - NSDictionary *checkinPlistContents = [self.plist contentAsDictionary]; - - NSString *plistDeviceAuthID = checkinPlistContents[kFIRInstanceIDDeviceAuthIdKey]; - NSString *plistSecretToken = checkinPlistContents[kFIRInstanceIDSecretTokenKey]; - - // If deviceID and secret not found in the keychain verify that we don't have them in the - // checkin preferences plist. - if (![checkinPreferences.deviceID length] && ![checkinPreferences.secretToken length]) { - if ([plistDeviceAuthID length] && [plistSecretToken length]) { - // Couldn't find checkin credentials in keychain but found them in the plist. - checkinPreferences = - [[FIRInstanceIDCheckinPreferences alloc] initWithDeviceID:plistDeviceAuthID - secretToken:plistSecretToken]; - } else { - // Couldn't find checkin credentials in keychain nor plist - return nil; - } - } else if (kOldCheckinPlistCount == checkinPlistContents.count) { - // same check as above but just to be extra sure that we cover all upgrade cases properly. - // TODO(chliangGoogle): Remove this case, after verifying it's not needed - if ([plistDeviceAuthID length] && [plistSecretToken length]) { - checkinPreferences = - [[FIRInstanceIDCheckinPreferences alloc] initWithDeviceID:plistDeviceAuthID - secretToken:plistSecretToken]; - } - } - - [checkinPreferences updateWithCheckinPlistContents:checkinPlistContents]; - return checkinPreferences; -} - -- (void)migrateCheckinItemIfNeeded { - // Check for checkin in the old location, using the legacy keys - // Query the keychain for deviceID and secret - NSData *dataInOldLocation = - [self.keychain dataForService:kFIRInstanceIDLegacyCheckinKeychainService - account:kFIRInstanceIDLegacyCheckinKeychainAccount]; - if (dataInOldLocation) { - // Save to new location - [self.keychain setData:dataInOldLocation - forService:kFIRInstanceIDCheckinKeychainService - accessibility:NULL - account:self.bundleIdentifierForKeychainAccount - handler:nil]; - // Remove from old location - [self.keychain removeItemsMatchingService:kFIRInstanceIDLegacyCheckinKeychainService - account:kFIRInstanceIDLegacyCheckinKeychainAccount - handler:nil]; - } -} - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDConstants.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDConstants.h @@ -1,63 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -#pragma mark - Commands - -/** - * Value included in a structured response or GCM message from IID, indicating - * an identity reset. - */ -FOUNDATION_EXPORT NSString *const kFIRInstanceID_CMD_RST; - -#pragma mark - Notifications - -/// Notification used to deliver GCM messages for InstanceID. -FOUNDATION_EXPORT NSString *const kFIRInstanceIDCheckinFetchedNotification; -FOUNDATION_EXPORT NSString *const kFIRInstanceIDAPNSTokenNotification; -FOUNDATION_EXPORT NSString *const kFIRInstanceIDDefaultGCMTokenNotification; -FOUNDATION_EXPORT NSString *const kFIRInstanceIDDefaultGCMTokenFailNotification; - -FOUNDATION_EXPORT NSString *const kFIRInstanceIDIdentityInvalidatedNotification; - -#pragma mark - Miscellaneous - -/// The scope used to save the IID "*" scope token. This is used for saving the -/// IID auth token that we receive from the server. This feature was never -/// implemented on the server side. -FOUNDATION_EXPORT NSString *const kFIRInstanceIDAllScopeIdentifier; -/// The scope used to save the IID "*" scope token. -FOUNDATION_EXPORT NSString *const kFIRInstanceIDDefaultTokenScope; - -/// Subdirectory in Application Support directory to store InstanceID preferences. -FOUNDATION_EXPORT NSString *const kFIRInstanceIDApplicationSupportSubDirectory; - -/// The key for APNS token in options dictionary. -FOUNDATION_EXPORT NSString *const kFIRInstanceIDTokenOptionsAPNSKey; - -/// The key for APNS token environment type in options dictionary. -FOUNDATION_EXPORT NSString *const kFIRInstanceIDTokenOptionsAPNSIsSandboxKey; - -/// The key for GMP AppID sent in registration requests. -FOUNDATION_EXPORT NSString *const kFIRInstanceIDTokenOptionsFirebaseAppIDKey; - -/// The key to enable auto-register by swizzling AppDelegate's methods. -FOUNDATION_EXPORT NSString *const kFIRInstanceIDAppDelegateProxyEnabledInfoPlistKey; - -/// Error code for missing entitlements in Keychain. iOS Keychain error -/// https://forums.developer.apple.com/thread/4743 -FOUNDATION_EXPORT const int kFIRInstanceIDSecMissingEntitlementErrorCode; diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDConstants.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDConstants.m @@ -1,46 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDConstants.h" - -// Commands -NSString *const kFIRInstanceID_CMD_RST = @"RST"; - -// NOTIFICATIONS -NSString *const kFIRInstanceIDCheckinFetchedNotification = @"com.google.gcm.notif-checkin-fetched"; -NSString *const kFIRInstanceIDAPNSTokenNotification = @"com.firebase.iid.notif.apns-token"; -NSString *const kFIRInstanceIDDefaultGCMTokenNotification = @"com.firebase.iid.notif.fcm-token"; -NSString *const kFIRInstanceIDDefaultGCMTokenFailNotification = - @"com.firebase.iid.notif.fcm-token-fail"; - -NSString *const kFIRInstanceIDIdentityInvalidatedNotification = @"com.google.iid.identity-invalid"; - -// Miscellaneous -NSString *const kFIRInstanceIDAllScopeIdentifier = @"iid-all"; -NSString *const kFIRInstanceIDDefaultTokenScope = @"*"; -NSString *const kFIRInstanceIDApplicationSupportSubDirectory = @"Google/FirebaseInstanceID"; - -// Registration Options -NSString *const kFIRInstanceIDTokenOptionsAPNSKey = @"apns_token"; -NSString *const kFIRInstanceIDTokenOptionsAPNSIsSandboxKey = @"apns_sandbox"; -NSString *const kFIRInstanceIDTokenOptionsFirebaseAppIDKey = @"gmp_app_id"; - -NSString *const kFIRInstanceIDAppDelegateProxyEnabledInfoPlistKey = - @"FirebaseAppDelegateProxyEnabled"; - -// iOS Keychain error https://forums.developer.apple.com/thread/4743 -// An undocumented error code hence need to be redeclared. -const int kFIRInstanceIDSecMissingEntitlementErrorCode = -34018; diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDDefines.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDDefines.h @@ -1,70 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FIRInstanceIDLib_FIRInstanceIDDefines_h -#define FIRInstanceIDLib_FIRInstanceIDDefines_h - -#define _FIRInstanceID_VERBOSE_LOGGING 1 - -// Verbose Logging -#if (_FIRInstanceID_VERBOSE_LOGGING) -#define FIRInstanceID_DEV_VERBOSE_LOG(...) NSLog(__VA_ARGS__) -#else -#define FIRInstanceID_DEV_VERBOSE_LOG(...) \ - do { \ - } while (0) -#endif // VERBOSE_LOGGING - -// WEAKIFY & STRONGIFY -// Helper macro. -#define _FIRInstanceID_WEAKNAME(VAR) VAR##_weak_ - -#define FIRInstanceID_WEAKIFY(VAR) __weak __typeof__(VAR) _FIRInstanceID_WEAKNAME(VAR) = (VAR); - -#define FIRInstanceID_STRONGIFY(VAR) \ - _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wshadow\"") \ - __strong __typeof__(VAR) VAR = _FIRInstanceID_WEAKNAME(VAR); \ - _Pragma("clang diagnostic pop") - -// Type Conversions (used for NSInteger etc) -#ifndef _FIRInstanceID_L -#define _FIRInstanceID_L(v) (long)(v) -#endif - -#endif - -// Debug Assert -#ifndef _FIRInstanceIDDevAssert -// we directly invoke the NSAssert handler so we can pass on the varargs -// (NSAssert doesn't have a macro we can use that takes varargs) -#if !defined(NS_BLOCK_ASSERTIONS) -#define _FIRInstanceIDDevAssert(condition, ...) \ - do { \ - if (!(condition)) { \ - [[NSAssertionHandler currentHandler] \ - handleFailureInFunction:(NSString *)[NSString stringWithUTF8String:__PRETTY_FUNCTION__] \ - file:(NSString *)[NSString stringWithUTF8String:__FILE__] \ - lineNumber:__LINE__ \ - description:__VA_ARGS__]; \ - } \ - } while (0) -#else // !defined(NS_BLOCK_ASSERTIONS) -#define _FIRInstanceIDDevAssert(condition, ...) \ - do { \ - } while (0) -#endif // !defined(NS_BLOCK_ASSERTIONS) - -#endif // _FIRInstanceIDDevAssert diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPair.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPair.h @@ -1,78 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -@interface FIRInstanceIDKeyPair : NSObject - -- (instancetype)init __attribute__(( - unavailable("Use -initWithPrivateKey:publicKey:publicKeyData:privateKeyData: instead."))); -; - -/** - * Initialize a new 2048 bit RSA keypair. This also stores the keypair in the Keychain - * Preferences. - * - * @param publicKey The publicKey stored in Keychain. - * @param privateKey The privateKey stored in Keychain. - * @param publicKeyData The publicKey in NSData format. - * @param privateKeyData The privateKey in NSData format. - * - * @return A new KeyPair instance with the generated public and private key. - */ -- (instancetype)initWithPrivateKey:(SecKeyRef)privateKey - publicKey:(SecKeyRef)publicKey - publicKeyData:(NSData *)publicKeyData - privateKeyData:(NSData *)privateKeyData NS_DESIGNATED_INITIALIZER; - -/** - * The public key in the RSA 20148 bit generated KeyPair. - * - * @return The 2048 bit RSA KeyPair's public key. - */ -@property(nonatomic, readonly, strong) NSData *publicKeyData; - -/** - * The private key in the RSA 20148 bit generated KeyPair. - * - * @return The 2048 bit RSA KeyPair's private key. - */ -@property(nonatomic, readonly, strong) NSData *privateKeyData; - -#pragma mark - Info - -/** - * Checks if the private and public keyPair are valid or not. - * - * @return YES if keypair is valid else NO. - */ -- (BOOL)isValid; - -/** - * The public key in the RSA 2048 bit generated KeyPair. - * - * @return The 2048 bit RSA KeyPair's public key. - */ -- (SecKeyRef)publicKey; - -/** - * The private key in the RSA 2048 bit generated KeyPair. - * - * @return The 2048 bit RSA KeyPair's private key. - */ -- (SecKeyRef)privateKey; - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPair.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPair.m @@ -1,73 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDKeyPair.h" - -#import <Security/Security.h> - -#import "FIRInstanceIDKeyPairUtilities.h" -#import "FIRInstanceIDKeychain.h" -#import "FIRInstanceIDLogger.h" -#import "NSError+FIRInstanceID.h" - -@interface FIRInstanceIDKeyPair () { - SecKeyRef _privateKey; - SecKeyRef _publicKey; -} - -@property(nonatomic, readwrite, strong) NSData *publicKeyData; -@property(nonatomic, readwrite, strong) NSData *privateKeyData; -@end - -@implementation FIRInstanceIDKeyPair -- (instancetype)initWithPrivateKey:(SecKeyRef)privateKey - publicKey:(SecKeyRef)publicKey - publicKeyData:(NSData *)publicKeyData - privateKeyData:(NSData *)privateKeyData { - self = [super init]; - if (self) { - _privateKey = privateKey; - _publicKey = publicKey; - _publicKeyData = publicKeyData; - _privateKeyData = privateKeyData; - } - return self; -} - -- (void)dealloc { - if (_privateKey) { - CFRelease(_privateKey); - } - if (_publicKey) { - CFRelease(_publicKey); - } -} - -#pragma mark - Info - -- (BOOL)isValid { - return _privateKey != NULL && _publicKey != NULL; -} - -- (SecKeyRef)publicKey { - return _publicKey; -} - -- (SecKeyRef)privateKey { - return _privateKey; -} - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairStore.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairStore.h @@ -1,85 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -@class FIRInstanceIDKeyPair; - -extern NSString *const kFIRInstanceIDKeyPairSubType; - -@class FIRInstanceIDKeyPairStore; - -@interface FIRInstanceIDKeyPairStore : NSObject - -/** - * Invalidates the cached keypairs in the Keychain, if needed. The keypair metadata plist is - * checked for existence. If the plist file does not exist, it is a signal of a new installation, - * and therefore the key pairs are not valid. - * - * Returns YES if keypair has been invalidated. - */ -- (BOOL)invalidateKeyPairsIfNeeded; - -/** - * Delete the cached RSA keypair from Keychain with the given subtype. - * - * @param subtype The subtype used to cache the RSA keypair in Keychain. - * @param handler The callback handler which is invoked when the keypair deletion is - * complete, with an error if there is any. - */ -- (void)deleteSavedKeyPairWithSubtype:(NSString *)subtype handler:(void (^)(NSError *))handler; - -/** - * Delete the plist that caches KeyPair generation timestamps. - * - * @param error The error if any while deleting the plist else nil. - * - * @return YES if the delete was successful else NO. - */ -- (BOOL)removeKeyPairCreationTimePlistWithError:(NSError **)error; - -/** - * Loads a cached KeyPair if it exists in the Keychain else generate a new - * one. If a keyPair already exists in memory this will just return that. This should - * not be called from the main thread since it could potentially lead to creating a new - * RSA-2048 bit keyPair which is an expensive operation. - * - * @param error The error, if any, while accessing the Keychain. - * - * @return A valid 2048 bit RSA key pair. - */ -- (FIRInstanceIDKeyPair *)loadKeyPairWithError:(NSError **)error; - -/** - * Check if the Keychain has any cached keypairs or not. - * - * @return YES if the Keychain has cached RSA KeyPairs else NO. - */ -- (BOOL)hasCachedKeyPairs; - -/** - * Return an identifier for the app instance. The result is a short identifier that can - * be used as a key when storing information about the app. This method will return the same - * ID as long as the application identity remains active. If the identity has been revoked or - * expired the method will generate and return a new identifier. - * - * @param error The error if any while loading the RSA KeyPair. - * - * @return The identifier, as url safe string. - */ -- (NSString *)appIdentityWithError:(NSError *__autoreleasing *)error; - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairStore.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairStore.m @@ -1,526 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDKeyPairStore.h" - -#import "FIRInstanceIDBackupExcludedPlist.h" -#import "FIRInstanceIDConstants.h" -#import "FIRInstanceIDDefines.h" -#import "FIRInstanceIDKeyPair.h" -#import "FIRInstanceIDKeyPairUtilities.h" -#import "FIRInstanceIDKeychain.h" -#import "FIRInstanceIDLogger.h" -#import "FIRInstanceIDUtilities.h" -#import "NSError+FIRInstanceID.h" - -// NOTE: These values should be in sync with what InstanceID saves in as. -static NSString *const kFIRInstanceIDKeyPairStoreFileName = @"com.google.iid-keypair"; - -static NSString *const kFIRInstanceIDStoreKeyGenerationTime = @"cre"; - -static NSString *const kFIRInstanceIDStoreKeyPrefix = @"com.google.iid-"; -static NSString *const kFIRInstanceIDStoreKeyPublic = @"|P|"; -static NSString *const kFIRInstanceIDStoreKeyPrivate = @"|K|"; -static NSString *const kFIRInstanceIDStoreKeySubtype = @"|S|"; - -static NSString *const kFIRInstanceIDKeyPairPublicTagPrefix = @"com.google.iid.keypair.public-"; -static NSString *const kFIRInstanceIDKeyPairPrivateTagPrefix = @"com.google.iid.keypair.private-"; - -static const int kMaxMissingEntitlementErrorCount = 3; - -NSString *const kFIRInstanceIDKeyPairSubType = @""; - -// Query the key with NSData format -NSData *FIRInstanceIDKeyDataWithTag(NSString *tag) { - _FIRInstanceIDDevAssert([tag length], @"Invalid tag for keychain specified"); - if (![tag length]) { - return NULL; - } - NSDictionary *queryKey = FIRInstanceIDKeyPairQuery(tag, YES, YES); - CFTypeRef result = [[FIRInstanceIDKeychain sharedInstance] itemWithQuery:queryKey]; - if (!result) { - return NULL; - } - return (__bridge NSData *)result; -} - -// Query the key given a tag -SecKeyRef FIRInstanceIDCachedKeyRefWithTag(NSString *tag) { - _FIRInstanceIDDevAssert([tag length], @"Invalid tag for keychain specified"); - if (![tag length]) { - return NULL; - } - NSDictionary *queryKey = FIRInstanceIDKeyPairQuery(tag, YES, NO); - CFTypeRef result = [[FIRInstanceIDKeychain sharedInstance] itemWithQuery:queryKey]; - return (SecKeyRef)result; -} - -// Check if keypair has been migrated from the legacy to the new version -BOOL FIRInstanceIDHasMigratedKeyPair(NSString *legacyPublicKeyTag, NSString *newPublicKeyTag) { - NSData *oldPublicKeyData = FIRInstanceIDKeyDataWithTag(legacyPublicKeyTag); - NSData *newPublicKeyData = FIRInstanceIDKeyDataWithTag(newPublicKeyTag); - return [oldPublicKeyData isEqualToData:newPublicKeyData]; -} - -// The legacy value is hardcoded to be the same key. This is a potential problem in shared keychain -// environments. -NSString *FIRInstanceIDLegacyPublicTagWithSubtype(NSString *subtype) { - NSString *prefix = kFIRInstanceIDStoreKeyPrefix; - return [NSString stringWithFormat:@"%@%@%@", prefix, subtype, kFIRInstanceIDStoreKeyPublic]; -} - -// The legacy value is hardcoded to be the same key. This is a potential problem in shared keychain -// environments. -NSString *FIRInstanceIDLegacyPrivateTagWithSubtype(NSString *subtype) { - NSString *prefix = kFIRInstanceIDStoreKeyPrefix; - return [NSString stringWithFormat:@"%@%@%@", prefix, subtype, kFIRInstanceIDStoreKeyPrivate]; -} - -NSString *FIRInstanceIDPublicTagWithSubtype(NSString *subtype) { - static NSString *publicTag; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSString *mainAppBundleID = FIRInstanceIDAppIdentifier(); - publicTag = - [NSString stringWithFormat:@"%@%@", kFIRInstanceIDKeyPairPublicTagPrefix, mainAppBundleID]; - }); - return publicTag; -} - -NSString *FIRInstanceIDPrivateTagWithSubtype(NSString *subtype) { - static NSString *privateTag; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSString *mainAppBundleID = FIRInstanceIDAppIdentifier(); - privateTag = - [NSString stringWithFormat:@"%@%@", kFIRInstanceIDKeyPairPrivateTagPrefix, mainAppBundleID]; - }); - return privateTag; -} - -NSString *FIRInstanceIDCreationTimeKeyWithSubtype(NSString *subtype) { - return [NSString stringWithFormat:@"%@%@%@", subtype, kFIRInstanceIDStoreKeySubtype, - kFIRInstanceIDStoreKeyGenerationTime]; -} - -@interface FIRInstanceIDKeyPairStore () - -@property(nonatomic, readwrite, strong) FIRInstanceIDBackupExcludedPlist *plist; -@property(nonatomic, readwrite, strong) FIRInstanceIDKeyPair *keyPair; -@property(nonatomic, readwrite, assign) NSInteger keychainEntitlementsErrorCount; - -@end - -@implementation FIRInstanceIDKeyPairStore - -- (instancetype)init { - self = [super init]; - if (self) { - NSString *fileName = [[self class] keyStoreFileName]; - _plist = [[FIRInstanceIDBackupExcludedPlist alloc] - initWithFileName:fileName - applicationSupportSubDirectory:kFIRInstanceIDApplicationSupportSubDirectory]; - } - return self; -} - -- (BOOL)invalidateKeyPairsIfNeeded { - // Currently keypairs are always invalidated if self.plist is missing. This normally indicates - // a fresh install (or an uninstall/reinstall). In those situations the key pairs should be - // deleted. - // NOTE: Although this class refers to multiple key pairs, with different subtypes, in practice - // only a single subtype is currently supported. (b/64906549) - if (![self.plist doesFileExist]) { - // A fresh install, clear all the key pairs in the key chain. Do not perform migration as all - // key pairs are gone. - [self deleteSavedKeyPairWithSubtype:kFIRInstanceIDKeyPairSubType handler:nil]; - return YES; - } - // Not a fresh install, perform migration at early state. - [self migrateKeyPairCacheIfNeededWithHandler:nil]; - return NO; -} - -- (BOOL)hasCachedKeyPairs { - NSError *error; - if ([self cachedKeyPairWithSubtype:kFIRInstanceIDKeyPairSubType error:&error] == nil) { - if (error) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeKeyPairStore000, - @"Failed to get cached keyPair %@", error); - } - error = nil; - [self removeKeyPairCreationTimePlistWithError:&error]; - if (error) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeKeyPairStore001, - @"Failed to remove keyPair creationTime plist %@", error); - } - return NO; - } - return YES; -} - -- (NSString *)appIdentityWithError:(NSError *__autoreleasing *)error { - // Load the keyPair from Keychain (or generate a key pair, if this is the first run of the app). - FIRInstanceIDKeyPair *keyPair = [self loadKeyPairWithError:error]; - if (!keyPair) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeKeyPairStoreCouldNotLoadKeyPair, - @"Keypair could not be loaded from Keychain. Error: %@", (*error)); - return nil; - } - - if (error) { - *error = nil; - } - NSString *appIdentity = FIRInstanceIDAppIdentity(keyPair); - if (!appIdentity.length) { - if (error) { - *error = [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeUnknown]; - } - } - return appIdentity; -} - -- (FIRInstanceIDKeyPair *)loadKeyPairWithError:(NSError **)error { - // In case we call this from different threads we don't want to generate or fetch the - // keyPair multiple times. Once we have a keyPair in the cache it would mostly be used - // from there. - @synchronized(self) { - if ([self.keyPair isValid]) { - return self.keyPair; - } - - if (self.keychainEntitlementsErrorCount >= kMaxMissingEntitlementErrorCount) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeKeyPairStore002, - @"Keychain not accessible, Entitlements missing error (-34018). " - @"Will not check token in cache."); - return nil; - } - - if (!self.keyPair) { - self.keyPair = [self validCachedKeyPairWithSubtype:kFIRInstanceIDKeyPairSubType error:error]; - } - - if ((*error).code == kFIRInstanceIDSecMissingEntitlementErrorCode) { - self.keychainEntitlementsErrorCount++; - } - - if (!self.keyPair) { - self.keyPair = [self generateAndSaveKeyWithSubtype:kFIRInstanceIDKeyPairSubType - creationTime:FIRInstanceIDCurrentTimestampInSeconds() - error:error]; - } - } - return self.keyPair; -} - -// TODO(chliangGoogle: Remove subtype support, as it's not being used. -- (FIRInstanceIDKeyPair *)generateAndSaveKeyWithSubtype:(NSString *)subtype - creationTime:(int64_t)creationTime - error:(NSError **)error { - NSString *publicKeyTag = FIRInstanceIDPublicTagWithSubtype(subtype); - NSString *privateKeyTag = FIRInstanceIDPrivateTagWithSubtype(subtype); - FIRInstanceIDKeyPair *keyPair = - [[FIRInstanceIDKeychain sharedInstance] generateKeyPairWithPrivateTag:privateKeyTag - publicTag:publicKeyTag]; - - if (![keyPair isValid]) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeKeyPairStore003, - @"Unable to generate keypair."); - return nil; - } - - NSString *creationTimeKey = FIRInstanceIDCreationTimeKeyWithSubtype(subtype); - NSDictionary *keyPairData = @{creationTimeKey : @(creationTime)}; - - if (error) { - *error = nil; - } - NSMutableDictionary *allKeyPairs = [[self.plist contentAsDictionary] mutableCopy]; - if (allKeyPairs.count) { - [allKeyPairs addEntriesFromDictionary:keyPairData]; - } else { - allKeyPairs = [keyPairData mutableCopy]; - } - if (![self.plist writeDictionary:allKeyPairs error:error]) { - [FIRInstanceIDKeyPairStore deleteKeyPairWithPrivateTag:privateKeyTag - publicTag:publicKeyTag - handler:nil]; - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeKeyPairStore004, - @"Failed to save keypair data to plist %@", error ? *error : @""); - return nil; - } - - return keyPair; -} - -- (FIRInstanceIDKeyPair *)validCachedKeyPairWithSubtype:(NSString *)subtype - error:(NSError **)error { - // On a new install (or if the ID was deleted), the plist will be missing, which should trigger - // a reset of the key pairs in Keychain (if they exist). - NSDictionary *allKeyPairs = [self.plist contentAsDictionary]; - NSString *creationTimeKey = FIRInstanceIDCreationTimeKeyWithSubtype(subtype); - - if (allKeyPairs[creationTimeKey] > 0) { - return [self cachedKeyPairWithSubtype:subtype error:error]; - } else { - // There is no need to reset keypair again here as FIRInstanceID init call is always - // going to be ahead of this call, which already trigger keypair reset if it's new install - FIRInstanceIDErrorCode code = kFIRInstanceIDErrorCodeInvalidKeyPairCreationTime; - *error = [NSError errorWithFIRInstanceIDErrorCode:code]; - return nil; - } -} - -- (FIRInstanceIDKeyPair *)cachedKeyPairWithSubtype:(NSString *)subtype - error:(NSError *__autoreleasing *)error { - // base64 encoded keys - NSString *publicKeyTag = FIRInstanceIDPublicTagWithSubtype(subtype); - NSString *privateKeyTag = FIRInstanceIDPrivateTagWithSubtype(subtype); - return [FIRInstanceIDKeyPairStore keyPairForPrivateKeyTag:privateKeyTag - publicKeyTag:publicKeyTag - error:error]; -} - -+ (FIRInstanceIDKeyPair *)keyPairForPrivateKeyTag:(NSString *)privateKeyTag - publicKeyTag:(NSString *)publicKeyTag - error:(NSError *__autoreleasing *)error { - _FIRInstanceIDDevAssert([privateKeyTag length] && [publicKeyTag length], - @"Invalid tags for keypair"); - if (![privateKeyTag length] || ![publicKeyTag length]) { - if (error) { - *error = [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeInvalidKeyPairTags]; - } - return nil; - } - - SecKeyRef privateKeyRef = FIRInstanceIDCachedKeyRefWithTag(privateKeyTag); - SecKeyRef publicKeyRef = FIRInstanceIDCachedKeyRefWithTag(publicKeyTag); - - if (!privateKeyRef || !publicKeyRef) { - if (error) { - *error = [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeMissingKeyPair]; - } - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeKeyPair000, - @"No keypair info is retrieved with tag %@", privateKeyTag); - return nil; - } - - NSData *publicKeyData = FIRInstanceIDKeyDataWithTag(publicKeyTag); - NSData *privateKeyData = FIRInstanceIDKeyDataWithTag(privateKeyTag); - - FIRInstanceIDKeyPair *keyPair = [[FIRInstanceIDKeyPair alloc] initWithPrivateKey:privateKeyRef - publicKey:publicKeyRef - publicKeyData:publicKeyData - privateKeyData:privateKeyData]; - return keyPair; -} - -// Migrates from keypair saved under legacy keys (hardcoded value) to dynamic keys (stable, but -// unique for the app's bundle id -- (void)migrateKeyPairCacheIfNeededWithHandler:(void (^)(NSError *error))handler { - // Attempt to load keypair using legacy keys - NSString *legacyPublicKeyTag = - FIRInstanceIDLegacyPublicTagWithSubtype(kFIRInstanceIDKeyPairSubType); - NSString *legacyPrivateKeyTag = - FIRInstanceIDLegacyPrivateTagWithSubtype(kFIRInstanceIDKeyPairSubType); - NSError *error; - FIRInstanceIDKeyPair *keyPair = - [FIRInstanceIDKeyPairStore keyPairForPrivateKeyTag:legacyPrivateKeyTag - publicKeyTag:legacyPublicKeyTag - error:&error]; - if (![keyPair isValid]) { - if (handler) { - handler(nil); - } - return; - } - - // Check whether migration already done. - NSString *publicKeyTag = FIRInstanceIDPublicTagWithSubtype(kFIRInstanceIDKeyPairSubType); - if (FIRInstanceIDHasMigratedKeyPair(legacyPublicKeyTag, publicKeyTag)) { - if (handler) { - handler(nil); - } - return; - } - - // Also cache locally since we are sure to use the migrated key pair. - self.keyPair = keyPair; - - // Either new key pair doesn't exist or it's different than legacy key pair, start the migration. - NSString *privateKeyTag = FIRInstanceIDPrivateTagWithSubtype(kFIRInstanceIDKeyPairSubType); - [self updateKeyRef:keyPair.publicKey - withTag:publicKeyTag - handler:^(NSError *error) { - if (error) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeKeyPairMigrationError, - @"Unable to migrate key pair from legacy ones."); - } - [self updateKeyRef:keyPair.privateKey - withTag:privateKeyTag - handler:^(NSError *error) { - if (error) { - FIRInstanceIDLoggerError( - kFIRInstanceIDMessageCodeKeyPairMigrationError, - @"Unable to migrate key pair from legacy ones."); - return; - } - FIRInstanceIDLoggerDebug( - kFIRInstanceIDMessageCodeKeyPairMigrationSuccess, - @"Successfully migrated the key pair from legacy ones."); - if (handler) { - handler(error); - } - }]; - }]; -} - -// Used for migrating from legacy tags to updated tags. The legacy keychain is not deleted for -// backward compatibility. -// TODO(chliangGoogle) Delete the legacy keychain when GCM is fully deprecated. -- (void)updateKeyRef:(SecKeyRef)keyRef - withTag:(NSString *)tag - handler:(void (^)(NSError *error))handler { - NSData *updatedTagData = [tag dataUsingEncoding:NSUTF8StringEncoding]; - - // Always delete the old keychain before adding a new one to avoid conflicts. - NSDictionary *deleteQuery = @{ - (__bridge id)kSecAttrApplicationTag : updatedTagData, - (__bridge id)kSecClass : (__bridge id)kSecClassKey, - (__bridge id)kSecAttrKeyType : (__bridge id)kSecAttrKeyTypeRSA, - (__bridge id)kSecReturnRef : @(YES), - }; - - [[FIRInstanceIDKeychain sharedInstance] - removeItemWithQuery:deleteQuery - handler:^(NSError *error) { - if (error) { - if (handler) { - handler(error); - } - return; - } - NSDictionary *addQuery = @{ - (__bridge id)kSecAttrApplicationTag : updatedTagData, - (__bridge id)kSecClass : (__bridge id)kSecClassKey, - (__bridge id)kSecValueRef : (__bridge id)keyRef, - (__bridge id) - kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAlwaysThisDeviceOnly, - }; - [[FIRInstanceIDKeychain sharedInstance] addItemWithQuery:addQuery - handler:^(NSError *addError) { - if (handler) { - handler(addError); - } - }]; - }]; -} - -- (void)deleteSavedKeyPairWithSubtype:(NSString *)subtype - handler:(void (^)(NSError *error))handler { - NSDictionary *allKeyPairs = [self.plist contentAsDictionary]; - - NSString *publicKeyTag = FIRInstanceIDPublicTagWithSubtype(subtype); - NSString *privateKeyTag = FIRInstanceIDPrivateTagWithSubtype(subtype); - NSString *creationTimeKey = FIRInstanceIDCreationTimeKeyWithSubtype(subtype); - - // remove the creation time - if (allKeyPairs[creationTimeKey] > 0) { - NSMutableDictionary *newKeyPairs = [NSMutableDictionary dictionaryWithDictionary:allKeyPairs]; - [newKeyPairs removeObjectForKey:creationTimeKey]; - - NSError *plistError; - if (![self.plist writeDictionary:newKeyPairs error:&plistError]) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeKeyPairStore006, - @"Unable to remove keypair creation time from plist %@", plistError); - } - } - - [FIRInstanceIDKeyPairStore - deleteKeyPairWithPrivateTag:privateKeyTag - publicTag:publicKeyTag - handler:^(NSError *error) { - // Delete legacy key pairs from GCM/FCM If they exist. All key pairs - // should be deleted when app is newly installed. - NSString *legacyPublicKeyTag = - FIRInstanceIDLegacyPublicTagWithSubtype(subtype); - NSString *legacyPrivateKeyTag = - FIRInstanceIDLegacyPrivateTagWithSubtype(subtype); - [FIRInstanceIDKeyPairStore - deleteKeyPairWithPrivateTag:legacyPrivateKeyTag - publicTag:legacyPublicKeyTag - handler:nil]; - if (error) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeKeyPairStore007, - @"Unable to remove RSA keypair, error: %@", - error); - if (handler) { - handler(error); - } - } else { - self.keyPair = nil; - if (handler) { - handler(nil); - } - } - }]; -} - -+ (void)deleteKeyPairWithPrivateTag:(NSString *)privateTag - publicTag:(NSString *)publicTag - handler:(void (^)(NSError *))handler { - NSDictionary *queryPublicKey = FIRInstanceIDKeyPairQuery(publicTag, NO, NO); - NSDictionary *queryPrivateKey = FIRInstanceIDKeyPairQuery(privateTag, NO, NO); - - // Always remove public key first because it is the key we generate IID. - [[FIRInstanceIDKeychain sharedInstance] removeItemWithQuery:queryPublicKey - handler:^(NSError *error) { - if (error) { - if (handler) { - handler(error); - } - return; - } - [[FIRInstanceIDKeychain sharedInstance] - removeItemWithQuery:queryPrivateKey - handler:^(NSError *error) { - if (error) { - if (handler) { - handler(error); - } - return; - } - if (handler) { - handler(nil); - } - }]; - }]; -} - -- (BOOL)removeKeyPairCreationTimePlistWithError:(NSError *__autoreleasing *)error { - if (![self.plist deleteFile:error]) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeKeyPairStore008, - @"Unable to delete keypair creation times plist"); - return NO; - } - return YES; -} - -+ (NSString *)keyStoreFileName { - return kFIRInstanceIDKeyPairStoreFileName; -} - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairUtilities.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairUtilities.h @@ -1,36 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -@class FIRInstanceIDKeyPair; - -/** - * A web-safe base64 encoded string with no padding. - * - * @param data The data to encode. - * - * @return A web-safe base 64 encoded string with no padding. - */ -FOUNDATION_EXPORT NSString *FIRInstanceIDWebSafeBase64(NSData *data); - -FOUNDATION_EXPORT NSData *FIRInstanceIDSHA1(NSData *data); - -FOUNDATION_EXPORT NSDictionary *FIRInstanceIDKeyPairQuery(NSString *tag, - BOOL addReturnAttr, - BOOL returnData); - -FOUNDATION_EXPORT NSString *FIRInstanceIDAppIdentity(FIRInstanceIDKeyPair *keyPair); diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairUtilities.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairUtilities.m @@ -1,84 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDKeyPairUtilities.h" - -#import <CommonCrypto/CommonDigest.h> - -#import "FIRInstanceIDDefines.h" -#import "FIRInstanceIDKeyPair.h" -#import "FIRInstanceIDLogger.h" -#import "FIRInstanceIDStringEncoding.h" - -NSString *FIRInstanceIDWebSafeBase64(NSData *data) { - // Websafe encoding with no padding. - FIRInstanceIDStringEncoding *encoding = - [FIRInstanceIDStringEncoding rfc4648Base64WebsafeStringEncoding]; - [encoding setDoPad:NO]; - return [encoding encode:data]; -} - -NSData *FIRInstanceIDSHA1(NSData *data) { - unsigned int outputLength = CC_SHA1_DIGEST_LENGTH; - unsigned char output[outputLength]; - unsigned int length = (unsigned int)[data length]; - - CC_SHA1(data.bytes, length, output); - return [NSMutableData dataWithBytes:output length:outputLength]; -} - -NSDictionary *FIRInstanceIDKeyPairQuery(NSString *tag, BOOL addReturnAttr, BOOL returnData) { - NSMutableDictionary *queryKey = [NSMutableDictionary dictionary]; - NSData *tagData = [tag dataUsingEncoding:NSUTF8StringEncoding]; - - queryKey[(__bridge id)kSecClass] = (__bridge id)kSecClassKey; - queryKey[(__bridge id)kSecAttrApplicationTag] = tagData; - queryKey[(__bridge id)kSecAttrKeyType] = (__bridge id)kSecAttrKeyTypeRSA; - if (addReturnAttr) { - if (returnData) { - queryKey[(__bridge id)kSecReturnData] = @(YES); - } else { - queryKey[(__bridge id)kSecReturnRef] = @(YES); - } - } - return queryKey; -} - -NSString *FIRInstanceIDAppIdentity(FIRInstanceIDKeyPair *keyPair) { - // An Instance-ID is a 64 bit (8 byte) integer with a fixed 4-bit header of 0111 (=^ 0x7). - // The variable 60 bits are obtained by truncating the SHA1 of the app-instance's public key. - SecKeyRef publicKeyRef = [keyPair publicKey]; - if (!publicKeyRef) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeKeyPair002, - @"Unable to create a valid asymmetric crypto key"); - return nil; - } - NSData *publicKeyData = keyPair.publicKeyData; - NSData *publicKeySHA1 = FIRInstanceIDSHA1(publicKeyData); - - const uint8_t *bytes = publicKeySHA1.bytes; - NSMutableData *identityData = [NSMutableData dataWithData:publicKeySHA1]; - - uint8_t b0 = bytes[0]; - // Take the first byte and make the initial four 7 by initially making the initial 4 bits 0 - // and then adding 0x70 to it. - b0 = 0x70 + (0xF & b0); - // failsafe should give you back b0 itself - b0 = (b0 & 0xFF); - [identityData replaceBytesInRange:NSMakeRange(0, 1) withBytes:&b0]; - NSData *data = [identityData subdataWithRange:NSMakeRange(0, 8 * sizeof(Byte))]; - return FIRInstanceIDWebSafeBase64(data); -} diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeychain.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeychain.h @@ -1,76 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -/* The Keychain error domain */ -extern NSString *const kFIRInstanceIDKeychainErrorDomain; - -@class FIRInstanceIDKeyPair; - -/* - * Wrapping the keychain operations in a serialize queue. This is to avoid keychain operation - * blocking main queue. - */ -@interface FIRInstanceIDKeychain : NSObject - -/** - * FIRInstanceIDKeychain. - * - * @return A shared instance of FIRInstanceIDKeychain. - */ -+ (instancetype)sharedInstance; - -/** - * Get keychain items matching the given a query. - * - * @param keychainQuery The keychain query. - * - * @return An CFTypeRef result matching the provided inputs. - */ -- (CFTypeRef)itemWithQuery:(NSDictionary *)keychainQuery; - -/** - * Remove the cached items from the keychain matching the query. - * - * @param keychainQuery The keychain query. - * @param handler The callback handler which is invoked when the remove operation is - * complete, with an error if there is any. - */ -- (void)removeItemWithQuery:(NSDictionary *)keychainQuery handler:(void (^)(NSError *error))handler; - -/** - * Add the item with a given query. - * - * @param keychainQuery The keychain query. - * @param handler The callback handler which is invoked when the add operation is - * complete, with an error if there is any. - */ -- (void)addItemWithQuery:(NSDictionary *)keychainQuery handler:(void (^)(NSError *))handler; - -#pragma mark - Keypair -/** - * Generate a public/private key pair given their tags. - * - * @param privateTag The private tag associated with the private key. - * @param publicTag The public tag associated with the public key. - * - * @return A new FIRInstanceIDKeyPair object. - */ -- (FIRInstanceIDKeyPair *)generateKeyPairWithPrivateTag:(NSString *)privateTag - publicTag:(NSString *)publicTag; - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeychain.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeychain.m @@ -1,175 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDKeychain.h" - -#import "FIRInstanceIDKeyPair.h" -#import "FIRInstanceIDKeyPairUtilities.h" -#import "FIRInstanceIDLogger.h" - -NSString *const kFIRInstanceIDKeychainErrorDomain = @"com.google.iid"; - -static const NSUInteger kRSA2048KeyPairSize = 2048; - -@interface FIRInstanceIDKeychain () { - dispatch_queue_t _keychainOperationQueue; -} - -@end - -@implementation FIRInstanceIDKeychain - -+ (instancetype)sharedInstance { - static FIRInstanceIDKeychain *sharedInstance; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - sharedInstance = [[FIRInstanceIDKeychain alloc] init]; - }); - return sharedInstance; -} - -- (instancetype)init { - self = [super init]; - if (self) { - _keychainOperationQueue = - dispatch_queue_create("com.google.FirebaseInstanceID.Keychain", DISPATCH_QUEUE_SERIAL); - } - return self; -} - -- (CFTypeRef)itemWithQuery:(NSDictionary *)keychainQuery { - __block SecKeyRef keyRef = NULL; - dispatch_sync(_keychainOperationQueue, ^{ - OSStatus status = - SecItemCopyMatching((__bridge CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyRef); - - if (status != noErr) { - if (keyRef) { - CFRelease(keyRef); - } - FIRInstanceIDLoggerDebug( - kFIRInstanceIDKeychainReadItemError, - @"No info is retrieved from Keychain OSStatus: %d with the keychain query %@", - (int)status, keychainQuery); - } - }); - return keyRef; -} - -- (void)removeItemWithQuery:(NSDictionary *)keychainQuery - handler:(void (^)(NSError *error))handler { - dispatch_async(_keychainOperationQueue, ^{ - OSStatus status = SecItemDelete((__bridge CFDictionaryRef)keychainQuery); - if (status != noErr) { - FIRInstanceIDLoggerDebug( - kFIRInstanceIDKeychainDeleteItemError, - @"Couldn't delete item from Keychain OSStatus: %d with the keychain query %@", - (int)status, keychainQuery); - } - - if (handler) { - NSError *error; - // When item is not found, it should NOT be considered as an error. The operation should - // continue. - if (status != noErr && status != errSecItemNotFound) { - error = [NSError errorWithDomain:kFIRInstanceIDKeychainErrorDomain - code:status - userInfo:nil]; - } - dispatch_async(dispatch_get_main_queue(), ^{ - handler(error); - }); - } - }); -} - -- (void)addItemWithQuery:(NSDictionary *)keychainQuery handler:(void (^)(NSError *))handler { - dispatch_async(_keychainOperationQueue, ^{ - OSStatus status = SecItemAdd((__bridge CFDictionaryRef)keychainQuery, NULL); - - if (handler) { - NSError *error; - if (status != noErr) { - FIRInstanceIDLoggerWarning(kFIRInstanceIDKeychainAddItemError, - @"Couldn't add item to Keychain OSStatus: %d", (int)status); - error = [NSError errorWithDomain:kFIRInstanceIDKeychainErrorDomain - code:status - userInfo:nil]; - } - dispatch_async(dispatch_get_main_queue(), ^{ - handler(error); - }); - } - }); -} - -- (FIRInstanceIDKeyPair *)generateKeyPairWithPrivateTag:(NSString *)privateTag - publicTag:(NSString *)publicTag { - // TODO(chliangGoogle) this is called by appInstanceID, which is an internal API used by other - // Firebase teams, will see if we can make it async. - NSData *publicTagData = [publicTag dataUsingEncoding:NSUTF8StringEncoding]; - NSData *privateTagData = [privateTag dataUsingEncoding:NSUTF8StringEncoding]; - - NSDictionary *privateKeyAttr = @{ - (__bridge id)kSecAttrIsPermanent : @YES, - (__bridge id)kSecAttrApplicationTag : privateTagData, - (__bridge id)kSecAttrLabel : @"Firebase InstanceID Key Pair Private Key", - (__bridge id)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAlwaysThisDeviceOnly, - }; - - NSDictionary *publicKeyAttr = @{ - (__bridge id)kSecAttrIsPermanent : @YES, - (__bridge id)kSecAttrApplicationTag : publicTagData, - (__bridge id)kSecAttrLabel : @"Firebase InstanceID Key Pair Public Key", - (__bridge id)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAlwaysThisDeviceOnly, - }; - - NSDictionary *keyPairAttributes = @{ - (__bridge id)kSecAttrKeyType : (__bridge id)kSecAttrKeyTypeRSA, - (__bridge id)kSecAttrLabel : @"Firebase InstanceID Key Pair", - (__bridge id)kSecAttrKeySizeInBits : @(kRSA2048KeyPairSize), - (__bridge id)kSecPrivateKeyAttrs : privateKeyAttr, - (__bridge id)kSecPublicKeyAttrs : publicKeyAttr, - }; - - __block SecKeyRef privateKey = NULL; - __block SecKeyRef publicKey = NULL; - dispatch_sync(_keychainOperationQueue, ^{ - // SecKeyGeneratePair does not allow you to set kSetAttrAccessible on the keys. We need the keys - // to be accessible even when the device is locked (i.e. app is woken up during a push - // notification, or some background refresh). - OSStatus status = - SecKeyGeneratePair((__bridge CFDictionaryRef)keyPairAttributes, &publicKey, &privateKey); - if (status != noErr || publicKey == NULL || privateKey == NULL) { - FIRInstanceIDLoggerWarning(kFIRInstanceIDKeychainCreateKeyPairError, - @"Couldn't create keypair from Keychain OSStatus: %d", - (int)status); - } - }); - // Extract the actual public and private key data from the Keychain - NSDictionary *publicKeyDataQuery = FIRInstanceIDKeyPairQuery(publicTag, YES, YES); - NSDictionary *privateKeyDataQuery = FIRInstanceIDKeyPairQuery(privateTag, YES, YES); - - NSData *publicKeyData = (__bridge NSData *)[self itemWithQuery:publicKeyDataQuery]; - NSData *privateKeyData = (__bridge NSData *)[self itemWithQuery:privateKeyDataQuery]; - - return [[FIRInstanceIDKeyPair alloc] initWithPrivateKey:privateKey - publicKey:publicKey - publicKeyData:publicKeyData - privateKeyData:privateKeyData]; -} - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDLogger.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDLogger.h @@ -1,66 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRIMessageCode.h" - -// The convenience macros are only defined if they haven't already been defined. -#ifndef FIRInstanceIDLoggerInfo - -// Convenience macros that log to the shared GTMLogger instance. These macros -// are how users should typically log to FIRInstanceIDLogger. -#define FIRInstanceIDLoggerDebug(code, ...) \ - [FIRInstanceIDSharedLogger() logFuncDebug:__func__ messageCode:code msg:__VA_ARGS__] -#define FIRInstanceIDLoggerInfo(code, ...) \ - [FIRInstanceIDSharedLogger() logFuncInfo:__func__ messageCode:code msg:__VA_ARGS__] -#define FIRInstanceIDLoggerNotice(code, ...) \ - [FIRInstanceIDSharedLogger() logFuncNotice:__func__ messageCode:code msg:__VA_ARGS__] -#define FIRInstanceIDLoggerWarning(code, ...) \ - [FIRInstanceIDSharedLogger() logFuncWarning:__func__ messageCode:code msg:__VA_ARGS__] -#define FIRInstanceIDLoggerError(code, ...) \ - [FIRInstanceIDSharedLogger() logFuncError:__func__ messageCode:code msg:__VA_ARGS__] - -#endif // !defined(FIRInstanceIDLoggerInfo) - -@interface FIRInstanceIDLogger : NSObject - -- (void)logFuncDebug:(const char *)func - messageCode:(FIRInstanceIDMessageCode)messageCode - msg:(NSString *)fmt, ... NS_FORMAT_FUNCTION(3, 4); - -- (void)logFuncInfo:(const char *)func - messageCode:(FIRInstanceIDMessageCode)messageCode - msg:(NSString *)fmt, ... NS_FORMAT_FUNCTION(3, 4); - -- (void)logFuncNotice:(const char *)func - messageCode:(FIRInstanceIDMessageCode)messageCode - msg:(NSString *)fmt, ... NS_FORMAT_FUNCTION(3, 4); - -- (void)logFuncWarning:(const char *)func - messageCode:(FIRInstanceIDMessageCode)messageCode - msg:(NSString *)fmt, ... NS_FORMAT_FUNCTION(3, 4); - -- (void)logFuncError:(const char *)func - messageCode:(FIRInstanceIDMessageCode)messageCode - msg:(NSString *)fmt, ... NS_FORMAT_FUNCTION(3, 4); - -@end - -/** - * Instantiates and/or returns a shared GTMLogger used exclusively - * for InstanceID log messages. - * @return the shared GTMLogger instance - */ -FIRInstanceIDLogger *FIRInstanceIDSharedLogger(void); diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDLogger.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDLogger.m @@ -1,92 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDLogger.h" - -#import <FirebaseCore/FIRLogger.h> - -// Re-definition of FIRLogger service, as it is not included in :FIRAppHeaders target -NSString *const kFIRInstanceIDLoggerService = @"[Firebase/InstanceID]"; - -@implementation FIRInstanceIDLogger - -#pragma mark - Log Helpers - -+ (NSString *)formatMessageCode:(FIRInstanceIDMessageCode)messageCode { - return [NSString stringWithFormat:@"I-IID%06ld", (long)messageCode]; -} - -- (void)logFuncDebug:(const char *)func - messageCode:(FIRInstanceIDMessageCode)messageCode - msg:(NSString *)fmt, ... { - va_list args; - va_start(args, fmt); - FIRLogBasic(FIRLoggerLevelDebug, kFIRInstanceIDLoggerService, - [FIRInstanceIDLogger formatMessageCode:messageCode], fmt, args); - va_end(args); -} - -- (void)logFuncInfo:(const char *)func - messageCode:(FIRInstanceIDMessageCode)messageCode - msg:(NSString *)fmt, ... { - va_list args; - va_start(args, fmt); - FIRLogBasic(FIRLoggerLevelInfo, kFIRInstanceIDLoggerService, - [FIRInstanceIDLogger formatMessageCode:messageCode], fmt, args); - va_end(args); -} - -- (void)logFuncNotice:(const char *)func - messageCode:(FIRInstanceIDMessageCode)messageCode - msg:(NSString *)fmt, ... { - va_list args; - va_start(args, fmt); - FIRLogBasic(FIRLoggerLevelNotice, kFIRInstanceIDLoggerService, - [FIRInstanceIDLogger formatMessageCode:messageCode], fmt, args); - va_end(args); -} - -- (void)logFuncWarning:(const char *)func - messageCode:(FIRInstanceIDMessageCode)messageCode - msg:(NSString *)fmt, ... { - va_list args; - va_start(args, fmt); - FIRLogBasic(FIRLoggerLevelWarning, kFIRInstanceIDLoggerService, - [FIRInstanceIDLogger formatMessageCode:messageCode], fmt, args); - va_end(args); -} - -- (void)logFuncError:(const char *)func - messageCode:(FIRInstanceIDMessageCode)messageCode - msg:(NSString *)fmt, ... { - va_list args; - va_start(args, fmt); - FIRLogBasic(FIRLoggerLevelError, kFIRInstanceIDLoggerService, - [FIRInstanceIDLogger formatMessageCode:messageCode], fmt, args); - va_end(args); -} - -@end - -FIRInstanceIDLogger *FIRInstanceIDSharedLogger() { - static dispatch_once_t onceToken; - static FIRInstanceIDLogger *logger; - dispatch_once(&onceToken, ^{ - logger = [[FIRInstanceIDLogger alloc] init]; - }); - - return logger; -} diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDStore.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDStore.h @@ -1,183 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -NS_ASSUME_NONNULL_BEGIN - -@class FIRInstanceIDBackupExcludedPlist; -@class FIRInstanceIDCheckinPreferences; -@class FIRInstanceIDCheckinStore; -@class FIRInstanceIDTokenInfo; -@class FIRInstanceIDTokenStore; - -@class FIRInstanceIDStore; -@protocol FIRInstanceIDStoreDelegate <NSObject> - -/** - * This is called when the store has decided to invalide its tokens associated with the - * previous checkin credentials. After deleting the tokens locally, it calls this method - * to notify the delegate of the change. If possible, the delegate should use this time - * to request the invalidation of the tokens on the server as well. - */ -- (void)store:(FIRInstanceIDStore *)store - didDeleteFCMScopedTokensForCheckin:(FIRInstanceIDCheckinPreferences *)checkin; - -@end - -/** - * Used to persist the InstanceID tokens. This is also used to cache the Checkin - * credentials. The store also checks for stale entries in the store and - * let's us know if things in the store are stale or not. It does not however - * acts on stale entries in anyway. - */ -@interface FIRInstanceIDStore : NSObject - -/** - * The delegate set in the initializer which is notified of changes in the store. - */ -@property(nonatomic, readonly, weak) NSObject<FIRInstanceIDStoreDelegate> *delegate; - -- (instancetype)init __attribute__((unavailable("Use initWithDelegate: instead."))); - -/** - * Initialize a default store to persist InstanceID tokens and options. - * - * @param delegate The delegate with which to be notified of changes in the store. - * @return Store to persist InstanceID tokens. - */ -- (instancetype)initWithDelegate:(NSObject<FIRInstanceIDStoreDelegate> *)delegate; - -/** - * Initialize a store with the token store used to persist tokens, and a checkin store. - * Used for testing. - * - * @param checkinStore Persistent store that persists checkin preferences. - * @param tokenStore Persistent store that persists tokens. - * - * @return Store to persist InstanceID tokens and options. - */ -- (instancetype)initWithCheckinStore:(FIRInstanceIDCheckinStore *)checkinStore - tokenStore:(FIRInstanceIDTokenStore *)tokenStore - delegate:(NSObject<FIRInstanceIDStoreDelegate> *)delegate - NS_DESIGNATED_INITIALIZER; - -#pragma mark - Save -/** - * Save the instanceID token info to the store. - * - * @param tokenInfo The token info to store. - * @param handler The callback handler which is invoked when the operation is complete, - * with an error if there is any. - */ -- (void)saveTokenInfo:(FIRInstanceIDTokenInfo *)tokenInfo handler:(void (^)(NSError *))handler; - -#pragma mark - Get - -/** - * Get the cached token info. - * - * @param authorizedEntity The authorized entity for which we want the token. - * @param scope The scope for which we want the token. - * - * @return The cached token info if any for the given authorizedEntity and scope else - * returns nil. - */ -- (FIRInstanceIDTokenInfo *)tokenInfoWithAuthorizedEntity:(NSString *)authorizedEntity - scope:(NSString *)scope; -/** - * Return all cached token infos from the Keychain. - * - * @return The cached token infos, if any, that are stored in the Keychain. - */ -- (NSArray<FIRInstanceIDTokenInfo *> *)cachedTokenInfos; - -#pragma mark - Delete - -/** - * Remove the cached token for a given authorizedEntity and scope. If the token was never - * cached or deleted from the cache before this is a no-op. - * - * @param authorizedEntity The authorizedEntity for the cached token. - * @param scope The scope for the cached token - */ -- (void)removeCachedTokenWithAuthorizedEntity:(NSString *)authorizedEntity scope:(NSString *)scope; - -/** - * Removes all cached tokens from the persistent store. In case deleting the cached tokens - * fails we try to delete the backup excluded plist that stores the tokens. - * - * @param handler The callback handler which is invoked when the operation is complete, - * with an error if there is any. - * - */ -- (void)removeAllCachedTokensWithHandler:(nullable void (^)(NSError *error))handler; - -#pragma mark - Persisting Checkin Preferences - -/** - * Save the checkin preferences - * - * @param preferences Checkin preferences to save. - * @param handler The callback handler which is invoked when the operation is complete, - * with an error if there is any. - */ -- (void)saveCheckinPreferences:(FIRInstanceIDCheckinPreferences *)preferences - handler:(nullable void (^)(NSError *error))handler; - -/** - * Return the cached checkin preferences. - * - * @return Checkin preferences. - */ -- (FIRInstanceIDCheckinPreferences *)cachedCheckinPreferences; - -/** - * Remove the cached checkin preferences from the store. - * - * @param handler The callback handler which is invoked when the operation is complete, - * with an error if there is any. - */ -- (void)removeCheckinPreferencesWithHandler:(nullable void (^)(NSError *error))handler; - -#pragma mark - ApplicationSupport sub-directory - -/** - * Check if Application Support directory has InstanceID subdirectory - * - * @return YES if the Application Support directory has InstanceID subdirectory else NO. - */ -+ (BOOL)hasApplicationSupportSubDirectory:(NSString *)subDirectoryName; - -/** - * Create InstanceID subdirectory in Application support directory. - * - * @return YES if the subdirectory was created successfully else NO. - */ -+ (BOOL)createApplicationSupportSubDirectory:(NSString *)subDirectoryName; - -/** - * Removes Application Support subdirectory for InstanceID. - * - * @param error The error object if any while trying to delete the sub-directory. - * - * @return YES if the deletion was successful else NO. - */ -+ (BOOL)removeApplicationSupportSubDirectory:(NSString *)subDirectoryName error:(NSError **)error; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDStore.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDStore.m @@ -1,232 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDStore.h" - -#import "FIRInstanceIDCheckinPreferences.h" -#import "FIRInstanceIDCheckinStore.h" -#import "FIRInstanceIDConstants.h" -#import "FIRInstanceIDLogger.h" -#import "FIRInstanceIDTokenStore.h" -#import "FIRInstanceIDVersionUtilities.h" - -// NOTE: These values should be in sync with what InstanceID saves in as. -static NSString *const kCheckinFileName = @"g-checkin"; - -// APNS token (use the old key value i.e. with prefix GMS) -static NSString *const kFIRInstanceIDLibraryVersion = @"GMSInstanceID-version"; - -@interface FIRInstanceIDStore () - -@property(nonatomic, readwrite, strong) FIRInstanceIDCheckinStore *checkinStore; -@property(nonatomic, readwrite, strong) FIRInstanceIDTokenStore *tokenStore; - -@end - -@implementation FIRInstanceIDStore - -- (instancetype)initWithDelegate:(NSObject<FIRInstanceIDStoreDelegate> *)delegate { - FIRInstanceIDCheckinStore *checkinStore = [[FIRInstanceIDCheckinStore alloc] - initWithCheckinPlistFileName:kCheckinFileName - applicationSupportSubDirectory:kFIRInstanceIDApplicationSupportSubDirectory]; - - FIRInstanceIDTokenStore *tokenStore = [FIRInstanceIDTokenStore defaultStore]; - - return [self initWithCheckinStore:checkinStore tokenStore:tokenStore delegate:delegate]; -} - -- (instancetype)initWithCheckinStore:(FIRInstanceIDCheckinStore *)checkinStore - tokenStore:(FIRInstanceIDTokenStore *)tokenStore - delegate:(NSObject<FIRInstanceIDStoreDelegate> *)delegate { - self = [super init]; - if (self) { - _checkinStore = checkinStore; - _tokenStore = tokenStore; - _delegate = delegate; - [self resetCredentialsIfNeeded]; - } - return self; -} - -#pragma mark - Upgrades - -+ (BOOL)hasApplicationSupportSubDirectory:(NSString *)subDirectoryName { - NSString *subDirectoryPath = [self pathForApplicationSupportSubDirectory:subDirectoryName]; - BOOL isDirectory; - if (![[NSFileManager defaultManager] fileExistsAtPath:subDirectoryPath - isDirectory:&isDirectory]) { - return NO; - } else if (!isDirectory) { - return NO; - } - return YES; -} - -+ (NSString *)pathForApplicationSupportSubDirectory:(NSString *)subDirectoryName { - NSArray *directoryPaths = - NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); - NSString *applicationSupportDirPath = directoryPaths.lastObject; - NSArray *components = @[ applicationSupportDirPath, subDirectoryName ]; - return [NSString pathWithComponents:components]; -} - -+ (BOOL)createApplicationSupportSubDirectory:(NSString *)subDirectoryName { - NSString *subDirectoryPath = [self pathForApplicationSupportSubDirectory:subDirectoryName]; - BOOL hasSubDirectory; - - if (![[NSFileManager defaultManager] fileExistsAtPath:subDirectoryPath - isDirectory:&hasSubDirectory]) { - NSError *error; - [[NSFileManager defaultManager] createDirectoryAtPath:subDirectoryPath - withIntermediateDirectories:YES - attributes:nil - error:&error]; - if (error) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeStore000, - @"Cannot create directory %@, error: %@", subDirectoryPath, error); - return NO; - } - } else { - if (!hasSubDirectory) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeStore001, - @"Found file instead of directory at %@", subDirectoryPath); - return NO; - } - } - return YES; -} - -+ (BOOL)removeApplicationSupportSubDirectory:(NSString *)subDirectoryName error:(NSError **)error { - if ([self hasApplicationSupportSubDirectory:subDirectoryName]) { - NSString *subDirectoryPath = [self pathForApplicationSupportSubDirectory:subDirectoryName]; - BOOL isDirectory; - if ([[NSFileManager defaultManager] fileExistsAtPath:subDirectoryPath - isDirectory:&isDirectory]) { - return [[NSFileManager defaultManager] removeItemAtPath:subDirectoryPath error:error]; - } - } - return YES; -} - -/** - * Reset the keychain preferences if the app had been deleted earlier and then reinstalled. - * Keychain preferences are not cleared in the above scenario so explicitly clear them. - * - * In case of an iCloud backup and restore the Keychain preferences should already be empty - * since the Keychain items are marked with `*BackupThisDeviceOnly`. - */ -- (void)resetCredentialsIfNeeded { - BOOL checkinPlistExists = [self.checkinStore hasCheckinPlist]; - // Checkin info existed in backup excluded plist. Should not be a fresh install. - if (checkinPlistExists) { - // FCM user can still have the old version of checkin, migration should only happen once. - [self.checkinStore migrateCheckinItemIfNeeded]; - return; - } - - // reset checkin in keychain if a fresh install. - // set the old checkin preferences to unregister pre-registered tokens - FIRInstanceIDCheckinPreferences *oldCheckinPreferences = - [self.checkinStore cachedCheckinPreferences]; - - if (oldCheckinPreferences) { - [self.checkinStore removeCheckinPreferencesWithHandler:^(NSError *error) { - if (!error) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeStore002, - @"Removed cached checkin preferences from Keychain."); - } else { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeStore003, - @"Couldn't remove cached checkin preferences. Error: %@", error); - } - if (oldCheckinPreferences.deviceID.length && oldCheckinPreferences.secretToken.length) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeStore006, - @"App reset detected. Will delete server registrations."); - // We don't really need to delete old FCM tokens created via IID auth tokens since - // those tokens are already hashed by APNS token as the has so creating a new - // token should automatically delete the old-token. - [self.delegate store:self didDeleteFCMScopedTokensForCheckin:oldCheckinPreferences]; - } else { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeStore009, - @"App reset detected but no valid checkin auth preferences found." - @" Will not delete server registrations."); - } - }]; - } -} - -#pragma mark - Get - -- (FIRInstanceIDTokenInfo *)tokenInfoWithAuthorizedEntity:(NSString *)authorizedEntity - scope:(NSString *)scope { - // TODO(chliangGoogle): If we don't have the token plist we should delete all the tokens from - // the keychain. This is because not having the plist signifies a backup and restore operation. - // In case the keychain has any tokens these would now be stale and therefore should be - // deleted. - if (![authorizedEntity length] || ![scope length]) { - return nil; - } - FIRInstanceIDTokenInfo *info = [self.tokenStore tokenInfoWithAuthorizedEntity:authorizedEntity - scope:scope]; - return info; -} - -- (NSArray<FIRInstanceIDTokenInfo *> *)cachedTokenInfos { - return [self.tokenStore cachedTokenInfos]; -} - -#pragma mark - Save - -- (void)saveTokenInfo:(FIRInstanceIDTokenInfo *)tokenInfo - handler:(void (^)(NSError *error))handler { - [self.tokenStore saveTokenInfo:tokenInfo handler:handler]; -} - -#pragma mark - Delete - -- (void)removeCachedTokenWithAuthorizedEntity:(NSString *)authorizedEntity scope:(NSString *)scope { - if (![authorizedEntity length] || ![scope length]) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeStore012, - @"Will not delete token with invalid entity: %@, scope: %@", - authorizedEntity, scope); - return; - } - [self.tokenStore removeTokenWithAuthorizedEntity:authorizedEntity scope:scope]; -} - -- (void)removeAllCachedTokensWithHandler:(void (^)(NSError *error))handler { - [self.tokenStore removeAllTokensWithHandler:handler]; -} - -#pragma mark - FIRInstanceIDCheckinCache protocol - -- (void)saveCheckinPreferences:(FIRInstanceIDCheckinPreferences *)preferences - handler:(void (^)(NSError *error))handler { - [self.checkinStore saveCheckinPreferences:preferences handler:handler]; -} - -- (FIRInstanceIDCheckinPreferences *)cachedCheckinPreferences { - return [self.checkinStore cachedCheckinPreferences]; -} - -- (void)removeCheckinPreferencesWithHandler:(void (^)(NSError *))handler { - [self.checkinStore removeCheckinPreferencesWithHandler:^(NSError *error) { - if (handler) { - handler(error); - } - }]; -} - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDStringEncoding.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDStringEncoding.h @@ -1,66 +0,0 @@ -// -// GTMStringEncoding.h -// -// Copyright 2010 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -// This is a copy of GTMStringEncoding. FIRInstanceID wants to avoid -// a CocoaPods GTM dependency. Hence we use our own version of StringEncoding. - -#import <Foundation/Foundation.h> - -// A generic class for arbitrary base-2 to 128 string encoding and decoding. -@interface FIRInstanceIDStringEncoding : NSObject { - @private - NSData *charMapData_; - char *charMap_; - int reverseCharMap_[128]; - int shift_; - unsigned int mask_; - BOOL doPad_; - char paddingChar_; - int padLen_; -} - -+ (id)rfc4648Base64WebsafeStringEncoding; - -// Create a new, autoreleased GTMStringEncoding object with the given string, -// as described below. -+ (id)stringEncodingWithString:(NSString *)string; - -// Initialize a new GTMStringEncoding object with the string. -// -// The length of the string must be a power of 2, at least 2 and at most 128. -// Only 7-bit ASCII characters are permitted in the string. -// -// These characters are the canonical set emitted during encoding. -// If the characters have alternatives (e.g. case, easily transposed) then use -// addDecodeSynonyms: to configure them. -- (id)initWithString:(NSString *)string; - -// Indicates whether padding is performed during encoding. -- (BOOL)doPad; -- (void)setDoPad:(BOOL)doPad; - -// Sets the padding character to use during encoding. -- (void)setPaddingChar:(char)c; - -// Encode a raw binary buffer to a 7-bit ASCII string. -- (NSString *)encode:(NSData *)data; - -// Decode a 7-bit ASCII string to a raw binary buffer. -- (NSData *)decode:(NSString *)string; - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDStringEncoding.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDStringEncoding.m @@ -1,202 +0,0 @@ -#import "FIRInstanceIDDefines.h" - -// -// FIRInstanceIDStringEncoding.m -// -// Copyright 2009 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -// This is a copy of GTMStringEncoding. FIRInstanceID wants to avoid -// a CocoaPods GTM dependency. Hence we use our own version of StringEncoding. - -#import "FIRInstanceIDStringEncoding.h" - -enum { kUnknownChar = -1, kPaddingChar = -2, kIgnoreChar = -3 }; - -@implementation FIRInstanceIDStringEncoding - -+ (id)rfc4648Base64WebsafeStringEncoding { - FIRInstanceIDStringEncoding *ret = [self - stringEncodingWithString:@"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"]; - - [ret setPaddingChar:'=']; - [ret setDoPad:YES]; - return ret; -} - -static inline int lcm(int a, int b) { - for (int aa = a, bb = b;;) { - if (aa == bb) - return aa; - else if (aa < bb) - aa += a; - else - bb += b; - } -} - -+ (id)stringEncodingWithString:(NSString *)string { - return [[FIRInstanceIDStringEncoding alloc] initWithString:string]; -} - -- (id)initWithString:(NSString *)string { - if ((self = [super init])) { - charMapData_ = [string dataUsingEncoding:NSASCIIStringEncoding]; - if (!charMapData_) { - // Unable to convert string to ASCII - return nil; - } - charMap_ = (char *)[charMapData_ bytes]; - NSUInteger length = [charMapData_ length]; - if (length < 2 || length > 128 || length & (length - 1)) { - // Length not a power of 2 between 2 and 128 - return nil; - } - - memset(reverseCharMap_, kUnknownChar, sizeof(reverseCharMap_)); - for (unsigned int i = 0; i < length; i++) { - if (reverseCharMap_[(int)charMap_[i]] != kUnknownChar) { - // Duplicate character at |i| - return nil; - } - reverseCharMap_[(int)charMap_[i]] = i; - } - - for (NSUInteger i = 1; i < length; i <<= 1) shift_++; - mask_ = (1 << shift_) - 1; - padLen_ = lcm(8, shift_) / shift_; - } - return self; -} - -- (NSString *)description { - return [NSString stringWithFormat:@"<Base%d StringEncoder: %@>", 1 << shift_, charMapData_]; -} - -- (BOOL)doPad { - return doPad_; -} - -- (void)setDoPad:(BOOL)doPad { - doPad_ = doPad; -} - -- (void)setPaddingChar:(char)c { - paddingChar_ = c; - reverseCharMap_[(int)c] = kPaddingChar; -} - -- (NSString *)encode:(NSData *)inData { - NSUInteger inLen = [inData length]; - if (inLen <= 0) { - // Empty input - return @""; - } - unsigned char *inBuf = (unsigned char *)[inData bytes]; - NSUInteger inPos = 0; - - NSUInteger outLen = (inLen * 8 + shift_ - 1) / shift_; - if (doPad_) { - outLen = ((outLen + padLen_ - 1) / padLen_) * padLen_; - } - NSMutableData *outData = [NSMutableData dataWithLength:outLen]; - unsigned char *outBuf = (unsigned char *)[outData mutableBytes]; - NSUInteger outPos = 0; - - unsigned int buffer = inBuf[inPos++]; - int bitsLeft = 8; - while (bitsLeft > 0 || inPos < inLen) { - if (bitsLeft < shift_) { - if (inPos < inLen) { - buffer <<= 8; - buffer |= (inBuf[inPos++] & 0xff); - bitsLeft += 8; - } else { - int pad = shift_ - bitsLeft; - buffer <<= pad; - bitsLeft += pad; - } - } - unsigned int idx = (buffer >> (bitsLeft - shift_)) & mask_; - bitsLeft -= shift_; - outBuf[outPos++] = charMap_[idx]; - } - - if (doPad_) { - while (outPos < outLen) outBuf[outPos++] = paddingChar_; - } - - _FIRInstanceIDDevAssert(outPos == outLen, @"Underflowed output buffer"); - [outData setLength:outPos]; - - return [[NSString alloc] initWithData:outData encoding:NSASCIIStringEncoding]; -} - -- (NSData *)decode:(NSString *)inString { - char *inBuf = (char *)[inString cStringUsingEncoding:NSASCIIStringEncoding]; - if (!inBuf) { - // Unable to convert buffer to ASCII - return nil; - } - NSUInteger inLen = strlen(inBuf); - - NSUInteger outLen = inLen * shift_ / 8; - NSMutableData *outData = [NSMutableData dataWithLength:outLen]; - unsigned char *outBuf = (unsigned char *)[outData mutableBytes]; - NSUInteger outPos = 0; - - int buffer = 0; - int bitsLeft = 0; - BOOL expectPad = NO; - for (NSUInteger i = 0; i < inLen; i++) { - int val = reverseCharMap_[(int)inBuf[i]]; - switch (val) { - case kIgnoreChar: - break; - case kPaddingChar: - expectPad = YES; - break; - case kUnknownChar: - // Unexpected data at input pos |i| - return nil; - default: - if (expectPad) { - // Expected further padding characters - return nil; - } - buffer <<= shift_; - buffer |= val & mask_; - bitsLeft += shift_; - if (bitsLeft >= 8) { - outBuf[outPos++] = (unsigned char)(buffer >> (bitsLeft - 8)); - bitsLeft -= 8; - } - break; - } - } - - if (bitsLeft && buffer & ((1 << bitsLeft) - 1)) { - // Incomplete trailing data - return nil; - } - - // Shorten buffer if needed due to padding chars - _FIRInstanceIDDevAssert(outPos <= outLen, @"Overflowed buffer"); - [outData setLength:outPos]; - - return outData; -} - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenDeleteOperation.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenDeleteOperation.h @@ -1,31 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDTokenOperation.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface FIRInstanceIDTokenDeleteOperation : FIRInstanceIDTokenOperation - -- (instancetype)initWithAuthorizedEntity:(nullable NSString *)authorizedEntity - scope:(NSString *)scope - checkinPreferences:(FIRInstanceIDCheckinPreferences *)checkinPreferences - keyPair:(nullable FIRInstanceIDKeyPair *)keyPair - action:(FIRInstanceIDTokenAction)action; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenDeleteOperation.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenDeleteOperation.m @@ -1,120 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDTokenDeleteOperation.h" - -#import "FIRInstanceIDCheckinPreferences.h" -#import "FIRInstanceIDDefines.h" -#import "FIRInstanceIDLogger.h" -#import "FIRInstanceIDTokenOperation+Private.h" -#import "FIRInstanceIDURLQueryItem.h" -#import "FIRInstanceIDUtilities.h" -#import "NSError+FIRInstanceID.h" - -@implementation FIRInstanceIDTokenDeleteOperation - -- (instancetype)initWithAuthorizedEntity:(NSString *)authorizedEntity - scope:(NSString *)scope - checkinPreferences:(FIRInstanceIDCheckinPreferences *)checkinPreferences - keyPair:(FIRInstanceIDKeyPair *)keyPair - action:(FIRInstanceIDTokenAction)action { - self = [super initWithAction:action - forAuthorizedEntity:authorizedEntity - scope:scope - options:nil - checkinPreferences:checkinPreferences - keyPair:keyPair]; - if (self) { - } - return self; -} - -- (void)performTokenOperation { - NSString *authHeader = - [FIRInstanceIDTokenOperation HTTPAuthHeaderFromCheckin:self.checkinPreferences]; - NSMutableURLRequest *request = [FIRInstanceIDTokenOperation requestWithAuthHeader:authHeader]; - - // Build form-encoded body - NSString *deviceAuthID = self.checkinPreferences.deviceID; - NSMutableArray<FIRInstanceIDURLQueryItem *> *queryItems = - [FIRInstanceIDTokenOperation standardQueryItemsWithDeviceID:deviceAuthID scope:self.scope]; - [queryItems addObject:[FIRInstanceIDURLQueryItem queryItemWithName:@"delete" value:@"true"]]; - if (self.action == FIRInstanceIDTokenActionDeleteTokenAndIID) { - [queryItems addObject:[FIRInstanceIDURLQueryItem queryItemWithName:@"iid-operation" - value:@"delete"]]; - } - if (self.authorizedEntity) { - [queryItems addObject:[FIRInstanceIDURLQueryItem queryItemWithName:@"sender" - value:self.authorizedEntity]]; - } - // Typically we include our public key-signed url items, but in some cases (like deleting all FCM - // tokens), we don't. - if (self.keyPair != nil) { - [queryItems addObjectsFromArray:[self queryItemsWithKeyPair:self.keyPair]]; - } - - NSString *content = FIRInstanceIDQueryFromQueryItems(queryItems); - request.HTTPBody = [content dataUsingEncoding:NSUTF8StringEncoding]; - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenDeleteOperationFetchRequest, - @"Unregister request to %@ content: %@", FIRInstanceIDRegisterServer(), - content); - - FIRInstanceID_WEAKIFY(self); - void (^requestHandler)(NSData *, NSURLResponse *, NSError *) = - ^(NSData *data, NSURLResponse *response, NSError *error) { - FIRInstanceID_STRONGIFY(self); - [self handleResponseWithData:data response:response error:error]; - }; - - // Test block - if (self.testBlock) { - self.testBlock(request, requestHandler); - return; - } - - NSURLSession *session = [FIRInstanceIDTokenOperation sharedURLSession]; - self.dataTask = [session dataTaskWithRequest:request completionHandler:requestHandler]; - [self.dataTask resume]; -} - -- (void)handleResponseWithData:(NSData *)data - response:(NSURLResponse *)response - error:(NSError *)error { - if (error) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenDeleteOperationRequestError, - @"Device unregister HTTP fetch error. Error code: %ld", - _FIRInstanceID_L(error.code)); - [self finishWithResult:FIRInstanceIDTokenOperationError token:nil error:error]; - return; - } - - NSString *dataResponse = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - if (dataResponse.length == 0) { - NSError *error = [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeUnknown]; - [self finishWithResult:FIRInstanceIDTokenOperationError token:nil error:error]; - return; - } - - if (![dataResponse hasPrefix:@"deleted="] && ![dataResponse hasPrefix:@"token="]) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenDeleteOperationBadResponse, - @"Invalid unregister response %@", response); - NSError *error = [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeUnknown]; - [self finishWithResult:FIRInstanceIDTokenOperationError token:nil error:error]; - return; - } - [self finishWithResult:FIRInstanceIDTokenOperationSucceeded token:nil error:nil]; -} -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenFetchOperation.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenFetchOperation.h @@ -1,29 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDTokenOperation.h" - -NS_ASSUME_NONNULL_BEGIN -@interface FIRInstanceIDTokenFetchOperation : FIRInstanceIDTokenOperation - -- (instancetype)initWithAuthorizedEntity:(NSString *)authorizedEntity - scope:(NSString *)scope - options:(nullable NSDictionary<NSString *, NSString *> *)options - checkinPreferences:(FIRInstanceIDCheckinPreferences *)checkinPreferences - keyPair:(FIRInstanceIDKeyPair *)keyPair; - -@end -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenFetchOperation.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenFetchOperation.m @@ -1,200 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDTokenFetchOperation.h" - -#import "FIRInstanceIDCheckinPreferences.h" -#import "FIRInstanceIDConstants.h" -#import "FIRInstanceIDDefines.h" -#import "FIRInstanceIDLogger.h" -#import "FIRInstanceIDTokenOperation+Private.h" -#import "FIRInstanceIDURLQueryItem.h" -#import "FIRInstanceIDUtilities.h" -#import "NSError+FIRInstanceID.h" - -// We can have a static int since this error should theoretically only -// happen once (for the first time). If it repeats there is something -// else that is wrong. -static int phoneRegistrationErrorRetryCount = 0; -static const int kMaxPhoneRegistrationErrorRetryCount = 10; - -@implementation FIRInstanceIDTokenFetchOperation - -- (instancetype)initWithAuthorizedEntity:(NSString *)authorizedEntity - scope:(NSString *)scope - options:(nullable NSDictionary<NSString *, NSString *> *)options - checkinPreferences:(FIRInstanceIDCheckinPreferences *)checkinPreferences - keyPair:(FIRInstanceIDKeyPair *)keyPair { - self = [super initWithAction:FIRInstanceIDTokenActionFetch - forAuthorizedEntity:authorizedEntity - scope:scope - options:options - checkinPreferences:checkinPreferences - keyPair:keyPair]; - if (self) { - } - return self; -} - -- (void)performTokenOperation { - NSString *authHeader = - [FIRInstanceIDTokenOperation HTTPAuthHeaderFromCheckin:self.checkinPreferences]; - NSMutableURLRequest *request = [[self class] requestWithAuthHeader:authHeader]; - NSString *checkinVersionInfo = self.checkinPreferences.versionInfo; - [request setValue:checkinVersionInfo forHTTPHeaderField:@"info"]; - - // Build form-encoded body - NSString *deviceAuthID = self.checkinPreferences.deviceID; - NSMutableArray<FIRInstanceIDURLQueryItem *> *queryItems = - [[self class] standardQueryItemsWithDeviceID:deviceAuthID scope:self.scope]; - [queryItems addObject:[FIRInstanceIDURLQueryItem queryItemWithName:@"sender" - value:self.authorizedEntity]]; - [queryItems addObject:[FIRInstanceIDURLQueryItem queryItemWithName:@"X-subtype" - value:self.authorizedEntity]]; - - [queryItems addObjectsFromArray:[self queryItemsWithKeyPair:self.keyPair]]; - - // Create query items from passed-in options - id apnsTokenData = self.options[kFIRInstanceIDTokenOptionsAPNSKey]; - id apnsSandboxValue = self.options[kFIRInstanceIDTokenOptionsAPNSIsSandboxKey]; - if ([apnsTokenData isKindOfClass:[NSData class]] && - [apnsSandboxValue isKindOfClass:[NSNumber class]]) { - NSString *APNSString = FIRInstanceIDAPNSTupleStringForTokenAndServerType( - apnsTokenData, ((NSNumber *)apnsSandboxValue).boolValue); - // The name of the query item happens to be the same as the dictionary key - FIRInstanceIDURLQueryItem *item = - [FIRInstanceIDURLQueryItem queryItemWithName:kFIRInstanceIDTokenOptionsAPNSKey - value:APNSString]; - [queryItems addObject:item]; - } - id firebaseAppID = self.options[kFIRInstanceIDTokenOptionsFirebaseAppIDKey]; - if ([firebaseAppID isKindOfClass:[NSString class]]) { - // The name of the query item happens to be the same as the dictionary key - FIRInstanceIDURLQueryItem *item = - [FIRInstanceIDURLQueryItem queryItemWithName:kFIRInstanceIDTokenOptionsFirebaseAppIDKey - value:(NSString *)firebaseAppID]; - [queryItems addObject:item]; - } - - NSString *content = FIRInstanceIDQueryFromQueryItems(queryItems); - request.HTTPBody = [content dataUsingEncoding:NSUTF8StringEncoding]; - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenFetchOperationFetchRequest, - @"Register request to %@ content: %@", FIRInstanceIDRegisterServer(), - content); - - FIRInstanceID_WEAKIFY(self); - void (^requestHandler)(NSData *, NSURLResponse *, NSError *) = - ^(NSData *data, NSURLResponse *response, NSError *error) { - FIRInstanceID_STRONGIFY(self); - [self handleResponseWithData:data response:response error:error]; - }; - - // Test block - if (self.testBlock) { - self.testBlock(request, requestHandler); - return; - } - - NSURLSession *session = [FIRInstanceIDTokenOperation sharedURLSession]; - self.dataTask = [session dataTaskWithRequest:request completionHandler:requestHandler]; - [self.dataTask resume]; -} - -#pragma mark - Request Handling - -- (void)handleResponseWithData:(NSData *)data - response:(NSURLResponse *)response - error:(NSError *)error { - if (error) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenFetchOperationRequestError, - @"Token fetch HTTP error. Error Code: %ld", (long)error.code); - [self finishWithResult:FIRInstanceIDTokenOperationError token:nil error:error]; - return; - } - NSString *dataResponse = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - - if (dataResponse.length == 0) { - NSError *error = [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeUnknown]; - [self finishWithResult:FIRInstanceIDTokenOperationError token:nil error:error]; - return; - } - NSDictionary *parsedResponse = [self parseFetchTokenResponse:dataResponse]; - _FIRInstanceIDDevAssert(parsedResponse.count, @"Invalid registration response"); - - if ([parsedResponse[@"token"] length]) { - [self finishWithResult:FIRInstanceIDTokenOperationSucceeded - token:parsedResponse[@"token"] - error:nil]; - return; - } - - NSString *errorValue = parsedResponse[@"Error"]; - NSError *responseError; - if (errorValue.length) { - NSArray *errorComponents = [errorValue componentsSeparatedByString:@":"]; - // HACK (Kansas replication delay), PHONE_REGISTRATION_ERROR on App - // uninstall and reinstall. - if ([errorComponents containsObject:@"PHONE_REGISTRATION_ERROR"]) { - // Encountered issue http://b/27043795 - // Retry register until successful or another error encountered or a - // certain number of tries are over. - - if (phoneRegistrationErrorRetryCount < kMaxPhoneRegistrationErrorRetryCount) { - const int nextRetryInterval = 1 << phoneRegistrationErrorRetryCount; - FIRInstanceID_WEAKIFY(self); - - dispatch_after( - dispatch_time(DISPATCH_TIME_NOW, (int64_t)(nextRetryInterval * NSEC_PER_SEC)), - dispatch_get_main_queue(), ^{ - FIRInstanceID_STRONGIFY(self); - phoneRegistrationErrorRetryCount++; - [self performTokenOperation]; - }); - return; - } - } else if ([errorComponents containsObject:kFIRInstanceID_CMD_RST]) { - // Server detected the identity we use is no longer valid. - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - [center postNotificationName:kFIRInstanceIDIdentityInvalidatedNotification object:nil]; - - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeInternal001, - @"Identity is invalid. Server request identity reset."); - responseError = - [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeInvalidIdentity]; - } - } - if (!responseError) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenFetchOperationBadResponse, - @"Invalid fetch response, expected 'token' or 'Error' key"); - responseError = [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeUnknown]; - } - [self finishWithResult:FIRInstanceIDTokenOperationError token:nil error:responseError]; -} - -// expect a response e.g. "token=<reg id>\nGOOG.ttl=123" -- (NSDictionary *)parseFetchTokenResponse:(NSString *)response { - NSArray *lines = [response componentsSeparatedByString:@"\n"]; - NSMutableDictionary *parsedResponse = [NSMutableDictionary dictionary]; - for (NSString *line in lines) { - NSArray *keyAndValue = [line componentsSeparatedByString:@"="]; - if ([keyAndValue count] > 1) { - parsedResponse[keyAndValue[0]] = keyAndValue[1]; - } - } - return parsedResponse; -} - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenInfo.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenInfo.h @@ -1,82 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -#import "FIRInstanceIDAPNSInfo.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - * Represents an Instance ID token, and all of the relevant information - * associated with it. It can read from and write to an NSDictionary object, for - * simple serialization. - */ -@interface FIRInstanceIDTokenInfo : NSObject <NSCoding> - -/// The authorized entity (also known as Sender ID), associated with the token. -@property(nonatomic, readonly, copy) NSString *authorizedEntity; -/// The scope associated with the token. This is an arbitrary string, typically "*". -@property(nonatomic, readonly, copy) NSString *scope; -/// The token value itself, with which all other properties are associated. -@property(nonatomic, readonly, copy) NSString *token; - -// These properties are nullable because they might not exist for tokens fetched from -// legacy storage formats. - -/// The app version that this token represents. -@property(nonatomic, readonly, copy, nullable) NSString *appVersion; -/// The Firebase app ID (also known as GMP App ID), that this token is associated with. -@property(nonatomic, readonly, copy, nullable) NSString *firebaseAppID; - -/// Tokens may not always be associated with an APNs token, and may be associated after -/// being created. -@property(nonatomic, strong, nullable) FIRInstanceIDAPNSInfo *APNSInfo; -/// The time that this token info was updated. The cache time is writeable, since in -/// some cases the token info may be refreshed from the server. In those situations, -/// the cacheTime would be updated. -@property(nonatomic, copy, nullable) NSDate *cacheTime; - -/** - * Initializes a FIRInstanceIDTokenInfo object with the required parameters. These - * parameters represent all the relevant associated data with a token. - * - * @param authorizedEntity The authorized entity (also known as Sender ID). - * @param scope The scope of the token, typically "*" meaning - * it's a "default scope". - * @param token The token value itself. - * @param appVersion The application version that this token is associated with. - * @param firebaseAppID The Firebase app ID which this token is associated with. - * @return An instance of FIRInstanceIDTokenInfo. - */ -- (instancetype)initWithAuthorizedEntity:(NSString *)authorizedEntity - scope:(NSString *)scope - token:(NSString *)token - appVersion:(nullable NSString *)appVersion - firebaseAppID:(nullable NSString *)firebaseAppID; - -/** - * Check whether the token is still fresh based on: - * 1. Last fetch token is within the 7 days. - * 2. Language setting is not changed. - * 3. App version is current. - * 4. GMP App ID is current. - */ -- (BOOL)isFresh; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenInfo.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenInfo.m @@ -1,188 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDTokenInfo.h" - -#import "FIRInstanceIDLogger.h" -#import "FIRInstanceIDUtilities.h" - -/** - * @enum Token Info Dictionary Key Constants - * @discussion The keys that are checked when a token info is - * created from a dictionary. The same keys are used - * when decoding/encoding an archive. - */ -/// Specifies a dictonary key whose value represents the authorized entity, or -/// Sender ID for the token. -static NSString *const kFIRInstanceIDAuthorizedEntityKey = @"authorized_entity"; -/// Specifies a dictionary key whose value represents the scope of the token, -/// typically "*". -static NSString *const kFIRInstanceIDScopeKey = @"scope"; -/// Specifies a dictionary key which represents the token value itself. -static NSString *const kFIRInstanceIDTokenKey = @"token"; -/// Specifies a dictionary key which represents the app version associated -/// with the token. -static NSString *const kFIRInstanceIDAppVersionKey = @"app_version"; -/// Specifies a dictionary key which represents the GMP App ID associated with -/// the token. -static NSString *const kFIRInstanceIDFirebaseAppIDKey = @"firebase_app_id"; -/// Specifies a dictionary key representing an archive for a -/// `FIRInstanceIDAPNSInfo` object. -static NSString *const kFIRInstanceIDAPNSInfoKey = @"apns_info"; -/// Specifies a dictionary key representing the "last cached" time for the token. -static NSString *const kFIRInstanceIDCacheTimeKey = @"cache_time"; -/// Default interval that token stays fresh. -const NSTimeInterval kDefaultFetchTokenInterval = 7 * 24 * 60 * 60; // 7 days. - -@implementation FIRInstanceIDTokenInfo - -- (instancetype)initWithAuthorizedEntity:(NSString *)authorizedEntity - scope:(NSString *)scope - token:(NSString *)token - appVersion:(NSString *)appVersion - firebaseAppID:(NSString *)firebaseAppID { - self = [super init]; - if (self) { - _authorizedEntity = [authorizedEntity copy]; - _scope = [scope copy]; - _token = [token copy]; - _appVersion = [appVersion copy]; - _firebaseAppID = [firebaseAppID copy]; - } - return self; -} - -- (BOOL)isFresh { - // Last fetch token cache time could be null if token is from legacy storage format. Then token is - // considered not fresh and should be refreshed and overwrite with the latest storage format. - if (!_cacheTime) { - return NO; - } - - // Check if app has just been updated to a new version. - NSString *currentAppVersion = FIRInstanceIDCurrentAppVersion(); - if (!_appVersion || ![_appVersion isEqualToString:currentAppVersion]) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenManager004, - @"Invalidating cached token for %@ (%@) due to app version change.", - _authorizedEntity, _scope); - return NO; - } - - // Check if GMP App ID has changed - NSString *currentFirebaseAppID = FIRInstanceIDFirebaseAppID(); - if (!_firebaseAppID || ![_firebaseAppID isEqualToString:currentFirebaseAppID]) { - FIRInstanceIDLoggerDebug( - kFIRInstanceIDMessageCodeTokenInfoFirebaseAppIDChanged, - @"Invalidating cached token due to Firebase App IID change from %@ to %@", _firebaseAppID, - currentFirebaseAppID); - return NO; - } - - // Check whether locale has changed, if yes, token needs to be updated with server for locale - // information. - if (FIRInstanceIDHasLocaleChanged()) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenInfoLocaleChanged, - @"Invalidating cached token due to locale change"); - return NO; - } - - // Locale is not changed, check whether token has been fetched within 7 days. - NSTimeInterval lastFetchTokenTimestamp = [_cacheTime timeIntervalSince1970]; - NSTimeInterval currentTimestamp = FIRInstanceIDCurrentTimestampInSeconds(); - NSTimeInterval timeSinceLastFetchToken = currentTimestamp - lastFetchTokenTimestamp; - return (timeSinceLastFetchToken < kDefaultFetchTokenInterval); -} -#pragma mark - NSCoding - -- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { - // These value cannot be nil - - id authorizedEntity = [aDecoder decodeObjectForKey:kFIRInstanceIDAuthorizedEntityKey]; - if (![authorizedEntity isKindOfClass:[NSString class]]) { - return nil; - } - - id scope = [aDecoder decodeObjectForKey:kFIRInstanceIDScopeKey]; - if (![scope isKindOfClass:[NSString class]]) { - return nil; - } - - id token = [aDecoder decodeObjectForKey:kFIRInstanceIDTokenKey]; - if (![token isKindOfClass:[NSString class]]) { - return nil; - } - - // These values are nullable, so only fail the decode if the type does not match - - id appVersion = [aDecoder decodeObjectForKey:kFIRInstanceIDAppVersionKey]; - if (appVersion && ![appVersion isKindOfClass:[NSString class]]) { - return nil; - } - - id firebaseAppID = [aDecoder decodeObjectForKey:kFIRInstanceIDFirebaseAppIDKey]; - if (firebaseAppID && ![firebaseAppID isKindOfClass:[NSString class]]) { - return nil; - } - - id rawAPNSInfo = [aDecoder decodeObjectForKey:kFIRInstanceIDAPNSInfoKey]; - if (rawAPNSInfo && ![rawAPNSInfo isKindOfClass:[NSData class]]) { - return nil; - } - - FIRInstanceIDAPNSInfo *APNSInfo = nil; - if (rawAPNSInfo) { - @try { - APNSInfo = [NSKeyedUnarchiver unarchiveObjectWithData:rawAPNSInfo]; - } @catch (NSException *exception) { - FIRInstanceIDLoggerInfo(kFIRInstanceIDMessageCodeTokenInfoBadAPNSInfo, - @"Could not parse raw APNS Info while parsing archived token info."); - APNSInfo = nil; - } @finally { - } - } - - id cacheTime = [aDecoder decodeObjectForKey:kFIRInstanceIDCacheTimeKey]; - if (cacheTime && ![cacheTime isKindOfClass:[NSDate class]]) { - return nil; - } - - self = [super init]; - if (self) { - _authorizedEntity = authorizedEntity; - _scope = scope; - _token = token; - _appVersion = appVersion; - _firebaseAppID = firebaseAppID; - _APNSInfo = APNSInfo; - _cacheTime = cacheTime; - } - return self; -} - -- (void)encodeWithCoder:(NSCoder *)aCoder { - [aCoder encodeObject:self.authorizedEntity forKey:kFIRInstanceIDAuthorizedEntityKey]; - [aCoder encodeObject:self.scope forKey:kFIRInstanceIDScopeKey]; - [aCoder encodeObject:self.token forKey:kFIRInstanceIDTokenKey]; - [aCoder encodeObject:self.appVersion forKey:kFIRInstanceIDAppVersionKey]; - [aCoder encodeObject:self.firebaseAppID forKey:kFIRInstanceIDFirebaseAppIDKey]; - if (self.APNSInfo) { - NSData *rawAPNSInfo = [NSKeyedArchiver archivedDataWithRootObject:self.APNSInfo]; - [aCoder encodeObject:rawAPNSInfo forKey:kFIRInstanceIDAPNSInfoKey]; - } - [aCoder encodeObject:self.cacheTime forKey:kFIRInstanceIDCacheTimeKey]; -} - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenManager.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenManager.h @@ -1,149 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceID.h" - -@class FIRInstanceIDAuthService; -@class FIRInstanceIDCheckinPreferences; -@class FIRInstanceIDKeyPair; -@class FIRInstanceIDTokenInfo; -@class FIRInstanceIDStore; - -typedef NS_OPTIONS(NSUInteger, FIRInstanceIDInvalidTokenReason) { - FIRInstanceIDInvalidTokenReasonNone = 0, // 0 - FIRInstanceIDInvalidTokenReasonAppVersion = (1 << 0), // 0...00001 - FIRInstanceIDInvalidTokenReasonAPNSToken = (1 << 1), // 0...00010 -}; - -/** - * Manager for the InstanceID token requests i.e `newToken` and `deleteToken`. This - * manages the overall interaction of the `InstanceIDStore`, the token register - * service and the callbacks associated with `GCMInstanceID`. - */ -@interface FIRInstanceIDTokenManager : NSObject - -/// Expose the auth service, so it can be used by others -@property(nonatomic, readonly, strong) FIRInstanceIDAuthService *authService; - -/** - * Fetch new token for the given authorizedEntity and scope. This makes an - * asynchronous request to the InstanceID backend to create a new token for - * the service and returns it. This will replace any old token for the given - * authorizedEntity and scope that has been cached before. - * - * @param authorizedEntity The authorized entity for the token, should not be nil. - * @param scope The scope for the token, should not be nil. - * @param keyPair The keyPair that represents the app identity. - * @param options The options to be added to the fetch request. - * @param handler The handler to be invoked once we have the token or the - * fetch request to InstanceID backend results in an error. Also - * since it's a public handler it should always be called - * asynchronously. This should be non-nil. - */ -- (void)fetchNewTokenWithAuthorizedEntity:(NSString *)authorizedEntity - scope:(NSString *)scope - keyPair:(FIRInstanceIDKeyPair *)keyPair - options:(NSDictionary *)options - handler:(FIRInstanceIDTokenHandler)handler; - -/** - * Return the cached token info, if one exists, for the given authorizedEntity and scope. - * - * @param authorizedEntity The authorized entity for the token. - * @param scope The scope for the token. - * - * @return The cached token info, if available, matching the parameters. - */ -- (FIRInstanceIDTokenInfo *)cachedTokenInfoWithAuthorizedEntity:(NSString *)authorizedEntity - scope:(NSString *)scope; - -/** - * Delete the token for the given authorizedEntity and scope. If the token has - * been cached, it will be deleted from the store. It will also make an - * asynchronous request to the InstanceID backend to invalidate the token. - * - * @param authorizedEntity The authorized entity for the token, should not be nil. - * @param scope The scope for the token, should not be nil. - * @param keyPair The keyPair that represents the app identity. - * @param handler The handler to be invoked once the delete request to - * InstanceID backend has returned. If the request was - * successful we invoke the handler with a nil error; - * otherwise we call it with an appropriate error. Also since - * it's a public handler it should always be called - * asynchronously. This should be non-nil. - */ -- (void)deleteTokenWithAuthorizedEntity:(NSString *)authorizedEntity - scope:(NSString *)scope - keyPair:(FIRInstanceIDKeyPair *)keyPair - handler:(FIRInstanceIDDeleteTokenHandler)handler; - -/** - * Deletes all cached tokens from the persistent store. This method should only be triggered - * when InstanceID is deleted - * - * @param keyPair The keyPair for the given app. - * @param handler The handler to be invoked once the delete request to InstanceID backend - * has returned. If the request was successful we invoke the handler with - * a nil error; else we pass in an appropriate error. This should be non-nil - * and be called asynchronously. - */ -- (void)deleteAllTokensWithKeyPair:(FIRInstanceIDKeyPair *)keyPair - handler:(FIRInstanceIDDeleteHandler)handler; - -/** - * Deletes all cached tokens from the persistent store. - * @param handler The callback handler which is invoked when tokens deletion is complete, - * with an error if there is any. - * - */ -- (void)deleteAllTokensLocallyWithHandler:(void (^)(NSError *error))handler; - -/** - * Stop any ongoing token operations. - */ -- (void)stopAllTokenOperations; - -#pragma mark - Invalidating Cached Tokens - -/** - * Invalidate any cached tokens, if the app version has changed since last launch or if the token - * is cached for more than 7 days. - * - * @return Whether we should fetch default token from server. - * - * @discussion This should safely be called prior to any tokens being retrieved from - * the cache or being fetched from the network. - */ -- (BOOL)checkForTokenRefreshPolicy; - -/** - * Upon being provided with different APNs or sandbox, any locally cached tokens - * should be deleted, and the new APNs token should be cached. - * - * @discussion It is possible for this method to be called while token operations are - * in-progress or queued. In this case, the in-flight token operations will have stale - * APNs information. The default token is checked for being out-of-date by Instance ID, - * and re-fetched. Custom tokens are not currently checked. - * - * @param deviceToken The APNS device token, provided by the operating system. - * @param isSandbox YES if the device token is for the sandbox environment, NO otherwise. - * - * @return The array of FIRInstanceIDTokenInfo objects which were invalidated. - */ -- (NSArray<FIRInstanceIDTokenInfo *> *)updateTokensToAPNSDeviceToken:(NSData *)deviceToken - isSandbox:(BOOL)isSandbox; - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenManager.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenManager.m @@ -1,341 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDTokenManager.h" - -#import "FIRInstanceIDAuthKeyChain.h" -#import "FIRInstanceIDAuthService.h" -#import "FIRInstanceIDCheckinPreferences.h" -#import "FIRInstanceIDConstants.h" -#import "FIRInstanceIDDefines.h" -#import "FIRInstanceIDLogger.h" -#import "FIRInstanceIDStore.h" -#import "FIRInstanceIDTokenDeleteOperation.h" -#import "FIRInstanceIDTokenFetchOperation.h" -#import "FIRInstanceIDTokenInfo.h" -#import "FIRInstanceIDTokenOperation.h" -#import "NSError+FIRInstanceID.h" - -@interface FIRInstanceIDTokenManager () <FIRInstanceIDStoreDelegate> - -@property(nonatomic, readwrite, strong) FIRInstanceIDStore *instanceIDStore; -@property(nonatomic, readwrite, strong) FIRInstanceIDAuthService *authService; -@property(nonatomic, readonly, strong) NSOperationQueue *tokenOperations; - -@property(nonatomic, readwrite, strong) FIRInstanceIDAPNSInfo *currentAPNSInfo; - -@end - -@implementation FIRInstanceIDTokenManager - -- (instancetype)init { - self = [super init]; - if (self) { - _instanceIDStore = [[FIRInstanceIDStore alloc] initWithDelegate:self]; - _authService = [[FIRInstanceIDAuthService alloc] initWithStore:_instanceIDStore]; - [self configureTokenOperations]; - } - return self; -} - -- (void)dealloc { - [self stopAllTokenOperations]; -} - -- (void)configureTokenOperations { - _tokenOperations = [[NSOperationQueue alloc] init]; - _tokenOperations.name = @"com.google.iid-token-operations"; - // For now, restrict the operations to be serial, because in some cases (like if the - // authorized entity and scope are the same), order matters. - // If we have to deal with several different token requests simultaneously, it would be a good - // idea to add some better intelligence around this (performing unrelated token operations - // simultaneously, etc.). - _tokenOperations.maxConcurrentOperationCount = 1; - if ([_tokenOperations respondsToSelector:@selector(qualityOfService)]) { - _tokenOperations.qualityOfService = NSOperationQualityOfServiceUtility; - } -} - -- (void)fetchNewTokenWithAuthorizedEntity:(NSString *)authorizedEntity - scope:(NSString *)scope - keyPair:(FIRInstanceIDKeyPair *)keyPair - options:(NSDictionary *)options - handler:(FIRInstanceIDTokenHandler)handler { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenManager000, - @"Fetch new token for authorizedEntity: %@, scope: %@", authorizedEntity, - scope); - FIRInstanceIDTokenFetchOperation *operation = - [self createFetchOperationWithAuthorizedEntity:authorizedEntity - scope:scope - options:options - keyPair:keyPair]; - FIRInstanceID_WEAKIFY(self); - FIRInstanceIDTokenOperationCompletion completion = - ^(FIRInstanceIDTokenOperationResult result, NSString *_Nullable token, - NSError *_Nullable error) { - FIRInstanceID_STRONGIFY(self); - if (error) { - handler(nil, error); - return; - } - NSString *firebaseAppID = options[kFIRInstanceIDTokenOptionsFirebaseAppIDKey]; - FIRInstanceIDTokenInfo *tokenInfo = [[FIRInstanceIDTokenInfo alloc] - initWithAuthorizedEntity:authorizedEntity - scope:scope - token:token - appVersion:FIRInstanceIDCurrentAppVersion() - firebaseAppID:firebaseAppID]; - tokenInfo.APNSInfo = [[FIRInstanceIDAPNSInfo alloc] initWithTokenOptionsDictionary:options]; - - [self.instanceIDStore - saveTokenInfo:tokenInfo - handler:^(NSError *error) { - if (!error) { - // Do not send the token back in case the save was unsuccessful. Since with - // the new asychronous fetch mechanism this can lead to infinite loops, for - // example, we will return a valid token even though we weren't able to store - // it in our cache. The first token will lead to a onTokenRefresh callback - // wherein the user again calls `getToken` but since we weren't able to save - // it we won't hit the cache but hit the server again leading to an infinite - // loop. - FIRInstanceIDLoggerDebug( - kFIRInstanceIDMessageCodeTokenManager001, - @"Token fetch successful, token: %@, authorizedEntity: %@, scope:%@", - token, authorizedEntity, scope); - - if (handler) { - handler(token, nil); - } - } else { - if (handler) { - handler(nil, error); - } - } - }]; - }; - // Add completion handler, and ensure it's called on the main queue - [operation addCompletionHandler:^(FIRInstanceIDTokenOperationResult result, - NSString *_Nullable token, NSError *_Nullable error) { - dispatch_async(dispatch_get_main_queue(), ^{ - completion(result, token, error); - }); - }]; - [self.tokenOperations addOperation:operation]; -} - -- (FIRInstanceIDTokenInfo *)cachedTokenInfoWithAuthorizedEntity:(NSString *)authorizedEntity - scope:(NSString *)scope { - return [self.instanceIDStore tokenInfoWithAuthorizedEntity:authorizedEntity scope:scope]; -} - -- (void)deleteTokenWithAuthorizedEntity:(NSString *)authorizedEntity - scope:(NSString *)scope - keyPair:(FIRInstanceIDKeyPair *)keyPair - handler:(FIRInstanceIDDeleteTokenHandler)handler { - if ([self.instanceIDStore tokenInfoWithAuthorizedEntity:authorizedEntity scope:scope]) { - [self.instanceIDStore removeCachedTokenWithAuthorizedEntity:authorizedEntity scope:scope]; - } - // Does not matter if we cannot find it in the cache. Still make an effort to unregister - // from the server. - FIRInstanceIDCheckinPreferences *checkinPreferences = self.authService.checkinPreferences; - FIRInstanceIDTokenDeleteOperation *operation = - [self createDeleteOperationWithAuthorizedEntity:authorizedEntity - scope:scope - checkinPreferences:checkinPreferences - keyPair:keyPair - action:FIRInstanceIDTokenActionDeleteToken]; - - if (handler) { - [operation addCompletionHandler:^(FIRInstanceIDTokenOperationResult result, - NSString *_Nullable token, NSError *_Nullable error) { - dispatch_async(dispatch_get_main_queue(), ^{ - handler(error); - }); - }]; - } - [self.tokenOperations addOperation:operation]; -} - -- (void)deleteAllTokensWithKeyPair:(FIRInstanceIDKeyPair *)keyPair - handler:(FIRInstanceIDDeleteHandler)handler { - // delete all tokens - FIRInstanceIDCheckinPreferences *checkinPreferences = self.authService.checkinPreferences; - if (!checkinPreferences) { - // The checkin is already deleted. No need to trigger the token delete operation as client no - // longer has the checkin information for server to delete. - dispatch_async(dispatch_get_main_queue(), ^{ - handler(nil); - }); - return; - } - FIRInstanceIDTokenDeleteOperation *operation = - [self createDeleteOperationWithAuthorizedEntity:kFIRInstanceIDKeychainWildcardIdentifier - scope:kFIRInstanceIDKeychainWildcardIdentifier - checkinPreferences:checkinPreferences - keyPair:keyPair - action:FIRInstanceIDTokenActionDeleteTokenAndIID]; - if (handler) { - [operation addCompletionHandler:^(FIRInstanceIDTokenOperationResult result, - NSString *_Nullable token, NSError *_Nullable error) { - dispatch_async(dispatch_get_main_queue(), ^{ - handler(error); - }); - }]; - } - [self.tokenOperations addOperation:operation]; -} - -- (void)deleteAllTokensLocallyWithHandler:(void (^)(NSError *error))handler { - [self.instanceIDStore removeAllCachedTokensWithHandler:handler]; -} - -- (void)stopAllTokenOperations { - [self.authService stopCheckinRequest]; - [self.tokenOperations cancelAllOperations]; -} - -#pragma mark - FIRInstanceIDStoreDelegate - -- (void)store:(FIRInstanceIDStore *)store - didDeleteFCMScopedTokensForCheckin:(FIRInstanceIDCheckinPreferences *)checkin { - // Make a best effort try to delete the old client related state on the FCM server. This is - // required to delete old pubusb registrations which weren't cleared when the app was deleted. - // - // This is only a one time effort. If this call fails the client would still receive duplicate - // pubsub notifications if he is again subscribed to the same topic. - // - // The client state should be cleared on the server for the provided checkin preferences. - FIRInstanceIDTokenDeleteOperation *operation = - [self createDeleteOperationWithAuthorizedEntity:nil - scope:nil - checkinPreferences:checkin - keyPair:nil - action:FIRInstanceIDTokenActionDeleteToken]; - [operation addCompletionHandler:^(FIRInstanceIDTokenOperationResult result, - NSString *_Nullable token, NSError *_Nullable error) { - if (error) { - FIRInstanceIDMessageCode code = - kFIRInstanceIDMessageCodeTokenManagerErrorDeletingFCMTokensOnAppReset; - FIRInstanceIDLoggerDebug(code, @"Failed to delete GCM server registrations on app reset."); - } else { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenManagerDeletedFCMTokensOnAppReset, - @"Successfully deleted GCM server registrations on app reset"); - } - }]; - - [self.tokenOperations addOperation:operation]; -} - -#pragma mark - Unit Testing Stub Helpers -// We really have this method so that we can more easily stub it out for unit testing -- (FIRInstanceIDTokenFetchOperation *) - createFetchOperationWithAuthorizedEntity:(NSString *)authorizedEntity - scope:(NSString *)scope - options:(NSDictionary<NSString *, NSString *> *)options - keyPair:(FIRInstanceIDKeyPair *)keyPair { - FIRInstanceIDCheckinPreferences *checkinPreferences = self.authService.checkinPreferences; - FIRInstanceIDTokenFetchOperation *operation = - [[FIRInstanceIDTokenFetchOperation alloc] initWithAuthorizedEntity:authorizedEntity - scope:scope - options:options - checkinPreferences:checkinPreferences - keyPair:keyPair]; - return operation; -} - -// We really have this method so that we can more easily stub it out for unit testing -- (FIRInstanceIDTokenDeleteOperation *) - createDeleteOperationWithAuthorizedEntity:(NSString *)authorizedEntity - scope:(NSString *)scope - checkinPreferences:(FIRInstanceIDCheckinPreferences *)checkinPreferences - keyPair:(FIRInstanceIDKeyPair *)keyPair - action:(FIRInstanceIDTokenAction)action { - FIRInstanceIDTokenDeleteOperation *operation = - [[FIRInstanceIDTokenDeleteOperation alloc] initWithAuthorizedEntity:authorizedEntity - scope:scope - checkinPreferences:checkinPreferences - keyPair:keyPair - action:action]; - return operation; -} - -#pragma mark - Invalidating Cached Tokens -- (BOOL)checkForTokenRefreshPolicy { - // We know at least one cached token exists. - BOOL shouldFetchDefaultToken = NO; - NSArray<FIRInstanceIDTokenInfo *> *tokenInfos = [self.instanceIDStore cachedTokenInfos]; - - NSMutableArray<FIRInstanceIDTokenInfo *> *tokenInfosToDelete = - [NSMutableArray arrayWithCapacity:tokenInfos.count]; - for (FIRInstanceIDTokenInfo *tokenInfo in tokenInfos) { - BOOL isTokenFresh = [tokenInfo isFresh]; - if (isTokenFresh) { - // Token is fresh, do nothing. - continue; - } - if ([tokenInfo.scope isEqualToString:kFIRInstanceIDDefaultTokenScope]) { - // Default token is expired, do not mark for deletion. Fetch directly from server to - // replace the current one. - shouldFetchDefaultToken = YES; - } else { - // Non-default token is expired, mark for deletion. - [tokenInfosToDelete addObject:tokenInfo]; - } - FIRInstanceIDLoggerDebug( - kFIRInstanceIDMessageCodeTokenManagerInvalidateStaleToken, - @"Invalidating cached token for %@ (%@) due to token is no longer fresh.", - tokenInfo.authorizedEntity, tokenInfo.scope); - } - for (FIRInstanceIDTokenInfo *tokenInfoToDelete in tokenInfosToDelete) { - [self.instanceIDStore removeCachedTokenWithAuthorizedEntity:tokenInfoToDelete.authorizedEntity - scope:tokenInfoToDelete.scope]; - } - return shouldFetchDefaultToken; -} - -- (NSArray<FIRInstanceIDTokenInfo *> *)updateTokensToAPNSDeviceToken:(NSData *)deviceToken - isSandbox:(BOOL)isSandbox { - // Each cached IID token that is missing an APNSInfo, or has an APNSInfo associated should be - // checked and invalidated if needed. - FIRInstanceIDAPNSInfo *APNSInfo = [[FIRInstanceIDAPNSInfo alloc] initWithDeviceToken:deviceToken - isSandbox:isSandbox]; - if ([self.currentAPNSInfo isEqualToAPNSInfo:APNSInfo]) { - return @[]; - } - self.currentAPNSInfo = APNSInfo; - - NSArray<FIRInstanceIDTokenInfo *> *tokenInfos = [self.instanceIDStore cachedTokenInfos]; - NSMutableArray<FIRInstanceIDTokenInfo *> *tokenInfosToDelete = - [NSMutableArray arrayWithCapacity:tokenInfos.count]; - for (FIRInstanceIDTokenInfo *cachedTokenInfo in tokenInfos) { - // Check if the cached APNSInfo is nil, or if it is an old APNSInfo. - if (!cachedTokenInfo.APNSInfo || - ![cachedTokenInfo.APNSInfo isEqualToAPNSInfo:self.currentAPNSInfo]) { - // Mark for invalidation. - [tokenInfosToDelete addObject:cachedTokenInfo]; - } - } - for (FIRInstanceIDTokenInfo *tokenInfoToDelete in tokenInfosToDelete) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenManagerAPNSChangedTokenInvalidated, - @"Invalidating cached token for %@ (%@) due to APNs token change.", - tokenInfoToDelete.authorizedEntity, tokenInfoToDelete.scope); - [self.instanceIDStore removeCachedTokenWithAuthorizedEntity:tokenInfoToDelete.authorizedEntity - scope:tokenInfoToDelete.scope]; - } - return tokenInfosToDelete; -} - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation+Private.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation+Private.h @@ -1,67 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDTokenOperation.h" - -#import "FIRInstanceIDUtilities.h" - -@class FIRInstanceIDKeyPair; -@class FIRInstanceIDURLQueryItem; - -NS_ASSUME_NONNULL_BEGIN - -@interface FIRInstanceIDTokenOperation (Private) - -@property(atomic, strong) NSURLSessionDataTask *dataTask; -@property(readonly, strong) - NSMutableArray<FIRInstanceIDTokenOperationCompletion> *completionHandlers; - -// For testing only -@property(nonatomic, readwrite, copy) FIRInstanceIDURLRequestTestBlock testBlock; - -+ (NSURLSession *)sharedURLSession; - -#pragma mark - Initialization -- (instancetype)initWithAction:(FIRInstanceIDTokenAction)action - forAuthorizedEntity:(nullable NSString *)authorizedEntity - scope:(NSString *)scope - options:(nullable NSDictionary<NSString *, NSString *> *)options - checkinPreferences:(FIRInstanceIDCheckinPreferences *)checkinPreferences - keyPair:(FIRInstanceIDKeyPair *)keyPair; - -#pragma mark - Request Construction -+ (NSMutableURLRequest *)requestWithAuthHeader:(NSString *)authHeaderString; -+ (NSMutableArray<FIRInstanceIDURLQueryItem *> *)standardQueryItemsWithDeviceID:(NSString *)deviceID - scope:(NSString *)scope; -- (NSArray<FIRInstanceIDURLQueryItem *> *)queryItemsWithKeyPair:(FIRInstanceIDKeyPair *)keyPair; - -#pragma mark - HTTP Headers -/** - * Given a valid checkin preferences object, it will return a string that can be used - * in the "Authorization" HTTP header to authenticate this request. - * - * @param checkin The valid checkin preferences object, with a deviceID and secretToken. - */ -+ (NSString *)HTTPAuthHeaderFromCheckin:(FIRInstanceIDCheckinPreferences *)checkin; - -#pragma mark - Result -- (void)finishWithResult:(FIRInstanceIDTokenOperationResult)result - token:(nullable NSString *)token - error:(nullable NSError *)error; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation.h @@ -1,73 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -@class FIRInstanceIDKeyPair; -@class FIRInstanceIDCheckinPreferences; - -NS_ASSUME_NONNULL_BEGIN - -/** - * Represents the action taken on an FCM token. - */ -typedef NS_ENUM(NSInteger, FIRInstanceIDTokenAction) { - FIRInstanceIDTokenActionFetch, - FIRInstanceIDTokenActionDeleteToken, - FIRInstanceIDTokenActionDeleteTokenAndIID, -}; - -/** - * Represents the possible results of a token operation. - */ -typedef NS_ENUM(NSInteger, FIRInstanceIDTokenOperationResult) { - FIRInstanceIDTokenOperationSucceeded, - FIRInstanceIDTokenOperationError, - FIRInstanceIDTokenOperationCancelled, -}; - -/** - * Callback to invoke once the HTTP call to FIRMessaging backend for updating - * subscription finishes. - * - * @param result The result of the operation. - * @param token If the action for fetching a token and the request was successful, this will hold - * the value of the token. Otherwise nil. - * @param error The error which occurred while performing the token operation. This will be nil - * in case the operation was successful, or if the operation was cancelled. - */ -typedef void (^FIRInstanceIDTokenOperationCompletion)(FIRInstanceIDTokenOperationResult result, - NSString *_Nullable token, - NSError *_Nullable error); - -@interface FIRInstanceIDTokenOperation : NSOperation - -@property(nonatomic, readonly) FIRInstanceIDTokenAction action; -@property(nonatomic, readonly, nullable) NSString *authorizedEntity; -@property(nonatomic, readonly) NSString *scope; -@property(nonatomic, readonly, nullable) NSDictionary<NSString *, NSString *> *options; -@property(nonatomic, readonly, strong) FIRInstanceIDCheckinPreferences *checkinPreferences; -@property(nonatomic, readonly, strong) FIRInstanceIDKeyPair *keyPair; - -@property(nonatomic, readonly) FIRInstanceIDTokenOperationResult result; - -- (instancetype)init NS_UNAVAILABLE; - -- (void)addCompletionHandler:(FIRInstanceIDTokenOperationCompletion)handler; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation.m @@ -1,243 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDTokenOperation.h" - -#import "FIRInstanceIDCheckinPreferences.h" -#import "FIRInstanceIDDefines.h" -#import "FIRInstanceIDKeyPair.h" -#import "FIRInstanceIDKeyPairUtilities.h" -#import "FIRInstanceIDLogger.h" -#import "FIRInstanceIDURLQueryItem.h" -#import "FIRInstanceIDUtilities.h" -#import "NSError+FIRInstanceID.h" - -static const NSInteger kFIRInstanceIDPlatformVersionIOS = 2; - -static NSString *const kFIRInstanceIDParamInstanceID = @"appid"; -// Scope parameter that defines the service using the token -static NSString *const kFIRInstanceIDParamScope = @"X-scope"; -// Defines the SDK version -static NSString *const kFIRInstanceIDParamFCMLibVersion = @"X-cliv"; - -@interface FIRInstanceIDTokenOperation () { - BOOL _isFinished; - BOOL _isExecuting; -} - -@property(nonatomic, readwrite, strong) FIRInstanceIDCheckinPreferences *checkinPreferences; -@property(nonatomic, readwrite, strong) FIRInstanceIDKeyPair *keyPair; - -@property(atomic, strong) NSURLSessionDataTask *dataTask; -@property(readonly, strong) - NSMutableArray<FIRInstanceIDTokenOperationCompletion> *completionHandlers; - -// For testing only -@property(nonatomic, readwrite, copy) FIRInstanceIDURLRequestTestBlock testBlock; - -@end - -@implementation FIRInstanceIDTokenOperation - -+ (NSURLSession *)sharedURLSession { - static NSURLSession *tokenOperationSharedSession; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; - config.timeoutIntervalForResource = 60.0f; // 1 minute - tokenOperationSharedSession = [NSURLSession sessionWithConfiguration:config]; - tokenOperationSharedSession.sessionDescription = @"com.google.iid.tokens.session"; - }); - return tokenOperationSharedSession; -} - -- (instancetype)initWithAction:(FIRInstanceIDTokenAction)action - forAuthorizedEntity:(NSString *)authorizedEntity - scope:(NSString *)scope - options:(NSDictionary<NSString *, NSString *> *)options - checkinPreferences:(FIRInstanceIDCheckinPreferences *)checkinPreferences - keyPair:(FIRInstanceIDKeyPair *)keyPair { - self = [super init]; - if (self) { - _action = action; - _authorizedEntity = [authorizedEntity copy]; - _scope = [scope copy]; - _options = [options copy]; - _checkinPreferences = checkinPreferences; - _keyPair = keyPair; - _completionHandlers = [NSMutableArray array]; - - _isExecuting = NO; - _isFinished = NO; - } - return self; -} - -- (void)dealloc { - _testBlock = nil; - _authorizedEntity = nil; - _scope = nil; - _options = nil; - _checkinPreferences = nil; - _keyPair = nil; - [_completionHandlers removeAllObjects]; - _completionHandlers = nil; -} - -- (void)addCompletionHandler:(FIRInstanceIDTokenOperationCompletion)handler { - [self.completionHandlers addObject:handler]; -} - -- (BOOL)isAsynchronous { - return YES; -} - -- (BOOL)isExecuting { - return _isExecuting; -} - -- (void)setExecuting:(BOOL)executing { - [self willChangeValueForKey:@"isExecuting"]; - _isExecuting = executing; - [self didChangeValueForKey:@"isExecuting"]; -} - -- (BOOL)isFinished { - return _isFinished; -} - -- (void)setFinished:(BOOL)finished { - [self willChangeValueForKey:@"isFinished"]; - _isFinished = finished; - [self didChangeValueForKey:@"isFinished"]; -} - -- (void)start { - if (self.isCancelled) { - [self finishWithResult:FIRInstanceIDTokenOperationCancelled token:nil error:nil]; - return; - } - - // Quickly validate whether or not the operation has all it needs to begin - BOOL checkinfoAvailable = [self.checkinPreferences hasCheckinInfo]; - _FIRInstanceIDDevAssert(checkinfoAvailable, @"Cannot fetch token invalid checkin state"); - if (!checkinfoAvailable) { - FIRInstanceIDErrorCode errorCode = kFIRInstanceIDErrorCodeRegistrarFailedToCheckIn; - [self finishWithResult:FIRInstanceIDTokenOperationError - token:nil - error:[NSError errorWithFIRInstanceIDErrorCode:errorCode]]; - return; - } - - [self setExecuting:YES]; - - [self performTokenOperation]; -} - -- (void)finishWithResult:(FIRInstanceIDTokenOperationResult)result - token:(nullable NSString *)token - error:(nullable NSError *)error { - // Add a check to prevent this finish from being called more than once. - if (self.isFinished) { - return; - } - self.dataTask = nil; - _result = result; - // TODO(chliangGoogle): Call these in the main thread? - for (FIRInstanceIDTokenOperationCompletion completionHandler in self.completionHandlers) { - completionHandler(result, token, error); - } - - [self setExecuting:NO]; - [self setFinished:YES]; -} - -- (void)cancel { - [super cancel]; - [self.dataTask cancel]; - [self finishWithResult:FIRInstanceIDTokenOperationCancelled token:nil error:nil]; -} - -- (void)performTokenOperation { -} - -#pragma mark - Request Construction -+ (NSMutableURLRequest *)requestWithAuthHeader:(NSString *)authHeaderString { - NSURL *url = [NSURL URLWithString:FIRInstanceIDRegisterServer()]; - NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; - - // Add HTTP headers - [request setValue:authHeaderString forHTTPHeaderField:@"Authorization"]; - [request setValue:FIRInstanceIDAppIdentifier() forHTTPHeaderField:@"app"]; - request.HTTPMethod = @"POST"; - return request; -} - -+ (NSMutableArray<FIRInstanceIDURLQueryItem *> *)standardQueryItemsWithDeviceID:(NSString *)deviceID - scope:(NSString *)scope { - NSMutableArray<FIRInstanceIDURLQueryItem *> *queryItems = [NSMutableArray arrayWithCapacity:8]; - - // E.g. X-osv=10.2.1 - NSString *systemVersion = FIRInstanceIDOperatingSystemVersion(); - [queryItems addObject:[FIRInstanceIDURLQueryItem queryItemWithName:@"X-osv" value:systemVersion]]; - // E.g. device= - if (deviceID) { - [queryItems addObject:[FIRInstanceIDURLQueryItem queryItemWithName:@"device" value:deviceID]]; - } - // E.g. X-scope=fcm - if (scope) { - [queryItems addObject:[FIRInstanceIDURLQueryItem queryItemWithName:kFIRInstanceIDParamScope - value:scope]]; - } - // E.g. plat=2 - NSString *platform = [NSString stringWithFormat:@"%ld", (long)kFIRInstanceIDPlatformVersionIOS]; - [queryItems addObject:[FIRInstanceIDURLQueryItem queryItemWithName:@"plat" value:platform]]; - // E.g. app=com.myapp.foo - NSString *appIdentifier = FIRInstanceIDAppIdentifier(); - [queryItems addObject:[FIRInstanceIDURLQueryItem queryItemWithName:@"app" value:appIdentifier]]; - // E.g. app_ver=1.5 - NSString *appVersion = FIRInstanceIDCurrentAppVersion(); - [queryItems addObject:[FIRInstanceIDURLQueryItem queryItemWithName:@"app_ver" value:appVersion]]; - // E.g. X-cliv=fiid-1.2.3 - NSString *fcmLibraryVersion = - [NSString stringWithFormat:@"fiid-%@", FIRInstanceIDCurrentGCMVersion()]; - if (fcmLibraryVersion.length) { - FIRInstanceIDURLQueryItem *gcmLibVersion = - [FIRInstanceIDURLQueryItem queryItemWithName:kFIRInstanceIDParamFCMLibVersion - value:fcmLibraryVersion]; - [queryItems addObject:gcmLibVersion]; - } - - return queryItems; -} - -- (NSArray<FIRInstanceIDURLQueryItem *> *)queryItemsWithKeyPair:(FIRInstanceIDKeyPair *)keyPair { - NSMutableArray<FIRInstanceIDURLQueryItem *> *items = [NSMutableArray arrayWithCapacity:3]; - // appid= - NSString *instanceID = FIRInstanceIDAppIdentity(keyPair); - [items addObject:[FIRInstanceIDURLQueryItem queryItemWithName:kFIRInstanceIDParamInstanceID - value:instanceID]]; - return items; -} - -#pragma mark - HTTP Header - -+ (NSString *)HTTPAuthHeaderFromCheckin:(FIRInstanceIDCheckinPreferences *)checkin { - NSString *deviceID = checkin.deviceID; - NSString *secret = checkin.secretToken; - return [NSString stringWithFormat:@"AidLogin %@:%@", deviceID, secret]; -} -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenStore.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenStore.h @@ -1,106 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -@class FIRInstanceIDAPNSInfo; -@class FIRInstanceIDAuthKeychain; -@class FIRInstanceIDTokenInfo; - -/** - * This class is responsible for retrieving and saving `FIRInstanceIDTokenInfo` objects from the - * keychain. The keychain keys that are used are: - * Account: <Main App Bundle ID> (e.g. com.mycompany.myapp) - * Service: <Sender ID>:<Scope> (e.g. 1234567890:*) - */ -@interface FIRInstanceIDTokenStore : NSObject - -NS_ASSUME_NONNULL_BEGIN - -/** - * Create a default InstanceID token store. Uses a valid Keychain object as it's - * persistent backing store. - * - * @return A valid token store object. - */ -+ (instancetype)defaultStore; - -- (instancetype)init __attribute__((unavailable("Use -initWithKeychain: instead."))); - -/** - * Initialize a token store object with a Keychain object. Used for testing. - * - * @param keychain The Keychain object to use as the backing store for tokens. - * - * @return A valid token store object with the given Keychain as backing store. - */ -- (instancetype)initWithKeychain:(FIRInstanceIDAuthKeychain *)keychain; - -#pragma mark - Get - -/** - * Get the cached token from the Keychain. - * - * @param authorizedEntity The authorized entity for the token. - * @param scope The scope for the token. - * - * @return The cached token info if any for the given authorizedEntity and scope else - * nil. - */ -- (nullable FIRInstanceIDTokenInfo *)tokenInfoWithAuthorizedEntity:(NSString *)authorizedEntity - scope:(NSString *)scope; - -/** - * Return all cached token infos from the Keychain. - * - * @return The cached token infos, if any, that are stored in the Keychain. - */ -- (NSArray<FIRInstanceIDTokenInfo *> *)cachedTokenInfos; - -#pragma mark - Save - -/** - * Save the instanceID token info to the persistent store. - * - * @param tokenInfo The token info to store. - * @param handler The callback handler which is invoked when token saving is complete, - * with an error if there is any. - */ -- (void)saveTokenInfo:(FIRInstanceIDTokenInfo *)tokenInfo - handler:(nullable void (^)(NSError *))handler; - -#pragma mark - Delete - -/** - * Remove the cached token from Keychain. - * - * @param authorizedEntity The authorized entity for the token. - * @param scope The scope for the token. - * - */ -- (void)removeTokenWithAuthorizedEntity:(NSString *)authorizedEntity scope:(NSString *)scope; - -/** - * Remove all the cached tokens from the Keychain. - * @param handler The callback handler which is invoked when tokens deletion is complete, - * with an error if there is any. - * - */ -- (void)removeAllTokensWithHandler:(nullable void (^)(NSError *))handler; - -NS_ASSUME_NONNULL_END - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenStore.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenStore.m @@ -1,137 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDTokenStore.h" - -#import "FIRInstanceIDAuthKeyChain.h" -#import "FIRInstanceIDConstants.h" -#import "FIRInstanceIDLogger.h" -#import "FIRInstanceIDTokenInfo.h" -#import "FIRInstanceIDUtilities.h" - -static NSString *const kFIRInstanceIDTokenKeychainId = @"com.google.iid-tokens"; - -@interface FIRInstanceIDTokenStore () - -@property(nonatomic, readwrite, strong) FIRInstanceIDAuthKeychain *keychain; - -@end - -@implementation FIRInstanceIDTokenStore - -+ (instancetype)defaultStore { - FIRInstanceIDAuthKeychain *tokenKeychain = - [[FIRInstanceIDAuthKeychain alloc] initWithIdentifier:kFIRInstanceIDTokenKeychainId]; - return [[FIRInstanceIDTokenStore alloc] initWithKeychain:tokenKeychain]; -} - -- (instancetype)initWithKeychain:(FIRInstanceIDAuthKeychain *)keychain { - self = [super init]; - if (self) { - _keychain = keychain; - } - return self; -} - -#pragma mark - Get - -+ (NSString *)serviceKeyForAuthorizedEntity:(NSString *)authorizedEntity scope:(NSString *)scope { - return [NSString stringWithFormat:@"%@:%@", authorizedEntity, scope]; -} - -- (nullable FIRInstanceIDTokenInfo *)tokenInfoWithAuthorizedEntity:(NSString *)authorizedEntity - scope:(NSString *)scope { - NSString *account = FIRInstanceIDAppIdentifier(); - NSString *service = [[self class] serviceKeyForAuthorizedEntity:authorizedEntity scope:scope]; - NSData *item = [self.keychain dataForService:service account:account]; - if (!item) { - return nil; - } - // Token infos created from legacy storage don't have appVersion, firebaseAppID, or APNSInfo. - FIRInstanceIDTokenInfo *tokenInfo = [[self class] tokenInfoFromKeychainItem:item]; - return tokenInfo; -} - -- (NSArray<FIRInstanceIDTokenInfo *> *)cachedTokenInfos { - NSString *account = FIRInstanceIDAppIdentifier(); - NSArray<NSData *> *items = - [self.keychain itemsMatchingService:kFIRInstanceIDKeychainWildcardIdentifier account:account]; - NSMutableArray<FIRInstanceIDTokenInfo *> *tokenInfos = - [NSMutableArray arrayWithCapacity:items.count]; - for (NSData *item in items) { - FIRInstanceIDTokenInfo *tokenInfo = [[self class] tokenInfoFromKeychainItem:item]; - if (tokenInfo) { - [tokenInfos addObject:tokenInfo]; - } - } - return tokenInfos; -} - -+ (nullable FIRInstanceIDTokenInfo *)tokenInfoFromKeychainItem:(NSData *)item { - // Check if it is saved as an archived FIRInstanceIDTokenInfo, otherwise return nil. - FIRInstanceIDTokenInfo *tokenInfo = nil; - // NOTE: Passing in nil to unarchiveObjectWithData will result in an iOS error logged - // in the console on iOS 10 and below. Avoid by checking item.data's existence. - if (item) { - @try { - tokenInfo = [NSKeyedUnarchiver unarchiveObjectWithData:item]; - } @catch (NSException *exception) { - FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenStoreExceptionUnarchivingTokenInfo, - @"Unable to parse token info from Keychain item; item was in an " - @"invalid format"); - tokenInfo = nil; - } @finally { - } - } - return tokenInfo; -} - -#pragma mark - Save -// Token Infos will be saved under these Keychain keys: -// Account: <Main App Bundle ID> (e.g. com.mycompany.myapp) -// Service: <Sender ID>:<Scope> (e.g. 1234567890:*) -- (void)saveTokenInfo:(FIRInstanceIDTokenInfo *)tokenInfo - handler:(void (^)(NSError *))handler { // Keep the cachetime up-to-date. - tokenInfo.cacheTime = [NSDate date]; - // Always write to the Keychain, so that the cacheTime is up-to-date. - NSData *tokenInfoData = [NSKeyedArchiver archivedDataWithRootObject:tokenInfo]; - NSString *account = FIRInstanceIDAppIdentifier(); - NSString *service = [[self class] serviceKeyForAuthorizedEntity:tokenInfo.authorizedEntity - scope:tokenInfo.scope]; - [self.keychain setData:tokenInfoData - forService:service - accessibility:NULL - account:account - handler:handler]; -} - -#pragma mark - Delete - -- (void)removeTokenWithAuthorizedEntity:(nonnull NSString *)authorizedEntity - scope:(nonnull NSString *)scope { - NSString *account = FIRInstanceIDAppIdentifier(); - NSString *service = [[self class] serviceKeyForAuthorizedEntity:authorizedEntity scope:scope]; - [self.keychain removeItemsMatchingService:service account:account handler:nil]; -} - -- (void)removeAllTokensWithHandler:(void (^)(NSError *error))handler { - NSString *account = FIRInstanceIDAppIdentifier(); - [self.keychain removeItemsMatchingService:kFIRInstanceIDKeychainWildcardIdentifier - account:account - handler:handler]; -} - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDURLQueryItem.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDURLQueryItem.h @@ -1,39 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -NS_ASSUME_NONNULL_BEGIN - -// Stand-in for NSURLQueryItem, which is only available on iOS 8.0 and up. -@interface FIRInstanceIDURLQueryItem : NSObject - -@property(nonatomic, readonly) NSString *name; -@property(nonatomic, readonly) NSString *value; - -+ (instancetype)queryItemWithName:(NSString *)name value:(NSString *)value; -- (instancetype)initWithName:(NSString *)name value:(NSString *)value; - -@end - -/** - * Given an array of query items, construct a URL query. On iOS 8.0 and above, this will use - * NSURLQueryItems internally to perform the string creation, and will be done manually in iOS - * 7 and below. - */ -NSString *FIRInstanceIDQueryFromQueryItems(NSArray<FIRInstanceIDURLQueryItem *> *queryItems); - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDURLQueryItem.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDURLQueryItem.m @@ -1,55 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDURLQueryItem.h" - -@implementation FIRInstanceIDURLQueryItem - -+ (instancetype)queryItemWithName:(NSString *)name value:(NSString *)value { - return [[[self class] alloc] initWithName:name value:value]; -} - -- (instancetype)initWithName:(NSString *)name value:(NSString *)value { - self = [super init]; - if (self) { - _name = [name copy]; - _value = [value copy]; - } - return self; -} -@end - -NSString *FIRInstanceIDQueryFromQueryItems(NSArray<FIRInstanceIDURLQueryItem *> *queryItems) { - if ([NSURLQueryItem class]) { - // We are iOS 8.0 and above. Convert to NSURLQueryItems and get query that way - // to take advantage of any automatic encoding - NSMutableArray<NSURLQueryItem *> *urlItems = - [NSMutableArray arrayWithCapacity:queryItems.count]; - for (FIRInstanceIDURLQueryItem *queryItem in queryItems) { - [urlItems addObject:[NSURLQueryItem queryItemWithName:queryItem.name value:queryItem.value]]; - } - NSURLComponents *components = [[NSURLComponents alloc] init]; - components.queryItems = urlItems; - return components.query; - } else { - // We are on iOS 7.0. Manually create the query string - NSMutableArray<NSString *> *pairs = [NSMutableArray arrayWithCapacity:queryItems.count]; - for (FIRInstanceIDURLQueryItem *queryItem in queryItems) { - [pairs addObject:[NSString stringWithFormat:@"%@=%@", queryItem.name, queryItem.value]]; - } - return [pairs componentsJoinedByString:@"&"]; - } -} diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDUtilities.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDUtilities.h @@ -1,85 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -/// FIRMessaging Class that responds to the FIRMessaging SDK version selector. -/// Verify at runtime if the class exists and implements the required method. -FOUNDATION_EXPORT NSString *const kFIRInstanceIDFCMSDKClassString; - -/// locale key stored in GULUserDefaults -FOUNDATION_EXPORT NSString *const kFIRInstanceIDUserDefaultsKeyLocale; - -#pragma mark - Test Blocks - -/** - * Response block for mock registration requests made during tests. - * - * @param data The data as returned by the mock request. - * @param response The response as returned by the mock request. - * @param error The error if any as returned by the mock request. - */ -typedef void (^FIRInstanceIDURLRequestTestResponseBlock)(NSData *data, - NSURLResponse *response, - NSError *error); - -/** - * Test block to mock registration requests response. - * - * @param request The request to mock response for. - * @param response The response block for the mocked request. - */ -typedef void (^FIRInstanceIDURLRequestTestBlock)(NSURLRequest *request, - FIRInstanceIDURLRequestTestResponseBlock response); - -#pragma mark - URL Helpers - -FOUNDATION_EXPORT NSString *FIRInstanceIDRegisterServer(void); - -#pragma mark - Time - -FOUNDATION_EXPORT int64_t FIRInstanceIDCurrentTimestampInSeconds(void); -FOUNDATION_EXPORT int64_t FIRInstanceIDCurrentTimestampInMilliseconds(void); - -#pragma mark - App Info - -FOUNDATION_EXPORT NSString *FIRInstanceIDCurrentAppVersion(void); -FOUNDATION_EXPORT NSString *FIRInstanceIDAppIdentifier(void); -FOUNDATION_EXPORT NSString *FIRInstanceIDFirebaseAppID(void); - -#pragma mark - Device Info - -FOUNDATION_EXPORT NSString *FIRInstanceIDDeviceModel(void); -FOUNDATION_EXPORT NSString *FIRInstanceIDOperatingSystemVersion(void); -FOUNDATION_EXPORT BOOL FIRInstanceIDHasLocaleChanged(void); - -#pragma mark - Helpers - -FOUNDATION_EXPORT BOOL FIRInstanceIDIsValidGCMScope(NSString *scope); -FOUNDATION_EXPORT NSString *FIRInstanceIDStringForAPNSDeviceToken(NSData *deviceToken); -FOUNDATION_EXPORT NSString *FIRInstanceIDAPNSTupleStringForTokenAndServerType(NSData *deviceToken, - BOOL isSandbox); - -#pragma mark - GCM Helpers -/// Returns the current GCM version if GCM library is found else returns nil. -FOUNDATION_EXPORT NSString *FIRInstanceIDCurrentGCMVersion(void); - -/// Returns the current locale. If GCM is present it queries GCM for a -/// Context Manager specific locale. Otherwise, it returns the system's first -/// preferred language (which may be set independently from locale). If the -/// system returns no preferred languages, this method returns the most common -/// language for the user's given locale. Guaranteed to return a nonnull value. -FOUNDATION_EXPORT NSString *FIRInstanceIDCurrentLocale(void); diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDUtilities.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDUtilities.m @@ -1,194 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDUtilities.h" - -#import <UIKit/UIKit.h> -#import <sys/utsname.h> - -#import <FirebaseCore/FIROptions.h> -#import <GoogleUtilities/GULUserDefaults.h> -#import "FIRInstanceID.h" -#import "FIRInstanceIDConstants.h" -#import "FIRInstanceIDDefines.h" -#import "FIRInstanceIDLogger.h" - -// Convert the macro to a string -#define STR_EXPAND(x) #x -#define STR(x) STR_EXPAND(x) - -static NSString *const kFIRInstanceIDAPNSSandboxPrefix = @"s_"; -static NSString *const kFIRInstanceIDAPNSProdPrefix = @"p_"; - -/// FIRMessaging Class that responds to the FIRMessaging SDK version selector. -/// Verify at runtime if the class exists and implements the required method. -NSString *const kFIRInstanceIDFCMSDKClassString = @"FIRMessaging"; - -/// FIRMessaging selector that returns the current FIRMessaging library version. -static NSString *const kFIRInstanceIDFCMSDKVersionSelectorString = @"FIRMessagingSDKVersion"; - -/// FIRMessaging selector that returns the current device locale. -static NSString *const kFIRInstanceIDFCMSDKLocaleSelectorString = @"FIRMessagingSDKCurrentLocale"; - -NSString *const kFIRInstanceIDUserDefaultsKeyLocale = - @"com.firebase.instanceid.user_defaults.locale"; // locale key stored in GULUserDefaults - -/// Static values which will be populated once retrieved using -/// |FIRInstanceIDRetrieveEnvironmentInfoFromFirebaseCore|. -static NSString *operatingSystemVersion; -static NSString *hardwareDeviceModel; - -#pragma mark - URL Helpers - -NSString *FIRInstanceIDRegisterServer() { - return @"https://fcmtoken.googleapis.com/register"; -} - -#pragma mark - Time - -int64_t FIRInstanceIDCurrentTimestampInSeconds() { - return (int64_t)[[NSDate date] timeIntervalSince1970]; -} - -int64_t FIRInstanceIDCurrentTimestampInMilliseconds() { - return (int64_t)(FIRInstanceIDCurrentTimestampInSeconds() * 1000.0); -} - -#pragma mark - App Info - -NSString *FIRInstanceIDCurrentAppVersion() { - NSString *version = [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"]; - if (![version length]) { - return @""; - } - return version; -} - -NSString *FIRInstanceIDAppIdentifier() { - NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier]; - if (!bundleIdentifier.length) { - FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeUtilitiesMissingBundleIdentifier, - @"The mainBundle's bundleIdentifier returned '%@'. Bundle identifier " - @"expected to be non-empty.", - bundleIdentifier); - return @""; - } - return bundleIdentifier; -} - -NSString *FIRInstanceIDFirebaseAppID() { - return [FIROptions defaultOptions].googleAppID; -} - -#pragma mark - Device Info -// Get the device model from Firebase Core's App Environment Util -NSString *FIRInstanceIDDeviceModel() { - static dispatch_once_t once; - dispatch_once(&once, ^{ - struct utsname systemInfo; - if (uname(&systemInfo) == 0) { - hardwareDeviceModel = [NSString stringWithUTF8String:systemInfo.machine]; - } - }); - return hardwareDeviceModel; -} - -// Get the system version from Firebase Core's App Environment Util -NSString *FIRInstanceIDOperatingSystemVersion() { -#if TARGET_OS_IOS - return [UIDevice currentDevice].systemVersion; -#elif TARGET_OS_OSX - return [NSProcessInfo processInfo].operatingSystemVersionString; -#endif -} - -BOOL FIRInstanceIDHasLocaleChanged() { - NSString *lastLocale = - [[GULUserDefaults standardUserDefaults] stringForKey:kFIRInstanceIDUserDefaultsKeyLocale]; - NSString *currentLocale = FIRInstanceIDCurrentLocale(); - if (lastLocale) { - if ([currentLocale isEqualToString:lastLocale]) { - return NO; - } - } - return YES; -} - -#pragma mark - Helpers - -BOOL FIRInstanceIDIsValidGCMScope(NSString *scope) { - return [scope compare:kFIRInstanceIDScopeFirebaseMessaging - options:NSCaseInsensitiveSearch] == NSOrderedSame; -} - -NSString *FIRInstanceIDStringForAPNSDeviceToken(NSData *deviceToken) { - NSMutableString *APNSToken = [NSMutableString string]; - unsigned char *bytes = (unsigned char *)[deviceToken bytes]; - for (int i = 0; i < (int)deviceToken.length; i++) { - [APNSToken appendFormat:@"%02x", bytes[i]]; - } - return APNSToken; -} - -NSString *FIRInstanceIDAPNSTupleStringForTokenAndServerType(NSData *deviceToken, BOOL isSandbox) { - if (deviceToken == nil) { - // A nil deviceToken leads to an invalid tuple string, so return nil. - return nil; - } - NSString *prefix = isSandbox ? kFIRInstanceIDAPNSSandboxPrefix : kFIRInstanceIDAPNSProdPrefix; - NSString *APNSString = FIRInstanceIDStringForAPNSDeviceToken(deviceToken); - NSString *APNSTupleString = [NSString stringWithFormat:@"%@%@", prefix, APNSString]; - - return APNSTupleString; -} - -#pragma mark - GCM Helpers - -NSString *FIRInstanceIDCurrentGCMVersion() { - Class versionClass = NSClassFromString(kFIRInstanceIDFCMSDKClassString); - SEL versionSelector = NSSelectorFromString(kFIRInstanceIDFCMSDKVersionSelectorString); - if ([versionClass respondsToSelector:versionSelector]) { - IMP getVersionIMP = [versionClass methodForSelector:versionSelector]; - NSString *(*getVersion)(id, SEL) = (void *)getVersionIMP; - return getVersion(versionClass, versionSelector); - } - return nil; -} - -NSString *FIRInstanceIDCurrentLocale() { - Class localeClass = NSClassFromString(kFIRInstanceIDFCMSDKClassString); - SEL localeSelector = NSSelectorFromString(kFIRInstanceIDFCMSDKLocaleSelectorString); - - if ([localeClass respondsToSelector:localeSelector]) { - IMP getLocaleIMP = [localeClass methodForSelector:localeSelector]; - NSString *(*getLocale)(id, SEL) = (void *)getLocaleIMP; - NSString *fcmLocale = getLocale(localeClass, localeSelector); - if (fcmLocale != nil) { - return fcmLocale; - } - } - - NSString *systemLanguage = [[NSLocale preferredLanguages] firstObject]; - if (systemLanguage != nil) { - return systemLanguage; - } - - if (@available(iOS 10.0, *)) { - return [NSLocale currentLocale].languageCode; - } else { - return nil; - } -} diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDVersionUtilities.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDVersionUtilities.h @@ -1,35 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -/** - * Parsing utility for InstanceID Library versions. InstanceID lib follows semantic versioning. - * This provides utilities to parse the library versions to enable features and do - * updates based on appropriate library versions. - * - * Some example semantic versions are 1.0.1, 2.1.0, 2.1.1, 2.2.0-alpha1, 2.2.1-beta1 - */ - -FOUNDATION_EXPORT NSString *FIRInstanceIDCurrentLibraryVersion(void); -/// Returns the current Major version of GCM library. -FOUNDATION_EXPORT int FIRInstanceIDCurrentLibraryVersionMajor(void); -/// Returns the current Minor version of GCM library. -FOUNDATION_EXPORT int FIRInstanceIDCurrentLibraryVersionMinor(void); -/// Returns the current Patch version of GCM library. -FOUNDATION_EXPORT int FIRInstanceIDCurrentLibraryVersionPatch(void); -/// Returns YES if current library version is `beta` else NO. -FOUNDATION_EXPORT BOOL FIRInstanceIDCurrentLibraryVersionIsBeta(void); diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDVersionUtilities.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDVersionUtilities.m @@ -1,91 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceIDVersionUtilities.h" - -#import "FIRInstanceIDDefines.h" - -// Convert the macro to a string -#define STR(x) STR_EXPAND(x) -#define STR_EXPAND(x) #x - -static NSString *const kSemanticVersioningSeparator = @"."; -static NSString *const kBetaVersionPrefix = @"-beta"; - -static NSString *libraryVersion; - -static int majorVersion; -static int minorVersion; -static int patchVersion; -static int betaVersion; - -void FIRInstanceIDParseCurrentLibraryVersion() { - static NSArray *allVersions; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSMutableString *daylightVersion = - [NSMutableString stringWithUTF8String:STR(FIRInstanceID_LIB_VERSION)]; - // Parse versions - // major, minor, patch[-beta#] - allVersions = [daylightVersion componentsSeparatedByString:kSemanticVersioningSeparator]; - _FIRInstanceIDDevAssert(allVersions.count == 3, @"Invalid versioning of FIRInstanceID library"); - if (allVersions.count == 3) { - majorVersion = [allVersions[0] intValue]; - minorVersion = [allVersions[1] intValue]; - - // Parse patch and beta versions - NSArray *patchAndBetaVersion = - [allVersions[2] componentsSeparatedByString:kBetaVersionPrefix]; - _FIRInstanceIDDevAssert(patchAndBetaVersion.count <= 2, - @"Invalid versioning of FIRInstanceID library"); - - if (patchAndBetaVersion.count == 2) { - patchVersion = [patchAndBetaVersion[0] intValue]; - betaVersion = [patchAndBetaVersion[1] intValue]; - } else if (patchAndBetaVersion.count == 1) { - patchVersion = [patchAndBetaVersion[0] intValue]; - } - } - - // Copy library version - libraryVersion = [daylightVersion copy]; - }); -} - -NSString *FIRInstanceIDCurrentLibraryVersion() { - FIRInstanceIDParseCurrentLibraryVersion(); - return libraryVersion; -} - -int FIRInstanceIDCurrentLibraryVersionMajor() { - FIRInstanceIDParseCurrentLibraryVersion(); - return majorVersion; -} - -int FIRInstanceIDCurrentLibraryVersionMinor() { - FIRInstanceIDParseCurrentLibraryVersion(); - return minorVersion; -} - -int FIRInstanceIDCurrentLibraryVersionPatch() { - FIRInstanceIDParseCurrentLibraryVersion(); - return patchVersion; -} - -BOOL FIRInstanceIDCurrentLibraryVersionIsBeta() { - FIRInstanceIDParseCurrentLibraryVersion(); - return betaVersion > 0; -} diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/NSError+FIRInstanceID.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/NSError+FIRInstanceID.h @@ -1,70 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -FOUNDATION_EXPORT NSString *const kFIRInstanceIDDomain; - -typedef NS_ENUM(NSUInteger, FIRInstanceIDErrorCode) { - // Unknown error. - kFIRInstanceIDErrorCodeUnknown = 0, - - // Http related errors. - kFIRInstanceIDErrorCodeAuthentication = 1, - kFIRInstanceIDErrorCodeNoAccess = 2, - kFIRInstanceIDErrorCodeTimeout = 3, - kFIRInstanceIDErrorCodeNetwork = 4, - - // Another operation is in progress. - kFIRInstanceIDErrorCodeOperationInProgress = 5, - - // Failed to perform device check in. - kFIRInstanceIDErrorCodeRegistrarFailedToCheckIn = 6, - - kFIRInstanceIDErrorCodeInvalidRequest = 7, - - // InstanceID generic errors - kFIRInstanceIDErrorCodeMissingDeviceID = 501, - - // InstanceID Token specific errors - kFIRInstanceIDErrorCodeMissingAPNSToken = 1001, - kFIRInstanceIDErrorCodeMissingAPNSServerType = 1002, - kFIRInstanceIDErrorCodeInvalidAuthorizedEntity = 1003, - kFIRInstanceIDErrorCodeInvalidScope = 1004, - kFIRInstanceIDErrorCodeInvalidStart = 1005, - kFIRInstanceIDErrorCodeInvalidKeyPair = 1006, - - // InstanceID Identity specific errors - // Generic InstanceID keypair error - kFIRInstanceIDErrorCodeMissingKeyPair = 2001, - kFIRInstanceIDErrorCodeInvalidKeyPairTags = 2002, - kFIRInstanceIDErrorCodeInvalidKeyPairCreationTime = 2005, - kFIRInstanceIDErrorCodeInvalidIdentity = 2006, - -}; - -@interface NSError (FIRInstanceID) - -@property(nonatomic, readonly) FIRInstanceIDErrorCode instanceIDErrorCode; - -+ (NSError *)errorWithFIRInstanceIDErrorCode:(FIRInstanceIDErrorCode)errorCode; - -+ (NSError *)errorWithFIRInstanceIDErrorCode:(FIRInstanceIDErrorCode)errorCode - userInfo:(NSDictionary *)userInfo; - -+ (NSError *)FIRInstanceIDErrorMissingCheckin; - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/NSError+FIRInstanceID.m b/Pods/FirebaseInstanceID/Firebase/InstanceID/NSError+FIRInstanceID.m @@ -1,44 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "NSError+FIRInstanceID.h" - -NSString *const kFIRInstanceIDDomain = @"com.firebase.iid"; - -@implementation NSError (FIRInstanceID) - -- (FIRInstanceIDErrorCode)instanceIDErrorCode { - return (FIRInstanceIDErrorCode)self.code; -} - -+ (NSError *)errorWithFIRInstanceIDErrorCode:(FIRInstanceIDErrorCode)errorCode { - return [NSError errorWithFIRInstanceIDErrorCode:errorCode userInfo:nil]; -} - -+ (NSError *)errorWithFIRInstanceIDErrorCode:(FIRInstanceIDErrorCode)errorCode - userInfo:(NSDictionary *)userInfo { - return [NSError errorWithDomain:kFIRInstanceIDDomain code:errorCode userInfo:userInfo]; -} - -+ (NSError *)FIRInstanceIDErrorMissingCheckin { - NSDictionary *userInfo = @{@"msg" : @"Missing device credentials. Retry later."}; - - return [NSError errorWithDomain:kFIRInstanceIDDomain - code:kFIRInstanceIDErrorCodeMissingDeviceID - userInfo:userInfo]; -} - -@end diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/Public/FIRInstanceID.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/Public/FIRInstanceID.h @@ -1,320 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -NS_ASSUME_NONNULL_BEGIN - -@class FIRInstanceIDResult; -/** - * @memberof FIRInstanceID - * - * The scope to be used when fetching/deleting a token for Firebase Messaging. - */ -FOUNDATION_EXPORT NSString *const kFIRInstanceIDScopeFirebaseMessaging - NS_SWIFT_NAME(InstanceIDScopeFirebaseMessaging); - -#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 -/** - * Called when the system determines that tokens need to be refreshed. - * This method is also called if Instance ID has been reset in which - * case, tokens and FCM topic subscriptions also need to be refreshed. - * - * Instance ID service will throttle the refresh event across all devices - * to control the rate of token updates on application servers. - */ -FOUNDATION_EXPORT const NSNotificationName kFIRInstanceIDTokenRefreshNotification - NS_SWIFT_NAME(InstanceIDTokenRefresh); -#else -/** - * Called when the system determines that tokens need to be refreshed. - * This method is also called if Instance ID has been reset in which - * case, tokens and FCM topic subscriptions also need to be refreshed. - * - * Instance ID service will throttle the refresh event across all devices - * to control the rate of token updates on application servers. - */ -FOUNDATION_EXPORT NSString *const kFIRInstanceIDTokenRefreshNotification - NS_SWIFT_NAME(InstanceIDTokenRefreshNotification); -#endif // defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 - -/** - * @related FIRInstanceID - * - * The completion handler invoked when the InstanceID token returns. If - * the call fails we return the appropriate `error code` as described below. - * - * @param token The valid token as returned by InstanceID backend. - * - * @param error The error describing why generating a new token - * failed. See the error codes below for a more detailed - * description. - */ -typedef void (^FIRInstanceIDTokenHandler)(NSString *__nullable token, NSError *__nullable error) - NS_SWIFT_NAME(InstanceIDTokenHandler); - -/** - * @related FIRInstanceID - * - * The completion handler invoked when the InstanceID `deleteToken` returns. If - * the call fails we return the appropriate `error code` as described below - * - * @param error The error describing why deleting the token failed. - * See the error codes below for a more detailed description. - */ -typedef void (^FIRInstanceIDDeleteTokenHandler)(NSError *error) - NS_SWIFT_NAME(InstanceIDDeleteTokenHandler); - -/** - * @related FIRInstanceID - * - * The completion handler invoked when the app identity is created. If the - * identity wasn't created for some reason we return the appropriate error code. - * - * @param identity A valid identity for the app instance, nil if there was an error - * while creating an identity. - * @param error The error if fetching the identity fails else nil. - */ -typedef void (^FIRInstanceIDHandler)(NSString *__nullable identity, NSError *__nullable error) - NS_SWIFT_NAME(InstanceIDHandler); - -/** - * @related FIRInstanceID - * - * The completion handler invoked when the app identity and all the tokens associated - * with it are deleted. Returns a valid error object in case of failure else nil. - * - * @param error The error if deleting the identity and all the tokens associated with - * it fails else nil. - */ -typedef void (^FIRInstanceIDDeleteHandler)(NSError *__nullable error) - NS_SWIFT_NAME(InstanceIDDeleteHandler); - -/** - * @related FIRInstanceID - * - * The completion handler invoked when the app identity and token are fetched. If the - * identity wasn't created for some reason we return the appropriate error code. - * - * @param result The result containing an identity for the app instance and a valid token, - * nil if there was an error while creating the result. - * @param error The error if fetching the identity or token fails else nil. - */ -typedef void (^FIRInstanceIDResultHandler)(FIRInstanceIDResult *__nullable result, - NSError *__nullable error) - NS_SWIFT_NAME(InstanceIDResultHandler); - -/** - * Public errors produced by InstanceID. - */ -typedef NS_ENUM(NSUInteger, FIRInstanceIDError) { - // Http related errors. - - /// Unknown error. - FIRInstanceIDErrorUnknown = 0, - - /// Auth Error -- GCM couldn't validate request from this client. - FIRInstanceIDErrorAuthentication = 1, - - /// NoAccess -- InstanceID service cannot be accessed. - FIRInstanceIDErrorNoAccess = 2, - - /// Timeout -- Request to InstanceID backend timed out. - FIRInstanceIDErrorTimeout = 3, - - /// Network -- No network available to reach the servers. - FIRInstanceIDErrorNetwork = 4, - - /// OperationInProgress -- Another similar operation in progress, - /// bailing this one. - FIRInstanceIDErrorOperationInProgress = 5, - - /// InvalidRequest -- Some parameters of the request were invalid. - FIRInstanceIDErrorInvalidRequest = 7, -} NS_SWIFT_NAME(InstanceIDError); - -/** - * A class contains the results of InstanceID and token query. - */ -NS_SWIFT_NAME(InstanceIDResult) -@interface FIRInstanceIDResult : NSObject <NSCopying> - -/** - * An instanceID uniquely identifies the app instance. - */ -@property(nonatomic, readonly, copy) NSString *instanceID; - -/* - * Returns a Firebase Messaging scoped token for the firebase app. - */ -@property(nonatomic, readonly, copy) NSString *token; - -@end - -/** - * Instance ID provides a unique identifier for each app instance and a mechanism - * to authenticate and authorize actions (for example, sending an FCM message). - * - * Once an InstanceID is generated, the library periodically sends information about the - * application and the device where it's running to the Firebase backend. To stop this. see - * `[FIRInstanceID deleteIDWithHandler:]`. - * - * Instance ID is long lived but, may be reset if the device is not used for - * a long time or the Instance ID service detects a problem. - * If Instance ID is reset, the app will be notified via - * `kFIRInstanceIDTokenRefreshNotification`. - * - * If the Instance ID has become invalid, the app can request a new one and - * send it to the app server. - * To prove ownership of Instance ID and to allow servers to access data or - * services associated with the app, call - * `[FIRInstanceID tokenWithAuthorizedEntity:scope:options:handler]`. - */ -NS_SWIFT_NAME(InstanceID) -@interface FIRInstanceID : NSObject - -/** - * FIRInstanceID. - * - * @return A shared instance of FIRInstanceID. - */ -+ (instancetype)instanceID NS_SWIFT_NAME(instanceID()); - -/** - * Unavailable. Use +instanceID instead. - */ -- (instancetype)init __attribute__((unavailable("Use +instanceID instead."))); - -#pragma mark - Tokens - -/** - * Returns a result of app instance identifier InstanceID and a Firebase Messaging scoped token. - * param handler The callback handler invoked when an app instanceID and a default token - * are generated and returned. If instanceID and token fetching fail for some - * reason the callback is invoked with nil `result` and the appropriate error. - */ -- (void)instanceIDWithHandler:(FIRInstanceIDResultHandler)handler; - -/** - * Returns a Firebase Messaging scoped token for the firebase app. - * - * @return Returns the stored token if the device has registered with Firebase Messaging, otherwise - * returns nil. - */ -- (nullable NSString *)token __deprecated_msg("Use instanceIDWithHandler: instead."); - -/** - * Returns a token that authorizes an Entity (example: cloud service) to perform - * an action on behalf of the application identified by Instance ID. - * - * This is similar to an OAuth2 token except, it applies to the - * application instance instead of a user. - * - * This is an asynchronous call. If the token fetching fails for some reason - * we invoke the completion callback with nil `token` and the appropriate - * error. - * - * This generates an Instance ID if it does not exist yet, which starts periodically sending - * information to the Firebase backend (see `[FIRInstanceID getIDWithHandler:]`). - * - * Note, you can only have one `token` or `deleteToken` call for a given - * authorizedEntity and scope at any point of time. Making another such call with the - * same authorizedEntity and scope before the last one finishes will result in an - * error with code `OperationInProgress`. - * - * @see FIRInstanceID deleteTokenWithAuthorizedEntity:scope:handler: - * - * @param authorizedEntity Entity authorized by the token. - * @param scope Action authorized for authorizedEntity. - * @param options The extra options to be sent with your token request. The - * value for the `apns_token` should be the NSData object - * passed to the UIApplicationDelegate's - * `didRegisterForRemoteNotificationsWithDeviceToken` method. - * The value for `apns_sandbox` should be a boolean (or an - * NSNumber representing a BOOL in Objective C) set to true if - * your app is a debug build, which means that the APNs - * device token is for the sandbox environment. It should be - * set to false otherwise. If the `apns_sandbox` key is not - * provided, an automatically-detected value shall be used. - * @param handler The callback handler which is invoked when the token is - * successfully fetched. In case of success a valid `token` and - * `nil` error are returned. In case of any error the `token` - * is nil and a valid `error` is returned. The valid error - * codes have been documented above. - */ -- (void)tokenWithAuthorizedEntity:(NSString *)authorizedEntity - scope:(NSString *)scope - options:(nullable NSDictionary *)options - handler:(FIRInstanceIDTokenHandler)handler; - -/** - * Revokes access to a scope (action) for an entity previously - * authorized by `[FIRInstanceID tokenWithAuthorizedEntity:scope:options:handler]`. - * - * This is an asynchronous call. Call this on the main thread since InstanceID lib - * is not thread safe. In case token deletion fails for some reason we invoke the - * `handler` callback passed in with the appropriate error code. - * - * Note, you can only have one `token` or `deleteToken` call for a given - * authorizedEntity and scope at a point of time. Making another such call with the - * same authorizedEntity and scope before the last one finishes will result in an error - * with code `OperationInProgress`. - * - * @param authorizedEntity Entity that must no longer have access. - * @param scope Action that entity is no longer authorized to perform. - * @param handler The handler that is invoked once the unsubscribe call ends. - * In case of error an appropriate error object is returned - * else error is nil. - */ -- (void)deleteTokenWithAuthorizedEntity:(NSString *)authorizedEntity - scope:(NSString *)scope - handler:(FIRInstanceIDDeleteTokenHandler)handler; - -#pragma mark - Identity - -/** - * Asynchronously fetch a stable identifier that uniquely identifies the app - * instance. If the identifier has been revoked or has expired, this method will - * return a new identifier. - * - * Once an InstanceID is generated, the library periodically sends information about the - * application and the device where it's running to the Firebase backend. To stop this. see - * `[FIRInstanceID deleteIDWithHandler:]`. - * - * @param handler The handler to invoke once the identifier has been fetched. - * In case of error an appropriate error object is returned else - * a valid identifier is returned and a valid identifier for the - * application instance. - */ -- (void)getIDWithHandler:(FIRInstanceIDHandler)handler NS_SWIFT_NAME(getID(handler:)); - -/** - * Resets Instance ID and revokes all tokens. - * - * This method also triggers a request to fetch a new Instance ID and Firebase Messaging scope - * token. Please listen to kFIRInstanceIDTokenRefreshNotification when the new ID and token are - * ready. - * - * This stops the periodic sending of data to the Firebase backend that began when the Instance ID - * was generated. No more data is sent until another library calls Instance ID internally again - * (like FCM, RemoteConfig or Analytics) or user explicitly calls Instance ID APIs to get an - * Instance ID and token again. - */ -- (void)deleteIDWithHandler:(FIRInstanceIDDeleteHandler)handler NS_SWIFT_NAME(deleteID(handler:)); - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstanceID/Firebase/InstanceID/Public/FirebaseInstanceID.h b/Pods/FirebaseInstanceID/Firebase/InstanceID/Public/FirebaseInstanceID.h @@ -1,17 +0,0 @@ -/* - * Copyright 2019 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "FIRInstanceID.h" diff --git a/Pods/FirebaseInstanceID/LICENSE b/Pods/FirebaseInstanceID/LICENSE @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Pods/FirebaseInstanceID/README.md b/Pods/FirebaseInstanceID/README.md @@ -1,197 +0,0 @@ -# Firebase iOS Open Source Development [![Build Status](https://travis-ci.org/firebase/firebase-ios-sdk.svg?branch=master)](https://travis-ci.org/firebase/firebase-ios-sdk) - -This repository contains a subset of the Firebase iOS SDK source. It currently -includes FirebaseCore, FirebaseAuth, FirebaseDatabase, FirebaseFirestore, -FirebaseFunctions, FirebaseInstanceID, FirebaseInAppMessaging, -FirebaseInAppMessagingDisplay, FirebaseMessaging and FirebaseStorage. - -The repository also includes GoogleUtilities source. The -[GoogleUtilities](GoogleUtilities/README.md) pod is -a set of utilities used by Firebase and other Google products. - -Firebase is an app development platform with tools to help you build, grow and -monetize your app. More information about Firebase can be found at -[https://firebase.google.com](https://firebase.google.com). - -## Installation - -See the three subsections for details about three different installation methods. -1. [Standard pod install](README.md#standard-pod-install) -1. [Installing from the GitHub repo](README.md#installing-from-github) -1. [Experimental Carthage](README.md#carthage-ios-only) - -### Standard pod install - -Go to -[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup). - -### Installing from GitHub - -For releases starting with 5.0.0, the source for each release is also deployed -to CocoaPods master and available via standard -[CocoaPods Podfile syntax](https://guides.cocoapods.org/syntax/podfile.html#pod). - -These instructions can be used to access the Firebase repo at other branches, -tags, or commits. - -#### Background - -See -[the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod) -for instructions and options about overriding pod source locations. - -#### Accessing Firebase Source Snapshots - -All of the official releases are tagged in this repo and available via CocoaPods. To access a local -source snapshot or unreleased branch, use Podfile directives like the following: - -To access FirebaseFirestore via a branch: -``` -pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' -pod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' -``` - -To access FirebaseMessaging via a checked out version of the firebase-ios-sdk repo do: - -``` -pod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk' -pod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk' -``` - -### Carthage (iOS only) - -Instructions for the experimental Carthage distribution are at -[Carthage](Carthage.md). - -### Rome - -Instructions for installing binary frameworks via -[Rome](https://github.com/CocoaPods/Rome) are at [Rome](Rome.md). - -## Development - -Follow the subsequent instructions to develop, debug, unit test, run integration -tests, and try out reference samples: - -``` -$ git clone git@github.com:firebase/firebase-ios-sdk.git -$ cd firebase-ios-sdk/Example -$ pod update -$ open Firebase.xcworkspace -``` - -Firestore and Functions have self contained Xcode projects. See -[Firestore/README.md](Firestore/README.md) and -[Functions/README.md](Functions/README.md). - -### Code Formatting - -To ensure that the code is formatted consistently, run the script -[./scripts/style.sh](https://github.com/firebase/firebase-ios-sdk/blob/master/scripts/style.sh) -before creating a PR. - -Travis will verify that any code changes are done in a style compliant way. Install -`clang-format` and `swiftformat`. -This command will get the right `clang-format` version: - -`brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/773cb75d360b58f32048f5964038d09825a507c8/Formula/clang-format.rb` - -### Running Unit Tests - -Select a scheme and press Command-u to build a component and run its unit tests. - -### Running Sample Apps -In order to run the sample apps and integration tests, you'll need valid -`GoogleService-Info.plist` files for those samples. The Firebase Xcode project contains dummy plist -files without real values, but can be replaced with real plist files. To get your own -`GoogleService-Info.plist` files: - -1. Go to the [Firebase Console](https://console.firebase.google.com/) -2. Create a new Firebase project, if you don't already have one -3. For each sample app you want to test, create a new Firebase app with the sample app's bundle -identifier (e.g. `com.google.Database-Example`) -4. Download the resulting `GoogleService-Info.plist` and replace the appropriate dummy plist file -(e.g. in [Example/Database/App/](Example/Database/App/)); - -Some sample apps like Firebase Messaging ([Example/Messaging/App](Example/Messaging/App)) require -special Apple capabilities, and you will have to change the sample app to use a unique bundle -identifier that you can control in your own Apple Developer account. - -## Specific Component Instructions -See the sections below for any special instructions for those components. - -### Firebase Auth - -If you're doing specific Firebase Auth development, see -[the Auth Sample README](Example/Auth/README.md) for instructions about -building and running the FirebaseAuth pod along with various samples and tests. - -### Firebase Database - -To run the Database Integration tests, make your database authentication rules -[public](https://firebase.google.com/docs/database/security/quickstart). - -### Firebase Storage - -To run the Storage Integration tests, follow the instructions in -[FIRStorageIntegrationTests.m](Example/Storage/Tests/Integration/FIRStorageIntegrationTests.m). - -#### Push Notifications - -Push notifications can only be delivered to specially provisioned App IDs in the developer portal. -In order to actually test receiving push notifications, you will need to: - -1. Change the bundle identifier of the sample app to something you own in your Apple Developer -account, and enable that App ID for push notifications. -2. You'll also need to -[upload your APNs Provider Authentication Key or certificate to the Firebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs) -at **Project Settings > Cloud Messaging > [Your Firebase App]**. -3. Ensure your iOS device is added to your Apple Developer portal as a test device. - -#### iOS Simulator - -The iOS Simulator cannot register for remote notifications, and will not receive push notifications. -In order to receive push notifications, you'll have to follow the steps above and run the app on a -physical device. - -## Community Supported Efforts - -We've seen an amazing amount of interest and contributions to improve the Firebase SDKs, and we are -very grateful! We'd like to empower as many developers as we can to be able to use Firebase and -participate in the Firebase community. - -### macOS and tvOS -FirebaseAuth, FirebaseCore, FirebaseDatabase and FirebaseStorage now compile, run unit tests, and -work on macOS and tvOS, thanks to contributions from the community. There are a few tweaks needed, -like ensuring iOS-only, macOS-only, or tvOS-only code is correctly guarded with checks for -`TARGET_OS_IOS`, `TARGET_OS_OSX` and `TARGET_OS_TV`. - -For tvOS, checkout the [Sample](Example/tvOSSample). - -Keep in mind that macOS and tvOS are not officially supported by Firebase, and this repository is -actively developed primarily for iOS. While we can catch basic unit test issues with Travis, there -may be some changes where the SDK no longer works as expected on macOS or tvOS. If you encounter -this, please [file an issue](https://github.com/firebase/firebase-ios-sdk/issues). - -For installation instructions, see [above](README.md#accessing-firebase-source-snapshots). - -Note that the Firebase pod is not available for macOS and tvOS. Install a selection of the -`FirebaseAuth`, `FirebaseCore`, `FirebaseDatabase` and `FirebaseStorage` CocoaPods. - -## Roadmap - -See [Roadmap](ROADMAP.md) for more about the Firebase iOS SDK Open Source -plans and directions. - -## Contributing - -See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase -iOS SDK. - -## License - -The contents of this repository is licensed under the -[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). - -Your use of Firebase is governed by the -[Terms of Service for Firebase Services](https://firebase.google.com/terms/). diff --git a/Pods/GTMSessionFetcher/LICENSE b/Pods/GTMSessionFetcher/LICENSE @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Pods/GTMSessionFetcher/README.md b/Pods/GTMSessionFetcher/README.md @@ -1,23 +0,0 @@ -# Google Toolbox for Mac - Session Fetcher # - -**Project site** <https://github.com/google/gtm-session-fetcher><br> -**Discussion group** <http://groups.google.com/group/google-toolbox-for-mac> - -[![Build Status](https://travis-ci.org/google/gtm-session-fetcher.svg?branch=master)](https://travis-ci.org/google/gtm-session-fetcher) - -`GTMSessionFetcher` makes it easy for Cocoa applications to perform http -operations. The fetcher is implemented as a wrapper on `NSURLSession`, so its -behavior is asynchronous and uses operating-system settings on iOS and Mac OS X. - -Features include: -- Simple to build; only one source/header file pair is required -- Simple to use: takes just two lines of code to fetch a request -- Supports upload and download sessions -- Flexible cookie storage -- Automatic retry on errors, with exponential backoff -- Support for generating multipart MIME upload streams -- Easy, convenient logging of http requests and responses -- Supports plug-in authentication such as with GTMAppAuth -- Easily testable; self-mocking -- Automatic rate limiting when created by the `GTMSessionFetcherService` factory class -- Fully independent of other projects diff --git a/Pods/GTMSessionFetcher/Source/GTMGatherInputStream.h b/Pods/GTMSessionFetcher/Source/GTMGatherInputStream.h @@ -1,52 +0,0 @@ -/* Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// The GTMGatherInput stream is an input stream implementation that is to be -// instantiated with an NSArray of NSData objects. It works in the traditional -// scatter/gather vector I/O model. Rather than allocating a big NSData object -// to hold all of the data and performing a copy into that object, the -// GTMGatherInputStream will maintain a reference to the NSArray and read from -// each NSData in turn as the read method is called. You should not alter the -// underlying set of NSData objects until all read operations on this input -// stream have completed. - -#import <Foundation/Foundation.h> - -#ifndef GTM_NONNULL - #if defined(__has_attribute) - #if __has_attribute(nonnull) - #define GTM_NONNULL(x) __attribute__((nonnull x)) - #else - #define GTM_NONNULL(x) - #endif - #else - #define GTM_NONNULL(x) - #endif -#endif - -// Avoid multiple declaration of this class. -// -// Note: This should match the declaration of GTMGatherInputStream in GTMMIMEDocument.m - -#ifndef GTM_GATHERINPUTSTREAM_DECLARED -#define GTM_GATHERINPUTSTREAM_DECLARED - -@interface GTMGatherInputStream : NSInputStream <NSStreamDelegate> - -+ (NSInputStream *)streamWithArray:(NSArray *)dataArray GTM_NONNULL((1)); - -@end - -#endif // GTM_GATHERINPUTSTREAM_DECLARED diff --git a/Pods/GTMSessionFetcher/Source/GTMGatherInputStream.m b/Pods/GTMSessionFetcher/Source/GTMGatherInputStream.m @@ -1,185 +0,0 @@ -/* Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -#import "GTMGatherInputStream.h" - -@implementation GTMGatherInputStream { - NSArray *_dataArray; // NSDatas that should be "gathered" and streamed. - NSUInteger _arrayIndex; // Index in the array of the current NSData. - long long _dataOffset; // Offset in the current NSData we are processing. - NSStreamStatus _streamStatus; - id<NSStreamDelegate> __weak _delegate; // Stream delegate, defaults to self. -} - -+ (NSInputStream *)streamWithArray:(NSArray *)dataArray { - return [(GTMGatherInputStream *)[self alloc] initWithArray:dataArray]; -} - -- (instancetype)initWithArray:(NSArray *)dataArray { - self = [super init]; - if (self) { - _dataArray = dataArray; - _delegate = self; // An NSStream's default delegate should be self. - } - return self; -} - -#pragma mark - NSStream - -- (void)open { - _arrayIndex = 0; - _dataOffset = 0; - _streamStatus = NSStreamStatusOpen; -} - -- (void)close { - _streamStatus = NSStreamStatusClosed; -} - -- (id<NSStreamDelegate>)delegate { - return _delegate; -} - -- (void)setDelegate:(id<NSStreamDelegate>)delegate { - if (delegate == nil) { - _delegate = self; - } else { - _delegate = delegate; - } -} - -- (id)propertyForKey:(NSString *)key { - if ([key isEqual:NSStreamFileCurrentOffsetKey]) { - return @([self absoluteOffset]); - } - return nil; -} - -- (BOOL)setProperty:(id)property forKey:(NSString *)key { - if ([key isEqual:NSStreamFileCurrentOffsetKey]) { - NSNumber *absoluteOffsetNumber = property; - [self setAbsoluteOffset:absoluteOffsetNumber.longLongValue]; - return YES; - } - return NO; -} - -- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode { -} - -- (void)removeFromRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode { -} - -- (NSStreamStatus)streamStatus { - return _streamStatus; -} - -- (NSError *)streamError { - return nil; -} - -#pragma mark - NSInputStream - -- (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)len { - NSInteger bytesRead = 0; - NSUInteger bytesRemaining = len; - - // Read bytes from the currently-indexed array. - while ((bytesRemaining > 0) && (_arrayIndex < _dataArray.count)) { - NSData *data = [_dataArray objectAtIndex:_arrayIndex]; - - NSUInteger dataLen = data.length; - NSUInteger dataBytesLeft = dataLen - (NSUInteger)_dataOffset; - - NSUInteger bytesToCopy = MIN(bytesRemaining, dataBytesLeft); - NSRange range = NSMakeRange((NSUInteger) _dataOffset, bytesToCopy); - - [data getBytes:(buffer + bytesRead) range:range]; - - bytesRead += bytesToCopy; - _dataOffset += bytesToCopy; - bytesRemaining -= bytesToCopy; - - if (_dataOffset == (long long)dataLen) { - _dataOffset = 0; - _arrayIndex++; - } - } - if (_arrayIndex >= _dataArray.count) { - _streamStatus = NSStreamStatusAtEnd; - } - return bytesRead; -} - -- (BOOL)getBuffer:(uint8_t **)buffer length:(NSUInteger *)len { - return NO; // We don't support this style of reading. -} - -- (BOOL)hasBytesAvailable { - // If we return no, the read never finishes, even if we've already delivered all the bytes. - return YES; -} - -#pragma mark - NSStreamDelegate - -- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent { - id<NSStreamDelegate> delegate = _delegate; - if (delegate != self) { - [delegate stream:self handleEvent:streamEvent]; - } -} - -#pragma mark - Private - -- (long long)absoluteOffset { - long long absoluteOffset = 0; - NSUInteger index = 0; - for (NSData *data in _dataArray) { - if (index >= _arrayIndex) { - break; - } - absoluteOffset += data.length; - ++index; - } - absoluteOffset += _dataOffset; - return absoluteOffset; -} - -- (void)setAbsoluteOffset:(long long)absoluteOffset { - if (absoluteOffset < 0) { - absoluteOffset = 0; - } - _arrayIndex = 0; - _dataOffset = absoluteOffset; - for (NSData *data in _dataArray) { - long long dataLen = (long long) data.length; - if (dataLen > _dataOffset) { - break; - } - _arrayIndex++; - _dataOffset -= dataLen; - } - if (_arrayIndex == _dataArray.count) { - if (_dataOffset > 0) { - _dataOffset = 0; - } - } -} - -@end diff --git a/Pods/GTMSessionFetcher/Source/GTMMIMEDocument.h b/Pods/GTMSessionFetcher/Source/GTMMIMEDocument.h @@ -1,148 +0,0 @@ -/* Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// This is a simple class to create or parse a MIME document. - -// To create a MIME document, allocate a new GTMMIMEDocument and start adding parts. -// When you are done adding parts, call generateInputStream or generateDispatchData. -// -// A good reference for MIME is http://en.wikipedia.org/wiki/MIME - -#import <Foundation/Foundation.h> - -#ifndef GTM_NONNULL - #if defined(__has_attribute) - #if __has_attribute(nonnull) - #define GTM_NONNULL(x) __attribute__((nonnull x)) - #else - #define GTM_NONNULL(x) - #endif - #else - #define GTM_NONNULL(x) - #endif -#endif - -#ifndef GTM_DECLARE_GENERICS - #if __has_feature(objc_generics) - #define GTM_DECLARE_GENERICS 1 - #else - #define GTM_DECLARE_GENERICS 0 - #endif -#endif - -#ifndef GTM_NSArrayOf - #if GTM_DECLARE_GENERICS - #define GTM_NSArrayOf(value) NSArray<value> - #define GTM_NSDictionaryOf(key, value) NSDictionary<key, value> - #else - #define GTM_NSArrayOf(value) NSArray - #define GTM_NSDictionaryOf(key, value) NSDictionary - #endif // GTM_DECLARE_GENERICS -#endif // GTM_NSArrayOf - - -// GTMMIMEDocumentPart represents a part of a MIME document. -// -// +[GTMMIMEDocument MIMEPartsWithBoundary:data:] returns an array of these. -@interface GTMMIMEDocumentPart : NSObject - -@property(nonatomic, readonly) GTM_NSDictionaryOf(NSString *, NSString *) *headers; -@property(nonatomic, readonly) NSData *headerData; -@property(nonatomic, readonly) NSData *body; -@property(nonatomic, readonly) NSUInteger length; - -+ (instancetype)partWithHeaders:(NSDictionary *)headers body:(NSData *)body; - -@end - -@interface GTMMIMEDocument : NSObject - -// Get or set the unique boundary for the parts that have been added. -// -// When creating a MIME document from parts, this is typically calculated -// automatically after all parts have been added. -@property(nonatomic, copy) NSString *boundary; - -#pragma mark - Methods for Creating a MIME Document - -+ (instancetype)MIMEDocument; - -// Adds a new part to this mime document with the given headers and body. -// The headers keys and values should be NSStrings. -// Adding a part may cause the boundary string to change. -- (void)addPartWithHeaders:(GTM_NSDictionaryOf(NSString *, NSString *) *)headers - body:(NSData *)body GTM_NONNULL((1,2)); - -// An inputstream that can be used to efficiently read the contents of the MIME document. -// -// Any parameter may be null if the result is not wanted. -- (void)generateInputStream:(NSInputStream **)outStream - length:(unsigned long long *)outLength - boundary:(NSString **)outBoundary; - -// A dispatch_data_t with the contents of the MIME document. -// -// Note: dispatch_data_t is one-way toll-free bridged so the result -// may be cast directly to NSData *. -// -// Any parameter may be null if the result is not wanted. -- (void)generateDispatchData:(dispatch_data_t *)outDispatchData - length:(unsigned long long *)outLength - boundary:(NSString **)outBoundary; - -// Utility method for making a header section, including trailing newlines. -+ (NSData *)dataWithHeaders:(GTM_NSDictionaryOf(NSString *, NSString *) *)headers; - -#pragma mark - Methods for Parsing a MIME Document - -// Method for parsing out an array of MIME parts from a MIME document. -// -// Returns an array of GTMMIMEDocumentParts. Returns nil if no part can -// be found. -+ (GTM_NSArrayOf(GTMMIMEDocumentPart *) *)MIMEPartsWithBoundary:(NSString *)boundary - data:(NSData *)fullDocumentData; - -// Utility method for efficiently searching possibly discontiguous NSData -// for occurrences of target byte. This method does not "flatten" an NSData -// that is composed of discontiguous blocks. -// -// The byte offsets of non-overlapping occurrences of the target are returned as -// NSNumbers in the array. -+ (void)searchData:(NSData *)data - targetBytes:(const void *)targetBytes - targetLength:(NSUInteger)targetLength - foundOffsets:(GTM_NSArrayOf(NSNumber *) **)outFoundOffsets; - -// Utility method to parse header bytes into an NSDictionary. -+ (GTM_NSDictionaryOf(NSString *, NSString *) *)headersWithData:(NSData *)data; - -// ------ UNIT TESTING ONLY BELOW ------ - -// Internal methods, exposed for unit testing only. -- (void)seedRandomWith:(u_int32_t)seed; - -+ (NSUInteger)findBytesWithNeedle:(const unsigned char *)needle - needleLength:(NSUInteger)needleLength - haystack:(const unsigned char *)haystack - haystackLength:(NSUInteger)haystackLength - foundOffset:(NSUInteger *)foundOffset; - -+ (void)searchData:(NSData *)data - targetBytes:(const void *)targetBytes - targetLength:(NSUInteger)targetLength - foundOffsets:(GTM_NSArrayOf(NSNumber *) **)outFoundOffsets - foundBlockNumbers:(GTM_NSArrayOf(NSNumber *) **)outFoundBlockNumbers; - -@end diff --git a/Pods/GTMSessionFetcher/Source/GTMMIMEDocument.m b/Pods/GTMSessionFetcher/Source/GTMMIMEDocument.m @@ -1,631 +0,0 @@ -/* Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -#import "GTMMIMEDocument.h" - -// Avoid a hard dependency on GTMGatherInputStream. -#ifndef GTM_GATHERINPUTSTREAM_DECLARED -#define GTM_GATHERINPUTSTREAM_DECLARED - -@interface GTMGatherInputStream : NSInputStream <NSStreamDelegate> - -+ (NSInputStream *)streamWithArray:(NSArray *)dataArray GTM_NONNULL((1)); - -@end -#endif // GTM_GATHERINPUTSTREAM_DECLARED - -// FindBytes -// -// Helper routine to search for the existence of a set of bytes (needle) within -// a presumed larger set of bytes (haystack). Can find the first part of the -// needle at the very end of the haystack. -// -// Returns the needle length on complete success, the number of bytes matched -// if a partial needle was found at the end of the haystack, and 0 on failure. -static NSUInteger FindBytes(const unsigned char *needle, NSUInteger needleLen, - const unsigned char *haystack, NSUInteger haystackLen, - NSUInteger *foundOffset); - -// SearchDataForBytes -// -// This implements the functionality of the +searchData: methods below. See the documentation -// for those methods. -static void SearchDataForBytes(NSData *data, const void *targetBytes, NSUInteger targetLength, - NSMutableArray *foundOffsets, NSMutableArray *foundBlockNumbers); - -@implementation GTMMIMEDocumentPart { - NSDictionary *_headers; - NSData *_headerData; // Header content including the ending "\r\n". - NSData *_bodyData; -} - -@synthesize headers = _headers, - headerData = _headerData, - body = _bodyData; - -@dynamic length; - -+ (instancetype)partWithHeaders:(NSDictionary *)headers body:(NSData *)body { - return [[self alloc] initWithHeaders:headers body:body]; -} - -- (instancetype)initWithHeaders:(NSDictionary *)headers body:(NSData *)body { - self = [super init]; - if (self) { - _bodyData = body; - _headers = headers; - } - return self; -} - -// Returns true if the part's header or data contain the given set of bytes. -// -// NOTE: We assume that the 'bytes' we are checking for do not contain "\r\n", -// so we don't need to check the concatenation of the header and body bytes. -- (BOOL)containsBytes:(const unsigned char *)bytes length:(NSUInteger)length { - // This uses custom search code rather than strcpy because the encoded data may contain - // null values. - NSData *headerData = self.headerData; - return (FindBytes(bytes, length, headerData.bytes, headerData.length, NULL) == length || - FindBytes(bytes, length, _bodyData.bytes, _bodyData.length, NULL) == length); -} - -- (NSData *)headerData { - if (!_headerData) { - _headerData = [GTMMIMEDocument dataWithHeaders:_headers]; - } - return _headerData; -} - -- (NSData *)body { - return _bodyData; -} - -- (NSUInteger)length { - return _headerData.length + _bodyData.length; -} - -- (NSString *)description { - return [NSString stringWithFormat:@"%@ %p (headers %lu keys, body %lu bytes)", - [self class], self, (unsigned long)_headers.count, - (unsigned long)_bodyData.length]; -} - -- (BOOL)isEqual:(GTMMIMEDocumentPart *)other { - if (self == other) return YES; - if (![other isKindOfClass:[GTMMIMEDocumentPart class]]) return NO; - return ((_bodyData == other->_bodyData || [_bodyData isEqual:other->_bodyData]) - && (_headers == other->_headers || [_headers isEqual:other->_headers])); -} - -- (NSUInteger)hash { - return _bodyData.hash | _headers.hash; -} - -@end - -@implementation GTMMIMEDocument { - NSMutableArray *_parts; // Ordered array of GTMMIMEDocumentParts. - unsigned long long _length; // Length in bytes of the document. - NSString *_boundary; - u_int32_t _randomSeed; // For testing. -} - -+ (instancetype)MIMEDocument { - return [[self alloc] init]; -} - -- (instancetype)init { - self = [super init]; - if (self) { - _parts = [[NSMutableArray alloc] init]; - } - return self; -} - -- (NSString *)description { - return [NSString stringWithFormat:@"%@ %p (%lu parts)", - [self class], self, (unsigned long)_parts.count]; -} - -#pragma mark - Joining Parts - -// Adds a new part to this mime document with the given headers and body. -- (void)addPartWithHeaders:(NSDictionary *)headers body:(NSData *)body { - GTMMIMEDocumentPart *part = [GTMMIMEDocumentPart partWithHeaders:headers body:body]; - [_parts addObject:part]; - _boundary = nil; -} - -// For unit testing only, seeds the random number generator so that we will -// have reproducible boundary strings. -- (void)seedRandomWith:(u_int32_t)seed { - _randomSeed = seed; - _boundary = nil; -} - -- (u_int32_t)random { - if (_randomSeed) { - // For testing only. - return _randomSeed++; - } else { - return arc4random(); - } -} - -// Computes the mime boundary to use. This should only be called -// after all the desired document parts have been added since it must compute -// a boundary that does not exist in the document data. -- (NSString *)boundary { - if (_boundary) { - return _boundary; - } - - // Use an easily-readable boundary string. - NSString *const kBaseBoundary = @"END_OF_PART"; - - _boundary = kBaseBoundary; - - // If the boundary isn't unique, append random numbers, up to 10 attempts; - // if that's still not unique, use a random number sequence instead, and call it good. - BOOL didCollide = NO; - - const int maxTries = 10; // Arbitrarily chosen maximum attempts. - for (int tries = 0; tries < maxTries; ++tries) { - - NSData *data = [_boundary dataUsingEncoding:NSUTF8StringEncoding]; - const void *dataBytes = data.bytes; - NSUInteger dataLen = data.length; - - for (GTMMIMEDocumentPart *part in _parts) { - didCollide = [part containsBytes:dataBytes length:dataLen]; - if (didCollide) break; - } - - if (!didCollide) break; // We're fine, no more attempts needed. - - // Try again with a random number appended. - _boundary = [NSString stringWithFormat:@"%@_%08x", kBaseBoundary, [self random]]; - } - - if (didCollide) { - // Fallback... two random numbers. - _boundary = [NSString stringWithFormat:@"%08x_tedborg_%08x", [self random], [self random]]; - } - return _boundary; -} - -- (void)setBoundary:(NSString *)str { - _boundary = [str copy]; -} - -// Internal method. -- (void)generateDataArray:(NSMutableArray *)dataArray - length:(unsigned long long *)outLength - boundary:(NSString **)outBoundary { - - // The input stream is of the form: - // --boundary - // [part_1_headers] - // [part_1_data] - // --boundary - // [part_2_headers] - // [part_2_data] - // --boundary-- - - // First we set up our boundary NSData objects. - NSString *boundary = self.boundary; - - NSString *mainBoundary = [NSString stringWithFormat:@"\r\n--%@\r\n", boundary]; - NSString *endBoundary = [NSString stringWithFormat:@"\r\n--%@--\r\n", boundary]; - - NSData *mainBoundaryData = [mainBoundary dataUsingEncoding:NSUTF8StringEncoding]; - NSData *endBoundaryData = [endBoundary dataUsingEncoding:NSUTF8StringEncoding]; - - // Now we add them all in proper order to our dataArray. - unsigned long long length = 0; - - for (GTMMIMEDocumentPart *part in _parts) { - [dataArray addObject:mainBoundaryData]; - [dataArray addObject:part.headerData]; - [dataArray addObject:part.body]; - - length += part.length + mainBoundaryData.length; - } - - [dataArray addObject:endBoundaryData]; - length += endBoundaryData.length; - - if (outLength) *outLength = length; - if (outBoundary) *outBoundary = boundary; -} - -- (void)generateInputStream:(NSInputStream **)outStream - length:(unsigned long long *)outLength - boundary:(NSString **)outBoundary { - NSMutableArray *dataArray = outStream ? [NSMutableArray array] : nil; - [self generateDataArray:dataArray - length:outLength - boundary:outBoundary]; - - if (outStream) { - Class streamClass = NSClassFromString(@"GTMGatherInputStream"); - NSAssert(streamClass != nil, @"GTMGatherInputStream not available."); - - *outStream = [streamClass streamWithArray:dataArray]; - } -} - -- (void)generateDispatchData:(dispatch_data_t *)outDispatchData - length:(unsigned long long *)outLength - boundary:(NSString **)outBoundary { - NSMutableArray *dataArray = outDispatchData ? [NSMutableArray array] : nil; - [self generateDataArray:dataArray - length:outLength - boundary:outBoundary]; - - if (outDispatchData) { - // Create an empty data accumulator. - dispatch_data_t dataAccumulator; - - dispatch_queue_t bgQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); - - for (NSData *partData in dataArray) { - __block NSData *immutablePartData = [partData copy]; - dispatch_data_t newDataPart = - dispatch_data_create(immutablePartData.bytes, immutablePartData.length, bgQueue, ^{ - // We want the data retained until this block executes. - immutablePartData = nil; - }); - - if (dataAccumulator == nil) { - // First part. - dataAccumulator = newDataPart; - } else { - // Append the additional part. - dataAccumulator = dispatch_data_create_concat(dataAccumulator, newDataPart); - } - } - *outDispatchData = dataAccumulator; - } -} - -+ (NSData *)dataWithHeaders:(NSDictionary *)headers { - // Generate the header data by coalescing the dictionary as lines of "key: value\r\n". - NSMutableString* headerString = [NSMutableString string]; - - // Sort the header keys so we have a deterministic order for unit testing. - SEL sortSel = @selector(caseInsensitiveCompare:); - NSArray *sortedKeys = [headers.allKeys sortedArrayUsingSelector:sortSel]; - - for (NSString *key in sortedKeys) { - NSString *value = [headers objectForKey:key]; - -#if DEBUG - // Look for troublesome characters in the header keys & values. - NSCharacterSet *badKeyChars = [NSCharacterSet characterSetWithCharactersInString:@":\r\n"]; - NSCharacterSet *badValueChars = [NSCharacterSet characterSetWithCharactersInString:@"\r\n"]; - - NSRange badRange = [key rangeOfCharacterFromSet:badKeyChars]; - NSAssert(badRange.location == NSNotFound, @"invalid key: %@", key); - - badRange = [value rangeOfCharacterFromSet:badValueChars]; - NSAssert(badRange.location == NSNotFound, @"invalid value: %@", value); -#endif - - [headerString appendFormat:@"%@: %@\r\n", key, value]; - } - // Headers end with an extra blank line. - [headerString appendString:@"\r\n"]; - - NSData *result = [headerString dataUsingEncoding:NSUTF8StringEncoding]; - return result; -} - -#pragma mark - Separating Parts - -+ (NSArray *)MIMEPartsWithBoundary:(NSString *)boundary - data:(NSData *)fullDocumentData { - // In MIME documents, the boundary is preceded by CRLF and two dashes, and followed - // at the end by two dashes. - NSData *boundaryData = [boundary dataUsingEncoding:NSUTF8StringEncoding]; - NSUInteger boundaryLength = boundaryData.length; - - NSMutableArray *foundBoundaryOffsets; - [self searchData:fullDocumentData - targetBytes:boundaryData.bytes - targetLength:boundaryLength - foundOffsets:&foundBoundaryOffsets]; - - // According to rfc1341, ignore anything before the first boundary, or after the last, though two - // dashes are expected to follow the last boundary. - if (foundBoundaryOffsets.count < 2) { - return nil; - } - - // Wrap the full document data with a dispatch_data_t for more efficient slicing - // and dicing. - dispatch_data_t dataWrapper; - if ([fullDocumentData conformsToProtocol:@protocol(OS_dispatch_data)]) { - dataWrapper = (dispatch_data_t)fullDocumentData; - } else { - // A no-op self invocation on fullDocumentData will keep it retained until the block is invoked. - dispatch_queue_t bgQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); - dataWrapper = dispatch_data_create(fullDocumentData.bytes, - fullDocumentData.length, - bgQueue, ^{ [fullDocumentData self]; }); - } - NSMutableArray *parts; - NSInteger previousBoundaryOffset = -1; - NSInteger partCounter = -1; - NSInteger numberOfPartsWithHeaders = 0; - for (NSNumber *currentBoundaryOffset in foundBoundaryOffsets) { - ++partCounter; - if (previousBoundaryOffset == -1) { - // This is the first boundary. - previousBoundaryOffset = currentBoundaryOffset.integerValue; - continue; - } else { - // Create a part data subrange between the previous boundary and this one. - // - // The last four bytes before a boundary are CRLF--. - // The first two bytes following a boundary are either CRLF or, for the last boundary, --. - NSInteger previousPartDataStartOffset = - previousBoundaryOffset + (NSInteger)boundaryLength + 2; - NSInteger previousPartDataEndOffset = currentBoundaryOffset.integerValue - 4; - NSInteger previousPartDataLength = previousPartDataEndOffset - previousPartDataStartOffset; - - if (previousPartDataLength < 2) { - // The preceding part was too short to be useful. -#if DEBUG - NSLog(@"MIME part %ld has %ld bytes", (long)partCounter - 1, - (long)previousPartDataLength); -#endif - } else { - if (!parts) parts = [NSMutableArray array]; - - dispatch_data_t partData = - dispatch_data_create_subrange(dataWrapper, - (size_t)previousPartDataStartOffset, (size_t)previousPartDataLength); - // Scan the part data for the separator between headers and body. After the CRLF, - // either the headers start immediately, or there's another CRLF and there are no headers. - // - // We need to map the part data to get the first two bytes. (Or we could cast it to - // NSData and get the bytes pointer of that.) If we're concerned that a single part - // data may be expensive to map, we could make a subrange here for just the first two bytes, - // and map that two-byte subrange. - const void *partDataBuffer; - size_t partDataBufferSize; - dispatch_data_t mappedPartData NS_VALID_UNTIL_END_OF_SCOPE = - dispatch_data_create_map(partData, &partDataBuffer, &partDataBufferSize); - dispatch_data_t bodyData; - NSDictionary *headers; - BOOL hasAnotherCRLF = (((char *)partDataBuffer)[0] == '\r' - && ((char *)partDataBuffer)[1] == '\n'); - mappedPartData = nil; - - if (hasAnotherCRLF) { - // There are no headers; skip the CRLF to get to the body, and leave headers nil. - bodyData = dispatch_data_create_subrange(partData, 2, (size_t)previousPartDataLength - 2); - } else { - // There are part headers. They are separated from body data by CRLFCRLF. - NSArray *crlfOffsets; - [self searchData:(NSData *)partData - targetBytes:"\r\n\r\n" - targetLength:4 - foundOffsets:&crlfOffsets]; - if (crlfOffsets.count == 0) { -#if DEBUG - // We could not distinguish body and headers. - NSLog(@"MIME part %ld lacks a header separator: %@", (long)partCounter - 1, - [[NSString alloc] initWithData:(NSData *)partData encoding:NSUTF8StringEncoding]); -#endif - } else { - NSInteger headerSeparatorOffset = ((NSNumber *)crlfOffsets.firstObject).integerValue; - dispatch_data_t headerData = - dispatch_data_create_subrange(partData, 0, (size_t)headerSeparatorOffset); - headers = [self headersWithData:(NSData *)headerData]; - - bodyData = dispatch_data_create_subrange(partData, (size_t)headerSeparatorOffset + 4, - (size_t)(previousPartDataLength - (headerSeparatorOffset + 4))); - - numberOfPartsWithHeaders++; - } // crlfOffsets.count == 0 - } // hasAnotherCRLF - GTMMIMEDocumentPart *part = [GTMMIMEDocumentPart partWithHeaders:headers - body:(NSData *)bodyData]; - [parts addObject:part]; - } // previousPartDataLength < 2 - previousBoundaryOffset = currentBoundaryOffset.integerValue; - } - } -#if DEBUG - // In debug builds, warn if a reasonably long document lacks any CRLF characters. - if (numberOfPartsWithHeaders == 0) { - NSUInteger length = fullDocumentData.length; - if (length > 20) { // Reasonably long. - NSMutableArray *foundCRLFs; - [self searchData:fullDocumentData - targetBytes:"\r\n" - targetLength:2 - foundOffsets:&foundCRLFs]; - if (foundCRLFs.count == 0) { - // Parts were logged above (due to lacking header separators.) - NSLog(@"Warning: MIME document lacks any headers (may have wrong line endings)"); - } - } - } -#endif // DEBUG - return parts; -} - -// Efficiently search the supplied data for the target bytes. -// -// This uses enumerateByteRangesUsingBlock: to scan for bytes. It can find -// the target even if it spans multiple separate byte ranges. -// -// Returns an array of found byte offset values, as NSNumbers. -+ (void)searchData:(NSData *)data - targetBytes:(const void *)targetBytes - targetLength:(NSUInteger)targetLength - foundOffsets:(GTM_NSArrayOf(NSNumber *) **)outFoundOffsets { - NSMutableArray *foundOffsets = [NSMutableArray array]; - SearchDataForBytes(data, targetBytes, targetLength, foundOffsets, NULL); - *outFoundOffsets = foundOffsets; -} - - -// This version of searchData: also returns the block numbers (0-based) where the -// target was found, used for testing that the supplied dispatch_data buffer -// has not been flattened. -+ (void)searchData:(NSData *)data - targetBytes:(const void *)targetBytes - targetLength:(NSUInteger)targetLength - foundOffsets:(GTM_NSArrayOf(NSNumber *) **)outFoundOffsets - foundBlockNumbers:(GTM_NSArrayOf(NSNumber *) **)outFoundBlockNumbers { - NSMutableArray *foundOffsets = [NSMutableArray array]; - NSMutableArray *foundBlockNumbers = [NSMutableArray array]; - - SearchDataForBytes(data, targetBytes, targetLength, foundOffsets, foundBlockNumbers); - *outFoundOffsets = foundOffsets; - *outFoundBlockNumbers = foundBlockNumbers; -} - -static void SearchDataForBytes(NSData *data, const void *targetBytes, NSUInteger targetLength, - NSMutableArray *foundOffsets, NSMutableArray *foundBlockNumbers) { - __block NSUInteger priorPartialMatchAmount = 0; - __block NSInteger priorPartialMatchStartingBlockNumber = -1; - __block NSInteger blockNumber = -1; - - [data enumerateByteRangesUsingBlock:^(const void *bytes, - NSRange byteRange, - BOOL *stop) { - // Search for the first character in the current range. - const void *ptr = bytes; - NSInteger remainingInCurrentRange = (NSInteger)byteRange.length; - ++blockNumber; - - if (priorPartialMatchAmount > 0) { - NSUInteger amountRemainingToBeMatched = targetLength - priorPartialMatchAmount; - NSUInteger remainingFoundOffset; - NSUInteger amountMatched = FindBytes(targetBytes + priorPartialMatchAmount, - amountRemainingToBeMatched, - ptr, (NSUInteger)remainingInCurrentRange, &remainingFoundOffset); - if (amountMatched == 0 || remainingFoundOffset > 0) { - // No match of the rest of the prior partial match in this range. - } else if (amountMatched < amountRemainingToBeMatched) { - // Another partial match; we're done with this range. - priorPartialMatchAmount = priorPartialMatchAmount + amountMatched; - return; - } else { - // The offset is in an earlier range. - NSUInteger offset = byteRange.location - priorPartialMatchAmount; - [foundOffsets addObject:@(offset)]; - [foundBlockNumbers addObject:@(priorPartialMatchStartingBlockNumber)]; - priorPartialMatchStartingBlockNumber = -1; - } - priorPartialMatchAmount = 0; - } - - while (remainingInCurrentRange > 0) { - NSUInteger offsetFromPtr; - NSUInteger amountMatched = FindBytes(targetBytes, targetLength, ptr, - (NSUInteger)remainingInCurrentRange, &offsetFromPtr); - if (amountMatched == 0) { - // No match in this range. - return; - } - if (amountMatched < targetLength) { - // Found a partial target. If there's another range, we'll check for the rest. - priorPartialMatchAmount = amountMatched; - priorPartialMatchStartingBlockNumber = blockNumber; - return; - } - // Found the full target. - NSUInteger globalOffset = byteRange.location + (NSUInteger)(ptr - bytes) + offsetFromPtr; - - [foundOffsets addObject:@(globalOffset)]; - [foundBlockNumbers addObject:@(blockNumber)]; - - ptr += targetLength + offsetFromPtr; - remainingInCurrentRange -= (targetLength + offsetFromPtr); - } - }]; -} - -// Internal method only for testing; this calls through the static method. -+ (NSUInteger)findBytesWithNeedle:(const unsigned char *)needle - needleLength:(NSUInteger)needleLength - haystack:(const unsigned char *)haystack - haystackLength:(NSUInteger)haystackLength - foundOffset:(NSUInteger *)foundOffset { - return FindBytes(needle, needleLength, haystack, haystackLength, foundOffset); -} - -// Utility method to parse header bytes into an NSDictionary. -+ (NSDictionary *)headersWithData:(NSData *)data { - NSString *headersString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - if (!headersString) return nil; - - NSMutableDictionary *headers = [NSMutableDictionary dictionary]; - NSScanner *scanner = [NSScanner scannerWithString:headersString]; - // The scanner is skipping leading whitespace and newline characters by default. - NSCharacterSet *newlineCharacters = [NSCharacterSet newlineCharacterSet]; - NSString *key; - NSString *value; - while ([scanner scanUpToString:@":" intoString:&key] - && [scanner scanString:@":" intoString:NULL] - && [scanner scanUpToCharactersFromSet:newlineCharacters intoString:&value]) { - [headers setObject:value forKey:key]; - // Discard the trailing newline. - [scanner scanCharactersFromSet:newlineCharacters intoString:NULL]; - } - return headers; -} - -@end - -// Return how much of the needle was found in the haystack. -// -// If the result is less than needleLen, then the beginning of the needle -// was found at the end of the haystack. -static NSUInteger FindBytes(const unsigned char* needle, NSUInteger needleLen, - const unsigned char* haystack, NSUInteger haystackLen, - NSUInteger *foundOffset) { - const unsigned char *ptr = haystack; - NSInteger remain = (NSInteger)haystackLen; - // Assume memchr is an efficient way to find a match for the first - // byte of the needle, and memcmp is an efficient way to compare a - // range of bytes. - while (remain > 0 && (ptr = memchr(ptr, needle[0], (size_t)remain)) != 0) { - // The first character is present. - NSUInteger offset = (NSUInteger)(ptr - haystack); - remain = (NSInteger)(haystackLen - offset); - - NSUInteger amountToCompare = MIN((NSUInteger)remain, needleLen); - if (memcmp(ptr, needle, amountToCompare) == 0) { - if (foundOffset) *foundOffset = offset; - return amountToCompare; - } - ptr++; - remain--; - } - if (foundOffset) *foundOffset = 0; - return 0; -} diff --git a/Pods/GTMSessionFetcher/Source/GTMReadMonitorInputStream.h b/Pods/GTMSessionFetcher/Source/GTMReadMonitorInputStream.h @@ -1,49 +0,0 @@ -/* Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -#ifndef GTM_NONNULL - #if defined(__has_attribute) - #if __has_attribute(nonnull) - #define GTM_NONNULL(x) __attribute__((nonnull x)) - #else - #define GTM_NONNULL(x) - #endif - #else - #define GTM_NONNULL(x) - #endif -#endif - - -@interface GTMReadMonitorInputStream : NSInputStream <NSStreamDelegate> - -+ (instancetype)inputStreamWithStream:(NSInputStream *)input GTM_NONNULL((1)); - -- (instancetype)initWithStream:(NSInputStream *)input GTM_NONNULL((1)); - -// The read monitor selector is called when bytes have been read. It should have this signature: -// -// - (void)inputStream:(GTMReadMonitorInputStream *)stream -// readIntoBuffer:(uint8_t *)buffer -// length:(int64_t)length; - -@property(atomic, weak) id readDelegate; -@property(atomic, assign) SEL readSelector; - -// Modes for invoking callbacks, when necessary. -@property(atomic, strong) NSArray *runLoopModes; - -@end diff --git a/Pods/GTMSessionFetcher/Source/GTMReadMonitorInputStream.m b/Pods/GTMSessionFetcher/Source/GTMReadMonitorInputStream.m @@ -1,190 +0,0 @@ -/* Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -#import "GTMReadMonitorInputStream.h" - -@implementation GTMReadMonitorInputStream { - NSInputStream *_inputStream; // Encapsulated stream that does the work. - - NSThread *_thread; // Thread in which this object was created. - NSArray *_runLoopModes; // Modes for calling callbacks, when necessary. -} - - -@synthesize readDelegate = _readDelegate; -@synthesize readSelector = _readSelector; -@synthesize runLoopModes = _runLoopModes; - -// We'll forward all unhandled messages to the NSInputStream class or to the encapsulated input -// stream. This is needed for all messages sent to NSInputStream which aren't handled by our -// superclass; that includes various private run loop calls. -+ (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { - return [NSInputStream methodSignatureForSelector:selector]; -} - -+ (void)forwardInvocation:(NSInvocation*)invocation { - [invocation invokeWithTarget:[NSInputStream class]]; -} - -- (BOOL)respondsToSelector:(SEL)selector { - return [_inputStream respondsToSelector:selector]; -} - -- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector { - return [_inputStream methodSignatureForSelector:selector]; -} - -- (void)forwardInvocation:(NSInvocation*)invocation { - [invocation invokeWithTarget:_inputStream]; -} - -#pragma mark - - -+ (instancetype)inputStreamWithStream:(NSInputStream *)input { - return [[self alloc] initWithStream:input]; -} - -- (instancetype)initWithStream:(NSInputStream *)input { - self = [super init]; - if (self) { - _inputStream = input; - _thread = [NSThread currentThread]; - } - return self; -} - -- (instancetype)init { - [self doesNotRecognizeSelector:_cmd]; - return nil; -} - -#pragma mark - - -- (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)len { - // Read from the encapsulated stream. - NSInteger numRead = [_inputStream read:buffer maxLength:len]; - if (numRead > 0) { - if (_readDelegate && _readSelector) { - // Call the read selector with the buffer and number of bytes actually read into it. - BOOL isOnOriginalThread = [_thread isEqual:[NSThread currentThread]]; - if (isOnOriginalThread) { - // Invoke immediately. - NSData *data = [NSData dataWithBytesNoCopy:buffer - length:(NSUInteger)numRead - freeWhenDone:NO]; - [self invokeReadSelectorWithBuffer:data]; - } else { - // Copy the buffer into an NSData to be retained by the performSelector, - // and invoke on the proper thread. - SEL sel = @selector(invokeReadSelectorWithBuffer:); - NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numRead]; -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warc-performSelector-leaks" - if (_runLoopModes) { - [self performSelector:sel - onThread:_thread - withObject:data - waitUntilDone:NO - modes:_runLoopModes]; - } else { - [self performSelector:sel - onThread:_thread - withObject:data - waitUntilDone:NO]; - } -#pragma clang diagnostic pop - } - } - } - return numRead; -} - -- (void)invokeReadSelectorWithBuffer:(NSData *)data { - const void *buffer = data.bytes; - int64_t length = (int64_t)data.length; - - id argSelf = self; - id readDelegate = _readDelegate; - if (readDelegate) { - NSMethodSignature *signature = [readDelegate methodSignatureForSelector:_readSelector]; - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; - [invocation setSelector:_readSelector]; - [invocation setTarget:readDelegate]; - [invocation setArgument:&argSelf atIndex:2]; - [invocation setArgument:&buffer atIndex:3]; - [invocation setArgument:&length atIndex:4]; - [invocation invoke]; - } -} - -- (BOOL)getBuffer:(uint8_t **)buffer length:(NSUInteger *)len { - return [_inputStream getBuffer:buffer length:len]; -} - -- (BOOL)hasBytesAvailable { - return [_inputStream hasBytesAvailable]; -} - -#pragma mark Standard messages - -// Pass expected messages to our encapsulated stream. -// -// We want our encapsulated NSInputStream to handle the standard messages; -// we don't want the superclass to handle them. -- (void)open { - [_inputStream open]; -} - -- (void)close { - [_inputStream close]; -} - -- (id)delegate { - return [_inputStream delegate]; -} - -- (void)setDelegate:(id)delegate { - [_inputStream setDelegate:delegate]; -} - -- (id)propertyForKey:(NSString *)key { - return [_inputStream propertyForKey:key]; -} - -- (BOOL)setProperty:(id)property forKey:(NSString *)key { - return [_inputStream setProperty:property forKey:key]; -} - -- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode { - [_inputStream scheduleInRunLoop:aRunLoop forMode:mode]; -} - -- (void)removeFromRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode { - [_inputStream removeFromRunLoop:aRunLoop forMode:mode]; -} - -- (NSStreamStatus)streamStatus { - return [_inputStream streamStatus]; -} - -- (NSError *)streamError { - return [_inputStream streamError]; -} - -@end diff --git a/Pods/GTMSessionFetcher/Source/GTMSessionFetcher.h b/Pods/GTMSessionFetcher/Source/GTMSessionFetcher.h @@ -1,1305 +0,0 @@ -/* Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// GTMSessionFetcher is a wrapper around NSURLSession for http operations. -// -// What does this offer on top of of NSURLSession? -// -// - Block-style callbacks for useful functionality like progress rather -// than delegate methods. -// - Out-of-process uploads and downloads using NSURLSession, including -// management of fetches after relaunch. -// - Integration with GTMAppAuth for invisible management and refresh of -// authorization tokens. -// - Pretty-printed http logging. -// - Cookies handling that does not interfere with or get interfered with -// by WebKit cookies or on Mac by Safari and other apps. -// - Credentials handling for the http operation. -// - Rate-limiting and cookie grouping when fetchers are created with -// GTMSessionFetcherService. -// -// If the bodyData or bodyFileURL property is set, then a POST request is assumed. -// -// Each fetcher is assumed to be for a one-shot fetch request; don't reuse the object -// for a second fetch. -// -// The fetcher will be self-retained as long as a connection is pending. -// -// To keep user activity private, URLs must have an https scheme (unless the property -// allowedInsecureSchemes is set to permit the scheme.) -// -// Callbacks will be released when the fetch completes or is stopped, so there is no need -// to use weak self references in the callback blocks. -// -// Sample usage: -// -// _fetcherService = [[GTMSessionFetcherService alloc] init]; -// -// GTMSessionFetcher *myFetcher = [_fetcherService fetcherWithURLString:myURLString]; -// myFetcher.retryEnabled = YES; -// myFetcher.comment = @"First profile image"; -// -// // Optionally specify a file URL or NSData for the request body to upload. -// myFetcher.bodyData = [postString dataUsingEncoding:NSUTF8StringEncoding]; -// -// [myFetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error) { -// if (error != nil) { -// // Server status code or network error. -// // -// // If the domain is kGTMSessionFetcherStatusDomain then the error code -// // is a failure status from the server. -// } else { -// // Fetch succeeded. -// } -// }]; -// -// There is also a beginFetch call that takes a pointer and selector for the completion handler; -// a pointer and selector is a better style when the callback is a substantial, separate method. -// -// NOTE: Fetches may retrieve data from the server even though the server -// returned an error, so the criteria for success is a non-nil error. -// The completion handler is called when the server status is >= 300 with an NSError -// having domain kGTMSessionFetcherStatusDomain and code set to the server status. -// -// Status codes are at <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html> -// -// -// Background session support: -// -// Out-of-process uploads and downloads may be created by setting the fetcher's -// useBackgroundSession property. Data to be uploaded should be provided via -// the uploadFileURL property; the download destination should be specified with -// the destinationFileURL. NOTE: Background upload files should be in a location -// that will be valid even after the device is restarted, so the file should not -// be uploaded from a system temporary or cache directory. -// -// Background session transfers are slower, and should typically be used only -// for very large downloads or uploads (hundreds of megabytes). -// -// When background sessions are used in iOS apps, the application delegate must -// pass through the parameters from UIApplicationDelegate's -// application:handleEventsForBackgroundURLSession:completionHandler: to the -// fetcher class. -// -// When the application has been relaunched, it may also create a new fetcher -// instance to handle completion of the transfers. -// -// - (void)application:(UIApplication *)application -// handleEventsForBackgroundURLSession:(NSString *)identifier -// completionHandler:(void (^)())completionHandler { -// // Application was re-launched on completing an out-of-process download. -// -// // Pass the URLSession info related to this re-launch to the fetcher class. -// [GTMSessionFetcher application:application -// handleEventsForBackgroundURLSession:identifier -// completionHandler:completionHandler]; -// -// // Get a fetcher related to this re-launch and re-hook up a completionHandler to it. -// GTMSessionFetcher *fetcher = [GTMSessionFetcher fetcherWithSessionIdentifier:identifier]; -// NSURL *destinationFileURL = fetcher.destinationFileURL; -// fetcher.completionHandler = ^(NSData *data, NSError *error) { -// [self downloadCompletedToFile:destinationFileURL error:error]; -// }; -// } -// -// -// Threading and queue support: -// -// Networking always happens on a background thread; there is no advantage to -// changing thread or queue to create or start a fetcher. -// -// Callbacks are run on the main thread; alternatively, the app may set the -// fetcher's callbackQueue to a dispatch queue. -// -// Once the fetcher's beginFetch method has been called, the fetcher's methods and -// properties may be accessed from any thread. -// -// Downloading to disk: -// -// To have downloaded data saved directly to disk, specify a file URL for the -// destinationFileURL property. -// -// HTTP methods and headers: -// -// Alternative HTTP methods, like PUT, and custom headers can be specified by -// creating the fetcher with an appropriate NSMutableURLRequest. -// -// -// Caching: -// -// The fetcher avoids caching. That is best for API requests, but may hurt -// repeat fetches of static data. Apps may enable a persistent disk cache by -// customizing the config: -// -// fetcher.configurationBlock = ^(GTMSessionFetcher *configFetcher, -// NSURLSessionConfiguration *config) { -// config.URLCache = [NSURLCache sharedURLCache]; -// }; -// -// Or use the standard system config to share cookie storage with web views -// and to enable disk caching: -// -// fetcher.configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; -// -// -// Cookies: -// -// There are three supported mechanisms for remembering cookies between fetches. -// -// By default, a standalone GTMSessionFetcher uses a mutable array held -// statically to track cookies for all instantiated fetchers. This avoids -// cookies being set by servers for the application from interfering with -// Safari and WebKit cookie settings, and vice versa. -// The fetcher cookies are lost when the application quits. -// -// To rely instead on WebKit's global NSHTTPCookieStorage, set the fetcher's -// cookieStorage property: -// myFetcher.cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; -// -// To share cookies with other apps, use the method introduced in iOS 9/OS X 10.11: -// myFetcher.cookieStorage = -// [NSHTTPCookieStorage sharedCookieStorageForGroupContainerIdentifier:kMyCompanyContainedID]; -// -// To ignore existing cookies and only have cookies related to the single fetch -// be applied, make a temporary cookie storage object: -// myFetcher.cookieStorage = [[GTMSessionCookieStorage alloc] init]; -// -// Note: cookies set while following redirects will be sent to the server, as -// the redirects are followed by the fetcher. -// -// To completely disable cookies, similar to setting cookieStorageMethod to -// kGTMHTTPFetcherCookieStorageMethodNone, adjust the session configuration -// appropriately in the fetcher or fetcher service: -// fetcher.configurationBlock = ^(GTMSessionFetcher *configFetcher, -// NSURLSessionConfiguration *config) { -// config.HTTPCookieAcceptPolicy = NSHTTPCookieAcceptPolicyNever; -// config.HTTPShouldSetCookies = NO; -// }; -// -// If the fetcher is created from a GTMSessionFetcherService object -// then the cookie storage mechanism is set to use the cookie storage in the -// service object rather than the static storage. Disabling cookies in the -// session configuration set on a service object will disable cookies for all -// fetchers created from that GTMSessionFetcherService object, since the session -// configuration is propagated to the fetcher. -// -// -// Monitoring data transfers. -// -// The fetcher supports a variety of properties for progress monitoring -// progress with callback blocks. -// GTMSessionFetcherSendProgressBlock sendProgressBlock -// GTMSessionFetcherReceivedProgressBlock receivedProgressBlock -// GTMSessionFetcherDownloadProgressBlock downloadProgressBlock -// -// If supplied by the server, the anticipated total download size is available -// as [[myFetcher response] expectedContentLength] (and may be -1 for unknown -// download sizes.) -// -// -// Automatic retrying of fetches -// -// The fetcher can optionally create a timer and reattempt certain kinds of -// fetch failures (status codes 408, request timeout; 502, gateway failure; -// 503, service unavailable; 504, gateway timeout; networking errors -// NSURLErrorTimedOut and NSURLErrorNetworkConnectionLost.) The user may -// set a retry selector to customize the type of errors which will be retried. -// -// Retries are done in an exponential-backoff fashion (that is, after 1 second, -// 2, 4, 8, and so on.) -// -// Enabling automatic retries looks like this: -// myFetcher.retryEnabled = YES; -// -// With retries enabled, the completion callbacks are called only -// when no more retries will be attempted. Calling the fetcher's stopFetching -// method will terminate the retry timer, without the finished or failure -// selectors being invoked. -// -// Optionally, the client may set the maximum retry interval: -// myFetcher.maxRetryInterval = 60.0; // in seconds; default is 60 seconds -// // for downloads, 600 for uploads -// -// Servers should never send a 400 or 500 status for errors that are retryable -// by clients, as those values indicate permanent failures. In nearly all -// cases, the default standard retry behavior is correct for clients, and no -// custom client retry behavior is needed or appropriate. Servers that send -// non-retryable status codes and expect the client to retry the request are -// faulty. -// -// Still, the client may provide a block to determine if a status code or other -// error should be retried. The block returns YES to set the retry timer or NO -// to fail without additional fetch attempts. -// -// The retry method may return the |suggestedWillRetry| argument to get the -// default retry behavior. Server status codes are present in the -// error argument, and have the domain kGTMSessionFetcherStatusDomain. The -// user's method may look something like this: -// -// myFetcher.retryBlock = ^(BOOL suggestedWillRetry, NSError *error, -// GTMSessionFetcherRetryResponse response) { -// // Perhaps examine error.domain and error.code, or fetcher.retryCount -// // -// // Respond with YES to start the retry timer, NO to proceed to the failure -// // callback, or suggestedWillRetry to get default behavior for the -// // current error domain and code values. -// response(suggestedWillRetry); -// }; - - -#import <Foundation/Foundation.h> - -#if TARGET_OS_IPHONE -#import <UIKit/UIKit.h> -#endif -#if TARGET_OS_WATCH -#import <WatchKit/WatchKit.h> -#endif - -// By default it is stripped from non DEBUG builds. Developers can override -// this in their project settings. -#ifndef STRIP_GTM_FETCH_LOGGING - #if !DEBUG - #define STRIP_GTM_FETCH_LOGGING 1 - #else - #define STRIP_GTM_FETCH_LOGGING 0 - #endif -#endif - -// Logs in debug builds. -#ifndef GTMSESSION_LOG_DEBUG - #if DEBUG - #define GTMSESSION_LOG_DEBUG(...) NSLog(__VA_ARGS__) - #else - #define GTMSESSION_LOG_DEBUG(...) do { } while (0) - #endif -#endif - -// Asserts in debug builds (or logs in debug builds if GTMSESSION_ASSERT_AS_LOG -// or NS_BLOCK_ASSERTIONS are defined.) -#ifndef GTMSESSION_ASSERT_DEBUG - #if DEBUG && !defined(NS_BLOCK_ASSERTIONS) && !GTMSESSION_ASSERT_AS_LOG - #undef GTMSESSION_ASSERT_AS_LOG - #define GTMSESSION_ASSERT_AS_LOG 1 - #endif - - #if DEBUG && !GTMSESSION_ASSERT_AS_LOG - #define GTMSESSION_ASSERT_DEBUG(...) NSAssert(__VA_ARGS__) - #elif DEBUG - #define GTMSESSION_ASSERT_DEBUG(pred, ...) if (!(pred)) { NSLog(__VA_ARGS__); } - #else - #define GTMSESSION_ASSERT_DEBUG(pred, ...) do { } while (0) - #endif -#endif - -// Asserts in debug builds, logs in release builds (or logs in debug builds if -// GTMSESSION_ASSERT_AS_LOG is defined.) -#ifndef GTMSESSION_ASSERT_DEBUG_OR_LOG - #if DEBUG && !GTMSESSION_ASSERT_AS_LOG - #define GTMSESSION_ASSERT_DEBUG_OR_LOG(...) NSAssert(__VA_ARGS__) - #else - #define GTMSESSION_ASSERT_DEBUG_OR_LOG(pred, ...) if (!(pred)) { NSLog(__VA_ARGS__); } - #endif -#endif - -// Macro useful for examining messages from NSURLSession during debugging. -#if 0 -#define GTM_LOG_SESSION_DELEGATE(...) GTMSESSION_LOG_DEBUG(__VA_ARGS__) -#else -#define GTM_LOG_SESSION_DELEGATE(...) -#endif - -#ifndef GTM_NULLABLE - #if __has_feature(nullability) // Available starting in Xcode 6.3 - #define GTM_NULLABLE_TYPE __nullable - #define GTM_NONNULL_TYPE __nonnull - #define GTM_NULLABLE nullable - #define GTM_NONNULL_DECL nonnull // GTM_NONNULL is used by GTMDefines.h - #define GTM_NULL_RESETTABLE null_resettable - - #define GTM_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN - #define GTM_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END - #else - #define GTM_NULLABLE_TYPE - #define GTM_NONNULL_TYPE - #define GTM_NULLABLE - #define GTM_NONNULL_DECL - #define GTM_NULL_RESETTABLE - #define GTM_ASSUME_NONNULL_BEGIN - #define GTM_ASSUME_NONNULL_END - #endif // __has_feature(nullability) -#endif // GTM_NULLABLE - -#if (TARGET_OS_TV \ - || TARGET_OS_WATCH \ - || (!TARGET_OS_IPHONE && defined(MAC_OS_X_VERSION_10_12) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_12) \ - || (TARGET_OS_IPHONE && defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0)) -#define GTMSESSION_DEPRECATE_ON_2016_SDKS(_MSG) __attribute__((deprecated("" _MSG))) -#else -#define GTMSESSION_DEPRECATE_ON_2016_SDKS(_MSG) -#endif - -#ifndef GTM_DECLARE_GENERICS - #if __has_feature(objc_generics) - #define GTM_DECLARE_GENERICS 1 - #else - #define GTM_DECLARE_GENERICS 0 - #endif -#endif - -#ifndef GTM_NSArrayOf - #if GTM_DECLARE_GENERICS - #define GTM_NSArrayOf(value) NSArray<value> - #define GTM_NSDictionaryOf(key, value) NSDictionary<key, value> - #else - #define GTM_NSArrayOf(value) NSArray - #define GTM_NSDictionaryOf(key, value) NSDictionary - #endif // __has_feature(objc_generics) -#endif // GTM_NSArrayOf - -// For iOS, the fetcher can declare itself a background task to allow fetches -// to finish when the app leaves the foreground. -// -// (This is unrelated to providing a background configuration, which allows -// out-of-process uploads and downloads.) -// -// To disallow use of background tasks during fetches, the target should define -// GTM_BACKGROUND_TASK_FETCHING to 0, or alternatively may set the -// skipBackgroundTask property to YES. -#if TARGET_OS_IPHONE && !TARGET_OS_WATCH && !defined(GTM_BACKGROUND_TASK_FETCHING) - #define GTM_BACKGROUND_TASK_FETCHING 1 -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#if (TARGET_OS_TV \ - || TARGET_OS_WATCH \ - || (!TARGET_OS_IPHONE && defined(MAC_OS_X_VERSION_10_11) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11) \ - || (TARGET_OS_IPHONE && defined(__IPHONE_9_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0)) - #ifndef GTM_USE_SESSION_FETCHER - #define GTM_USE_SESSION_FETCHER 1 - #endif -#endif - -#if !defined(GTMBridgeFetcher) - // These bridge macros should be identical in GTMHTTPFetcher.h and GTMSessionFetcher.h - #if GTM_USE_SESSION_FETCHER - // Macros to new fetcher class. - #define GTMBridgeFetcher GTMSessionFetcher - #define GTMBridgeFetcherService GTMSessionFetcherService - #define GTMBridgeFetcherServiceProtocol GTMSessionFetcherServiceProtocol - #define GTMBridgeAssertValidSelector GTMSessionFetcherAssertValidSelector - #define GTMBridgeCookieStorage GTMSessionCookieStorage - #define GTMBridgeCleanedUserAgentString GTMFetcherCleanedUserAgentString - #define GTMBridgeSystemVersionString GTMFetcherSystemVersionString - #define GTMBridgeApplicationIdentifier GTMFetcherApplicationIdentifier - #define kGTMBridgeFetcherStatusDomain kGTMSessionFetcherStatusDomain - #define kGTMBridgeFetcherStatusBadRequest GTMSessionFetcherStatusBadRequest - #else - // Macros to old fetcher class. - #define GTMBridgeFetcher GTMHTTPFetcher - #define GTMBridgeFetcherService GTMHTTPFetcherService - #define GTMBridgeFetcherServiceProtocol GTMHTTPFetcherServiceProtocol - #define GTMBridgeAssertValidSelector GTMAssertSelectorNilOrImplementedWithArgs - #define GTMBridgeCookieStorage GTMCookieStorage - #define GTMBridgeCleanedUserAgentString GTMCleanedUserAgentString - #define GTMBridgeSystemVersionString GTMSystemVersionString - #define GTMBridgeApplicationIdentifier GTMApplicationIdentifier - #define kGTMBridgeFetcherStatusDomain kGTMHTTPFetcherStatusDomain - #define kGTMBridgeFetcherStatusBadRequest kGTMHTTPFetcherStatusBadRequest - #endif // GTM_USE_SESSION_FETCHER -#endif - -GTM_ASSUME_NONNULL_BEGIN - -// Notifications -// -// Fetch started and stopped, and fetch retry delay started and stopped. -extern NSString *const kGTMSessionFetcherStartedNotification; -extern NSString *const kGTMSessionFetcherStoppedNotification; -extern NSString *const kGTMSessionFetcherRetryDelayStartedNotification; -extern NSString *const kGTMSessionFetcherRetryDelayStoppedNotification; - -// Completion handler notification. This is intended for use by code capturing -// and replaying fetch requests and results for testing. For fetches where -// destinationFileURL or accumulateDataBlock is set for the fetcher, the data -// will be nil for successful fetches. -// -// This notification is posted on the main thread. -extern NSString *const kGTMSessionFetcherCompletionInvokedNotification; -extern NSString *const kGTMSessionFetcherCompletionDataKey; -extern NSString *const kGTMSessionFetcherCompletionErrorKey; - -// Constants for NSErrors created by the fetcher (excluding server status errors, -// and error objects originating in the OS.) -extern NSString *const kGTMSessionFetcherErrorDomain; - -// The fetcher turns server error status values (3XX, 4XX, 5XX) into NSErrors -// with domain kGTMSessionFetcherStatusDomain. -// -// Any server response body data accompanying the status error is added to the -// userInfo dictionary with key kGTMSessionFetcherStatusDataKey. -extern NSString *const kGTMSessionFetcherStatusDomain; -extern NSString *const kGTMSessionFetcherStatusDataKey; -extern NSString *const kGTMSessionFetcherStatusDataContentTypeKey; - -// When a fetch fails with an error, these keys are included in the error userInfo -// dictionary if retries were attempted. -extern NSString *const kGTMSessionFetcherNumberOfRetriesDoneKey; -extern NSString *const kGTMSessionFetcherElapsedIntervalWithRetriesKey; - -// Background session support requires access to NSUserDefaults. -// If [NSUserDefaults standardUserDefaults] doesn't yield the correct NSUserDefaults for your usage, -// ie for an App Extension, then implement this class/method to return the correct NSUserDefaults. -// https://developer.apple.com/library/ios/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html#//apple_ref/doc/uid/TP40014214-CH21-SW6 -@interface GTMSessionFetcherUserDefaultsFactory : NSObject - -+ (NSUserDefaults *)fetcherUserDefaults; - -@end - -#ifdef __cplusplus -} -#endif - -typedef NS_ENUM(NSInteger, GTMSessionFetcherError) { - GTMSessionFetcherErrorDownloadFailed = -1, - GTMSessionFetcherErrorUploadChunkUnavailable = -2, - GTMSessionFetcherErrorBackgroundExpiration = -3, - GTMSessionFetcherErrorBackgroundFetchFailed = -4, - GTMSessionFetcherErrorInsecureRequest = -5, - GTMSessionFetcherErrorTaskCreationFailed = -6, -}; - -typedef NS_ENUM(NSInteger, GTMSessionFetcherStatus) { - // Standard http status codes. - GTMSessionFetcherStatusNotModified = 304, - GTMSessionFetcherStatusBadRequest = 400, - GTMSessionFetcherStatusUnauthorized = 401, - GTMSessionFetcherStatusForbidden = 403, - GTMSessionFetcherStatusPreconditionFailed = 412 -}; - -#ifdef __cplusplus -extern "C" { -#endif - -@class GTMSessionCookieStorage; -@class GTMSessionFetcher; - -// The configuration block is for modifying the NSURLSessionConfiguration only. -// DO NOT change any fetcher properties in the configuration block. -typedef void (^GTMSessionFetcherConfigurationBlock)(GTMSessionFetcher *fetcher, - NSURLSessionConfiguration *configuration); -typedef void (^GTMSessionFetcherSystemCompletionHandler)(void); -typedef void (^GTMSessionFetcherCompletionHandler)(NSData * GTM_NULLABLE_TYPE data, - NSError * GTM_NULLABLE_TYPE error); -typedef void (^GTMSessionFetcherBodyStreamProviderResponse)(NSInputStream *bodyStream); -typedef void (^GTMSessionFetcherBodyStreamProvider)(GTMSessionFetcherBodyStreamProviderResponse response); -typedef void (^GTMSessionFetcherDidReceiveResponseDispositionBlock)(NSURLSessionResponseDisposition disposition); -typedef void (^GTMSessionFetcherDidReceiveResponseBlock)(NSURLResponse *response, - GTMSessionFetcherDidReceiveResponseDispositionBlock dispositionBlock); -typedef void (^GTMSessionFetcherChallengeDispositionBlock)(NSURLSessionAuthChallengeDisposition disposition, - NSURLCredential * GTM_NULLABLE_TYPE credential); -typedef void (^GTMSessionFetcherChallengeBlock)(GTMSessionFetcher *fetcher, - NSURLAuthenticationChallenge *challenge, - GTMSessionFetcherChallengeDispositionBlock dispositionBlock); -typedef void (^GTMSessionFetcherWillRedirectResponse)(NSURLRequest * GTM_NULLABLE_TYPE redirectedRequest); -typedef void (^GTMSessionFetcherWillRedirectBlock)(NSHTTPURLResponse *redirectResponse, - NSURLRequest *redirectRequest, - GTMSessionFetcherWillRedirectResponse response); -typedef void (^GTMSessionFetcherAccumulateDataBlock)(NSData * GTM_NULLABLE_TYPE buffer); -typedef void (^GTMSessionFetcherSimulateByteTransferBlock)(NSData * GTM_NULLABLE_TYPE buffer, - int64_t bytesWritten, - int64_t totalBytesWritten, - int64_t totalBytesExpectedToWrite); -typedef void (^GTMSessionFetcherReceivedProgressBlock)(int64_t bytesWritten, - int64_t totalBytesWritten); -typedef void (^GTMSessionFetcherDownloadProgressBlock)(int64_t bytesWritten, - int64_t totalBytesWritten, - int64_t totalBytesExpectedToWrite); -typedef void (^GTMSessionFetcherSendProgressBlock)(int64_t bytesSent, - int64_t totalBytesSent, - int64_t totalBytesExpectedToSend); -typedef void (^GTMSessionFetcherWillCacheURLResponseResponse)(NSCachedURLResponse * GTM_NULLABLE_TYPE cachedResponse); -typedef void (^GTMSessionFetcherWillCacheURLResponseBlock)(NSCachedURLResponse *proposedResponse, - GTMSessionFetcherWillCacheURLResponseResponse responseBlock); -typedef void (^GTMSessionFetcherRetryResponse)(BOOL shouldRetry); -typedef void (^GTMSessionFetcherRetryBlock)(BOOL suggestedWillRetry, - NSError * GTM_NULLABLE_TYPE error, - GTMSessionFetcherRetryResponse response); - -typedef void (^GTMSessionFetcherTestResponse)(NSHTTPURLResponse * GTM_NULLABLE_TYPE response, - NSData * GTM_NULLABLE_TYPE data, - NSError * GTM_NULLABLE_TYPE error); -typedef void (^GTMSessionFetcherTestBlock)(GTMSessionFetcher *fetcherToTest, - GTMSessionFetcherTestResponse testResponse); - -void GTMSessionFetcherAssertValidSelector(id GTM_NULLABLE_TYPE obj, SEL GTM_NULLABLE_TYPE sel, ...); - -// Utility functions for applications self-identifying to servers via a -// user-agent header - -// The "standard" user agent includes the application identifier, taken from the bundle, -// followed by a space and the system version string. Pass nil to use +mainBundle as the source -// of the bundle identifier. -// -// Applications may use this as a starting point for their own user agent strings, perhaps -// with additional sections appended. Use GTMFetcherCleanedUserAgentString() below to -// clean up any string being added to the user agent. -NSString *GTMFetcherStandardUserAgentString(NSBundle * GTM_NULLABLE_TYPE bundle); - -// Make a generic name and version for the current application, like -// com.example.MyApp/1.2.3 relying on the bundle identifier and the -// CFBundleShortVersionString or CFBundleVersion. -// -// The bundle ID may be overridden as the base identifier string by -// adding to the bundle's Info.plist a "GTMUserAgentID" key. -// -// If no bundle ID or override is available, the process name preceded -// by "proc_" is used. -NSString *GTMFetcherApplicationIdentifier(NSBundle * GTM_NULLABLE_TYPE bundle); - -// Make an identifier like "MacOSX/10.7.1" or "iPod_Touch/4.1 hw/iPod1_1" -NSString *GTMFetcherSystemVersionString(void); - -// Make a parseable user-agent identifier from the given string, replacing whitespace -// and commas with underscores, and removing other characters that may interfere -// with parsing of the full user-agent string. -// -// For example, @"[My App]" would become @"My_App" -NSString *GTMFetcherCleanedUserAgentString(NSString *str); - -// Grab the data from an input stream. Since streams cannot be assumed to be rewindable, -// this may be destructive; the caller can try to rewind the stream (by setting the -// NSStreamFileCurrentOffsetKey property) or can just use the NSData to make a new -// NSInputStream. This function is intended to facilitate testing rather than be used in -// production. -// -// This function operates synchronously on the current thread. Depending on how the -// input stream is implemented, it may be appropriate to dispatch to a different -// queue before calling this function. -// -// Failure is indicated by a returned data value of nil. -NSData * GTM_NULLABLE_TYPE GTMDataFromInputStream(NSInputStream *inputStream, NSError **outError); - -#ifdef __cplusplus -} // extern "C" -#endif - - -#if !GTM_USE_SESSION_FETCHER -@protocol GTMHTTPFetcherServiceProtocol; -#endif - -// This protocol allows abstract references to the fetcher service, primarily for -// fetchers (which may be compiled without the fetcher service class present.) -// -// Apps should not need to use this protocol. -@protocol GTMSessionFetcherServiceProtocol <NSObject> -// This protocol allows us to call into the service without requiring -// GTMSessionFetcherService sources in this project - -@property(atomic, strong) dispatch_queue_t callbackQueue; - -- (BOOL)fetcherShouldBeginFetching:(GTMSessionFetcher *)fetcher; -- (void)fetcherDidCreateSession:(GTMSessionFetcher *)fetcher; -- (void)fetcherDidBeginFetching:(GTMSessionFetcher *)fetcher; -- (void)fetcherDidStop:(GTMSessionFetcher *)fetcher; - -- (GTMSessionFetcher *)fetcherWithRequest:(NSURLRequest *)request; -- (BOOL)isDelayingFetcher:(GTMSessionFetcher *)fetcher; - -@property(atomic, assign) BOOL reuseSession; -- (GTM_NULLABLE NSURLSession *)session; -- (GTM_NULLABLE NSURLSession *)sessionForFetcherCreation; -- (GTM_NULLABLE id<NSURLSessionDelegate>)sessionDelegate; -- (GTM_NULLABLE NSDate *)stoppedAllFetchersDate; - -// Methods for compatibility with the old GTMHTTPFetcher. -@property(readonly, strong, GTM_NULLABLE) NSOperationQueue *delegateQueue; - -@end // @protocol GTMSessionFetcherServiceProtocol - -#ifndef GTM_FETCHER_AUTHORIZATION_PROTOCOL -#define GTM_FETCHER_AUTHORIZATION_PROTOCOL 1 -@protocol GTMFetcherAuthorizationProtocol <NSObject> -@required -// This protocol allows us to call the authorizer without requiring its sources -// in this project. -- (void)authorizeRequest:(GTM_NULLABLE NSMutableURLRequest *)request - delegate:(id)delegate - didFinishSelector:(SEL)sel; - -- (void)stopAuthorization; - -- (void)stopAuthorizationForRequest:(NSURLRequest *)request; - -- (BOOL)isAuthorizingRequest:(NSURLRequest *)request; - -- (BOOL)isAuthorizedRequest:(NSURLRequest *)request; - -@property(strong, readonly, GTM_NULLABLE) NSString *userEmail; - -@optional - -// Indicate if authorization may be attempted. Even if this succeeds, -// authorization may fail if the user's permissions have been revoked. -@property(readonly) BOOL canAuthorize; - -// For development only, allow authorization of non-SSL requests, allowing -// transmission of the bearer token unencrypted. -@property(assign) BOOL shouldAuthorizeAllRequests; - -- (void)authorizeRequest:(GTM_NULLABLE NSMutableURLRequest *)request - completionHandler:(void (^)(NSError * GTM_NULLABLE_TYPE error))handler; - -#if GTM_USE_SESSION_FETCHER -@property (weak, GTM_NULLABLE) id<GTMSessionFetcherServiceProtocol> fetcherService; -#else -@property (weak, GTM_NULLABLE) id<GTMHTTPFetcherServiceProtocol> fetcherService; -#endif - -- (BOOL)primeForRefresh; - -@end -#endif // GTM_FETCHER_AUTHORIZATION_PROTOCOL - -#if GTM_BACKGROUND_TASK_FETCHING -// A protocol for an alternative target for messages from GTMSessionFetcher to UIApplication. -// Set the target using +[GTMSessionFetcher setSubstituteUIApplication:] -@protocol GTMUIApplicationProtocol <NSObject> -- (UIBackgroundTaskIdentifier)beginBackgroundTaskWithName:(nullable NSString *)taskName - expirationHandler:(void(^ __nullable)(void))handler; -- (void)endBackgroundTask:(UIBackgroundTaskIdentifier)identifier; -@end -#endif - -#pragma mark - - -// GTMSessionFetcher objects are used for async retrieval of an http get or post -// -// See additional comments at the beginning of this file -@interface GTMSessionFetcher : NSObject <NSURLSessionDelegate> - -// Create a fetcher -// -// fetcherWithRequest will return an autoreleased fetcher, but if -// the connection is successfully created, the connection should retain the -// fetcher for the life of the connection as well. So the caller doesn't have -// to retain the fetcher explicitly unless they want to be able to cancel it. -+ (instancetype)fetcherWithRequest:(GTM_NULLABLE NSURLRequest *)request; - -// Convenience methods that make a request, like +fetcherWithRequest -+ (instancetype)fetcherWithURL:(NSURL *)requestURL; -+ (instancetype)fetcherWithURLString:(NSString *)requestURLString; - -// Methods for creating fetchers to continue previous fetches. -+ (instancetype)fetcherWithDownloadResumeData:(NSData *)resumeData; -+ (GTM_NULLABLE instancetype)fetcherWithSessionIdentifier:(NSString *)sessionIdentifier; - -// Returns an array of currently active fetchers for background sessions, -// both restarted and newly created ones. -+ (GTM_NSArrayOf(GTMSessionFetcher *) *)fetchersForBackgroundSessions; - -// Designated initializer. -// -// Applications should create fetchers with a "fetcherWith..." method on a fetcher -// service or a class method, not with this initializer. -// -// The configuration should typically be nil. Applications needing to customize -// the configuration may do so by setting the configurationBlock property. -- (instancetype)initWithRequest:(GTM_NULLABLE NSURLRequest *)request - configuration:(GTM_NULLABLE NSURLSessionConfiguration *)configuration; - -// The fetcher's request. This may not be set after beginFetch has been invoked. The request -// may change due to redirects. -@property(strong, GTM_NULLABLE) NSURLRequest *request; - -// Set a header field value on the request. Header field value changes will not -// affect a fetch after the fetch has begun. -- (void)setRequestValue:(GTM_NULLABLE NSString *)value forHTTPHeaderField:(NSString *)field; - -// Data used for resuming a download task. -@property(atomic, readonly, GTM_NULLABLE) NSData *downloadResumeData; - -// The configuration; this must be set before the fetch begins. If no configuration is -// set or inherited from the fetcher service, then the fetcher uses an ephemeral config. -// -// NOTE: This property should typically be nil. Applications needing to customize -// the configuration should do so by setting the configurationBlock property. -// That allows the fetcher to pick an appropriate base configuration, with the -// application setting only the configuration properties it needs to customize. -@property(atomic, strong, GTM_NULLABLE) NSURLSessionConfiguration *configuration; - -// A block the client may use to customize the configuration used to create the session. -// -// This is called synchronously, either on the thread that begins the fetch or, during a retry, -// on the main thread. The configuration block may be called repeatedly if multiple fetchers are -// created. -// -// The configuration block is for modifying the NSURLSessionConfiguration only. -// DO NOT change any fetcher properties in the configuration block. Fetcher properties -// may be set in the fetcher service prior to fetcher creation, or on the fetcher prior -// to invoking beginFetch. -@property(atomic, copy, GTM_NULLABLE) GTMSessionFetcherConfigurationBlock configurationBlock; - -// A session is created as needed by the fetcher. A fetcher service object -// may maintain sessions for multiple fetches to the same host. -@property(atomic, strong, GTM_NULLABLE) NSURLSession *session; - -// The task in flight. -@property(atomic, readonly, GTM_NULLABLE) NSURLSessionTask *sessionTask; - -// The background session identifier. -@property(atomic, readonly, GTM_NULLABLE) NSString *sessionIdentifier; - -// Indicates a fetcher created to finish a background session task. -@property(atomic, readonly) BOOL wasCreatedFromBackgroundSession; - -// Additional user-supplied data to encode into the session identifier. Since session identifier -// length limits are unspecified, this should be kept small. Key names beginning with an underscore -// are reserved for use by the fetcher. -@property(atomic, strong, GTM_NULLABLE) GTM_NSDictionaryOf(NSString *, NSString *) *sessionUserInfo; - -// The human-readable description to be assigned to the task. -@property(atomic, copy, GTM_NULLABLE) NSString *taskDescription; - -// The priority assigned to the task, if any. Use NSURLSessionTaskPriorityLow, -// NSURLSessionTaskPriorityDefault, or NSURLSessionTaskPriorityHigh. -@property(atomic, assign) float taskPriority; - -// The fetcher encodes information used to resume a session in the session identifier. -// This method, intended for internal use returns the encoded information. The sessionUserInfo -// dictionary is stored as identifier metadata. -- (GTM_NULLABLE GTM_NSDictionaryOf(NSString *, NSString *) *)sessionIdentifierMetadata; - -#if TARGET_OS_IPHONE && !TARGET_OS_WATCH -// The app should pass to this method the completion handler passed in the app delegate method -// application:handleEventsForBackgroundURLSession:completionHandler: -+ (void)application:(UIApplication *)application - handleEventsForBackgroundURLSession:(NSString *)identifier - completionHandler:(GTMSessionFetcherSystemCompletionHandler)completionHandler; -#endif - -// Indicate that a newly created session should be a background session. -// A new session identifier will be created by the fetcher. -// -// Warning: The only thing background sessions are for is rare download -// of huge, batched files of data. And even just for those, there's a lot -// of pain and hackery needed to get transfers to actually happen reliably -// with background sessions. -// -// Don't try to upload or download in many background sessions, since the system -// will impose an exponentially increasing time penalty to prevent the app from -// getting too much background execution time. -// -// References: -// -// "Moving to Fewer, Larger Transfers" -// https://forums.developer.apple.com/thread/14853 -// -// "NSURLSession’s Resume Rate Limiter" -// https://forums.developer.apple.com/thread/14854 -// -// "Background Session Task state persistence" -// https://forums.developer.apple.com/thread/11554 -// -@property(assign) BOOL useBackgroundSession; - -// Indicates if the fetcher was started using a background session. -@property(atomic, readonly, getter=isUsingBackgroundSession) BOOL usingBackgroundSession; - -// Indicates if uploads should use an upload task. This is always set for file or stream-provider -// bodies, but may be set explicitly for NSData bodies. -@property(atomic, assign) BOOL useUploadTask; - -// Indicates that the fetcher is using a session that may be shared with other fetchers. -@property(atomic, readonly) BOOL canShareSession; - -// By default, the fetcher allows only secure (https) schemes unless this -// property is set, or the GTM_ALLOW_INSECURE_REQUESTS build flag is set. -// -// For example, during debugging when fetching from a development server that lacks SSL support, -// this may be set to @[ @"http" ], or when the fetcher is used to retrieve local files, -// this may be set to @[ @"file" ]. -// -// This should be left as nil for release builds to avoid creating the opportunity for -// leaking private user behavior and data. If a server is providing insecure URLs -// for fetching by the client app, report the problem as server security & privacy bug. -// -// For builds with the iOS 9/OS X 10.11 and later SDKs, this property is required only when -// the app specifies NSAppTransportSecurity/NSAllowsArbitraryLoads in the main bundle's Info.plist. -@property(atomic, copy, GTM_NULLABLE) GTM_NSArrayOf(NSString *) *allowedInsecureSchemes; - -// By default, the fetcher prohibits localhost requests unless this property is set, -// or the GTM_ALLOW_INSECURE_REQUESTS build flag is set. -// -// For localhost requests, the URL scheme is not checked when this property is set. -// -// For builds with the iOS 9/OS X 10.11 and later SDKs, this property is required only when -// the app specifies NSAppTransportSecurity/NSAllowsArbitraryLoads in the main bundle's Info.plist. -@property(atomic, assign) BOOL allowLocalhostRequest; - -// By default, the fetcher requires valid server certs. This may be bypassed -// temporarily for development against a test server with an invalid cert. -@property(atomic, assign) BOOL allowInvalidServerCertificates; - -// Cookie storage object for this fetcher. If nil, the fetcher will use a static cookie -// storage instance shared among fetchers. If this fetcher was created by a fetcher service -// object, it will be set to use the service object's cookie storage. See Cookies section above for -// the full discussion. -// -// Because as of Jan 2014 standalone instances of NSHTTPCookieStorage do not actually -// store any cookies (Radar 15735276) we use our own subclass, GTMSessionCookieStorage, -// to hold cookies in memory. -@property(atomic, strong, GTM_NULLABLE) NSHTTPCookieStorage *cookieStorage; - -// Setting the credential is optional; it is used if the connection receives -// an authentication challenge. -@property(atomic, strong, GTM_NULLABLE) NSURLCredential *credential; - -// Setting the proxy credential is optional; it is used if the connection -// receives an authentication challenge from a proxy. -@property(atomic, strong, GTM_NULLABLE) NSURLCredential *proxyCredential; - -// If body data, body file URL, or body stream provider is not set, then a GET request -// method is assumed. -@property(atomic, strong, GTM_NULLABLE) NSData *bodyData; - -// File to use as the request body. This forces use of an upload task. -@property(atomic, strong, GTM_NULLABLE) NSURL *bodyFileURL; - -// Length of body to send, expected or actual. -@property(atomic, readonly) int64_t bodyLength; - -// The body stream provider may be called repeatedly to provide a body. -// Setting a body stream provider forces use of an upload task. -@property(atomic, copy, GTM_NULLABLE) GTMSessionFetcherBodyStreamProvider bodyStreamProvider; - -// Object to add authorization to the request, if needed. -// -// This may not be changed once beginFetch has been invoked. -@property(atomic, strong, GTM_NULLABLE) id<GTMFetcherAuthorizationProtocol> authorizer; - -// The service object that created and monitors this fetcher, if any. -@property(atomic, strong) id<GTMSessionFetcherServiceProtocol> service; - -// The host, if any, used to classify this fetcher in the fetcher service. -@property(atomic, copy, GTM_NULLABLE) NSString *serviceHost; - -// The priority, if any, used for starting fetchers in the fetcher service. -// -// Lower values are higher priority; the default is 0, and values may -// be negative or positive. This priority affects only the start order of -// fetchers that are being delayed by a fetcher service when the running fetchers -// exceeds the service's maxRunningFetchersPerHost. A priority of NSIntegerMin will -// exempt this fetcher from delay. -@property(atomic, assign) NSInteger servicePriority; - -// The delegate's optional didReceiveResponse block may be used to inspect or alter -// the session task response. -// -// This is called on the callback queue. -@property(atomic, copy, GTM_NULLABLE) GTMSessionFetcherDidReceiveResponseBlock didReceiveResponseBlock; - -// The delegate's optional challenge block may be used to inspect or alter -// the session task challenge. -// -// If this block is not set, the fetcher's default behavior for the NSURLSessionTask -// didReceiveChallenge: delegate method is to use the fetcher's respondToChallenge: method -// which relies on the fetcher's credential and proxyCredential properties. -// -// Warning: This may be called repeatedly if the challenge fails. Check -// challenge.previousFailureCount to identify repeated invocations. -// -// This is called on the callback queue. -@property(atomic, copy, GTM_NULLABLE) GTMSessionFetcherChallengeBlock challengeBlock; - -// The delegate's optional willRedirect block may be used to inspect or alter -// the redirection. -// -// This is called on the callback queue. -@property(atomic, copy, GTM_NULLABLE) GTMSessionFetcherWillRedirectBlock willRedirectBlock; - -// The optional send progress block reports body bytes uploaded. -// -// This is called on the callback queue. -@property(atomic, copy, GTM_NULLABLE) GTMSessionFetcherSendProgressBlock sendProgressBlock; - -// The optional accumulate block may be set by clients wishing to accumulate data -// themselves rather than let the fetcher append each buffer to an NSData. -// -// When this is called with nil data (such as on redirect) the client -// should empty its accumulation buffer. -// -// This is called on the callback queue. -@property(atomic, copy, GTM_NULLABLE) GTMSessionFetcherAccumulateDataBlock accumulateDataBlock; - -// The optional received progress block may be used to monitor data -// received from a data task. -// -// This is called on the callback queue. -@property(atomic, copy, GTM_NULLABLE) GTMSessionFetcherReceivedProgressBlock receivedProgressBlock; - -// The delegate's optional downloadProgress block may be used to monitor download -// progress in writing to disk. -// -// This is called on the callback queue. -@property(atomic, copy, GTM_NULLABLE) GTMSessionFetcherDownloadProgressBlock downloadProgressBlock; - -// The delegate's optional willCacheURLResponse block may be used to alter the cached -// NSURLResponse. The user may prevent caching by passing nil to the block's response. -// -// This is called on the callback queue. -@property(atomic, copy, GTM_NULLABLE) GTMSessionFetcherWillCacheURLResponseBlock willCacheURLResponseBlock; - -// Enable retrying; see comments at the top of this file. Setting -// retryEnabled=YES resets the min and max retry intervals. -@property(atomic, assign, getter=isRetryEnabled) BOOL retryEnabled; - -// Retry block is optional for retries. -// -// If present, this block should call the response block with YES to cause a retry or NO to end the -// fetch. -// See comments at the top of this file. -@property(atomic, copy, GTM_NULLABLE) GTMSessionFetcherRetryBlock retryBlock; - -// Retry intervals must be strictly less than maxRetryInterval, else -// they will be limited to maxRetryInterval and no further retries will -// be attempted. Setting maxRetryInterval to 0.0 will reset it to the -// default value, 60 seconds for downloads and 600 seconds for uploads. -@property(atomic, assign) NSTimeInterval maxRetryInterval; - -// Starting retry interval. Setting minRetryInterval to 0.0 will reset it -// to a random value between 1.0 and 2.0 seconds. Clients should normally not -// set this except for unit testing. -@property(atomic, assign) NSTimeInterval minRetryInterval; - -// Multiplier used to increase the interval between retries, typically 2.0. -// Clients should not need to set this. -@property(atomic, assign) double retryFactor; - -// Number of retries attempted. -@property(atomic, readonly) NSUInteger retryCount; - -// Interval delay to precede next retry. -@property(atomic, readonly) NSTimeInterval nextRetryInterval; - -#if GTM_BACKGROUND_TASK_FETCHING -// Skip use of a UIBackgroundTask, thus requiring fetches to complete when the app is in the -// foreground. -// -// Targets should define GTM_BACKGROUND_TASK_FETCHING to 0 to avoid use of a UIBackgroundTask -// on iOS to allow fetches to complete in the background. This property is available when -// it's not practical to set the preprocessor define. -@property(atomic, assign) BOOL skipBackgroundTask; -#endif // GTM_BACKGROUND_TASK_FETCHING - -// Begin fetching the request -// -// The delegate may optionally implement the callback or pass nil for the selector or handler. -// -// The delegate and all callback blocks are retained between the beginFetch call until after the -// finish callback, or until the fetch is stopped. -// -// An error is passed to the callback for server statuses 300 or -// higher, with the status stored as the error object's code. -// -// finishedSEL has a signature like: -// - (void)fetcher:(GTMSessionFetcher *)fetcher -// finishedWithData:(NSData *)data -// error:(NSError *)error; -// -// If the application has specified a destinationFileURL or an accumulateDataBlock -// for the fetcher, the data parameter passed to the callback will be nil. - -- (void)beginFetchWithDelegate:(GTM_NULLABLE id)delegate - didFinishSelector:(GTM_NULLABLE SEL)finishedSEL; - -- (void)beginFetchWithCompletionHandler:(GTM_NULLABLE GTMSessionFetcherCompletionHandler)handler; - -// Returns YES if this fetcher is in the process of fetching a URL. -@property(atomic, readonly, getter=isFetching) BOOL fetching; - -// Cancel the fetch of the request that's currently in progress. The completion handler -// will not be called. -- (void)stopFetching; - -// A block to be called when the fetch completes. -@property(atomic, copy, GTM_NULLABLE) GTMSessionFetcherCompletionHandler completionHandler; - -// A block to be called if download resume data becomes available. -@property(atomic, strong, GTM_NULLABLE) void (^resumeDataBlock)(NSData *); - -// Return the status code from the server response. -@property(atomic, readonly) NSInteger statusCode; - -// Return the http headers from the response. -@property(atomic, strong, readonly, GTM_NULLABLE) GTM_NSDictionaryOf(NSString *, NSString *) *responseHeaders; - -// The response, once it's been received. -@property(atomic, strong, readonly, GTM_NULLABLE) NSURLResponse *response; - -// Bytes downloaded so far. -@property(atomic, readonly) int64_t downloadedLength; - -// Buffer of currently-downloaded data, if available. -@property(atomic, readonly, strong, GTM_NULLABLE) NSData *downloadedData; - -// Local path to which the downloaded file will be moved. -// -// If a file already exists at the path, it will be overwritten. -// Will create the enclosing folders if they are not present. -@property(atomic, strong, GTM_NULLABLE) NSURL *destinationFileURL; - -// The time this fetcher originally began fetching. This is useful as a time -// barrier for ignoring irrelevant fetch notifications or callbacks. -@property(atomic, strong, readonly, GTM_NULLABLE) NSDate *initialBeginFetchDate; - -// userData is retained solely for the convenience of the client. -@property(atomic, strong, GTM_NULLABLE) id userData; - -// Stored property values are retained solely for the convenience of the client. -@property(atomic, copy, GTM_NULLABLE) GTM_NSDictionaryOf(NSString *, id) *properties; - -- (void)setProperty:(GTM_NULLABLE id)obj forKey:(NSString *)key; // Pass nil for obj to remove the property. -- (GTM_NULLABLE id)propertyForKey:(NSString *)key; - -- (void)addPropertiesFromDictionary:(GTM_NSDictionaryOf(NSString *, id) *)dict; - -// Comments are useful for logging, so are strongly recommended for each fetcher. -@property(atomic, copy, GTM_NULLABLE) NSString *comment; - -- (void)setCommentWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1, 2); - -// Log of request and response, if logging is enabled -@property(atomic, copy, GTM_NULLABLE) NSString *log; - -// Callbacks are run on this queue. If none is supplied, the main queue is used. -@property(atomic, strong, GTM_NULL_RESETTABLE) dispatch_queue_t callbackQueue; - -// The queue used internally by the session to invoke its delegate methods in the fetcher. -// -// Application callbacks are always called by the fetcher on the callbackQueue above, -// not on this queue. Apps should generally not change this queue. -// -// The default delegate queue is the main queue. -// -// This value is ignored after the session has been created, so this -// property should be set in the fetcher service rather in the fetcher as it applies -// to a shared session. -@property(atomic, strong, GTM_NULL_RESETTABLE) NSOperationQueue *sessionDelegateQueue; - -// Spin the run loop or sleep the thread, discarding events, until the fetch has completed. -// -// This is only for use in testing or in tools without a user interface. -// -// Note: Synchronous fetches should never be used by shipping apps; they are -// sufficient reason for rejection from the app store. -// -// Returns NO if timed out. -- (BOOL)waitForCompletionWithTimeout:(NSTimeInterval)timeoutInSeconds; - -// Test block is optional for testing. -// -// If present, this block will cause the fetcher to skip starting the session, and instead -// use the test block response values when calling the completion handler and delegate code. -// -// Test code can set this on the fetcher or on the fetcher service. For testing libraries -// that use a fetcher without exposing either the fetcher or the fetcher service, the global -// method setGlobalTestBlock: will set the block for all fetchers that do not have a test -// block set. -// -// The test code can pass nil for all response parameters to indicate that the fetch -// should proceed. -// -// Applications can exclude test block support by setting GTM_DISABLE_FETCHER_TEST_BLOCK. -@property(atomic, copy, GTM_NULLABLE) GTMSessionFetcherTestBlock testBlock; - -+ (void)setGlobalTestBlock:(GTM_NULLABLE GTMSessionFetcherTestBlock)block; - -// When using the testBlock, |testBlockAccumulateDataChunkCount| is the desired number of chunks to -// divide the response data into if the client has streaming enabled. The data will be divided up to -// |testBlockAccumulateDataChunkCount| chunks; however, the exact amount may vary depending on the -// size of the response data (e.g. a 1-byte response can only be divided into one chunk). -@property(atomic, readwrite) NSUInteger testBlockAccumulateDataChunkCount; - -#if GTM_BACKGROUND_TASK_FETCHING -// For testing or to override UIApplication invocations, apps may specify an alternative -// target for messages to UIApplication. -+ (void)setSubstituteUIApplication:(nullable id<GTMUIApplicationProtocol>)substituteUIApplication; -+ (nullable id<GTMUIApplicationProtocol>)substituteUIApplication; -#endif // GTM_BACKGROUND_TASK_FETCHING - -// Exposed for testing. -+ (GTMSessionCookieStorage *)staticCookieStorage; -+ (BOOL)appAllowsInsecureRequests; - -#if STRIP_GTM_FETCH_LOGGING -// If logging is stripped, provide a stub for the main method -// for controlling logging. -+ (void)setLoggingEnabled:(BOOL)flag; -+ (BOOL)isLoggingEnabled; - -#else - -// These methods let an application log specific body text, such as the text description of a binary -// request or response. The application should set the fetcher to defer response body logging until -// the response has been received and the log response body has been set by the app. For example: -// -// fetcher.logRequestBody = [binaryObject stringDescription]; -// fetcher.deferResponseBodyLogging = YES; -// [fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error) { -// if (error == nil) { -// fetcher.logResponseBody = [[[MyThing alloc] initWithData:data] stringDescription]; -// } -// fetcher.deferResponseBodyLogging = NO; -// }]; - -@property(atomic, copy, GTM_NULLABLE) NSString *logRequestBody; -@property(atomic, assign) BOOL deferResponseBodyLogging; -@property(atomic, copy, GTM_NULLABLE) NSString *logResponseBody; - -// Internal logging support. -@property(atomic, readonly) NSData *loggedStreamData; -@property(atomic, assign) BOOL hasLoggedError; -@property(atomic, strong, GTM_NULLABLE) NSURL *redirectedFromURL; -- (void)appendLoggedStreamData:(NSData *)dataToAdd; -- (void)clearLoggedStreamData; - -#endif // STRIP_GTM_FETCH_LOGGING - -@end - -@interface GTMSessionFetcher (BackwardsCompatibilityOnly) -// Clients using GTMSessionFetcher should set the cookie storage explicitly themselves. -// This method is just for compatibility with the old GTMHTTPFetcher class. -- (void)setCookieStorageMethod:(NSInteger)method; -@end - -// Until we can just instantiate NSHTTPCookieStorage for local use, we'll -// implement all the public methods ourselves. This stores cookies only in -// memory. Additional methods are provided for testing. -// -// iOS 9/OS X 10.11 added +[NSHTTPCookieStorage sharedCookieStorageForGroupContainerIdentifier:] -// which may also be used to create cookie storage. -@interface GTMSessionCookieStorage : NSHTTPCookieStorage - -// Add the array off cookies to the storage, replacing duplicates. -// Also removes expired cookies from the storage. -- (void)setCookies:(GTM_NULLABLE GTM_NSArrayOf(NSHTTPCookie *) *)cookies; - -- (void)removeAllCookies; - -@end - -// Macros to monitor synchronization blocks in debug builds. -// These report problems using GTMSessionCheckDebug. -// -// GTMSessionMonitorSynchronized Start monitoring a top-level-only -// @sync scope. -// GTMSessionMonitorRecursiveSynchronized Start monitoring a top-level or -// recursive @sync scope. -// GTMSessionCheckSynchronized Verify that the current execution -// is inside a @sync scope. -// GTMSessionCheckNotSynchronized Verify that the current execution -// is not inside a @sync scope. -// -// Example usage: -// -// - (void)myExternalMethod { -// @synchronized(self) { -// GTMSessionMonitorSynchronized(self) -// -// - (void)myInternalMethod { -// GTMSessionCheckSynchronized(self); -// -// - (void)callMyCallbacks { -// GTMSessionCheckNotSynchronized(self); -// -// GTMSessionCheckNotSynchronized is available for verifying the code isn't -// in a deadlockable @sync state when posting notifications and invoking -// callbacks. Don't use GTMSessionCheckNotSynchronized immediately before a -// @sync scope; the normal recursiveness check of GTMSessionMonitorSynchronized -// can catch those. - -#ifdef __OBJC__ -// If asserts are entirely no-ops, the synchronization monitor is just a bunch -// of counting code that doesn't report exceptional circumstances in any way. -// Only build the synchronization monitor code if NS_BLOCK_ASSERTIONS is not -// defined or asserts are being logged instead. -#if DEBUG && (!defined(NS_BLOCK_ASSERTIONS) || GTMSESSION_ASSERT_AS_LOG) - #define __GTMSessionMonitorSynchronizedVariableInner(varname, counter) \ - varname ## counter - #define __GTMSessionMonitorSynchronizedVariable(varname, counter) \ - __GTMSessionMonitorSynchronizedVariableInner(varname, counter) - - #define GTMSessionMonitorSynchronized(obj) \ - NS_VALID_UNTIL_END_OF_SCOPE id \ - __GTMSessionMonitorSynchronizedVariable(__monitor, __COUNTER__) = \ - [[GTMSessionSyncMonitorInternal alloc] initWithSynchronizationObject:obj \ - allowRecursive:NO \ - functionName:__func__] - - #define GTMSessionMonitorRecursiveSynchronized(obj) \ - NS_VALID_UNTIL_END_OF_SCOPE id \ - __GTMSessionMonitorSynchronizedVariable(__monitor, __COUNTER__) = \ - [[GTMSessionSyncMonitorInternal alloc] initWithSynchronizationObject:obj \ - allowRecursive:YES \ - functionName:__func__] - - #define GTMSessionCheckSynchronized(obj) { \ - GTMSESSION_ASSERT_DEBUG( \ - [GTMSessionSyncMonitorInternal functionsHoldingSynchronizationOnObject:obj], \ - @"GTMSessionCheckSynchronized(" #obj ") failed: not sync'd" \ - @" on " #obj " in %s. Call stack:\n%@", \ - __func__, [NSThread callStackSymbols]); \ - } - - #define GTMSessionCheckNotSynchronized(obj) { \ - GTMSESSION_ASSERT_DEBUG( \ - ![GTMSessionSyncMonitorInternal functionsHoldingSynchronizationOnObject:obj], \ - @"GTMSessionCheckNotSynchronized(" #obj ") failed: was sync'd" \ - @" on " #obj " in %s by %@. Call stack:\n%@", __func__, \ - [GTMSessionSyncMonitorInternal functionsHoldingSynchronizationOnObject:obj], \ - [NSThread callStackSymbols]); \ - } - -// GTMSessionSyncMonitorInternal is a private class that keeps track of the -// beginning and end of synchronized scopes. -// -// This class should not be used directly, but only via the -// GTMSessionMonitorSynchronized macro. -@interface GTMSessionSyncMonitorInternal : NSObject -- (instancetype)initWithSynchronizationObject:(id)object - allowRecursive:(BOOL)allowRecursive - functionName:(const char *)functionName; -// Return the names of the functions that hold sync on the object, or nil if none. -+ (NSArray *)functionsHoldingSynchronizationOnObject:(id)object; -@end - -#else - #define GTMSessionMonitorSynchronized(obj) do { } while (0) - #define GTMSessionMonitorRecursiveSynchronized(obj) do { } while (0) - #define GTMSessionCheckSynchronized(obj) do { } while (0) - #define GTMSessionCheckNotSynchronized(obj) do { } while (0) -#endif // !DEBUG -#endif // __OBJC__ - - -GTM_ASSUME_NONNULL_END diff --git a/Pods/GTMSessionFetcher/Source/GTMSessionFetcher.m b/Pods/GTMSessionFetcher/Source/GTMSessionFetcher.m @@ -1,4579 +0,0 @@ -/* Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -#import "GTMSessionFetcher.h" - -#import <sys/utsname.h> - -#ifndef STRIP_GTM_FETCH_LOGGING - #error GTMSessionFetcher headers should have defaulted this if it wasn't already defined. -#endif - -GTM_ASSUME_NONNULL_BEGIN - -NSString *const kGTMSessionFetcherStartedNotification = @"kGTMSessionFetcherStartedNotification"; -NSString *const kGTMSessionFetcherStoppedNotification = @"kGTMSessionFetcherStoppedNotification"; -NSString *const kGTMSessionFetcherRetryDelayStartedNotification = @"kGTMSessionFetcherRetryDelayStartedNotification"; -NSString *const kGTMSessionFetcherRetryDelayStoppedNotification = @"kGTMSessionFetcherRetryDelayStoppedNotification"; - -NSString *const kGTMSessionFetcherCompletionInvokedNotification = @"kGTMSessionFetcherCompletionInvokedNotification"; -NSString *const kGTMSessionFetcherCompletionDataKey = @"data"; -NSString *const kGTMSessionFetcherCompletionErrorKey = @"error"; - -NSString *const kGTMSessionFetcherErrorDomain = @"com.google.GTMSessionFetcher"; -NSString *const kGTMSessionFetcherStatusDomain = @"com.google.HTTPStatus"; -NSString *const kGTMSessionFetcherStatusDataKey = @"data"; // data returned with a kGTMSessionFetcherStatusDomain error -NSString *const kGTMSessionFetcherStatusDataContentTypeKey = @"data_content_type"; - -NSString *const kGTMSessionFetcherNumberOfRetriesDoneKey = @"kGTMSessionFetcherNumberOfRetriesDoneKey"; -NSString *const kGTMSessionFetcherElapsedIntervalWithRetriesKey = @"kGTMSessionFetcherElapsedIntervalWithRetriesKey"; - -static NSString *const kGTMSessionIdentifierPrefix = @"com.google.GTMSessionFetcher"; -static NSString *const kGTMSessionIdentifierDestinationFileURLMetadataKey = @"_destURL"; -static NSString *const kGTMSessionIdentifierBodyFileURLMetadataKey = @"_bodyURL"; - -// The default max retry interview is 10 minutes for uploads (POST/PUT/PATCH), -// 1 minute for downloads. -static const NSTimeInterval kUnsetMaxRetryInterval = -1.0; -static const NSTimeInterval kDefaultMaxDownloadRetryInterval = 60.0; -static const NSTimeInterval kDefaultMaxUploadRetryInterval = 60.0 * 10.; - -// The maximum data length that can be loaded to the error userInfo -static const int64_t kMaximumDownloadErrorDataLength = 20000; - -#ifdef GTMSESSION_PERSISTED_DESTINATION_KEY -// Projects using unique class names should also define a unique persisted destination key. -static NSString * const kGTMSessionFetcherPersistedDestinationKey = - GTMSESSION_PERSISTED_DESTINATION_KEY; -#else -static NSString * const kGTMSessionFetcherPersistedDestinationKey = - @"com.google.GTMSessionFetcher.downloads"; -#endif - -GTM_ASSUME_NONNULL_END - -// -// GTMSessionFetcher -// - -#if 0 -#define GTM_LOG_BACKGROUND_SESSION(...) GTMSESSION_LOG_DEBUG(__VA_ARGS__) -#else -#define GTM_LOG_BACKGROUND_SESSION(...) -#endif - -#ifndef GTM_TARGET_SUPPORTS_APP_TRANSPORT_SECURITY - #if (TARGET_OS_TV \ - || TARGET_OS_WATCH \ - || (!TARGET_OS_IPHONE && defined(MAC_OS_X_VERSION_10_11) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11) \ - || (TARGET_OS_IPHONE && defined(__IPHONE_9_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0)) - #define GTM_TARGET_SUPPORTS_APP_TRANSPORT_SECURITY 1 - #endif -#endif - -@interface GTMSessionFetcher () - -@property(atomic, strong, readwrite, GTM_NULLABLE) NSData *downloadedData; -@property(atomic, strong, readwrite, GTM_NULLABLE) NSData *downloadResumeData; - -#if GTM_BACKGROUND_TASK_FETCHING -// Should always be accessed within an @synchronized(self). -@property(assign, nonatomic) UIBackgroundTaskIdentifier backgroundTaskIdentifier; -#endif - -@property(atomic, readwrite, getter=isUsingBackgroundSession) BOOL usingBackgroundSession; - -@end - -#if !GTMSESSION_BUILD_COMBINED_SOURCES -@interface GTMSessionFetcher (GTMSessionFetcherLoggingInternal) -- (void)logFetchWithError:(NSError *)error; -- (void)logNowWithError:(GTM_NULLABLE NSError *)error; -- (NSInputStream *)loggedInputStreamForInputStream:(NSInputStream *)inputStream; -- (GTMSessionFetcherBodyStreamProvider)loggedStreamProviderForStreamProvider: - (GTMSessionFetcherBodyStreamProvider)streamProvider; -@end -#endif // !GTMSESSION_BUILD_COMBINED_SOURCES - -GTM_ASSUME_NONNULL_BEGIN - -static NSTimeInterval InitialMinRetryInterval(void) { - return 1.0 + ((double)(arc4random_uniform(0x0FFFF)) / (double) 0x0FFFF); -} - -static BOOL IsLocalhost(NSString * GTM_NULLABLE_TYPE host) { - // We check if there's host, and then make the comparisons. - if (host == nil) return NO; - return ([host caseInsensitiveCompare:@"localhost"] == NSOrderedSame - || [host isEqual:@"::1"] - || [host isEqual:@"127.0.0.1"]); -} - -static NSDictionary *GTM_NULLABLE_TYPE GTMErrorUserInfoForData( - NSData *GTM_NULLABLE_TYPE data, NSDictionary *GTM_NULLABLE_TYPE responseHeaders) { - NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; - - if (data.length > 0) { - userInfo[kGTMSessionFetcherStatusDataKey] = data; - - NSString *contentType = responseHeaders[@"Content-Type"]; - if (contentType) { - userInfo[kGTMSessionFetcherStatusDataContentTypeKey] = contentType; - } - } - - return userInfo.count > 0 ? userInfo : nil; -} - -static GTMSessionFetcherTestBlock GTM_NULLABLE_TYPE gGlobalTestBlock; - -@implementation GTMSessionFetcher { - NSMutableURLRequest *_request; // after beginFetch, changed only in delegate callbacks - BOOL _useUploadTask; // immutable after beginFetch - NSURL *_bodyFileURL; // immutable after beginFetch - GTMSessionFetcherBodyStreamProvider _bodyStreamProvider; // immutable after beginFetch - NSURLSession *_session; - BOOL _shouldInvalidateSession; // immutable after beginFetch - NSURLSession *_sessionNeedingInvalidation; - NSURLSessionConfiguration *_configuration; - NSURLSessionTask *_sessionTask; - NSString *_taskDescription; - float _taskPriority; - NSURLResponse *_response; - NSString *_sessionIdentifier; - BOOL _wasCreatedFromBackgroundSession; - BOOL _didCreateSessionIdentifier; - NSString *_sessionIdentifierUUID; - BOOL _userRequestedBackgroundSession; - BOOL _usingBackgroundSession; - NSMutableData * GTM_NULLABLE_TYPE _downloadedData; - NSError *_downloadFinishedError; - NSData *_downloadResumeData; // immutable after construction - NSData * GTM_NULLABLE_TYPE _downloadTaskErrorData; // Data for when download task fails - NSURL *_destinationFileURL; - int64_t _downloadedLength; - NSURLCredential *_credential; // username & password - NSURLCredential *_proxyCredential; // credential supplied to proxy servers - BOOL _isStopNotificationNeeded; // set when start notification has been sent - BOOL _isUsingTestBlock; // set when a test block was provided (remains set when the block is released) - id _userData; // retained, if set by caller - NSMutableDictionary *_properties; // more data retained for caller - dispatch_queue_t _callbackQueue; - dispatch_group_t _callbackGroup; // read-only after creation - NSOperationQueue *_delegateQueue; // immutable after beginFetch - - id<GTMFetcherAuthorizationProtocol> _authorizer; // immutable after beginFetch - - // The service object that created and monitors this fetcher, if any. - id<GTMSessionFetcherServiceProtocol> _service; // immutable; set by the fetcher service upon creation - NSString *_serviceHost; - NSInteger _servicePriority; // immutable after beginFetch - BOOL _hasStoppedFetching; // counterpart to _initialBeginFetchDate - BOOL _userStoppedFetching; - - BOOL _isRetryEnabled; // user wants auto-retry - NSTimer *_retryTimer; - NSUInteger _retryCount; - NSTimeInterval _maxRetryInterval; // default 60 (download) or 600 (upload) seconds - NSTimeInterval _minRetryInterval; // random between 1 and 2 seconds - NSTimeInterval _retryFactor; // default interval multiplier is 2 - NSTimeInterval _lastRetryInterval; - NSDate *_initialBeginFetchDate; // date that beginFetch was first invoked; immutable after initial beginFetch - NSDate *_initialRequestDate; // date of first request to the target server (ignoring auth) - BOOL _hasAttemptedAuthRefresh; // accessed only in shouldRetryNowForStatus: - - NSString *_comment; // comment for log - NSString *_log; -#if !STRIP_GTM_FETCH_LOGGING - NSMutableData *_loggedStreamData; - NSURL *_redirectedFromURL; - NSString *_logRequestBody; - NSString *_logResponseBody; - BOOL _hasLoggedError; - BOOL _deferResponseBodyLogging; -#endif -} - -#if !GTMSESSION_UNIT_TESTING -+ (void)load { - [self fetchersForBackgroundSessions]; -} -#endif - -+ (instancetype)fetcherWithRequest:(GTM_NULLABLE NSURLRequest *)request { - return [[self alloc] initWithRequest:request configuration:nil]; -} - -+ (instancetype)fetcherWithURL:(NSURL *)requestURL { - return [self fetcherWithRequest:[NSURLRequest requestWithURL:requestURL]]; -} - -+ (instancetype)fetcherWithURLString:(NSString *)requestURLString { - return [self fetcherWithURL:(NSURL *)[NSURL URLWithString:requestURLString]]; -} - -+ (instancetype)fetcherWithDownloadResumeData:(NSData *)resumeData { - GTMSessionFetcher *fetcher = [self fetcherWithRequest:nil]; - fetcher.comment = @"Resuming download"; - fetcher.downloadResumeData = resumeData; - return fetcher; -} - -+ (GTM_NULLABLE instancetype)fetcherWithSessionIdentifier:(NSString *)sessionIdentifier { - GTMSESSION_ASSERT_DEBUG(sessionIdentifier != nil, @"Invalid session identifier"); - NSMapTable *sessionIdentifierToFetcherMap = [self sessionIdentifierToFetcherMap]; - GTMSessionFetcher *fetcher = [sessionIdentifierToFetcherMap objectForKey:sessionIdentifier]; - if (!fetcher && [sessionIdentifier hasPrefix:kGTMSessionIdentifierPrefix]) { - fetcher = [self fetcherWithRequest:nil]; - [fetcher setSessionIdentifier:sessionIdentifier]; - [sessionIdentifierToFetcherMap setObject:fetcher forKey:sessionIdentifier]; - fetcher->_wasCreatedFromBackgroundSession = YES; - [fetcher setCommentWithFormat:@"Resuming %@", - fetcher && fetcher->_sessionIdentifierUUID ? fetcher->_sessionIdentifierUUID : @"?"]; - } - return fetcher; -} - -+ (NSMapTable *)sessionIdentifierToFetcherMap { - // TODO: What if a service is involved in creating the fetcher? Currently, when re-creating - // fetchers, if a service was involved, it is not re-created. Should the service maintain a map? - static NSMapTable *gSessionIdentifierToFetcherMap = nil; - - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - gSessionIdentifierToFetcherMap = [NSMapTable strongToWeakObjectsMapTable]; - }); - return gSessionIdentifierToFetcherMap; -} - -#if !GTM_ALLOW_INSECURE_REQUESTS -+ (BOOL)appAllowsInsecureRequests { - // If the main bundle Info.plist key NSAppTransportSecurity is present, and it specifies - // NSAllowsArbitraryLoads, then we need to explicitly enforce secure schemes. -#if GTM_TARGET_SUPPORTS_APP_TRANSPORT_SECURITY - static BOOL allowsInsecureRequests; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSBundle *mainBundle = [NSBundle mainBundle]; - NSDictionary *appTransportSecurity = - [mainBundle objectForInfoDictionaryKey:@"NSAppTransportSecurity"]; - allowsInsecureRequests = - [[appTransportSecurity objectForKey:@"NSAllowsArbitraryLoads"] boolValue]; - }); - return allowsInsecureRequests; -#else - // For builds targeting iOS 8 or 10.10 and earlier, we want to require fetcher - // security checks. - return YES; -#endif // GTM_TARGET_SUPPORTS_APP_TRANSPORT_SECURITY -} -#else // GTM_ALLOW_INSECURE_REQUESTS -+ (BOOL)appAllowsInsecureRequests { - return YES; -} -#endif // !GTM_ALLOW_INSECURE_REQUESTS - - -- (instancetype)init { - return [self initWithRequest:nil configuration:nil]; -} - -- (instancetype)initWithRequest:(NSURLRequest *)request { - return [self initWithRequest:request configuration:nil]; -} - -- (instancetype)initWithRequest:(GTM_NULLABLE NSURLRequest *)request - configuration:(GTM_NULLABLE NSURLSessionConfiguration *)configuration { - self = [super init]; - if (self) { -#if GTM_BACKGROUND_TASK_FETCHING - _backgroundTaskIdentifier = UIBackgroundTaskInvalid; -#endif - _request = [request mutableCopy]; - _configuration = configuration; - - NSData *bodyData = request.HTTPBody; - if (bodyData) { - _bodyLength = (int64_t)bodyData.length; - } else { - _bodyLength = NSURLSessionTransferSizeUnknown; - } - - _callbackQueue = dispatch_get_main_queue(); - _callbackGroup = dispatch_group_create(); - _delegateQueue = [NSOperationQueue mainQueue]; - - _minRetryInterval = InitialMinRetryInterval(); - _maxRetryInterval = kUnsetMaxRetryInterval; - - _taskPriority = -1.0f; // Valid values if set are 0.0...1.0. - - _testBlockAccumulateDataChunkCount = 1; - -#if !STRIP_GTM_FETCH_LOGGING - // Encourage developers to set the comment property or use - // setCommentWithFormat: by providing a default string. - _comment = @"(No fetcher comment set)"; -#endif - } - return self; -} - -- (id)copyWithZone:(NSZone *)zone { - // disallow use of fetchers in a copy property - [self doesNotRecognizeSelector:_cmd]; - return nil; -} - -- (NSString *)description { - NSString *requestStr = self.request.URL.description; - if (requestStr.length == 0) { - if (self.downloadResumeData.length > 0) { - requestStr = @"<download resume data>"; - } else if (_wasCreatedFromBackgroundSession) { - requestStr = @"<from bg session>"; - } else { - requestStr = @"<no request>"; - } - } - return [NSString stringWithFormat:@"%@ %p (%@)", [self class], self, requestStr]; -} - -- (void)dealloc { - GTMSESSION_ASSERT_DEBUG(!_isStopNotificationNeeded, - @"unbalanced fetcher notification for %@", _request.URL); - [self forgetSessionIdentifierForFetcherWithoutSyncCheck]; - - // Note: if a session task or a retry timer was pending, then this instance - // would be retained by those so it wouldn't be getting dealloc'd, - // hence we don't need to stopFetch here -} - -#pragma mark - - -// Begin fetching the URL (or begin a retry fetch). The delegate is retained -// for the duration of the fetch connection. - -- (void)beginFetchWithCompletionHandler:(GTM_NULLABLE GTMSessionFetcherCompletionHandler)handler { - GTMSessionCheckNotSynchronized(self); - - _completionHandler = [handler copy]; - - // The user may have called setDelegate: earlier if they want to use other - // delegate-style callbacks during the fetch; otherwise, the delegate is nil, - // which is fine. - [self beginFetchMayDelay:YES mayAuthorize:YES]; -} - -// Begin fetching the URL for a retry fetch. The delegate and completion handler -// are already provided, and do not need to be copied. -- (void)beginFetchForRetry { - GTMSessionCheckNotSynchronized(self); - - [self beginFetchMayDelay:YES mayAuthorize:YES]; -} - -- (GTMSessionFetcherCompletionHandler)completionHandlerWithTarget:(GTM_NULLABLE_TYPE id)target - didFinishSelector:(GTM_NULLABLE_TYPE SEL)finishedSelector { - GTMSessionFetcherAssertValidSelector(target, finishedSelector, @encode(GTMSessionFetcher *), - @encode(NSData *), @encode(NSError *), 0); - GTMSessionFetcherCompletionHandler completionHandler = ^(NSData *data, NSError *error) { - if (target && finishedSelector) { - id selfArg = self; // Placate ARC. - NSMethodSignature *sig = [target methodSignatureForSelector:finishedSelector]; - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig]; - [invocation setSelector:(SEL)finishedSelector]; - [invocation setTarget:target]; - [invocation setArgument:&selfArg atIndex:2]; - [invocation setArgument:&data atIndex:3]; - [invocation setArgument:&error atIndex:4]; - [invocation invoke]; - } - }; - return completionHandler; -} - -- (void)beginFetchWithDelegate:(GTM_NULLABLE_TYPE id)target - didFinishSelector:(GTM_NULLABLE_TYPE SEL)finishedSelector { - GTMSessionCheckNotSynchronized(self); - - GTMSessionFetcherCompletionHandler handler = [self completionHandlerWithTarget:target - didFinishSelector:finishedSelector]; - [self beginFetchWithCompletionHandler:handler]; -} - -- (void)beginFetchMayDelay:(BOOL)mayDelay - mayAuthorize:(BOOL)mayAuthorize { - // This is the internal entry point for re-starting fetches. - GTMSessionCheckNotSynchronized(self); - - NSMutableURLRequest *fetchRequest = _request; // The request property is now externally immutable. - NSURL *fetchRequestURL = fetchRequest.URL; - NSString *priorSessionIdentifier = self.sessionIdentifier; - - // A utility block for creating error objects when we fail to start the fetch. - NSError *(^beginFailureError)(NSInteger) = ^(NSInteger code){ - NSString *urlString = fetchRequestURL.absoluteString; - NSDictionary *userInfo = @{ - NSURLErrorFailingURLStringErrorKey : (urlString ? urlString : @"(missing URL)") - }; - return [NSError errorWithDomain:kGTMSessionFetcherErrorDomain - code:code - userInfo:userInfo]; - }; - - // Catch delegate queue maxConcurrentOperationCount values other than 1, particularly - // NSOperationQueueDefaultMaxConcurrentOperationCount (-1), to avoid the additional complexity - // of simultaneous or out-of-order delegate callbacks. - GTMSESSION_ASSERT_DEBUG(_delegateQueue.maxConcurrentOperationCount == 1, - @"delegate queue %@ should support one concurrent operation, not %ld", - _delegateQueue.name, - (long)_delegateQueue.maxConcurrentOperationCount); - - if (!_initialBeginFetchDate) { - // This ivar is set only here on the initial beginFetch so need not be synchronized. - _initialBeginFetchDate = [[NSDate alloc] init]; - } - - if (self.sessionTask != nil) { - // If cached fetcher returned through fetcherWithSessionIdentifier:, then it's - // already begun, but don't consider this a failure, since the user need not know this. - if (self.sessionIdentifier != nil) { - return; - } - GTMSESSION_ASSERT_DEBUG(NO, @"Fetch object %@ being reused; this should never happen", self); - [self failToBeginFetchWithError:beginFailureError(GTMSessionFetcherErrorDownloadFailed)]; - return; - } - - if (fetchRequestURL == nil && !_downloadResumeData && !priorSessionIdentifier) { - GTMSESSION_ASSERT_DEBUG(NO, @"Beginning a fetch requires a request with a URL"); - [self failToBeginFetchWithError:beginFailureError(GTMSessionFetcherErrorDownloadFailed)]; - return; - } - - // We'll respect the user's request for a background session (unless this is - // an upload fetcher, which does its initial request foreground.) - self.usingBackgroundSession = self.useBackgroundSession && [self canFetchWithBackgroundSession]; - - NSURL *bodyFileURL = self.bodyFileURL; - if (bodyFileURL) { - NSError *fileCheckError; - if (![bodyFileURL checkResourceIsReachableAndReturnError:&fileCheckError]) { - // This assert fires when the file being uploaded no longer exists once - // the fetcher is ready to start the upload. - GTMSESSION_ASSERT_DEBUG_OR_LOG(0, @"Body file is unreachable: %@\n %@", - bodyFileURL.path, fileCheckError); - [self failToBeginFetchWithError:fileCheckError]; - return; - } - } - - NSString *requestScheme = fetchRequestURL.scheme; - BOOL isDataRequest = [requestScheme isEqual:@"data"]; - if (isDataRequest) { - // NSURLSession does not support data URLs in background sessions. -#if DEBUG - if (priorSessionIdentifier || self.sessionIdentifier) { - GTMSESSION_LOG_DEBUG(@"Converting background to foreground session for %@", - fetchRequest); - } -#endif - [self setSessionIdentifierInternal:nil]; - self.useBackgroundSession = NO; - } - -#if GTM_ALLOW_INSECURE_REQUESTS - BOOL shouldCheckSecurity = NO; -#else - BOOL shouldCheckSecurity = (fetchRequestURL != nil - && !isDataRequest - && [[self class] appAllowsInsecureRequests]); -#endif - - if (shouldCheckSecurity) { - // Allow https only for requests, unless overridden by the client. - // - // Non-https requests may too easily be snooped, so we disallow them by default. - // - // file: and data: schemes are usually safe if they are hardcoded in the client or provided - // by a trusted source, but since it's fairly rare to need them, it's safest to make clients - // explicitly whitelist them. - BOOL isSecure = - requestScheme != nil && [requestScheme caseInsensitiveCompare:@"https"] == NSOrderedSame; - if (!isSecure) { - BOOL allowRequest = NO; - NSString *host = fetchRequestURL.host; - - // Check schemes first. A file scheme request may be allowed here, or as a localhost request. - for (NSString *allowedScheme in _allowedInsecureSchemes) { - if (requestScheme != nil && - [requestScheme caseInsensitiveCompare:allowedScheme] == NSOrderedSame) { - allowRequest = YES; - break; - } - } - if (!allowRequest) { - // Check for localhost requests. Security checks only occur for non-https requests, so - // this check won't happen for an https request to localhost. - BOOL isLocalhostRequest = (host.length == 0 && [fetchRequestURL isFileURL]) || IsLocalhost(host); - if (isLocalhostRequest) { - if (self.allowLocalhostRequest) { - allowRequest = YES; - } else { - GTMSESSION_ASSERT_DEBUG(NO, @"Fetch request for localhost but fetcher" - @" allowLocalhostRequest is not set: %@", fetchRequestURL); - } - } else { - GTMSESSION_ASSERT_DEBUG(NO, @"Insecure fetch request has a scheme (%@)" - @" not found in fetcher allowedInsecureSchemes (%@): %@", - requestScheme, _allowedInsecureSchemes ?: @" @[] ", fetchRequestURL); - } - } - - if (!allowRequest) { -#if !DEBUG - NSLog(@"Insecure fetch disallowed for %@", fetchRequestURL.description ?: @"nil request URL"); -#endif - [self failToBeginFetchWithError:beginFailureError(GTMSessionFetcherErrorInsecureRequest)]; - return; - } - } // !isSecure - } // (requestURL != nil) && !isDataRequest - - if (self.cookieStorage == nil) { - self.cookieStorage = [[self class] staticCookieStorage]; - } - - BOOL isRecreatingSession = (self.sessionIdentifier != nil) && (fetchRequest == nil); - - self.canShareSession = !isRecreatingSession && !self.usingBackgroundSession; - - if (!self.session && self.canShareSession) { - self.session = [_service sessionForFetcherCreation]; - // If _session is nil, then the service's session creation semaphore will block - // until this fetcher invokes fetcherDidCreateSession: below, so this *must* invoke - // that method, even if the session fails to be created. - } - - if (!self.session) { - // Create a session. - if (!_configuration) { - if (priorSessionIdentifier || self.usingBackgroundSession) { - NSString *sessionIdentifier = priorSessionIdentifier; - if (!sessionIdentifier) { - sessionIdentifier = [self createSessionIdentifierWithMetadata:nil]; - } - NSMapTable *sessionIdentifierToFetcherMap = [[self class] sessionIdentifierToFetcherMap]; - [sessionIdentifierToFetcherMap setObject:self forKey:self.sessionIdentifier]; - -#if (TARGET_OS_TV \ - || TARGET_OS_WATCH \ - || (!TARGET_OS_IPHONE && defined(MAC_OS_X_VERSION_10_10) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10) \ - || (TARGET_OS_IPHONE && defined(__IPHONE_8_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0)) - // iOS 8/10.10 builds require the new backgroundSessionConfiguration method name. - _configuration = - [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:sessionIdentifier]; -#elif (!TARGET_OS_IPHONE && defined(MAC_OS_X_VERSION_10_10) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_10) \ - || (TARGET_OS_IPHONE && defined(__IPHONE_8_0) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0) - // Do a runtime check to avoid a deprecation warning about using - // +backgroundSessionConfiguration: on iOS 8. - if ([NSURLSessionConfiguration respondsToSelector:@selector(backgroundSessionConfigurationWithIdentifier:)]) { - // Running on iOS 8+/OS X 10.10+. -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" -// Disable unguarded availability warning as we can't use the @availability macro until we require -// all clients to build with Xcode 9 or above. - _configuration = - [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:sessionIdentifier]; -#pragma clang diagnostic pop - } else { - // Running on iOS 7/OS X 10.9. - _configuration = - [NSURLSessionConfiguration backgroundSessionConfiguration:sessionIdentifier]; - } -#else - // Building with an SDK earlier than iOS 8/OS X 10.10. - _configuration = - [NSURLSessionConfiguration backgroundSessionConfiguration:sessionIdentifier]; -#endif - self.usingBackgroundSession = YES; - self.canShareSession = NO; - } else { - _configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration]; - } -#if !GTM_ALLOW_INSECURE_REQUESTS - _configuration.TLSMinimumSupportedProtocol = kTLSProtocol12; -#endif - } // !_configuration - _configuration.HTTPCookieStorage = self.cookieStorage; - - if (_configurationBlock) { - _configurationBlock(self, _configuration); - } - - id<NSURLSessionDelegate> delegate = [_service sessionDelegate]; - if (!delegate || !self.canShareSession) { - delegate = self; - } - self.session = [NSURLSession sessionWithConfiguration:_configuration - delegate:delegate - delegateQueue:self.sessionDelegateQueue]; - GTMSESSION_ASSERT_DEBUG(self.session, @"Couldn't create session"); - - // Tell the service about the session created by this fetcher. This also signals the - // service's semaphore to allow other fetchers to request this session. - [_service fetcherDidCreateSession:self]; - - // If this assertion fires, the client probably tried to use a session identifier that was - // already used. The solution is to make the client use a unique identifier (or better yet let - // the session fetcher assign the identifier). - GTMSESSION_ASSERT_DEBUG(self.session.delegate == delegate, @"Couldn't assign delegate."); - - if (self.session) { - BOOL isUsingSharedDelegate = (delegate != self); - if (!isUsingSharedDelegate) { - _shouldInvalidateSession = YES; - } - } - } - - if (isRecreatingSession) { - _shouldInvalidateSession = YES; - - // Let's make sure there are tasks still running or if not that we get a callback from a - // completed one; otherwise, we assume the tasks failed. - // This is the observed behavior perhaps 25% of the time within the Simulator running 7.0.3 on - // exiting the app after starting an upload and relaunching the app if we manage to relaunch - // after the task has completed, but before the system relaunches us in the background. - [self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, - NSArray *downloadTasks) { - if (dataTasks.count == 0 && uploadTasks.count == 0 && downloadTasks.count == 0) { - double const kDelayInSeconds = 1.0; // We should get progress indication or completion soon - dispatch_time_t checkForFeedbackDelay = - dispatch_time(DISPATCH_TIME_NOW, (int64_t)(kDelayInSeconds * NSEC_PER_SEC)); - dispatch_after(checkForFeedbackDelay, dispatch_get_main_queue(), ^{ - if (!self.sessionTask && !fetchRequest) { - // If our task and/or request haven't been restored, then we assume task feedback lost. - [self removePersistedBackgroundSessionFromDefaults]; - NSError *sessionError = - [NSError errorWithDomain:kGTMSessionFetcherErrorDomain - code:GTMSessionFetcherErrorBackgroundFetchFailed - userInfo:nil]; - [self failToBeginFetchWithError:sessionError]; - } - }); - } - }]; - return; - } - - self.downloadedData = nil; - self.downloadedLength = 0; - - if (_servicePriority == NSIntegerMin) { - mayDelay = NO; - } - if (mayDelay && _service) { - BOOL shouldFetchNow = [_service fetcherShouldBeginFetching:self]; - if (!shouldFetchNow) { - // The fetch is deferred, but will happen later. - // - // If this session is held by the fetcher service, clear the session now so that we don't - // assume it's still valid after the fetcher is restarted. - if (self.canShareSession) { - self.session = nil; - } - return; - } - } - - NSString *effectiveHTTPMethod = [fetchRequest valueForHTTPHeaderField:@"X-HTTP-Method-Override"]; - if (effectiveHTTPMethod == nil) { - effectiveHTTPMethod = fetchRequest.HTTPMethod; - } - BOOL isEffectiveHTTPGet = (effectiveHTTPMethod == nil - || [effectiveHTTPMethod isEqual:@"GET"]); - - BOOL needsUploadTask = (self.useUploadTask || self.bodyFileURL || self.bodyStreamProvider); - if (_bodyData || self.bodyStreamProvider || fetchRequest.HTTPBodyStream) { - if (isEffectiveHTTPGet) { - fetchRequest.HTTPMethod = @"POST"; - isEffectiveHTTPGet = NO; - } - - if (_bodyData) { - if (!needsUploadTask) { - fetchRequest.HTTPBody = _bodyData; - } -#if !STRIP_GTM_FETCH_LOGGING - } else if (fetchRequest.HTTPBodyStream) { - if ([self respondsToSelector:@selector(loggedInputStreamForInputStream:)]) { - fetchRequest.HTTPBodyStream = - [self performSelector:@selector(loggedInputStreamForInputStream:) - withObject:fetchRequest.HTTPBodyStream]; - } -#endif - } - } - - // We authorize after setting up the http method and body in the request - // because OAuth 1 may need to sign the request body - if (mayAuthorize && _authorizer && !isDataRequest) { - BOOL isAuthorized = [_authorizer isAuthorizedRequest:fetchRequest]; - if (!isAuthorized) { - // Authorization needed. - // - // If this session is held by the fetcher service, clear the session now so that we don't - // assume it's still valid after authorization completes. - if (self.canShareSession) { - self.session = nil; - } - - // Authorizing the request will recursively call this beginFetch:mayDelay: - // or failToBeginFetchWithError:. - [self authorizeRequest]; - return; - } - } - - // set the default upload or download retry interval, if necessary - if ([self isRetryEnabled] && self.maxRetryInterval <= 0) { - if (isEffectiveHTTPGet || [effectiveHTTPMethod isEqual:@"HEAD"]) { - [self setMaxRetryInterval:kDefaultMaxDownloadRetryInterval]; - } else { - [self setMaxRetryInterval:kDefaultMaxUploadRetryInterval]; - } - } - - // finally, start the connection - NSURLSessionTask *newSessionTask; - BOOL needsDataAccumulator = NO; - if (_downloadResumeData) { - newSessionTask = [_session downloadTaskWithResumeData:_downloadResumeData]; - GTMSESSION_ASSERT_DEBUG_OR_LOG(newSessionTask, - @"Failed downloadTaskWithResumeData for %@, resume data %lu bytes", - _session, (unsigned long)_downloadResumeData.length); - } else if (_destinationFileURL && !isDataRequest) { - newSessionTask = [_session downloadTaskWithRequest:fetchRequest]; - GTMSESSION_ASSERT_DEBUG_OR_LOG(newSessionTask, @"Failed downloadTaskWithRequest for %@, %@", - _session, fetchRequest); - } else if (needsUploadTask) { - if (bodyFileURL) { - newSessionTask = [_session uploadTaskWithRequest:fetchRequest - fromFile:bodyFileURL]; - GTMSESSION_ASSERT_DEBUG_OR_LOG(newSessionTask, - @"Failed uploadTaskWithRequest for %@, %@, file %@", - _session, fetchRequest, bodyFileURL.path); - } else if (self.bodyStreamProvider) { - newSessionTask = [_session uploadTaskWithStreamedRequest:fetchRequest]; - GTMSESSION_ASSERT_DEBUG_OR_LOG(newSessionTask, - @"Failed uploadTaskWithStreamedRequest for %@, %@", - _session, fetchRequest); - } else { - GTMSESSION_ASSERT_DEBUG_OR_LOG(_bodyData != nil, - @"Upload task needs body data, %@", fetchRequest); - newSessionTask = [_session uploadTaskWithRequest:fetchRequest - fromData:(NSData * GTM_NONNULL_TYPE)_bodyData]; - GTMSESSION_ASSERT_DEBUG_OR_LOG(newSessionTask, - @"Failed uploadTaskWithRequest for %@, %@, body data %lu bytes", - _session, fetchRequest, (unsigned long)_bodyData.length); - } - needsDataAccumulator = YES; - } else { - newSessionTask = [_session dataTaskWithRequest:fetchRequest]; - needsDataAccumulator = YES; - GTMSESSION_ASSERT_DEBUG_OR_LOG(newSessionTask, @"Failed dataTaskWithRequest for %@, %@", - _session, fetchRequest); - } - self.sessionTask = newSessionTask; - - if (!newSessionTask) { - // We shouldn't get here; if we're here, an earlier assertion should have fired to explain - // which session task creation failed. - [self failToBeginFetchWithError:beginFailureError(GTMSessionFetcherErrorTaskCreationFailed)]; - return; - } - - if (needsDataAccumulator && _accumulateDataBlock == nil) { - self.downloadedData = [NSMutableData data]; - } - if (_taskDescription) { - newSessionTask.taskDescription = _taskDescription; - } - if (_taskPriority >= 0) { -#if TARGET_OS_TV || TARGET_OS_WATCH - BOOL hasTaskPriority = YES; -#elif (!TARGET_OS_IPHONE && defined(MAC_OS_X_VERSION_10_10) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10) \ - || (TARGET_OS_IPHONE && defined(__IPHONE_8_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0) - BOOL hasTaskPriority = YES; -#else - BOOL hasTaskPriority = [newSessionTask respondsToSelector:@selector(setPriority:)]; -#endif - if (hasTaskPriority) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" -// Disable unguarded availability warning as we can't use the @availability macro until we require -// all clients to build with Xcode 9 or above. - newSessionTask.priority = _taskPriority; -#pragma clang diagnostic pop - } - } - -#if GTM_DISABLE_FETCHER_TEST_BLOCK - GTMSESSION_ASSERT_DEBUG(_testBlock == nil && gGlobalTestBlock == nil, @"test blocks disabled"); - _testBlock = nil; -#else - if (!_testBlock) { - if (gGlobalTestBlock) { - // Note that the test block may pass nil for all of its response parameters, - // indicating that the fetch should actually proceed. This is useful when the - // global test block has been set, and the app is only testing a specific - // fetcher. The block simulation code will then resume the task. - _testBlock = gGlobalTestBlock; - } - } - _isUsingTestBlock = (_testBlock != nil); -#endif // GTM_DISABLE_FETCHER_TEST_BLOCK - -#if GTM_BACKGROUND_TASK_FETCHING - id<GTMUIApplicationProtocol> app = [[self class] fetcherUIApplication]; - // Background tasks seem to interfere with out-of-process uploads and downloads. - if (app && !self.skipBackgroundTask && !self.useBackgroundSession) { - // Tell UIApplication that we want to continue even when the app is in the - // background. -#if DEBUG - NSString *bgTaskName = [NSString stringWithFormat:@"%@-%@", - [self class], fetchRequest.URL.host]; -#else - NSString *bgTaskName = @"GTMSessionFetcher"; -#endif - __block UIBackgroundTaskIdentifier bgTaskID = [app beginBackgroundTaskWithName:bgTaskName - expirationHandler:^{ - // Background task expiration callback - this block is always invoked by - // UIApplication on the main thread. - if (bgTaskID != UIBackgroundTaskInvalid) { - @synchronized(self) { - if (bgTaskID == self.backgroundTaskIdentifier) { - self.backgroundTaskIdentifier = UIBackgroundTaskInvalid; - } - } - [app endBackgroundTask:bgTaskID]; - } - }]; - @synchronized(self) { - self.backgroundTaskIdentifier = bgTaskID; - } - } -#endif - - if (!_initialRequestDate) { - _initialRequestDate = [[NSDate alloc] init]; - } - - // We don't expect to reach here even on retry or auth until a stop notification has been sent - // for the previous task, but we should ensure that we don't unbalance that. - GTMSESSION_ASSERT_DEBUG(!_isStopNotificationNeeded, @"Start notification without a prior stop"); - [self sendStopNotificationIfNeeded]; - - [self addPersistedBackgroundSessionToDefaults]; - - [self setStopNotificationNeeded:YES]; - - [self postNotificationOnMainThreadWithName:kGTMSessionFetcherStartedNotification - userInfo:nil - requireAsync:NO]; - - // The service needs to know our task if it is serving as NSURLSession delegate. - [_service fetcherDidBeginFetching:self]; - - if (_testBlock) { -#if !GTM_DISABLE_FETCHER_TEST_BLOCK - [self simulateFetchForTestBlock]; -#endif - } else { - // We resume the session task after posting the notification since the - // delegate callbacks may happen immediately if the fetch is started off - // the main thread or the session delegate queue is on a background thread, - // and we don't want to post a start notification after a premature finish - // of the session task. - [newSessionTask resume]; - } -} - -NSData * GTM_NULLABLE_TYPE GTMDataFromInputStream(NSInputStream *inputStream, NSError **outError) { - NSMutableData *data = [NSMutableData data]; - - [inputStream open]; - NSInteger numberOfBytesRead = 0; - while ([inputStream hasBytesAvailable]) { - uint8_t buffer[512]; - numberOfBytesRead = [inputStream read:buffer maxLength:sizeof(buffer)]; - if (numberOfBytesRead > 0) { - [data appendBytes:buffer length:(NSUInteger)numberOfBytesRead]; - } else { - break; - } - } - [inputStream close]; - NSError *streamError = inputStream.streamError; - - if (streamError) { - data = nil; - } - if (outError) { - *outError = streamError; - } - return data; -} - -#if !GTM_DISABLE_FETCHER_TEST_BLOCK - -- (void)simulateFetchForTestBlock { - // This is invoked on the same thread as the beginFetch method was. - // - // Callbacks will all occur on the callback queue. - _testBlock(self, ^(NSURLResponse *response, NSData *responseData, NSError *error) { - // Callback from test block. - if (response == nil && responseData == nil && error == nil) { - // Assume the fetcher should execute rather than be tested. - self->_testBlock = nil; - self->_isUsingTestBlock = NO; - [self->_sessionTask resume]; - return; - } - - GTMSessionFetcherBodyStreamProvider bodyStreamProvider = self.bodyStreamProvider; - if (bodyStreamProvider) { - bodyStreamProvider(^(NSInputStream *bodyStream){ - // Read from the input stream into an NSData buffer. We'll drain the stream - // explicitly on a background queue. - [self invokeOnCallbackQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0) - afterUserStopped:NO - block:^{ - NSError *streamError; - NSData *streamedData = GTMDataFromInputStream(bodyStream, &streamError); - - dispatch_async(dispatch_get_main_queue(), ^{ - // Continue callbacks on the main thread, since serial behavior - // is more reliable for tests. - [self simulateDataCallbacksForTestBlockWithBodyData:streamedData - response:response - responseData:responseData - error:(error ?: streamError)]; - }); - }]; - }); - } else { - // No input stream; use the supplied data or file URL. - NSURL *bodyFileURL = self.bodyFileURL; - if (bodyFileURL) { - NSError *readError; - self->_bodyData = [NSData dataWithContentsOfURL:bodyFileURL - options:NSDataReadingMappedIfSafe - error:&readError]; - error = readError; - } - - // No stream provider. - - // In real fetches, nothing happens until the run loop spins, so apps have leeway to - // set callbacks after they call beginFetch. We'll mirror that fetcher behavior by - // delaying callbacks here at least to the next spin of the run loop. That keeps - // immediate, synchronous setting of callback blocks after beginFetch working in tests. - dispatch_async(dispatch_get_main_queue(), ^{ - [self simulateDataCallbacksForTestBlockWithBodyData:self->_bodyData - response:response - responseData:responseData - error:error]; - }); - } - }); -} - -- (void)simulateByteTransferReportWithDataLength:(int64_t)totalDataLength - block:(GTMSessionFetcherSendProgressBlock)block { - // This utility method simulates transfer progress with up to three callbacks. - // It is used to call back to any of the progress blocks. - int64_t sendReportSize = totalDataLength / 3 + 1; - int64_t totalSent = 0; - while (totalSent < totalDataLength) { - int64_t bytesRemaining = totalDataLength - totalSent; - sendReportSize = MIN(sendReportSize, bytesRemaining); - totalSent += sendReportSize; - [self invokeOnCallbackQueueUnlessStopped:^{ - block(sendReportSize, totalSent, totalDataLength); - }]; - } -} - -- (void)simulateDataCallbacksForTestBlockWithBodyData:(NSData * GTM_NULLABLE_TYPE)bodyData - response:(NSURLResponse *)response - responseData:(NSData *)suppliedData - error:(NSError *)suppliedError { - __block NSData *responseData = suppliedData; - __block NSError *responseError = suppliedError; - - // This method does the test simulation of callbacks once the upload - // and download data are known. - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - // Get copies of ivars we'll access in async invocations. This simulation assumes - // they won't change during fetcher execution. - NSURL *destinationFileURL = _destinationFileURL; - GTMSessionFetcherWillRedirectBlock willRedirectBlock = _willRedirectBlock; - GTMSessionFetcherDidReceiveResponseBlock didReceiveResponseBlock = _didReceiveResponseBlock; - GTMSessionFetcherSendProgressBlock sendProgressBlock = _sendProgressBlock; - GTMSessionFetcherDownloadProgressBlock downloadProgressBlock = _downloadProgressBlock; - GTMSessionFetcherAccumulateDataBlock accumulateDataBlock = _accumulateDataBlock; - GTMSessionFetcherReceivedProgressBlock receivedProgressBlock = _receivedProgressBlock; - GTMSessionFetcherWillCacheURLResponseBlock willCacheURLResponseBlock = - _willCacheURLResponseBlock; - - // Simulate receipt of redirection. - if (willRedirectBlock) { - [self invokeOnCallbackUnsynchronizedQueueAfterUserStopped:YES - block:^{ - willRedirectBlock((NSHTTPURLResponse *)response, self->_request, - ^(NSURLRequest *redirectRequest) { - // For simulation, we'll assume the app will just continue. - }); - }]; - } - - // If the fetcher has a challenge block, simulate a challenge. - // - // It might be nice to eventually let the user determine which testBlock - // fetches get challenged rather than always executing the supplied - // challenge block. - if (_challengeBlock) { - [self invokeOnCallbackUnsynchronizedQueueAfterUserStopped:YES - block:^{ - if (self->_challengeBlock) { - NSURL *requestURL = self->_request.URL; - NSString *host = requestURL.host; - NSURLProtectionSpace *pspace = - [[NSURLProtectionSpace alloc] initWithHost:host - port:requestURL.port.integerValue - protocol:requestURL.scheme - realm:nil - authenticationMethod:NSURLAuthenticationMethodHTTPBasic]; - id<NSURLAuthenticationChallengeSender> unusedSender = - (id<NSURLAuthenticationChallengeSender>)[NSNull null]; - NSURLAuthenticationChallenge *challenge = - [[NSURLAuthenticationChallenge alloc] initWithProtectionSpace:pspace - proposedCredential:nil - previousFailureCount:0 - failureResponse:nil - error:nil - sender:unusedSender]; - self->_challengeBlock(self, challenge, ^(NSURLSessionAuthChallengeDisposition disposition, - NSURLCredential * GTM_NULLABLE_TYPE credential){ - // We could change the responseData and responseError based on the disposition, - // but it's easier for apps to just supply the expected data and error - // directly to the test block. So this simulation ignores the disposition. - }); - } - }]; - } - - // Simulate receipt of an initial response. - if (response && didReceiveResponseBlock) { - [self invokeOnCallbackUnsynchronizedQueueAfterUserStopped:YES - block:^{ - didReceiveResponseBlock(response, ^(NSURLSessionResponseDisposition desiredDisposition) { - // For simulation, we'll assume the disposition is to continue. - }); - }]; - } - - // Simulate reporting send progress. - if (sendProgressBlock) { - [self simulateByteTransferReportWithDataLength:(int64_t)bodyData.length - block:^(int64_t bytesSent, - int64_t totalBytesSent, - int64_t totalBytesExpectedToSend) { - // This is invoked on the callback queue unless stopped. - sendProgressBlock(bytesSent, totalBytesSent, totalBytesExpectedToSend); - }]; - } - - if (destinationFileURL) { - // Simulate download to file progress. - if (downloadProgressBlock) { - [self simulateByteTransferReportWithDataLength:(int64_t)responseData.length - block:^(int64_t bytesDownloaded, - int64_t totalBytesDownloaded, - int64_t totalBytesExpectedToDownload) { - // This is invoked on the callback queue unless stopped. - downloadProgressBlock(bytesDownloaded, totalBytesDownloaded, - totalBytesExpectedToDownload); - }]; - } - - NSError *writeError; - [responseData writeToURL:destinationFileURL - options:NSDataWritingAtomic - error:&writeError]; - if (writeError) { - // Tell the test code that writing failed. - responseError = writeError; - } - } else { - // Simulate download to NSData progress. - if ((accumulateDataBlock || receivedProgressBlock) && responseData) { - [self simulateByteTransferWithData:responseData - block:^(NSData *data, - int64_t bytesReceived, - int64_t totalBytesReceived, - int64_t totalBytesExpectedToReceive) { - // This is invoked on the callback queue unless stopped. - if (accumulateDataBlock) { - accumulateDataBlock(data); - } - - if (receivedProgressBlock) { - receivedProgressBlock(bytesReceived, totalBytesReceived); - } - }]; - } - - if (!accumulateDataBlock) { - _downloadedData = [responseData mutableCopy]; - } - - if (willCacheURLResponseBlock) { - // Simulate letting the client inspect and alter the cached response. - NSData *cachedData = responseData ?: [[NSData alloc] init]; // Always have non-nil data. - NSCachedURLResponse *cachedResponse = - [[NSCachedURLResponse alloc] initWithResponse:response - data:cachedData]; - [self invokeOnCallbackUnsynchronizedQueueAfterUserStopped:YES - block:^{ - willCacheURLResponseBlock(cachedResponse, ^(NSCachedURLResponse *responseToCache){ - // The app may provide an alternative response, or nil to defeat caching. - }); - }]; - } - } - _response = response; - } // @synchronized(self) - - NSOperationQueue *queue = self.sessionDelegateQueue; - [queue addOperationWithBlock:^{ - // Rather than invoke failToBeginFetchWithError: we want to simulate completion of - // a connection that started and ended, so we'll call down to finishWithError: - NSInteger status = responseError ? responseError.code : 200; - if (status >= 200 && status <= 399) { - [self finishWithError:nil shouldRetry:NO]; - } else { - [self shouldRetryNowForStatus:status - error:responseError - forceAssumeRetry:NO - response:^(BOOL shouldRetry) { - [self finishWithError:responseError shouldRetry:shouldRetry]; - }]; - } - }]; -} - -- (void)simulateByteTransferWithData:(NSData *)responseData - block:(GTMSessionFetcherSimulateByteTransferBlock)transferBlock { - // This utility method simulates transfering data to the client. It divides the data into at most - // "chunkCount" chunks and then passes each chunk along with a progress update to transferBlock. - // This function can be used with accumulateDataBlock or receivedProgressBlock. - - NSUInteger chunkCount = MAX(self.testBlockAccumulateDataChunkCount, (NSUInteger) 1); - NSUInteger totalDataLength = responseData.length; - NSUInteger sendDataSize = totalDataLength / chunkCount + 1; - NSUInteger totalSent = 0; - while (totalSent < totalDataLength) { - NSUInteger bytesRemaining = totalDataLength - totalSent; - sendDataSize = MIN(sendDataSize, bytesRemaining); - NSData *chunkData = [responseData subdataWithRange:NSMakeRange(totalSent, sendDataSize)]; - totalSent += sendDataSize; - [self invokeOnCallbackQueueUnlessStopped:^{ - transferBlock(chunkData, - (int64_t)sendDataSize, - (int64_t)totalSent, - (int64_t)totalDataLength); - }]; - } -} - -#endif // !GTM_DISABLE_FETCHER_TEST_BLOCK - -- (void)setSessionTask:(NSURLSessionTask *)sessionTask { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (_sessionTask != sessionTask) { - _sessionTask = sessionTask; - if (_sessionTask) { - // Request could be nil on restoring this fetcher from a background session. - if (!_request) { - _request = [_sessionTask.originalRequest mutableCopy]; - } - } - } - } // @synchronized(self) -} - -- (NSURLSessionTask * GTM_NULLABLE_TYPE)sessionTask { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _sessionTask; - } // @synchronized(self) -} - -+ (NSUserDefaults *)fetcherUserDefaults { - static NSUserDefaults *gFetcherUserDefaults = nil; - - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - Class fetcherUserDefaultsClass = NSClassFromString(@"GTMSessionFetcherUserDefaultsFactory"); - if (fetcherUserDefaultsClass) { - gFetcherUserDefaults = [fetcherUserDefaultsClass fetcherUserDefaults]; - } else { - gFetcherUserDefaults = [NSUserDefaults standardUserDefaults]; - } - }); - return gFetcherUserDefaults; -} - -- (void)addPersistedBackgroundSessionToDefaults { - NSString *sessionIdentifier = self.sessionIdentifier; - if (!sessionIdentifier) { - return; - } - NSArray *oldBackgroundSessions = [[self class] activePersistedBackgroundSessions]; - if ([oldBackgroundSessions containsObject:_sessionIdentifier]) { - return; - } - NSMutableArray *newBackgroundSessions = - [NSMutableArray arrayWithArray:oldBackgroundSessions]; - [newBackgroundSessions addObject:sessionIdentifier]; - GTM_LOG_BACKGROUND_SESSION(@"Add to background sessions: %@", newBackgroundSessions); - - NSUserDefaults *userDefaults = [[self class] fetcherUserDefaults]; - [userDefaults setObject:newBackgroundSessions - forKey:kGTMSessionFetcherPersistedDestinationKey]; - [userDefaults synchronize]; -} - -- (void)removePersistedBackgroundSessionFromDefaults { - NSString *sessionIdentifier = self.sessionIdentifier; - if (!sessionIdentifier) return; - - NSArray *oldBackgroundSessions = [[self class] activePersistedBackgroundSessions]; - if (!oldBackgroundSessions) { - return; - } - NSMutableArray *newBackgroundSessions = - [NSMutableArray arrayWithArray:oldBackgroundSessions]; - NSUInteger sessionIndex = [newBackgroundSessions indexOfObject:sessionIdentifier]; - if (sessionIndex == NSNotFound) { - return; - } - [newBackgroundSessions removeObjectAtIndex:sessionIndex]; - GTM_LOG_BACKGROUND_SESSION(@"Remove from background sessions: %@", newBackgroundSessions); - - NSUserDefaults *userDefaults = [[self class] fetcherUserDefaults]; - if (newBackgroundSessions.count == 0) { - [userDefaults removeObjectForKey:kGTMSessionFetcherPersistedDestinationKey]; - } else { - [userDefaults setObject:newBackgroundSessions - forKey:kGTMSessionFetcherPersistedDestinationKey]; - } - [userDefaults synchronize]; -} - -+ (GTM_NULLABLE NSArray *)activePersistedBackgroundSessions { - NSUserDefaults *userDefaults = [[self class] fetcherUserDefaults]; - NSArray *oldBackgroundSessions = - [userDefaults arrayForKey:kGTMSessionFetcherPersistedDestinationKey]; - if (oldBackgroundSessions.count == 0) { - return nil; - } - NSMutableArray *activeBackgroundSessions = nil; - NSMapTable *sessionIdentifierToFetcherMap = [self sessionIdentifierToFetcherMap]; - for (NSString *sessionIdentifier in oldBackgroundSessions) { - GTMSessionFetcher *fetcher = [sessionIdentifierToFetcherMap objectForKey:sessionIdentifier]; - if (fetcher) { - if (!activeBackgroundSessions) { - activeBackgroundSessions = [[NSMutableArray alloc] init]; - } - [activeBackgroundSessions addObject:sessionIdentifier]; - } - } - return activeBackgroundSessions; -} - -+ (NSArray *)fetchersForBackgroundSessions { - NSUserDefaults *userDefaults = [[self class] fetcherUserDefaults]; - NSArray *backgroundSessions = - [userDefaults arrayForKey:kGTMSessionFetcherPersistedDestinationKey]; - NSMapTable *sessionIdentifierToFetcherMap = [self sessionIdentifierToFetcherMap]; - NSMutableArray *fetchers = [NSMutableArray array]; - for (NSString *sessionIdentifier in backgroundSessions) { - GTMSessionFetcher *fetcher = [sessionIdentifierToFetcherMap objectForKey:sessionIdentifier]; - if (!fetcher) { - fetcher = [self fetcherWithSessionIdentifier:sessionIdentifier]; - GTMSESSION_ASSERT_DEBUG(fetcher != nil, - @"Unexpected invalid session identifier: %@", sessionIdentifier); - [fetcher beginFetchWithCompletionHandler:nil]; - } - GTM_LOG_BACKGROUND_SESSION(@"%@ restoring session %@ by creating fetcher %@ %p", - [self class], sessionIdentifier, fetcher, fetcher); - if (fetcher != nil) { - [fetchers addObject:fetcher]; - } - } - return fetchers; -} - -#if TARGET_OS_IPHONE && !TARGET_OS_WATCH -+ (void)application:(UIApplication *)application - handleEventsForBackgroundURLSession:(NSString *)identifier - completionHandler:(GTMSessionFetcherSystemCompletionHandler)completionHandler { - GTMSessionFetcher *fetcher = [self fetcherWithSessionIdentifier:identifier]; - if (fetcher != nil) { - fetcher.systemCompletionHandler = completionHandler; - } else { - GTM_LOG_BACKGROUND_SESSION(@"%@ did not create background session identifier: %@", - [self class], identifier); - } -} -#endif - -- (NSString * GTM_NULLABLE_TYPE)sessionIdentifier { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _sessionIdentifier; - } // @synchronized(self) -} - -- (void)setSessionIdentifier:(NSString *)sessionIdentifier { - GTMSESSION_ASSERT_DEBUG(sessionIdentifier != nil, @"Invalid session identifier"); - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - GTMSESSION_ASSERT_DEBUG(!_session, @"Unable to set session identifier after session created"); - _sessionIdentifier = [sessionIdentifier copy]; - _usingBackgroundSession = YES; - _canShareSession = NO; - [self restoreDefaultStateForSessionIdentifierMetadata]; - } // @synchronized(self) -} - -- (void)setSessionIdentifierInternal:(GTM_NULLABLE NSString *)sessionIdentifier { - // This internal method only does a synchronized set of the session identifier. - // It does not have side effects on the background session, shared session, or - // session identifier metadata. - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _sessionIdentifier = [sessionIdentifier copy]; - } // @synchronized(self) -} - -- (NSDictionary * GTM_NULLABLE_TYPE)sessionUserInfo { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (_sessionUserInfo == nil) { - // We'll return the metadata dictionary with internal keys removed. This avoids the user - // re-using the userInfo dictionary later and accidentally including the internal keys. - NSMutableDictionary *metadata = [[self sessionIdentifierMetadataUnsynchronized] mutableCopy]; - NSSet *keysToRemove = [metadata keysOfEntriesPassingTest:^BOOL(id key, id obj, BOOL *stop) { - return [key hasPrefix:@"_"]; - }]; - [metadata removeObjectsForKeys:[keysToRemove allObjects]]; - if (metadata.count > 0) { - _sessionUserInfo = metadata; - } - } - return _sessionUserInfo; - } // @synchronized(self) -} - -- (void)setSessionUserInfo:(NSDictionary * GTM_NULLABLE_TYPE)dictionary { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - GTMSESSION_ASSERT_DEBUG(_sessionIdentifier == nil, @"Too late to assign userInfo"); - _sessionUserInfo = dictionary; - } // @synchronized(self) -} - -- (GTM_NULLABLE NSDictionary *)sessionIdentifierDefaultMetadata { - GTMSessionCheckSynchronized(self); - - NSMutableDictionary *defaultUserInfo = [[NSMutableDictionary alloc] init]; - if (_destinationFileURL) { - defaultUserInfo[kGTMSessionIdentifierDestinationFileURLMetadataKey] = - [_destinationFileURL absoluteString]; - } - if (_bodyFileURL) { - defaultUserInfo[kGTMSessionIdentifierBodyFileURLMetadataKey] = [_bodyFileURL absoluteString]; - } - return (defaultUserInfo.count > 0) ? defaultUserInfo : nil; -} - -- (void)restoreDefaultStateForSessionIdentifierMetadata { - GTMSessionCheckSynchronized(self); - - NSDictionary *metadata = [self sessionIdentifierMetadataUnsynchronized]; - NSString *destinationFileURLString = metadata[kGTMSessionIdentifierDestinationFileURLMetadataKey]; - if (destinationFileURLString) { - _destinationFileURL = [NSURL URLWithString:destinationFileURLString]; - GTM_LOG_BACKGROUND_SESSION(@"Restoring destination file URL: %@", _destinationFileURL); - } - NSString *bodyFileURLString = metadata[kGTMSessionIdentifierBodyFileURLMetadataKey]; - if (bodyFileURLString) { - _bodyFileURL = [NSURL URLWithString:bodyFileURLString]; - GTM_LOG_BACKGROUND_SESSION(@"Restoring body file URL: %@", _bodyFileURL); - } -} - -- (NSDictionary * GTM_NULLABLE_TYPE)sessionIdentifierMetadata { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return [self sessionIdentifierMetadataUnsynchronized]; - } -} - -- (NSDictionary * GTM_NULLABLE_TYPE)sessionIdentifierMetadataUnsynchronized { - GTMSessionCheckSynchronized(self); - - // Session Identifier format: "com.google.<ClassName>_<UUID>_<Metadata in JSON format> - if (!_sessionIdentifier) { - return nil; - } - NSScanner *metadataScanner = [NSScanner scannerWithString:_sessionIdentifier]; - [metadataScanner setCharactersToBeSkipped:nil]; - NSString *metadataString; - NSString *uuid; - if ([metadataScanner scanUpToString:@"_" intoString:NULL] && - [metadataScanner scanString:@"_" intoString:NULL] && - [metadataScanner scanUpToString:@"_" intoString:&uuid] && - [metadataScanner scanString:@"_" intoString:NULL] && - [metadataScanner scanUpToString:@"\n" intoString:&metadataString]) { - _sessionIdentifierUUID = uuid; - NSData *metadataData = [metadataString dataUsingEncoding:NSUTF8StringEncoding]; - NSError *error; - NSDictionary *metadataDict = - [NSJSONSerialization JSONObjectWithData:metadataData - options:0 - error:&error]; - GTM_LOG_BACKGROUND_SESSION(@"User Info from session identifier: %@ %@", - metadataDict, error ? error : @""); - return metadataDict; - } - return nil; -} - -- (NSString *)createSessionIdentifierWithMetadata:(NSDictionary * GTM_NULLABLE_TYPE)metadataToInclude { - NSString *result; - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - // Session Identifier format: "com.google.<ClassName>_<UUID>_<Metadata in JSON format> - GTMSESSION_ASSERT_DEBUG(!_sessionIdentifier, @"Session identifier already created"); - _sessionIdentifierUUID = [[NSUUID UUID] UUIDString]; - _sessionIdentifier = - [NSString stringWithFormat:@"%@_%@", kGTMSessionIdentifierPrefix, _sessionIdentifierUUID]; - // Start with user-supplied keys so they cannot accidentally override the fetcher's keys. - NSMutableDictionary *metadataDict = - [NSMutableDictionary dictionaryWithDictionary:(NSDictionary * GTM_NONNULL_TYPE)_sessionUserInfo]; - - if (metadataToInclude) { - [metadataDict addEntriesFromDictionary:(NSDictionary *)metadataToInclude]; - } - NSDictionary *defaultMetadataDict = [self sessionIdentifierDefaultMetadata]; - if (defaultMetadataDict) { - [metadataDict addEntriesFromDictionary:defaultMetadataDict]; - } - if (metadataDict.count > 0) { - NSData *metadataData = [NSJSONSerialization dataWithJSONObject:metadataDict - options:0 - error:NULL]; - GTMSESSION_ASSERT_DEBUG(metadataData != nil, - @"Session identifier user info failed to convert to JSON"); - if (metadataData.length > 0) { - NSString *metadataString = [[NSString alloc] initWithData:metadataData - encoding:NSUTF8StringEncoding]; - _sessionIdentifier = - [_sessionIdentifier stringByAppendingFormat:@"_%@", metadataString]; - } - } - _didCreateSessionIdentifier = YES; - result = _sessionIdentifier; - } // @synchronized(self) - return result; -} - -- (void)failToBeginFetchWithError:(NSError *)error { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _hasStoppedFetching = YES; - } - - if (error == nil) { - error = [NSError errorWithDomain:kGTMSessionFetcherErrorDomain - code:GTMSessionFetcherErrorDownloadFailed - userInfo:nil]; - } - - [self invokeFetchCallbacksOnCallbackQueueWithData:nil - error:error]; - [self releaseCallbacks]; - - [_service fetcherDidStop:self]; - - self.authorizer = nil; -} - -+ (GTMSessionCookieStorage *)staticCookieStorage { - static GTMSessionCookieStorage *gCookieStorage = nil; - - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - gCookieStorage = [[GTMSessionCookieStorage alloc] init]; - }); - return gCookieStorage; -} - -#if GTM_BACKGROUND_TASK_FETCHING - -- (void)endBackgroundTask { - // Whenever the connection stops or background execution expires, - // we need to tell UIApplication we're done. - UIBackgroundTaskIdentifier bgTaskID; - @synchronized(self) { - bgTaskID = self.backgroundTaskIdentifier; - if (bgTaskID != UIBackgroundTaskInvalid) { - self.backgroundTaskIdentifier = UIBackgroundTaskInvalid; - } - } - - if (bgTaskID != UIBackgroundTaskInvalid) { - id<GTMUIApplicationProtocol> app = [[self class] fetcherUIApplication]; - [app endBackgroundTask:bgTaskID]; - } -} - -#endif // GTM_BACKGROUND_TASK_FETCHING - -- (void)authorizeRequest { - GTMSessionCheckNotSynchronized(self); - - id authorizer = self.authorizer; - SEL asyncAuthSel = @selector(authorizeRequest:delegate:didFinishSelector:); - if ([authorizer respondsToSelector:asyncAuthSel]) { - SEL callbackSel = @selector(authorizer:request:finishedWithError:); - NSMutableURLRequest *mutableRequest = [self.request mutableCopy]; - [authorizer authorizeRequest:mutableRequest - delegate:self - didFinishSelector:callbackSel]; - } else { - GTMSESSION_ASSERT_DEBUG(authorizer == nil, @"invalid authorizer for fetch"); - - // No authorizing possible, and authorizing happens only after any delay; - // just begin fetching - [self beginFetchMayDelay:NO - mayAuthorize:NO]; - } -} - -- (void)authorizer:(id<GTMFetcherAuthorizationProtocol>)auth - request:(NSMutableURLRequest *)authorizedRequest - finishedWithError:(NSError *)error { - GTMSessionCheckNotSynchronized(self); - - if (error != nil) { - // We can't fetch without authorization - [self failToBeginFetchWithError:error]; - } else { - @synchronized(self) { - _request = authorizedRequest; - } - [self beginFetchMayDelay:NO - mayAuthorize:NO]; - } -} - - -- (BOOL)canFetchWithBackgroundSession { - // Subclasses may override. - return YES; -} - -// Returns YES if the fetcher has been started and has not yet stopped. -// -// Fetching includes waiting for authorization or for retry, waiting to be allowed by the -// service object to start the request, and actually fetching the request. -- (BOOL)isFetching { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return [self isFetchingUnsynchronized]; - } -} - -- (BOOL)isFetchingUnsynchronized { - GTMSessionCheckSynchronized(self); - - BOOL hasBegun = (_initialBeginFetchDate != nil); - return hasBegun && !_hasStoppedFetching; -} - -- (NSURLResponse * GTM_NULLABLE_TYPE)response { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - NSURLResponse *response = [self responseUnsynchronized]; - return response; - } // @synchronized(self) -} - -- (NSURLResponse * GTM_NULLABLE_TYPE)responseUnsynchronized { - GTMSessionCheckSynchronized(self); - - NSURLResponse *response = _sessionTask.response; - if (!response) response = _response; - return response; -} - -- (NSInteger)statusCode { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - NSInteger statusCode = [self statusCodeUnsynchronized]; - return statusCode; - } // @synchronized(self) -} - -- (NSInteger)statusCodeUnsynchronized { - GTMSessionCheckSynchronized(self); - - NSURLResponse *response = [self responseUnsynchronized]; - NSInteger statusCode; - - if ([response respondsToSelector:@selector(statusCode)]) { - statusCode = [(NSHTTPURLResponse *)response statusCode]; - } else { - // Default to zero, in hopes of hinting "Unknown" (we can't be - // sure that things are OK enough to use 200). - statusCode = 0; - } - return statusCode; -} - -- (NSDictionary * GTM_NULLABLE_TYPE)responseHeaders { - GTMSessionCheckNotSynchronized(self); - - NSURLResponse *response = self.response; - if ([response respondsToSelector:@selector(allHeaderFields)]) { - NSDictionary *headers = [(NSHTTPURLResponse *)response allHeaderFields]; - return headers; - } - return nil; -} - -- (NSDictionary * GTM_NULLABLE_TYPE)responseHeadersUnsynchronized { - GTMSessionCheckSynchronized(self); - - NSURLResponse *response = [self responseUnsynchronized]; - if ([response respondsToSelector:@selector(allHeaderFields)]) { - NSDictionary *headers = [(NSHTTPURLResponse *)response allHeaderFields]; - return headers; - } - return nil; -} - -- (void)releaseCallbacks { - // Avoid releasing blocks in the sync section since objects dealloc'd by - // the blocks being released may call back into the fetcher or fetcher - // service. - dispatch_queue_t NS_VALID_UNTIL_END_OF_SCOPE holdCallbackQueue; - GTMSessionFetcherCompletionHandler NS_VALID_UNTIL_END_OF_SCOPE holdCompletionHandler; - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - holdCallbackQueue = _callbackQueue; - holdCompletionHandler = _completionHandler; - - _callbackQueue = nil; - _completionHandler = nil; // Setter overridden in upload. Setter assumed to be used externally. - } - - // Set local callback pointers to nil here rather than let them release at the end of the scope - // to make any problems due to the blocks being released be a bit more obvious in a stack trace. - holdCallbackQueue = nil; - holdCompletionHandler = nil; - - self.configurationBlock = nil; - self.didReceiveResponseBlock = nil; - self.challengeBlock = nil; - self.willRedirectBlock = nil; - self.sendProgressBlock = nil; - self.receivedProgressBlock = nil; - self.downloadProgressBlock = nil; - self.accumulateDataBlock = nil; - self.willCacheURLResponseBlock = nil; - self.retryBlock = nil; - self.testBlock = nil; - self.resumeDataBlock = nil; -} - -- (void)forgetSessionIdentifierForFetcher { - GTMSessionCheckSynchronized(self); - [self forgetSessionIdentifierForFetcherWithoutSyncCheck]; -} - -- (void)forgetSessionIdentifierForFetcherWithoutSyncCheck { - // This should be called inside a @synchronized block (except during dealloc.) - if (_sessionIdentifier) { - NSMapTable *sessionIdentifierToFetcherMap = [[self class] sessionIdentifierToFetcherMap]; - [sessionIdentifierToFetcherMap removeObjectForKey:_sessionIdentifier]; - _sessionIdentifier = nil; - _didCreateSessionIdentifier = NO; - } -} - -// External stop method -- (void)stopFetching { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - // Prevent enqueued callbacks from executing. - _userStoppedFetching = YES; - } // @synchronized(self) - [self stopFetchReleasingCallbacks:YES]; -} - -// Cancel the fetch of the URL that's currently in progress. -// -// If shouldReleaseCallbacks is NO then the fetch will be retried so the callbacks -// need to still be retained. -- (void)stopFetchReleasingCallbacks:(BOOL)shouldReleaseCallbacks { - [self removePersistedBackgroundSessionFromDefaults]; - - id<GTMSessionFetcherServiceProtocol> service; - NSMutableURLRequest *request; - - // If the task or the retry timer is all that's retaining the fetcher, - // we want to be sure this instance survives stopping at least long enough for - // the stack to unwind. - __autoreleasing GTMSessionFetcher *holdSelf = self; - - BOOL hasCanceledTask = NO; - - [holdSelf destroyRetryTimer]; - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _hasStoppedFetching = YES; - - service = _service; - request = _request; - - if (_sessionTask) { - // In case cancelling the task or session calls this recursively, we want - // to ensure that we'll only release the task and delegate once, - // so first set _sessionTask to nil - // - // This may be called in a callback from the task, so use autorelease to avoid - // releasing the task in its own callback. - __autoreleasing NSURLSessionTask *oldTask = _sessionTask; - if (!_isUsingTestBlock) { - _response = _sessionTask.response; - } - _sessionTask = nil; - - if ([oldTask state] != NSURLSessionTaskStateCompleted) { - // For download tasks, when the fetch is stopped, we may provide resume data that can - // be used to create a new session. - BOOL mayResume = (_resumeDataBlock - && [oldTask respondsToSelector:@selector(cancelByProducingResumeData:)]); - if (!mayResume) { - [oldTask cancel]; - // A side effect of stopping the task is that URLSession:task:didCompleteWithError: - // will be invoked asynchronously on the delegate queue. - } else { - void (^resumeBlock)(NSData *) = _resumeDataBlock; - _resumeDataBlock = nil; - - // Save callbackQueue since releaseCallbacks clears it. - dispatch_queue_t callbackQueue = _callbackQueue; - dispatch_group_enter(_callbackGroup); - [(NSURLSessionDownloadTask *)oldTask cancelByProducingResumeData:^(NSData *resumeData) { - [self invokeOnCallbackQueue:callbackQueue - afterUserStopped:YES - block:^{ - resumeBlock(resumeData); - dispatch_group_leave(self->_callbackGroup); - }]; - }]; - } - hasCanceledTask = YES; - } - } - - // If the task was canceled, wait until the URLSession:task:didCompleteWithError: to call - // finishTasksAndInvalidate, since calling it immediately tends to crash, see radar 18471901. - if (_session) { - BOOL shouldInvalidate = _shouldInvalidateSession; -#if TARGET_OS_IPHONE - // Don't invalidate if we've got a systemCompletionHandler, since - // URLSessionDidFinishEventsForBackgroundURLSession: won't be called if invalidated. - shouldInvalidate = shouldInvalidate && !self.systemCompletionHandler; -#endif - if (shouldInvalidate) { - __autoreleasing NSURLSession *oldSession = _session; - _session = nil; - - if (!hasCanceledTask) { - [oldSession finishTasksAndInvalidate]; - } else { - _sessionNeedingInvalidation = oldSession; - } - } - } - } // @synchronized(self) - - // send the stopped notification - [self sendStopNotificationIfNeeded]; - - [_authorizer stopAuthorizationForRequest:request]; - - if (shouldReleaseCallbacks) { - [self releaseCallbacks]; - - self.authorizer = nil; - } - - [service fetcherDidStop:self]; - -#if GTM_BACKGROUND_TASK_FETCHING - [self endBackgroundTask]; -#endif -} - -- (void)setStopNotificationNeeded:(BOOL)flag { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _isStopNotificationNeeded = flag; - } // @synchronized(self) -} - -- (void)sendStopNotificationIfNeeded { - BOOL sendNow = NO; - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (_isStopNotificationNeeded) { - _isStopNotificationNeeded = NO; - sendNow = YES; - } - } // @synchronized(self) - - if (sendNow) { - [self postNotificationOnMainThreadWithName:kGTMSessionFetcherStoppedNotification - userInfo:nil - requireAsync:NO]; - } -} - -- (void)retryFetch { - [self stopFetchReleasingCallbacks:NO]; - - // A retry will need a configuration with a fresh session identifier. - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (_sessionIdentifier && _didCreateSessionIdentifier) { - [self forgetSessionIdentifierForFetcher]; - _configuration = nil; - } - - if (_canShareSession) { - // Force a grab of the current session from the fetcher service in case - // the service's old one has become invalid. - _session = nil; - } - } // @synchronized(self) - - [self beginFetchForRetry]; -} - -- (BOOL)waitForCompletionWithTimeout:(NSTimeInterval)timeoutInSeconds { - // Uncovered in upload fetcher testing, because the chunk fetcher is being waited on, and gets - // released by the upload code. The uploader just holds onto it with an ivar, and that gets - // nilled in the chunk fetcher callback. - // Used once in while loop just to avoid unused variable compiler warning. - __autoreleasing GTMSessionFetcher *holdSelf = self; - - NSDate *giveUpDate = [NSDate dateWithTimeIntervalSinceNow:timeoutInSeconds]; - - BOOL shouldSpinRunLoop = ([NSThread isMainThread] && - (!self.callbackQueue - || self.callbackQueue == dispatch_get_main_queue())); - BOOL expired = NO; - - // Loop until the callbacks have been called and released, and until - // the connection is no longer pending, until there are no callback dispatches - // in flight, or until the timeout has expired. - int64_t delta = (int64_t)(100 * NSEC_PER_MSEC); // 100 ms - while (1) { - BOOL isTaskInProgress = (holdSelf->_sessionTask - && [_sessionTask state] != NSURLSessionTaskStateCompleted); - BOOL needsToCallCompletion = (_completionHandler != nil); - BOOL isCallbackInProgress = (_callbackGroup - && dispatch_group_wait(_callbackGroup, dispatch_time(DISPATCH_TIME_NOW, delta))); - - if (!isTaskInProgress && !needsToCallCompletion && !isCallbackInProgress) break; - - expired = ([giveUpDate timeIntervalSinceNow] < 0); - if (expired) { - GTMSESSION_LOG_DEBUG(@"GTMSessionFetcher waitForCompletionWithTimeout:%0.1f expired -- " - @"%@%@%@", timeoutInSeconds, - isTaskInProgress ? @"taskInProgress " : @"", - needsToCallCompletion ? @"needsToCallCompletion " : @"", - isCallbackInProgress ? @"isCallbackInProgress" : @""); - break; - } - - // Run the current run loop 1/1000 of a second to give the networking - // code a chance to work - const NSTimeInterval kSpinInterval = 0.001; - if (shouldSpinRunLoop) { - NSDate *stopDate = [NSDate dateWithTimeIntervalSinceNow:kSpinInterval]; - [[NSRunLoop currentRunLoop] runUntilDate:stopDate]; - } else { - [NSThread sleepForTimeInterval:kSpinInterval]; - } - } - return !expired; -} - -+ (void)setGlobalTestBlock:(GTMSessionFetcherTestBlock GTM_NULLABLE_TYPE)block { -#if GTM_DISABLE_FETCHER_TEST_BLOCK - GTMSESSION_ASSERT_DEBUG(block == nil, @"test blocks disabled"); -#endif - gGlobalTestBlock = [block copy]; -} - -#if GTM_BACKGROUND_TASK_FETCHING - -static GTM_NULLABLE_TYPE id<GTMUIApplicationProtocol> gSubstituteUIApp; - -+ (void)setSubstituteUIApplication:(nullable id<GTMUIApplicationProtocol>)app { - gSubstituteUIApp = app; -} - -+ (nullable id<GTMUIApplicationProtocol>)substituteUIApplication { - return gSubstituteUIApp; -} - -+ (nullable id<GTMUIApplicationProtocol>)fetcherUIApplication { - id<GTMUIApplicationProtocol> app = gSubstituteUIApp; - if (app) return app; - - // iOS App extensions should not call [UIApplication sharedApplication], even - // if UIApplication responds to it. - - static Class applicationClass = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - BOOL isAppExtension = [[[NSBundle mainBundle] bundlePath] hasSuffix:@".appex"]; - if (!isAppExtension) { - Class cls = NSClassFromString(@"UIApplication"); - if (cls && [cls respondsToSelector:NSSelectorFromString(@"sharedApplication")]) { - applicationClass = cls; - } - } - }); - - if (applicationClass) { - app = (id<GTMUIApplicationProtocol>)[applicationClass sharedApplication]; - } - return app; -} -#endif // GTM_BACKGROUND_TASK_FETCHING - -#pragma mark NSURLSession Delegate Methods - -// NSURLSession documentation indicates that redirectRequest can be passed to the handler -// but empirically redirectRequest lacks the HTTP body, so passing it will break POSTs. -// Instead, we construct a new request, a copy of the original, with overrides from the -// redirect. - -- (void)URLSession:(NSURLSession *)session - task:(NSURLSessionTask *)task -willPerformHTTPRedirection:(NSHTTPURLResponse *)redirectResponse - newRequest:(NSURLRequest *)redirectRequest - completionHandler:(void (^)(NSURLRequest * GTM_NULLABLE_TYPE))handler { - [self setSessionTask:task]; - GTM_LOG_SESSION_DELEGATE(@"%@ %p URLSession:%@ task:%@ willPerformHTTPRedirection:%@ newRequest:%@", - [self class], self, session, task, redirectResponse, redirectRequest); - - if ([self userStoppedFetching]) { - handler(nil); - return; - } - if (redirectRequest && redirectResponse) { - // Copy the original request, including the body. - NSURLRequest *originalRequest = self.request; - NSMutableURLRequest *newRequest = [originalRequest mutableCopy]; - - // The new requests's URL overrides the original's URL. - [newRequest setURL:[GTMSessionFetcher redirectURLWithOriginalRequestURL:originalRequest.URL - redirectRequestURL:redirectRequest.URL]]; - - // Any headers in the redirect override headers in the original. - NSDictionary *redirectHeaders = redirectRequest.allHTTPHeaderFields; - for (NSString *key in redirectHeaders) { - NSString *value = [redirectHeaders objectForKey:key]; - [newRequest setValue:value forHTTPHeaderField:key]; - } - - redirectRequest = newRequest; - - // Log the response we just received - [self setResponse:redirectResponse]; - [self logNowWithError:nil]; - - GTMSessionFetcherWillRedirectBlock willRedirectBlock = self.willRedirectBlock; - if (willRedirectBlock) { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - [self invokeOnCallbackQueueAfterUserStopped:YES - block:^{ - willRedirectBlock(redirectResponse, redirectRequest, ^(NSURLRequest *clientRequest) { - - // Update the request for future logging. - [self updateMutableRequest:[clientRequest mutableCopy]]; - - handler(clientRequest); - }); - }]; - } // @synchronized(self) - return; - } - // Continues here if the client did not provide a redirect block. - - // Update the request for future logging. - [self updateMutableRequest:[redirectRequest mutableCopy]]; - } - handler(redirectRequest); -} - -- (void)URLSession:(NSURLSession *)session - dataTask:(NSURLSessionDataTask *)dataTask -didReceiveResponse:(NSURLResponse *)response - completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))handler { - [self setSessionTask:dataTask]; - GTM_LOG_SESSION_DELEGATE(@"%@ %p URLSession:%@ dataTask:%@ didReceiveResponse:%@", - [self class], self, session, dataTask, response); - void (^accumulateAndFinish)(NSURLSessionResponseDisposition) = - ^(NSURLSessionResponseDisposition dispositionValue) { - // This method is called when the server has determined that it - // has enough information to create the NSURLResponse - // it can be called multiple times, for example in the case of a - // redirect, so each time we reset the data. - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - BOOL hadPreviousData = self->_downloadedLength > 0; - - [self->_downloadedData setLength:0]; - self->_downloadedLength = 0; - - if (hadPreviousData && (dispositionValue != NSURLSessionResponseCancel)) { - // Tell the accumulate block to discard prior data. - GTMSessionFetcherAccumulateDataBlock accumulateBlock = self->_accumulateDataBlock; - if (accumulateBlock) { - [self invokeOnCallbackQueueUnlessStopped:^{ - accumulateBlock(nil); - }]; - } - } - } // @synchronized(self) - handler(dispositionValue); - }; - - GTMSessionFetcherDidReceiveResponseBlock receivedResponseBlock; - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - receivedResponseBlock = _didReceiveResponseBlock; - if (receivedResponseBlock) { - // We will ultimately need to call back to NSURLSession's handler with the disposition value - // for this delegate method even if the user has stopped the fetcher. - [self invokeOnCallbackQueueAfterUserStopped:YES - block:^{ - receivedResponseBlock(response, ^(NSURLSessionResponseDisposition desiredDisposition) { - accumulateAndFinish(desiredDisposition); - }); - }]; - } - } // @synchronized(self) - - if (receivedResponseBlock == nil) { - accumulateAndFinish(NSURLSessionResponseAllow); - } -} - -- (void)URLSession:(NSURLSession *)session - dataTask:(NSURLSessionDataTask *)dataTask -didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask { - GTM_LOG_SESSION_DELEGATE(@"%@ %p URLSession:%@ dataTask:%@ didBecomeDownloadTask:%@", - [self class], self, session, dataTask, downloadTask); - [self setSessionTask:downloadTask]; -} - - -- (void)URLSession:(NSURLSession *)session - task:(NSURLSessionTask *)task -didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge - completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, - NSURLCredential * GTM_NULLABLE_TYPE credential))handler { - [self setSessionTask:task]; - GTM_LOG_SESSION_DELEGATE(@"%@ %p URLSession:%@ task:%@ didReceiveChallenge:%@", - [self class], self, session, task, challenge); - - GTMSessionFetcherChallengeBlock challengeBlock = self.challengeBlock; - if (challengeBlock) { - // The fetcher user has provided custom challenge handling. - // - // We will ultimately need to call back to NSURLSession's handler with the disposition value - // for this delegate method even if the user has stopped the fetcher. - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - [self invokeOnCallbackQueueAfterUserStopped:YES - block:^{ - challengeBlock(self, challenge, handler); - }]; - } - } else { - // No challenge block was provided by the client. - [self respondToChallenge:challenge - completionHandler:handler]; - } -} - -- (void)respondToChallenge:(NSURLAuthenticationChallenge *)challenge - completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, - NSURLCredential * GTM_NULLABLE_TYPE credential))handler { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - NSInteger previousFailureCount = [challenge previousFailureCount]; - if (previousFailureCount <= 2) { - NSURLProtectionSpace *protectionSpace = [challenge protectionSpace]; - NSString *authenticationMethod = [protectionSpace authenticationMethod]; - if ([authenticationMethod isEqual:NSURLAuthenticationMethodServerTrust]) { - // SSL. - // - // Background sessions seem to require an explicit check of the server trust object - // rather than default handling. - SecTrustRef serverTrust = challenge.protectionSpace.serverTrust; - if (serverTrust == NULL) { - // No server trust information is available. - handler(NSURLSessionAuthChallengePerformDefaultHandling, nil); - } else { - // Server trust information is available. - void (^callback)(SecTrustRef, BOOL) = ^(SecTrustRef trustRef, BOOL allow){ - if (allow) { - NSURLCredential *trustCredential = [NSURLCredential credentialForTrust:trustRef]; - handler(NSURLSessionAuthChallengeUseCredential, trustCredential); - } else { - GTMSESSION_LOG_DEBUG(@"Cancelling authentication challenge for %@", self->_request.URL); - handler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil); - } - }; - if (_allowInvalidServerCertificates) { - callback(serverTrust, YES); - } else { - [[self class] evaluateServerTrust:serverTrust - forRequest:_request - completionHandler:callback]; - } - } - return; - } - - NSURLCredential *credential = _credential; - - if ([[challenge protectionSpace] isProxy] && _proxyCredential != nil) { - credential = _proxyCredential; - } - - if (credential) { - handler(NSURLSessionAuthChallengeUseCredential, credential); - } else { - // The credential is still nil; tell the OS to use the default handling. This is needed - // for things that can come out of the keychain (proxies, client certificates, etc.). - // - // Note: Looking up a credential with NSURLCredentialStorage's - // defaultCredentialForProtectionSpace: is *not* the same invoking the handler with - // NSURLSessionAuthChallengePerformDefaultHandling. In the case of - // NSURLAuthenticationMethodClientCertificate, you can get nil back from - // NSURLCredentialStorage, while using this code path instead works. - handler(NSURLSessionAuthChallengePerformDefaultHandling, nil); - } - - } else { - // We've failed auth 3 times. The completion handler will be called with code - // NSURLErrorCancelled. - handler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil); - } - } // @synchronized(self) -} - -// Return redirect URL based on the original request URL and redirect request URL. -// -// Method disallows any scheme changes between the original request URL and redirect request URL -// aside from "http" to "https". If a change in scheme is detected the redirect URL inherits the -// scheme from the original request URL. -+ (GTM_NULLABLE NSURL *)redirectURLWithOriginalRequestURL:(GTM_NULLABLE NSURL *)originalRequestURL - redirectRequestURL:(GTM_NULLABLE NSURL *)redirectRequestURL { - // In the case of an NSURLSession redirect, neither URL should ever be nil; as a sanity check - // if either is nil return the other URL. - if (!redirectRequestURL) return originalRequestURL; - if (!originalRequestURL) return redirectRequestURL; - - NSString *originalScheme = originalRequestURL.scheme; - NSString *redirectScheme = redirectRequestURL.scheme; - BOOL insecureToSecureRedirect = - (originalScheme != nil && [originalScheme caseInsensitiveCompare:@"http"] == NSOrderedSame && - redirectScheme != nil && [redirectScheme caseInsensitiveCompare:@"https"] == NSOrderedSame); - - // Check for changes to the scheme and disallow any changes except for http to https. - if (!insecureToSecureRedirect && - (redirectScheme.length != originalScheme.length || - [redirectScheme caseInsensitiveCompare:originalScheme] != NSOrderedSame)) { - NSURLComponents *components = - [NSURLComponents componentsWithURL:(NSURL * _Nonnull)redirectRequestURL - resolvingAgainstBaseURL:NO]; - components.scheme = originalScheme; - return components.URL; - } - - return redirectRequestURL; -} - -// Validate the certificate chain. -// -// This may become a public method if it appears to be useful to users. -+ (void)evaluateServerTrust:(SecTrustRef)serverTrust - forRequest:(NSURLRequest *)request - completionHandler:(void (^)(SecTrustRef trustRef, BOOL allow))handler { - // Retain the trust object to avoid a SecTrustEvaluate() crash on iOS 7. - CFRetain(serverTrust); - - // Evaluate the certificate chain. - // - // The delegate queue may be the main thread. Trust evaluation could cause some - // blocking network activity, so we must evaluate async, as documented at - // https://developer.apple.com/library/ios/technotes/tn2232/ - // - // We must also avoid multiple uses of the trust object, per docs: - // "It is not safe to call this function concurrently with any other function that uses - // the same trust management object, or to re-enter this function for the same trust - // management object." - // - // SecTrustEvaluateAsync both does sync execution of Evaluate and calls back on the - // queue passed to it, according to at sources in - // http://www.opensource.apple.com/source/libsecurity_keychain/libsecurity_keychain-55050.9/lib/SecTrust.cpp - // It would require a global serial queue to ensure the evaluate happens only on a - // single thread at a time, so we'll stick with using SecTrustEvaluate on a background - // thread. - dispatch_queue_t evaluateBackgroundQueue = - dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); - dispatch_async(evaluateBackgroundQueue, ^{ - // It looks like the implementation of SecTrustEvaluate() on Mac grabs a global lock, - // so it may be redundant for us to also lock, but it's easy to synchronize here - // anyway. - SecTrustResultType trustEval = kSecTrustResultInvalid; - BOOL shouldAllow; - OSStatus trustError; - @synchronized([GTMSessionFetcher class]) { - GTMSessionMonitorSynchronized([GTMSessionFetcher class]); - - trustError = SecTrustEvaluate(serverTrust, &trustEval); - } - if (trustError != errSecSuccess) { - GTMSESSION_LOG_DEBUG(@"Error %d evaluating trust for %@", - (int)trustError, request); - shouldAllow = NO; - } else { - // Having a trust level "unspecified" by the user is the usual result, described at - // https://developer.apple.com/library/mac/qa/qa1360 - if (trustEval == kSecTrustResultUnspecified - || trustEval == kSecTrustResultProceed) { - shouldAllow = YES; - } else { - shouldAllow = NO; - GTMSESSION_LOG_DEBUG(@"Challenge SecTrustResultType %u for %@, properties: %@", - trustEval, request.URL.host, - CFBridgingRelease(SecTrustCopyProperties(serverTrust))); - } - } - handler(serverTrust, shouldAllow); - - CFRelease(serverTrust); - }); -} - -- (void)invokeOnCallbackQueueUnlessStopped:(void (^)(void))block { - [self invokeOnCallbackQueueAfterUserStopped:NO - block:block]; -} - -- (void)invokeOnCallbackQueueAfterUserStopped:(BOOL)afterStopped - block:(void (^)(void))block { - GTMSessionCheckSynchronized(self); - - [self invokeOnCallbackUnsynchronizedQueueAfterUserStopped:afterStopped - block:block]; -} - -- (void)invokeOnCallbackUnsynchronizedQueueAfterUserStopped:(BOOL)afterStopped - block:(void (^)(void))block { - // testBlock simulation code may not be synchronizing when this is invoked. - [self invokeOnCallbackQueue:_callbackQueue - afterUserStopped:afterStopped - block:block]; -} - -- (void)invokeOnCallbackQueue:(dispatch_queue_t)callbackQueue - afterUserStopped:(BOOL)afterStopped - block:(void (^)(void))block { - if (callbackQueue) { - dispatch_group_async(_callbackGroup, callbackQueue, ^{ - if (!afterStopped) { - NSDate *serviceStoppedAllDate = [self->_service stoppedAllFetchersDate]; - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - // Avoid a race between stopFetching and the callback. - if (self->_userStoppedFetching) { - return; - } - - // Also avoid calling back if the service has stopped all fetchers - // since this one was created. The fetcher may have stopped before - // stopAllFetchers was invoked, so _userStoppedFetching wasn't set, - // but the app still won't expect the callback to fire after - // the service's stopAllFetchers was invoked. - if (serviceStoppedAllDate - && [self->_initialBeginFetchDate compare:serviceStoppedAllDate] != NSOrderedDescending) { - // stopAllFetchers was called after this fetcher began. - return; - } - } // @synchronized(self) - } - block(); - }); - } -} - -- (void)invokeFetchCallbacksOnCallbackQueueWithData:(GTM_NULLABLE NSData *)data - error:(GTM_NULLABLE NSError *)error { - // Callbacks will be released in the method stopFetchReleasingCallbacks: - GTMSessionFetcherCompletionHandler handler; - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - handler = _completionHandler; - - if (handler) { - [self invokeOnCallbackQueueUnlessStopped:^{ - handler(data, error); - - // Post a notification, primarily to allow code to collect responses for - // testing. - // - // The observing code is not likely on the fetcher's callback - // queue, so this posts explicitly to the main queue. - NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; - if (data) { - userInfo[kGTMSessionFetcherCompletionDataKey] = data; - } - if (error) { - userInfo[kGTMSessionFetcherCompletionErrorKey] = error; - } - [self postNotificationOnMainThreadWithName:kGTMSessionFetcherCompletionInvokedNotification - userInfo:userInfo - requireAsync:NO]; - }]; - } - } // @synchronized(self) -} - -- (void)postNotificationOnMainThreadWithName:(NSString *)noteName - userInfo:(GTM_NULLABLE NSDictionary *)userInfo - requireAsync:(BOOL)requireAsync { - dispatch_block_t postBlock = ^{ - [[NSNotificationCenter defaultCenter] postNotificationName:noteName - object:self - userInfo:userInfo]; - }; - - if ([NSThread isMainThread] && !requireAsync) { - // Post synchronously for compatibility with older code using the fetcher. - - // Avoid calling out to other code from inside a sync block to avoid risk - // of a deadlock or of recursive sync. - GTMSessionCheckNotSynchronized(self); - - postBlock(); - } else { - dispatch_async(dispatch_get_main_queue(), postBlock); - } -} - -- (void)URLSession:(NSURLSession *)session - task:(NSURLSessionTask *)uploadTask - needNewBodyStream:(void (^)(NSInputStream * GTM_NULLABLE_TYPE bodyStream))completionHandler { - [self setSessionTask:uploadTask]; - GTM_LOG_SESSION_DELEGATE(@"%@ %p URLSession:%@ task:%@ needNewBodyStream:", - [self class], self, session, uploadTask); - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - GTMSessionFetcherBodyStreamProvider provider = _bodyStreamProvider; -#if !STRIP_GTM_FETCH_LOGGING - if ([self respondsToSelector:@selector(loggedStreamProviderForStreamProvider:)]) { - provider = [self performSelector:@selector(loggedStreamProviderForStreamProvider:) - withObject:provider]; - } -#endif - if (provider) { - [self invokeOnCallbackQueueUnlessStopped:^{ - provider(completionHandler); - }]; - } else { - GTMSESSION_ASSERT_DEBUG(NO, @"NSURLSession expects a stream provider"); - - completionHandler(nil); - } - } // @synchronized(self) -} - -- (void)URLSession:(NSURLSession *)session - task:(NSURLSessionTask *)task - didSendBodyData:(int64_t)bytesSent - totalBytesSent:(int64_t)totalBytesSent -totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend { - [self setSessionTask:task]; - GTM_LOG_SESSION_DELEGATE(@"%@ %p URLSession:%@ task:%@ didSendBodyData:%lld" - @" totalBytesSent:%lld totalBytesExpectedToSend:%lld", - [self class], self, session, task, bytesSent, totalBytesSent, - totalBytesExpectedToSend); - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (!_sendProgressBlock) { - return; - } - // We won't hold on to send progress block; it's ok to not send it if the upload finishes. - [self invokeOnCallbackQueueUnlessStopped:^{ - GTMSessionFetcherSendProgressBlock progressBlock; - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - progressBlock = self->_sendProgressBlock; - } - if (progressBlock) { - progressBlock(bytesSent, totalBytesSent, totalBytesExpectedToSend); - } - }]; - } // @synchronized(self) -} - -- (void)URLSession:(NSURLSession *)session - dataTask:(NSURLSessionDataTask *)dataTask - didReceiveData:(NSData *)data { - [self setSessionTask:dataTask]; - NSUInteger bufferLength = data.length; - GTM_LOG_SESSION_DELEGATE(@"%@ %p URLSession:%@ dataTask:%@ didReceiveData:%p (%llu bytes)", - [self class], self, session, dataTask, data, - (unsigned long long)bufferLength); - if (bufferLength == 0) { - // Observed on completing an out-of-process upload. - return; - } - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - GTMSessionFetcherAccumulateDataBlock accumulateBlock = _accumulateDataBlock; - if (accumulateBlock) { - // Let the client accumulate the data. - _downloadedLength += bufferLength; - [self invokeOnCallbackQueueUnlessStopped:^{ - accumulateBlock(data); - }]; - } else if (!_userStoppedFetching) { - // Append to the mutable data buffer unless the fetch has been cancelled. - - // Resumed upload tasks may not yet have a data buffer. - if (_downloadedData == nil) { - // Using NSClassFromString for iOS 6 compatibility. - GTMSESSION_ASSERT_DEBUG( - ![dataTask isKindOfClass:NSClassFromString(@"NSURLSessionDownloadTask")], - @"Resumed download tasks should not receive data bytes"); - _downloadedData = [[NSMutableData alloc] init]; - } - - [_downloadedData appendData:data]; - _downloadedLength = (int64_t)_downloadedData.length; - - // We won't hold on to receivedProgressBlock here; it's ok to not send - // it if the transfer finishes. - if (_receivedProgressBlock) { - [self invokeOnCallbackQueueUnlessStopped:^{ - GTMSessionFetcherReceivedProgressBlock progressBlock; - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - progressBlock = self->_receivedProgressBlock; - } - if (progressBlock) { - progressBlock((int64_t)bufferLength, self->_downloadedLength); - } - }]; - } - } - } // @synchronized(self) -} - -- (void)URLSession:(NSURLSession *)session - dataTask:(NSURLSessionDataTask *)dataTask - willCacheResponse:(NSCachedURLResponse *)proposedResponse - completionHandler:(void (^)(NSCachedURLResponse *cachedResponse))completionHandler { - GTM_LOG_SESSION_DELEGATE(@"%@ %p URLSession:%@ dataTask:%@ willCacheResponse:%@ %@", - [self class], self, session, dataTask, - proposedResponse, proposedResponse.response); - GTMSessionFetcherWillCacheURLResponseBlock callback; - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - callback = _willCacheURLResponseBlock; - - if (callback) { - [self invokeOnCallbackQueueAfterUserStopped:YES - block:^{ - callback(proposedResponse, completionHandler); - }]; - } - } // @synchronized(self) - if (!callback) { - completionHandler(proposedResponse); - } -} - - -- (void)URLSession:(NSURLSession *)session - downloadTask:(NSURLSessionDownloadTask *)downloadTask - didWriteData:(int64_t)bytesWritten - totalBytesWritten:(int64_t)totalBytesWritten -totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite { - GTM_LOG_SESSION_DELEGATE(@"%@ %p URLSession:%@ downloadTask:%@ didWriteData:%lld" - @" bytesWritten:%lld totalBytesExpectedToWrite:%lld", - [self class], self, session, downloadTask, bytesWritten, - totalBytesWritten, totalBytesExpectedToWrite); - [self setSessionTask:downloadTask]; - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if ((totalBytesExpectedToWrite != NSURLSessionTransferSizeUnknown) && - (totalBytesExpectedToWrite < totalBytesWritten)) { - // Have observed cases were bytesWritten == totalBytesExpectedToWrite, - // but totalBytesWritten > totalBytesExpectedToWrite, so setting to unkown in these cases. - totalBytesExpectedToWrite = NSURLSessionTransferSizeUnknown; - } - // We won't hold on to download progress block during the enqueue; - // it's ok to not send it if the upload finishes. - - [self invokeOnCallbackQueueUnlessStopped:^{ - GTMSessionFetcherDownloadProgressBlock progressBlock; - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - progressBlock = self->_downloadProgressBlock; - } - if (progressBlock) { - progressBlock(bytesWritten, totalBytesWritten, totalBytesExpectedToWrite); - } - }]; - } // @synchronized(self) -} - -- (void)URLSession:(NSURLSession *)session - downloadTask:(NSURLSessionDownloadTask *)downloadTask - didResumeAtOffset:(int64_t)fileOffset -expectedTotalBytes:(int64_t)expectedTotalBytes { - GTM_LOG_SESSION_DELEGATE(@"%@ %p URLSession:%@ downloadTask:%@ didResumeAtOffset:%lld" - @" expectedTotalBytes:%lld", - [self class], self, session, downloadTask, fileOffset, - expectedTotalBytes); - [self setSessionTask:downloadTask]; -} - -- (void)URLSession:(NSURLSession *)session - downloadTask:(NSURLSessionDownloadTask *)downloadTask -didFinishDownloadingToURL:(NSURL *)downloadLocationURL { - // Download may have relaunched app, so update _sessionTask. - [self setSessionTask:downloadTask]; - GTM_LOG_SESSION_DELEGATE(@"%@ %p URLSession:%@ downloadTask:%@ didFinishDownloadingToURL:%@", - [self class], self, session, downloadTask, downloadLocationURL); - NSNumber *fileSizeNum; - [downloadLocationURL getResourceValue:&fileSizeNum - forKey:NSURLFileSizeKey - error:NULL]; - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - NSURL *destinationURL = _destinationFileURL; - - _downloadedLength = fileSizeNum.longLongValue; - - // Overwrite any previous file at the destination URL. - NSFileManager *fileMgr = [NSFileManager defaultManager]; - NSError *removeError; - if (![fileMgr removeItemAtURL:destinationURL error:&removeError] - && removeError.code != NSFileNoSuchFileError) { - GTMSESSION_LOG_DEBUG(@"Could not remove previous file at %@ due to %@", - downloadLocationURL.path, removeError); - } - - NSInteger statusCode = [self statusCodeUnsynchronized]; - if (statusCode < 200 || statusCode > 399) { - // In OS X 10.11, the response body is written to a file even on a server - // status error. For convenience of the fetcher client, we'll skip saving the - // downloaded body to the destination URL so that clients do not need to know - // to delete the file following fetch errors. - GTMSESSION_LOG_DEBUG(@"Abandoning download due to status %ld, file %@", - (long)statusCode, downloadLocationURL.path); - - // On error code, add the contents of the temporary file to _downloadTaskErrorData - // This way fetcher clients have access to error details possibly passed by the server. - if (_downloadedLength > 0 && _downloadedLength <= kMaximumDownloadErrorDataLength) { - _downloadTaskErrorData = [NSData dataWithContentsOfURL:downloadLocationURL]; - } else if (_downloadedLength > kMaximumDownloadErrorDataLength) { - GTMSESSION_LOG_DEBUG(@"Download error data for file %@ not passed to userInfo due to size " - @"%lld", downloadLocationURL.path, _downloadedLength); - } - } else { - NSError *moveError; - NSURL *destinationFolderURL = [destinationURL URLByDeletingLastPathComponent]; - BOOL didMoveDownload = NO; - if ([fileMgr createDirectoryAtURL:destinationFolderURL - withIntermediateDirectories:YES - attributes:nil - error:&moveError]) { - didMoveDownload = [fileMgr moveItemAtURL:downloadLocationURL - toURL:destinationURL - error:&moveError]; - } - if (!didMoveDownload) { - _downloadFinishedError = moveError; - } - GTM_LOG_BACKGROUND_SESSION(@"%@ %p Moved download from \"%@\" to \"%@\" %@", - [self class], self, - downloadLocationURL.path, destinationURL.path, - error ? error : @""); - } - } // @synchronized(self) -} - -/* Sent as the last message related to a specific task. Error may be - * nil, which implies that no error occurred and this task is complete. - */ -- (void)URLSession:(NSURLSession *)session - task:(NSURLSessionTask *)task -didCompleteWithError:(NSError *)error { - [self setSessionTask:task]; - GTM_LOG_SESSION_DELEGATE(@"%@ %p URLSession:%@ task:%@ didCompleteWithError:%@", - [self class], self, session, task, error); - - NSInteger status = self.statusCode; - BOOL forceAssumeRetry = NO; - BOOL succeeded = NO; - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - -#if !GTM_DISABLE_FETCHER_TEST_BLOCK - // The task is never resumed when a testBlock is used. When the session is destroyed, - // we should ignore the callback, since the testBlock support code itself invokes - // shouldRetryNowForStatus: and finishWithError:shouldRetry: - if (_isUsingTestBlock) return; -#endif - - if (error == nil) { - error = _downloadFinishedError; - } - succeeded = (error == nil && status >= 0 && status < 300); - if (succeeded) { - // Succeeded. - _bodyLength = task.countOfBytesSent; - } - } // @synchronized(self) - - if (succeeded) { - [self finishWithError:nil shouldRetry:NO]; - return; - } - // For background redirects, no delegate method is called, so we cannot restore a stripped - // Authorization header, so if a 403 ("Forbidden") was generated due to a missing OAuth 2 header, - // set the current request's URL to the redirected URL, so we in effect restore the Authorization - // header. - if ((status == 403) && self.usingBackgroundSession) { - NSURL *redirectURL = self.response.URL; - NSURLRequest *request = self.request; - if (![request.URL isEqual:redirectURL]) { - NSString *authorizationHeader = [request.allHTTPHeaderFields objectForKey:@"Authorization"]; - if (authorizationHeader != nil) { - NSMutableURLRequest *mutableRequest = [request mutableCopy]; - mutableRequest.URL = redirectURL; - [self updateMutableRequest:mutableRequest]; - // Avoid assuming the session is still valid. - self.session = nil; - forceAssumeRetry = YES; - } - } - } - - // If invalidating the session was deferred in stopFetchReleasingCallbacks: then do it now. - NSURLSession *oldSession = self.sessionNeedingInvalidation; - if (oldSession) { - [self setSessionNeedingInvalidation:NULL]; - [oldSession finishTasksAndInvalidate]; - } - - // Failed. - [self shouldRetryNowForStatus:status - error:error - forceAssumeRetry:forceAssumeRetry - response:^(BOOL shouldRetry) { - [self finishWithError:error shouldRetry:shouldRetry]; - }]; -} - -#if TARGET_OS_IPHONE -- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session { - GTM_LOG_SESSION_DELEGATE(@"%@ %p URLSessionDidFinishEventsForBackgroundURLSession:%@", - [self class], self, session); - [self removePersistedBackgroundSessionFromDefaults]; - - GTMSessionFetcherSystemCompletionHandler handler; - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - handler = self.systemCompletionHandler; - self.systemCompletionHandler = nil; - } // @synchronized(self) - if (handler) { - GTM_LOG_BACKGROUND_SESSION(@"%@ %p Calling system completionHandler", [self class], self); - handler(); - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - NSURLSession *oldSession = _session; - _session = nil; - if (_shouldInvalidateSession) { - [oldSession finishTasksAndInvalidate]; - } - } // @synchronized(self) - } -} -#endif - -- (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(GTM_NULLABLE NSError *)error { - // This may happen repeatedly for retries. On authentication callbacks, the retry - // may begin before the prior session sends the didBecomeInvalid delegate message. - GTM_LOG_SESSION_DELEGATE(@"%@ %p URLSession:%@ didBecomeInvalidWithError:%@", - [self class], self, session, error); - if (session == (NSURLSession *)self.session) { - GTM_LOG_SESSION_DELEGATE(@" Unexpected retained invalid session: %@", session); - self.session = nil; - } -} - -- (void)finishWithError:(GTM_NULLABLE NSError *)error shouldRetry:(BOOL)shouldRetry { - [self removePersistedBackgroundSessionFromDefaults]; - - BOOL shouldStopFetching = YES; - NSData *downloadedData = nil; -#if !STRIP_GTM_FETCH_LOGGING - BOOL shouldDeferLogging = NO; -#endif - BOOL shouldBeginRetryTimer = NO; - NSInteger status = [self statusCode]; - NSURL *destinationURL = self.destinationFileURL; - - BOOL fetchSucceeded = (error == nil && status >= 0 && status < 300); - -#if !STRIP_GTM_FETCH_LOGGING - if (!fetchSucceeded) { - if (!shouldDeferLogging && !self.hasLoggedError) { - [self logNowWithError:error]; - self.hasLoggedError = YES; - } - } -#endif // !STRIP_GTM_FETCH_LOGGING - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - -#if !STRIP_GTM_FETCH_LOGGING - shouldDeferLogging = _deferResponseBodyLogging; -#endif - if (fetchSucceeded) { - // Success - if ((_downloadedData.length > 0) && (destinationURL != nil)) { - // Overwrite any previous file at the destination URL. - NSFileManager *fileMgr = [NSFileManager defaultManager]; - [fileMgr removeItemAtURL:destinationURL - error:NULL]; - NSURL *destinationFolderURL = [destinationURL URLByDeletingLastPathComponent]; - BOOL didMoveDownload = NO; - if ([fileMgr createDirectoryAtURL:destinationFolderURL - withIntermediateDirectories:YES - attributes:nil - error:&error]) { - didMoveDownload = [_downloadedData writeToURL:destinationURL - options:NSDataWritingAtomic - error:&error]; - } - if (didMoveDownload) { - _downloadedData = nil; - } else { - _downloadFinishedError = error; - } - } - downloadedData = _downloadedData; - } else { - // Unsuccessful with error or status over 300. Retry or notify the delegate of failure - if (shouldRetry) { - // Retrying. - shouldBeginRetryTimer = YES; - shouldStopFetching = NO; - } else { - if (error == nil) { - // Create an error. - NSDictionary *userInfo = GTMErrorUserInfoForData( - _downloadedData.length > 0 ? _downloadedData : _downloadTaskErrorData, - [self responseHeadersUnsynchronized]); - - error = [NSError errorWithDomain:kGTMSessionFetcherStatusDomain - code:status - userInfo:userInfo]; - } else { - // If the error had resume data, and the client supplied a resume block, pass the - // data to the client. - void (^resumeBlock)(NSData *) = _resumeDataBlock; - _resumeDataBlock = nil; - if (resumeBlock) { - NSData *resumeData = [error.userInfo objectForKey:NSURLSessionDownloadTaskResumeData]; - if (resumeData) { - [self invokeOnCallbackQueueAfterUserStopped:YES block:^{ - resumeBlock(resumeData); - }]; - } - } - } - if (_downloadedData.length > 0) { - downloadedData = _downloadedData; - } - // If the error occurred after retries, report the number and duration of the - // retries. This provides a clue to a developer looking at the error description - // that the fetcher did retry before failing with this error. - if (_retryCount > 0) { - NSMutableDictionary *userInfoWithRetries = - [NSMutableDictionary dictionaryWithDictionary:(NSDictionary *)error.userInfo]; - NSTimeInterval timeSinceInitialRequest = -[_initialRequestDate timeIntervalSinceNow]; - [userInfoWithRetries setObject:@(timeSinceInitialRequest) - forKey:kGTMSessionFetcherElapsedIntervalWithRetriesKey]; - [userInfoWithRetries setObject:@(_retryCount) - forKey:kGTMSessionFetcherNumberOfRetriesDoneKey]; - error = [NSError errorWithDomain:(NSString *)error.domain - code:error.code - userInfo:userInfoWithRetries]; - } - } - } - } // @synchronized(self) - - if (shouldBeginRetryTimer) { - [self beginRetryTimer]; - } - - // We want to send the stop notification before calling the delegate's - // callback selector, since the callback selector may release all of - // the fetcher properties that the client is using to track the fetches. - // - // We'll also stop now so that, to any observers watching the notifications, - // it doesn't look like our wait for a retry (which may be long, - // 30 seconds or more) is part of the network activity. - [self sendStopNotificationIfNeeded]; - - if (shouldStopFetching) { - [self invokeFetchCallbacksOnCallbackQueueWithData:downloadedData - error:error]; - // The upload subclass doesn't want to release callbacks until upload chunks have completed. - BOOL shouldRelease = [self shouldReleaseCallbacksUponCompletion]; - [self stopFetchReleasingCallbacks:shouldRelease]; - } - -#if !STRIP_GTM_FETCH_LOGGING - // _hasLoggedError is only set by this method - if (!shouldDeferLogging && !_hasLoggedError) { - [self logNowWithError:error]; - } -#endif -} - -- (BOOL)shouldReleaseCallbacksUponCompletion { - // A subclass can override this to keep callbacks around after the - // connection has finished successfully - return YES; -} - -- (void)logNowWithError:(GTM_NULLABLE NSError *)error { - GTMSessionCheckNotSynchronized(self); - - // If the logging category is available, then log the current request, - // response, data, and error - if ([self respondsToSelector:@selector(logFetchWithError:)]) { - [self performSelector:@selector(logFetchWithError:) withObject:error]; - } -} - -#pragma mark Retries - -- (BOOL)isRetryError:(NSError *)error { - struct RetryRecord { - __unsafe_unretained NSString *const domain; - NSInteger code; - }; - - struct RetryRecord retries[] = { - { kGTMSessionFetcherStatusDomain, 408 }, // request timeout - { kGTMSessionFetcherStatusDomain, 502 }, // failure gatewaying to another server - { kGTMSessionFetcherStatusDomain, 503 }, // service unavailable - { kGTMSessionFetcherStatusDomain, 504 }, // request timeout - { NSURLErrorDomain, NSURLErrorTimedOut }, - { NSURLErrorDomain, NSURLErrorNetworkConnectionLost }, - { nil, 0 } - }; - - // NSError's isEqual always returns false for equal but distinct instances - // of NSError, so we have to compare the domain and code values explicitly - NSString *domain = error.domain; - NSInteger code = error.code; - for (int idx = 0; retries[idx].domain != nil; idx++) { - if (code == retries[idx].code && [domain isEqual:retries[idx].domain]) { - return YES; - } - } - return NO; -} - -// shouldRetryNowForStatus:error: responds with YES if the user has enabled retries -// and the status or error is one that is suitable for retrying. "Suitable" -// means either the isRetryError:'s list contains the status or error, or the -// user's retry block is present and returns YES when called, or the -// authorizer may be able to fix. -- (void)shouldRetryNowForStatus:(NSInteger)status - error:(NSError *)error - forceAssumeRetry:(BOOL)forceAssumeRetry - response:(GTMSessionFetcherRetryResponse)response { - // Determine if a refreshed authorizer may avoid an authorization error - BOOL willRetry = NO; - - // We assume _authorizer is immutable after beginFetch, and _hasAttemptedAuthRefresh is modified - // only in this method, and this method is invoked on the serial delegate queue. - // - // We want to avoid calling the authorizer from inside a sync block. - BOOL isFirstAuthError = (_authorizer != nil - && !_hasAttemptedAuthRefresh - && status == GTMSessionFetcherStatusUnauthorized); // 401 - - BOOL hasPrimed = NO; - if (isFirstAuthError) { - if ([_authorizer respondsToSelector:@selector(primeForRefresh)]) { - hasPrimed = [_authorizer primeForRefresh]; - } - } - - BOOL shouldRetryForAuthRefresh = NO; - if (hasPrimed) { - shouldRetryForAuthRefresh = YES; - _hasAttemptedAuthRefresh = YES; - [self updateRequestValue:nil forHTTPHeaderField:@"Authorization"]; - } - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - BOOL shouldDoRetry = [self isRetryEnabledUnsynchronized]; - if (shouldDoRetry && ![self hasRetryAfterInterval]) { - - // Determine if we're doing exponential backoff retries - shouldDoRetry = [self nextRetryIntervalUnsynchronized] < _maxRetryInterval; - - if (shouldDoRetry) { - // If an explicit max retry interval was set, we expect repeated backoffs to take - // up to roughly twice that for repeated fast failures. If the initial attempt is - // already more than 3 times the max retry interval, then failures have taken a long time - // (such as from network timeouts) so don't retry again to avoid the app becoming - // unexpectedly unresponsive. - if (_maxRetryInterval > 0) { - NSTimeInterval maxAllowedIntervalBeforeRetry = _maxRetryInterval * 3; - NSTimeInterval timeSinceInitialRequest = -[_initialRequestDate timeIntervalSinceNow]; - if (timeSinceInitialRequest > maxAllowedIntervalBeforeRetry) { - shouldDoRetry = NO; - } - } - } - } - BOOL canRetry = shouldRetryForAuthRefresh || forceAssumeRetry || shouldDoRetry; - if (canRetry) { - NSDictionary *userInfo = - GTMErrorUserInfoForData(_downloadedData, [self responseHeadersUnsynchronized]); - NSError *statusError = [NSError errorWithDomain:kGTMSessionFetcherStatusDomain - code:status - userInfo:userInfo]; - if (error == nil) { - error = statusError; - } - willRetry = shouldRetryForAuthRefresh || - forceAssumeRetry || - [self isRetryError:error] || - ((error != statusError) && [self isRetryError:statusError]); - - // If the user has installed a retry callback, consult that. - GTMSessionFetcherRetryBlock retryBlock = _retryBlock; - if (retryBlock) { - [self invokeOnCallbackQueueUnlessStopped:^{ - retryBlock(willRetry, error, response); - }]; - return; - } - } - } // @synchronized(self) - response(willRetry); -} - -- (BOOL)hasRetryAfterInterval { - GTMSessionCheckSynchronized(self); - - NSDictionary *responseHeaders = [self responseHeadersUnsynchronized]; - NSString *retryAfterValue = [responseHeaders valueForKey:@"Retry-After"]; - return (retryAfterValue != nil); -} - -- (NSTimeInterval)retryAfterInterval { - GTMSessionCheckSynchronized(self); - - NSDictionary *responseHeaders = [self responseHeadersUnsynchronized]; - NSString *retryAfterValue = [responseHeaders valueForKey:@"Retry-After"]; - if (retryAfterValue == nil) { - return 0; - } - // Retry-After formatted as HTTP-date | delta-seconds - // Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html - NSDateFormatter *rfc1123DateFormatter = [[NSDateFormatter alloc] init]; - rfc1123DateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]; - rfc1123DateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"]; - rfc1123DateFormatter.dateFormat = @"EEE',' dd MMM yyyy HH':'mm':'ss z"; - NSDate *retryAfterDate = [rfc1123DateFormatter dateFromString:retryAfterValue]; - NSTimeInterval retryAfterInterval = (retryAfterDate != nil) ? - retryAfterDate.timeIntervalSinceNow : retryAfterValue.intValue; - retryAfterInterval = MAX(0, retryAfterInterval); - return retryAfterInterval; -} - -- (void)beginRetryTimer { - if (![NSThread isMainThread]) { - // Defer creating and starting the timer until we're on the main thread to ensure it has - // a run loop. - dispatch_group_async(_callbackGroup, dispatch_get_main_queue(), ^{ - [self beginRetryTimer]; - }); - return; - } - - [self destroyRetryTimer]; - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - NSTimeInterval nextInterval = [self nextRetryIntervalUnsynchronized]; - NSTimeInterval maxInterval = _maxRetryInterval; - NSTimeInterval newInterval = MIN(nextInterval, (maxInterval > 0 ? maxInterval : DBL_MAX)); - NSTimeInterval newIntervalTolerance = (newInterval / 10) > 1.0 ?: 1.0; - - _lastRetryInterval = newInterval; - - _retryTimer = [NSTimer timerWithTimeInterval:newInterval - target:self - selector:@selector(retryTimerFired:) - userInfo:nil - repeats:NO]; - _retryTimer.tolerance = newIntervalTolerance; - [[NSRunLoop mainRunLoop] addTimer:_retryTimer - forMode:NSDefaultRunLoopMode]; - } // @synchronized(self) - - [self postNotificationOnMainThreadWithName:kGTMSessionFetcherRetryDelayStartedNotification - userInfo:nil - requireAsync:NO]; -} - -- (void)retryTimerFired:(NSTimer *)timer { - [self destroyRetryTimer]; - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _retryCount++; - } // @synchronized(self) - - NSOperationQueue *queue = self.sessionDelegateQueue; - [queue addOperationWithBlock:^{ - [self retryFetch]; - }]; -} - -- (void)destroyRetryTimer { - BOOL shouldNotify = NO; - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (_retryTimer) { - [_retryTimer invalidate]; - _retryTimer = nil; - shouldNotify = YES; - } - } - - if (shouldNotify) { - [self postNotificationOnMainThreadWithName:kGTMSessionFetcherRetryDelayStoppedNotification - userInfo:nil - requireAsync:NO]; - } -} - -- (NSUInteger)retryCount { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _retryCount; - } // @synchronized(self) -} - -- (NSTimeInterval)nextRetryInterval { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - NSTimeInterval interval = [self nextRetryIntervalUnsynchronized]; - return interval; - } // @synchronized(self) -} - -- (NSTimeInterval)nextRetryIntervalUnsynchronized { - GTMSessionCheckSynchronized(self); - - NSInteger statusCode = [self statusCodeUnsynchronized]; - if ((statusCode == 503) && [self hasRetryAfterInterval]) { - NSTimeInterval secs = [self retryAfterInterval]; - return secs; - } - // The next wait interval is the factor (2.0) times the last interval, - // but never less than the minimum interval. - NSTimeInterval secs = _lastRetryInterval * _retryFactor; - if (_maxRetryInterval > 0) { - secs = MIN(secs, _maxRetryInterval); - } - secs = MAX(secs, _minRetryInterval); - - return secs; -} - -- (NSTimer *)retryTimer { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _retryTimer; - } // @synchronized(self) -} - -- (BOOL)isRetryEnabled { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _isRetryEnabled; - } // @synchronized(self) -} - -- (BOOL)isRetryEnabledUnsynchronized { - GTMSessionCheckSynchronized(self); - - return _isRetryEnabled; -} - -- (void)setRetryEnabled:(BOOL)flag { - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (flag && !_isRetryEnabled) { - // We defer initializing these until the user calls setRetryEnabled - // to avoid using the random number generator if it's not needed. - // However, this means min and max intervals for this fetcher are reset - // as a side effect of calling setRetryEnabled. - // - // Make an initial retry interval random between 1.0 and 2.0 seconds - _minRetryInterval = InitialMinRetryInterval(); - _maxRetryInterval = kUnsetMaxRetryInterval; - _retryFactor = 2.0; - _lastRetryInterval = 0.0; - } - _isRetryEnabled = flag; - } // @synchronized(self) -}; - -- (NSTimeInterval)maxRetryInterval { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _maxRetryInterval; - } // @synchronized(self) -} - -- (void)setMaxRetryInterval:(NSTimeInterval)secs { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (secs > 0) { - _maxRetryInterval = secs; - } else { - _maxRetryInterval = kUnsetMaxRetryInterval; - } - } // @synchronized(self) -} - -- (double)minRetryInterval { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _minRetryInterval; - } // @synchronized(self) -} - -- (void)setMinRetryInterval:(NSTimeInterval)secs { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (secs > 0) { - _minRetryInterval = secs; - } else { - // Set min interval to a random value between 1.0 and 2.0 seconds - // so that if multiple clients start retrying at the same time, they'll - // repeat at different times and avoid overloading the server - _minRetryInterval = InitialMinRetryInterval(); - } - } // @synchronized(self) - -} - -#pragma mark iOS System Completion Handlers - -#if TARGET_OS_IPHONE -static NSMutableDictionary *gSystemCompletionHandlers = nil; - -- (GTM_NULLABLE GTMSessionFetcherSystemCompletionHandler)systemCompletionHandler { - return [[self class] systemCompletionHandlerForSessionIdentifier:_sessionIdentifier]; -} - -- (void)setSystemCompletionHandler:(GTM_NULLABLE GTMSessionFetcherSystemCompletionHandler)systemCompletionHandler { - [[self class] setSystemCompletionHandler:systemCompletionHandler - forSessionIdentifier:_sessionIdentifier]; -} - -+ (void)setSystemCompletionHandler:(GTM_NULLABLE GTMSessionFetcherSystemCompletionHandler)systemCompletionHandler - forSessionIdentifier:(NSString *)sessionIdentifier { - if (!sessionIdentifier) { - NSLog(@"%s with nil identifier", __PRETTY_FUNCTION__); - return; - } - - @synchronized([GTMSessionFetcher class]) { - if (gSystemCompletionHandlers == nil && systemCompletionHandler != nil) { - gSystemCompletionHandlers = [[NSMutableDictionary alloc] init]; - } - // Use setValue: to remove the object if completionHandler is nil. - [gSystemCompletionHandlers setValue:systemCompletionHandler - forKey:sessionIdentifier]; - } -} - -+ (GTM_NULLABLE GTMSessionFetcherSystemCompletionHandler)systemCompletionHandlerForSessionIdentifier:(NSString *)sessionIdentifier { - if (!sessionIdentifier) { - return nil; - } - @synchronized([GTMSessionFetcher class]) { - return [gSystemCompletionHandlers objectForKey:sessionIdentifier]; - } -} -#endif // TARGET_OS_IPHONE - -#pragma mark Getters and Setters - -@synthesize downloadResumeData = _downloadResumeData, - configuration = _configuration, - configurationBlock = _configurationBlock, - sessionTask = _sessionTask, - wasCreatedFromBackgroundSession = _wasCreatedFromBackgroundSession, - sessionUserInfo = _sessionUserInfo, - taskDescription = _taskDescription, - taskPriority = _taskPriority, - usingBackgroundSession = _usingBackgroundSession, - canShareSession = _canShareSession, - completionHandler = _completionHandler, - credential = _credential, - proxyCredential = _proxyCredential, - bodyData = _bodyData, - bodyLength = _bodyLength, - service = _service, - serviceHost = _serviceHost, - accumulateDataBlock = _accumulateDataBlock, - receivedProgressBlock = _receivedProgressBlock, - downloadProgressBlock = _downloadProgressBlock, - resumeDataBlock = _resumeDataBlock, - didReceiveResponseBlock = _didReceiveResponseBlock, - challengeBlock = _challengeBlock, - willRedirectBlock = _willRedirectBlock, - sendProgressBlock = _sendProgressBlock, - willCacheURLResponseBlock = _willCacheURLResponseBlock, - retryBlock = _retryBlock, - retryFactor = _retryFactor, - allowedInsecureSchemes = _allowedInsecureSchemes, - allowLocalhostRequest = _allowLocalhostRequest, - allowInvalidServerCertificates = _allowInvalidServerCertificates, - cookieStorage = _cookieStorage, - callbackQueue = _callbackQueue, - initialBeginFetchDate = _initialBeginFetchDate, - testBlock = _testBlock, - testBlockAccumulateDataChunkCount = _testBlockAccumulateDataChunkCount, - comment = _comment, - log = _log; - -#if !STRIP_GTM_FETCH_LOGGING -@synthesize redirectedFromURL = _redirectedFromURL, - logRequestBody = _logRequestBody, - logResponseBody = _logResponseBody, - hasLoggedError = _hasLoggedError; -#endif - -#if GTM_BACKGROUND_TASK_FETCHING -@synthesize backgroundTaskIdentifier = _backgroundTaskIdentifier, - skipBackgroundTask = _skipBackgroundTask; -#endif - -- (GTM_NULLABLE NSURLRequest *)request { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return [_request copy]; - } // @synchronized(self) -} - -- (void)setRequest:(GTM_NULLABLE NSURLRequest *)request { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (![self isFetchingUnsynchronized]) { - _request = [request mutableCopy]; - } else { - GTMSESSION_ASSERT_DEBUG(0, @"request may not be set after beginFetch has been invoked"); - } - } // @synchronized(self) -} - -- (GTM_NULLABLE NSMutableURLRequest *)mutableRequestForTesting { - // Allow tests only to modify the request, useful during retries. - return _request; -} - -// Internal method for updating the request property such as on redirects. -- (void)updateMutableRequest:(GTM_NULLABLE NSMutableURLRequest *)request { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _request = request; - } // @synchronized(self) -} - -// Set a header field value on the request. Header field value changes will not -// affect a fetch after the fetch has begun. -- (void)setRequestValue:(GTM_NULLABLE NSString *)value forHTTPHeaderField:(NSString *)field { - if (![self isFetching]) { - [self updateRequestValue:value forHTTPHeaderField:field]; - } else { - GTMSESSION_ASSERT_DEBUG(0, @"request may not be set after beginFetch has been invoked"); - } -} - -// Internal method for updating request headers. -- (void)updateRequestValue:(GTM_NULLABLE NSString *)value forHTTPHeaderField:(NSString *)field { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - [_request setValue:value forHTTPHeaderField:field]; - } // @synchronized(self) -} - -- (void)setResponse:(GTM_NULLABLE NSURLResponse *)response { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _response = response; - } // @synchronized(self) -} - -- (int64_t)bodyLength { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (_bodyLength == NSURLSessionTransferSizeUnknown) { - if (_bodyData) { - _bodyLength = (int64_t)_bodyData.length; - } else if (_bodyFileURL) { - NSNumber *fileSizeNum = nil; - NSError *fileSizeError = nil; - if ([_bodyFileURL getResourceValue:&fileSizeNum - forKey:NSURLFileSizeKey - error:&fileSizeError]) { - _bodyLength = [fileSizeNum longLongValue]; - } - } - } - return _bodyLength; - } // @synchronized(self) -} - -- (BOOL)useUploadTask { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _useUploadTask; - } // @synchronized(self) -} - -- (void)setUseUploadTask:(BOOL)flag { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (flag != _useUploadTask) { - GTMSESSION_ASSERT_DEBUG(![self isFetchingUnsynchronized], - @"useUploadTask should not change after beginFetch has been invoked"); - _useUploadTask = flag; - } - } // @synchronized(self) -} - -- (GTM_NULLABLE NSURL *)bodyFileURL { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _bodyFileURL; - } // @synchronized(self) -} - -- (void)setBodyFileURL:(GTM_NULLABLE NSURL *)fileURL { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - // The comparison here is a trivial optimization and forgiveness for any client that - // repeatedly sets the property, so it just uses pointer comparison rather than isEqual:. - if (fileURL != _bodyFileURL) { - GTMSESSION_ASSERT_DEBUG(![self isFetchingUnsynchronized], - @"fileURL should not change after beginFetch has been invoked"); - - _bodyFileURL = fileURL; - } - } // @synchronized(self) -} - -- (GTM_NULLABLE GTMSessionFetcherBodyStreamProvider)bodyStreamProvider { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _bodyStreamProvider; - } // @synchronized(self) -} - -- (void)setBodyStreamProvider:(GTM_NULLABLE GTMSessionFetcherBodyStreamProvider)block { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - GTMSESSION_ASSERT_DEBUG(![self isFetchingUnsynchronized], - @"stream provider should not change after beginFetch has been invoked"); - - _bodyStreamProvider = [block copy]; - } // @synchronized(self) -} - -- (GTM_NULLABLE id<GTMFetcherAuthorizationProtocol>)authorizer { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _authorizer; - } // @synchronized(self) -} - -- (void)setAuthorizer:(GTM_NULLABLE id<GTMFetcherAuthorizationProtocol>)authorizer { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (authorizer != _authorizer) { - if ([self isFetchingUnsynchronized]) { - GTMSESSION_ASSERT_DEBUG(0, @"authorizer should not change after beginFetch has been invoked"); - } else { - _authorizer = authorizer; - } - } - } // @synchronized(self) -} - -- (GTM_NULLABLE NSData *)downloadedData { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _downloadedData; - } // @synchronized(self) -} - -- (void)setDownloadedData:(GTM_NULLABLE NSData *)data { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _downloadedData = [data mutableCopy]; - } // @synchronized(self) -} - -- (int64_t)downloadedLength { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _downloadedLength; - } // @synchronized(self) -} - -- (void)setDownloadedLength:(int64_t)length { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _downloadedLength = length; - } // @synchronized(self) -} - -- (dispatch_queue_t GTM_NONNULL_TYPE)callbackQueue { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _callbackQueue; - } // @synchronized(self) -} - -- (void)setCallbackQueue:(dispatch_queue_t GTM_NULLABLE_TYPE)queue { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _callbackQueue = queue ?: dispatch_get_main_queue(); - } // @synchronized(self) -} - -- (GTM_NULLABLE NSURLSession *)session { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _session; - } // @synchronized(self) -} - -- (NSInteger)servicePriority { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _servicePriority; - } // @synchronized(self) -} - -- (void)setServicePriority:(NSInteger)value { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (value != _servicePriority) { - GTMSESSION_ASSERT_DEBUG(![self isFetchingUnsynchronized], - @"servicePriority should not change after beginFetch has been invoked"); - - _servicePriority = value; - } - } // @synchronized(self) -} - - -- (void)setSession:(GTM_NULLABLE NSURLSession *)session { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _session = session; - } // @synchronized(self) -} - -- (BOOL)canShareSession { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _canShareSession; - } // @synchronized(self) -} - -- (void)setCanShareSession:(BOOL)flag { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _canShareSession = flag; - } // @synchronized(self) -} - -- (BOOL)useBackgroundSession { - // This reflects if the user requested a background session, not necessarily - // if one was created. That is tracked with _usingBackgroundSession. - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _userRequestedBackgroundSession; - } // @synchronized(self) -} - -- (void)setUseBackgroundSession:(BOOL)flag { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (flag != _userRequestedBackgroundSession) { - GTMSESSION_ASSERT_DEBUG(![self isFetchingUnsynchronized], - @"useBackgroundSession should not change after beginFetch has been invoked"); - - _userRequestedBackgroundSession = flag; - } - } // @synchronized(self) -} - -- (BOOL)isUsingBackgroundSession { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _usingBackgroundSession; - } // @synchronized(self) -} - -- (void)setUsingBackgroundSession:(BOOL)flag { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _usingBackgroundSession = flag; - } // @synchronized(self) -} - -- (GTM_NULLABLE NSURLSession *)sessionNeedingInvalidation { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _sessionNeedingInvalidation; - } // @synchronized(self) -} - -- (void)setSessionNeedingInvalidation:(GTM_NULLABLE NSURLSession *)session { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _sessionNeedingInvalidation = session; - } // @synchronized(self) -} - -- (NSOperationQueue * GTM_NONNULL_TYPE)sessionDelegateQueue { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _delegateQueue; - } // @synchronized(self) -} - -- (void)setSessionDelegateQueue:(NSOperationQueue * GTM_NULLABLE_TYPE)queue { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (queue != _delegateQueue) { - if ([self isFetchingUnsynchronized]) { - GTMSESSION_ASSERT_DEBUG(0, @"sessionDelegateQueue should not change after fetch begins"); - } else { - _delegateQueue = queue ?: [NSOperationQueue mainQueue]; - } - } - } // @synchronized(self) -} - -- (BOOL)userStoppedFetching { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _userStoppedFetching; - } // @synchronized(self) -} - -- (GTM_NULLABLE id)userData { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _userData; - } // @synchronized(self) -} - -- (void)setUserData:(GTM_NULLABLE id)theObj { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _userData = theObj; - } // @synchronized(self) -} - -- (GTM_NULLABLE NSURL *)destinationFileURL { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _destinationFileURL; - } // @synchronized(self) -} - -- (void)setDestinationFileURL:(GTM_NULLABLE NSURL *)destinationFileURL { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (((_destinationFileURL == nil) && (destinationFileURL == nil)) || - [_destinationFileURL isEqual:destinationFileURL]) { - return; - } - if (_sessionIdentifier) { - // This is something we don't expect to happen in production. - // However if it ever happen, leave a system log. - NSLog(@"%@: Destination File URL changed from (%@) to (%@) after session identifier has " - @"been created.", - [self class], _destinationFileURL, destinationFileURL); -#if DEBUG - // On both the simulator and devices, the path can change to the download file, but the name - // shouldn't change. Technically, this isn't supported in the fetcher, but the change of - // URL is expected to happen only across development runs through Xcode. - NSString *oldFilename = [_destinationFileURL lastPathComponent]; - NSString *newFilename = [destinationFileURL lastPathComponent]; - #pragma unused(oldFilename) - #pragma unused(newFilename) - GTMSESSION_ASSERT_DEBUG([oldFilename isEqualToString:newFilename], - @"Destination File URL cannot be changed after session identifier has been created"); -#endif - } - _destinationFileURL = destinationFileURL; - } // @synchronized(self) -} - -- (void)setProperties:(GTM_NULLABLE NSDictionary *)dict { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _properties = [dict mutableCopy]; - } // @synchronized(self) -} - -- (GTM_NULLABLE NSDictionary *)properties { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _properties; - } // @synchronized(self) -} - -- (void)setProperty:(GTM_NULLABLE id)obj forKey:(NSString *)key { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (_properties == nil && obj != nil) { - _properties = [[NSMutableDictionary alloc] init]; - } - [_properties setValue:obj forKey:key]; - } // @synchronized(self) -} - -- (GTM_NULLABLE id)propertyForKey:(NSString *)key { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return [_properties objectForKey:key]; - } // @synchronized(self) -} - -- (void)addPropertiesFromDictionary:(NSDictionary *)dict { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (_properties == nil && dict != nil) { - [self setProperties:[dict mutableCopy]]; - } else { - [_properties addEntriesFromDictionary:dict]; - } - } // @synchronized(self) -} - -- (void)setCommentWithFormat:(id)format, ... { -#if !STRIP_GTM_FETCH_LOGGING - NSString *result = format; - if (format) { - va_list argList; - va_start(argList, format); - - result = [[NSString alloc] initWithFormat:format - arguments:argList]; - va_end(argList); - } - [self setComment:result]; -#endif -} - -#if !STRIP_GTM_FETCH_LOGGING -- (NSData *)loggedStreamData { - return _loggedStreamData; -} - -- (void)appendLoggedStreamData:dataToAdd { - if (!_loggedStreamData) { - _loggedStreamData = [NSMutableData data]; - } - [_loggedStreamData appendData:dataToAdd]; -} - -- (void)clearLoggedStreamData { - _loggedStreamData = nil; -} - -- (void)setDeferResponseBodyLogging:(BOOL)deferResponseBodyLogging { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (deferResponseBodyLogging != _deferResponseBodyLogging) { - _deferResponseBodyLogging = deferResponseBodyLogging; - if (!deferResponseBodyLogging && !self.hasLoggedError) { - [_delegateQueue addOperationWithBlock:^{ - [self logNowWithError:nil]; - }]; - } - } - } // @synchronized(self) -} - -- (BOOL)deferResponseBodyLogging { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _deferResponseBodyLogging; - } // @synchronized(self) -} - -#else -+ (void)setLoggingEnabled:(BOOL)flag { -} - -+ (BOOL)isLoggingEnabled { - return NO; -} -#endif // STRIP_GTM_FETCH_LOGGING - -@end - -@implementation GTMSessionFetcher (BackwardsCompatibilityOnly) - -- (void)setCookieStorageMethod:(NSInteger)method { - // For backwards compatibility with the old fetcher, we'll support the old constants. - // - // Clients using the GTMSessionFetcher class should set the cookie storage explicitly - // themselves. - NSHTTPCookieStorage *storage = nil; - switch(method) { - case 0: // kGTMHTTPFetcherCookieStorageMethodStatic - // nil storage will use [[self class] staticCookieStorage] when the fetch begins. - break; - case 1: // kGTMHTTPFetcherCookieStorageMethodFetchHistory - // Do nothing; use whatever was set by the fetcher service. - return; - case 2: // kGTMHTTPFetcherCookieStorageMethodSystemDefault - storage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; - break; - case 3: // kGTMHTTPFetcherCookieStorageMethodNone - // Create temporary storage for this fetcher only. - storage = [[GTMSessionCookieStorage alloc] init]; - break; - default: - GTMSESSION_ASSERT_DEBUG(0, @"Invalid cookie storage method: %d", (int)method); - } - self.cookieStorage = storage; -} - -@end - -@implementation GTMSessionCookieStorage { - NSMutableArray *_cookies; - NSHTTPCookieAcceptPolicy _policy; -} - -- (id)init { - self = [super init]; - if (self != nil) { - _cookies = [[NSMutableArray alloc] init]; - } - return self; -} - -- (GTM_NULLABLE NSArray *)cookies { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return [_cookies copy]; - } // @synchronized(self) -} - -- (void)setCookie:(NSHTTPCookie *)cookie { - if (!cookie) return; - if (_policy == NSHTTPCookieAcceptPolicyNever) return; - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - [self internalSetCookie:cookie]; - } // @synchronized(self) -} - -// Note: this should only be called from inside a @synchronized(self) block. -- (void)internalSetCookie:(NSHTTPCookie *)newCookie { - GTMSessionCheckSynchronized(self); - - if (_policy == NSHTTPCookieAcceptPolicyNever) return; - - BOOL isValidCookie = (newCookie.name.length > 0 - && newCookie.domain.length > 0 - && newCookie.path.length > 0); - GTMSESSION_ASSERT_DEBUG(isValidCookie, @"invalid cookie: %@", newCookie); - - if (isValidCookie) { - // Remove the cookie if it's currently in the array. - NSHTTPCookie *oldCookie = [self cookieMatchingCookie:newCookie]; - if (oldCookie) { - [_cookies removeObjectIdenticalTo:oldCookie]; - } - - if (![[self class] hasCookieExpired:newCookie]) { - [_cookies addObject:newCookie]; - } - } -} - -// Add all cookies in the new cookie array to the storage, -// replacing stored cookies as appropriate. -// -// Side effect: removes expired cookies from the storage array. -- (void)setCookies:(GTM_NULLABLE NSArray *)newCookies { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - [self removeExpiredCookies]; - - for (NSHTTPCookie *newCookie in newCookies) { - [self internalSetCookie:newCookie]; - } - } // @synchronized(self) -} - -- (void)setCookies:(NSArray *)cookies forURL:(GTM_NULLABLE NSURL *)URL mainDocumentURL:(GTM_NULLABLE NSURL *)mainDocumentURL { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (_policy == NSHTTPCookieAcceptPolicyNever) { - return; - } - - if (_policy == NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain) { - NSString *mainHost = mainDocumentURL.host; - NSString *associatedHost = URL.host; - if (!mainHost || ![associatedHost hasSuffix:mainHost]) { - return; - } - } - } // @synchronized(self) - [self setCookies:cookies]; -} - -- (void)deleteCookie:(NSHTTPCookie *)cookie { - if (!cookie) return; - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - NSHTTPCookie *foundCookie = [self cookieMatchingCookie:cookie]; - if (foundCookie) { - [_cookies removeObjectIdenticalTo:foundCookie]; - } - } // @synchronized(self) -} - -// Retrieve all cookies appropriate for the given URL, considering -// domain, path, cookie name, expiration, security setting. -// Side effect: removed expired cookies from the storage array. -- (GTM_NULLABLE NSArray *)cookiesForURL:(NSURL *)theURL { - NSMutableArray *foundCookies = nil; - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - [self removeExpiredCookies]; - - // We'll prepend "." to the desired domain, since we want the - // actual domain "nytimes.com" to still match the cookie domain - // ".nytimes.com" when we check it below with hasSuffix. - NSString *host = theURL.host.lowercaseString; - NSString *path = theURL.path; - NSString *scheme = [theURL scheme]; - - NSString *requestingDomain = nil; - BOOL isLocalhostRetrieval = NO; - - if (IsLocalhost(host)) { - isLocalhostRetrieval = YES; - } else { - if (host.length > 0) { - requestingDomain = [@"." stringByAppendingString:host]; - } - } - - for (NSHTTPCookie *storedCookie in _cookies) { - NSString *cookieDomain = storedCookie.domain.lowercaseString; - NSString *cookiePath = storedCookie.path; - BOOL cookieIsSecure = [storedCookie isSecure]; - - BOOL isDomainOK; - - if (isLocalhostRetrieval) { - // Prior to 10.5.6, the domain stored into NSHTTPCookies for localhost - // is "localhost.local" - isDomainOK = (IsLocalhost(cookieDomain) - || [cookieDomain isEqual:@"localhost.local"]); - } else { - // Ensure we're matching exact domain names. We prepended a dot to the - // requesting domain, so we can also prepend one here if needed before - // checking if the request contains the cookie domain. - if (![cookieDomain hasPrefix:@"."]) { - cookieDomain = [@"." stringByAppendingString:cookieDomain]; - } - isDomainOK = [requestingDomain hasSuffix:cookieDomain]; - } - - BOOL isPathOK = [cookiePath isEqual:@"/"] || [path hasPrefix:cookiePath]; - BOOL isSecureOK = (!cookieIsSecure - || [scheme caseInsensitiveCompare:@"https"] == NSOrderedSame); - - if (isDomainOK && isPathOK && isSecureOK) { - if (foundCookies == nil) { - foundCookies = [NSMutableArray array]; - } - [foundCookies addObject:storedCookie]; - } - } - } // @synchronized(self) - return foundCookies; -} - -// Override methods from the NSHTTPCookieStorage (NSURLSessionTaskAdditions) category. -- (void)storeCookies:(NSArray *)cookies forTask:(NSURLSessionTask *)task { - NSURLRequest *currentRequest = task.currentRequest; - [self setCookies:cookies forURL:currentRequest.URL mainDocumentURL:nil]; -} - -- (void)getCookiesForTask:(NSURLSessionTask *)task - completionHandler:(void (^)(GTM_NSArrayOf(NSHTTPCookie *) *))completionHandler { - if (completionHandler) { - NSURLRequest *currentRequest = task.currentRequest; - NSURL *currentRequestURL = currentRequest.URL; - NSArray *cookies = [self cookiesForURL:currentRequestURL]; - completionHandler(cookies); - } -} - -// Return a cookie from the array with the same name, domain, and path as the -// given cookie, or else return nil if none found. -// -// Both the cookie being tested and all cookies in the storage array should -// be valid (non-nil name, domains, paths). -// -// Note: this should only be called from inside a @synchronized(self) block -- (GTM_NULLABLE NSHTTPCookie *)cookieMatchingCookie:(NSHTTPCookie *)cookie { - GTMSessionCheckSynchronized(self); - - NSString *name = cookie.name; - NSString *domain = cookie.domain; - NSString *path = cookie.path; - - GTMSESSION_ASSERT_DEBUG(name && domain && path, - @"Invalid stored cookie (name:%@ domain:%@ path:%@)", name, domain, path); - - for (NSHTTPCookie *storedCookie in _cookies) { - if ([storedCookie.name isEqual:name] - && [storedCookie.domain isEqual:domain] - && [storedCookie.path isEqual:path]) { - return storedCookie; - } - } - return nil; -} - -// Internal routine to remove any expired cookies from the array, excluding -// cookies with nil expirations. -// -// Note: this should only be called from inside a @synchronized(self) block -- (void)removeExpiredCookies { - GTMSessionCheckSynchronized(self); - - // Count backwards since we're deleting items from the array - for (NSInteger idx = (NSInteger)_cookies.count - 1; idx >= 0; idx--) { - NSHTTPCookie *storedCookie = [_cookies objectAtIndex:(NSUInteger)idx]; - if ([[self class] hasCookieExpired:storedCookie]) { - [_cookies removeObjectAtIndex:(NSUInteger)idx]; - } - } -} - -+ (BOOL)hasCookieExpired:(NSHTTPCookie *)cookie { - NSDate *expiresDate = [cookie expiresDate]; - if (expiresDate == nil) { - // Cookies seem to have a Expires property even when the expiresDate method returns nil. - id expiresVal = [[cookie properties] objectForKey:NSHTTPCookieExpires]; - if ([expiresVal isKindOfClass:[NSDate class]]) { - expiresDate = expiresVal; - } - } - BOOL hasExpired = (expiresDate != nil && [expiresDate timeIntervalSinceNow] < 0); - return hasExpired; -} - -- (void)removeAllCookies { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - [_cookies removeAllObjects]; - } // @synchronized(self) -} - -- (NSHTTPCookieAcceptPolicy)cookieAcceptPolicy { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _policy; - } // @synchronized(self) -} - -- (void)setCookieAcceptPolicy:(NSHTTPCookieAcceptPolicy)cookieAcceptPolicy { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _policy = cookieAcceptPolicy; - } // @synchronized(self) -} - -@end - -void GTMSessionFetcherAssertValidSelector(id GTM_NULLABLE_TYPE obj, SEL GTM_NULLABLE_TYPE sel, ...) { - // Verify that the object's selector is implemented with the proper - // number and type of arguments -#if DEBUG - va_list argList; - va_start(argList, sel); - - if (obj && sel) { - // Check that the selector is implemented - if (![obj respondsToSelector:sel]) { - NSLog(@"\"%@\" selector \"%@\" is unimplemented or misnamed", - NSStringFromClass([(id)obj class]), - NSStringFromSelector((SEL)sel)); - NSCAssert(0, @"callback selector unimplemented or misnamed"); - } else { - const char *expectedArgType; - unsigned int argCount = 2; // skip self and _cmd - NSMethodSignature *sig = [obj methodSignatureForSelector:sel]; - - // Check that each expected argument is present and of the correct type - while ((expectedArgType = va_arg(argList, const char*)) != 0) { - - if ([sig numberOfArguments] > argCount) { - const char *foundArgType = [sig getArgumentTypeAtIndex:argCount]; - - if (0 != strncmp(foundArgType, expectedArgType, strlen(expectedArgType))) { - NSLog(@"\"%@\" selector \"%@\" argument %d should be type %s", - NSStringFromClass([(id)obj class]), - NSStringFromSelector((SEL)sel), (argCount - 2), expectedArgType); - NSCAssert(0, @"callback selector argument type mistake"); - } - } - argCount++; - } - - // Check that the proper number of arguments are present in the selector - if (argCount != [sig numberOfArguments]) { - NSLog(@"\"%@\" selector \"%@\" should have %d arguments", - NSStringFromClass([(id)obj class]), - NSStringFromSelector((SEL)sel), (argCount - 2)); - NSCAssert(0, @"callback selector arguments incorrect"); - } - } - } - - va_end(argList); -#endif -} - -NSString *GTMFetcherCleanedUserAgentString(NSString *str) { - // Reference http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html - // and http://www-archive.mozilla.org/build/user-agent-strings.html - - if (str == nil) return @""; - - NSMutableString *result = [NSMutableString stringWithString:str]; - - // Replace spaces and commas with underscores - [result replaceOccurrencesOfString:@" " - withString:@"_" - options:0 - range:NSMakeRange(0, result.length)]; - [result replaceOccurrencesOfString:@"," - withString:@"_" - options:0 - range:NSMakeRange(0, result.length)]; - - // Delete http token separators and remaining whitespace - static NSCharacterSet *charsToDelete = nil; - if (charsToDelete == nil) { - // Make a set of unwanted characters - NSString *const kSeparators = @"()<>@;:\\\"/[]?={}"; - - NSMutableCharacterSet *mutableChars = - [[NSCharacterSet whitespaceAndNewlineCharacterSet] mutableCopy]; - [mutableChars addCharactersInString:kSeparators]; - charsToDelete = [mutableChars copy]; // hang on to an immutable copy - } - - while (1) { - NSRange separatorRange = [result rangeOfCharacterFromSet:charsToDelete]; - if (separatorRange.location == NSNotFound) break; - - [result deleteCharactersInRange:separatorRange]; - }; - - return result; -} - -NSString *GTMFetcherSystemVersionString(void) { - static NSString *sSavedSystemString; - - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - // The Xcode 8 SDKs finally cleaned up this mess by providing TARGET_OS_OSX - // and TARGET_OS_IOS, but to build with older SDKs, those don't exist and - // instead one has to rely on TARGET_OS_MAC (which is true for iOS, watchOS, - // and tvOS) and TARGET_OS_IPHONE (which is true for iOS, watchOS, tvOS). So - // one has to order these carefully so you pick off the specific things - // first. - // If the code can ever assume Xcode 8 or higher (even when building for - // older OSes), then - // TARGET_OS_MAC -> TARGET_OS_OSX - // TARGET_OS_IPHONE -> TARGET_OS_IOS - // TARGET_IPHONE_SIMULATOR -> TARGET_OS_SIMULATOR -#if TARGET_OS_WATCH - // watchOS - WKInterfaceDevice - - WKInterfaceDevice *currentDevice = [WKInterfaceDevice currentDevice]; - - NSString *rawModel = [currentDevice model]; - NSString *model = GTMFetcherCleanedUserAgentString(rawModel); - - NSString *systemVersion = [currentDevice systemVersion]; - -#if TARGET_OS_SIMULATOR - NSString *hardwareModel = @"sim"; -#else - NSString *hardwareModel; - struct utsname unameRecord; - if (uname(&unameRecord) == 0) { - NSString *machineName = @(unameRecord.machine); - hardwareModel = GTMFetcherCleanedUserAgentString(machineName); - } - if (hardwareModel.length == 0) { - hardwareModel = @"unk"; - } -#endif - - sSavedSystemString = [[NSString alloc] initWithFormat:@"%@/%@ hw/%@", - model, systemVersion, hardwareModel]; - // Example: Apple_Watch/3.0 hw/Watch1_2 -#elif TARGET_OS_TV || TARGET_OS_IPHONE - // iOS and tvOS have UIDevice, use that. - UIDevice *currentDevice = [UIDevice currentDevice]; - - NSString *rawModel = [currentDevice model]; - NSString *model = GTMFetcherCleanedUserAgentString(rawModel); - - NSString *systemVersion = [currentDevice systemVersion]; - -#if TARGET_IPHONE_SIMULATOR || TARGET_OS_SIMULATOR - NSString *hardwareModel = @"sim"; -#else - NSString *hardwareModel; - struct utsname unameRecord; - if (uname(&unameRecord) == 0) { - NSString *machineName = @(unameRecord.machine); - hardwareModel = GTMFetcherCleanedUserAgentString(machineName); - } - if (hardwareModel.length == 0) { - hardwareModel = @"unk"; - } -#endif - - sSavedSystemString = [[NSString alloc] initWithFormat:@"%@/%@ hw/%@", - model, systemVersion, hardwareModel]; - // Example: iPod_Touch/2.2 hw/iPod1_1 - // Example: Apple_TV/9.2 hw/AppleTV5,3 -#elif TARGET_OS_MAC - // Mac build - NSProcessInfo *procInfo = [NSProcessInfo processInfo]; -#if !defined(MAC_OS_X_VERSION_10_10) - BOOL hasOperatingSystemVersion = NO; -#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_10 - BOOL hasOperatingSystemVersion = - [procInfo respondsToSelector:@selector(operatingSystemVersion)]; -#else - BOOL hasOperatingSystemVersion = YES; -#endif - NSString *versString; - if (hasOperatingSystemVersion) { -#if defined(MAC_OS_X_VERSION_10_10) - // A reference to NSOperatingSystemVersion requires the 10.10 SDK. -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" -// Disable unguarded availability warning as we can't use the @availability macro until we require -// all clients to build with Xcode 9 or above. - NSOperatingSystemVersion version = procInfo.operatingSystemVersion; -#pragma clang diagnostic pop - versString = [NSString stringWithFormat:@"%ld.%ld.%ld", - (long)version.majorVersion, (long)version.minorVersion, - (long)version.patchVersion]; -#else -#pragma unused(procInfo) -#endif - } else { - // With Gestalt inexplicably deprecated in 10.8, we're reduced to reading - // the system plist file. - NSString *const kPath = @"/System/Library/CoreServices/SystemVersion.plist"; - NSDictionary *plist = [NSDictionary dictionaryWithContentsOfFile:kPath]; - versString = [plist objectForKey:@"ProductVersion"]; - if (versString.length == 0) { - versString = @"10.?.?"; - } - } - - sSavedSystemString = [[NSString alloc] initWithFormat:@"MacOSX/%@", versString]; -#elif defined(_SYS_UTSNAME_H) - // Foundation-only build - struct utsname unameRecord; - uname(&unameRecord); - - sSavedSystemString = [NSString stringWithFormat:@"%s/%s", - unameRecord.sysname, unameRecord.release]; // "Darwin/8.11.1" -#else -#error No branch taken for a default user agent -#endif - }); - return sSavedSystemString; -} - -NSString *GTMFetcherStandardUserAgentString(NSBundle * GTM_NULLABLE_TYPE bundle) { - NSString *result = [NSString stringWithFormat:@"%@ %@", - GTMFetcherApplicationIdentifier(bundle), - GTMFetcherSystemVersionString()]; - return result; -} - -NSString *GTMFetcherApplicationIdentifier(NSBundle * GTM_NULLABLE_TYPE bundle) { - @synchronized([GTMSessionFetcher class]) { - static NSMutableDictionary *sAppIDMap = nil; - - // If there's a bundle ID, use that; otherwise, use the process name - if (bundle == nil) { - bundle = [NSBundle mainBundle]; - } - NSString *bundleID = [bundle bundleIdentifier]; - if (bundleID == nil) { - bundleID = @""; - } - - NSString *identifier = [sAppIDMap objectForKey:bundleID]; - if (identifier) return identifier; - - // Apps may add a string to the info.plist to uniquely identify different builds. - identifier = [bundle objectForInfoDictionaryKey:@"GTMUserAgentID"]; - if (identifier.length == 0) { - if (bundleID.length > 0) { - identifier = bundleID; - } else { - // Fall back on the procname, prefixed by "proc" to flag that it's - // autogenerated and perhaps unreliable - NSString *procName = [[NSProcessInfo processInfo] processName]; - identifier = [NSString stringWithFormat:@"proc_%@", procName]; - } - } - - // Clean up whitespace and special characters - identifier = GTMFetcherCleanedUserAgentString(identifier); - - // If there's a version number, append that - NSString *version = [bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; - if (version.length == 0) { - version = [bundle objectForInfoDictionaryKey:@"CFBundleVersion"]; - } - - // Clean up whitespace and special characters - version = GTMFetcherCleanedUserAgentString(version); - - // Glue the two together (cleanup done above or else cleanup would strip the - // slash) - if (version.length > 0) { - identifier = [identifier stringByAppendingFormat:@"/%@", version]; - } - - if (sAppIDMap == nil) { - sAppIDMap = [[NSMutableDictionary alloc] init]; - } - [sAppIDMap setObject:identifier forKey:bundleID]; - return identifier; - } -} - -#if DEBUG && (!defined(NS_BLOCK_ASSERTIONS) || GTMSESSION_ASSERT_AS_LOG) -@implementation GTMSessionSyncMonitorInternal { - NSValue *_objectKey; // The synchronize target object. - const char *_functionName; // The function containing the monitored sync block. -} - -- (instancetype)initWithSynchronizationObject:(id)object - allowRecursive:(BOOL)allowRecursive - functionName:(const char *)functionName { - self = [super init]; - if (self) { - Class threadKey = [GTMSessionSyncMonitorInternal class]; - _objectKey = [NSValue valueWithNonretainedObject:object]; - _functionName = functionName; - - NSMutableDictionary *threadDict = [NSThread currentThread].threadDictionary; - NSMutableDictionary *counters = threadDict[threadKey]; - if (counters == nil) { - counters = [NSMutableDictionary dictionary]; - threadDict[(id)threadKey] = counters; - } - NSCountedSet *functionNamesCounter = counters[_objectKey]; - NSUInteger numberOfSyncingFunctions = functionNamesCounter.count; - - if (!allowRecursive) { - BOOL isTopLevelSyncScope = (numberOfSyncingFunctions == 0); - NSArray *stack = [NSThread callStackSymbols]; - GTMSESSION_ASSERT_DEBUG(isTopLevelSyncScope, - @"*** Recursive sync on %@ at %s; previous sync at %@\n%@", - [object class], functionName, functionNamesCounter.allObjects, - [stack subarrayWithRange:NSMakeRange(1, stack.count - 1)]); - } - - if (!functionNamesCounter) { - functionNamesCounter = [NSCountedSet set]; - counters[_objectKey] = functionNamesCounter; - } - [functionNamesCounter addObject:(id _Nonnull)@(functionName)]; - } - return self; -} - -- (void)dealloc { - Class threadKey = [GTMSessionSyncMonitorInternal class]; - - NSMutableDictionary *threadDict = [NSThread currentThread].threadDictionary; - NSMutableDictionary *counters = threadDict[threadKey]; - NSCountedSet *functionNamesCounter = counters[_objectKey]; - NSString *functionNameStr = @(_functionName); - NSUInteger numberOfSyncsByThisFunction = [functionNamesCounter countForObject:functionNameStr]; - NSArray *stack = [NSThread callStackSymbols]; - GTMSESSION_ASSERT_DEBUG(numberOfSyncsByThisFunction > 0, @"Sync not found on %@ at %s\n%@", - [_objectKey.nonretainedObjectValue class], _functionName, - [stack subarrayWithRange:NSMakeRange(1, stack.count - 1)]); - [functionNamesCounter removeObject:functionNameStr]; - if (functionNamesCounter.count == 0) { - [counters removeObjectForKey:_objectKey]; - } -} - -+ (NSArray *)functionsHoldingSynchronizationOnObject:(id)object { - Class threadKey = [GTMSessionSyncMonitorInternal class]; - NSValue *localObjectKey = [NSValue valueWithNonretainedObject:object]; - - NSMutableDictionary *threadDict = [NSThread currentThread].threadDictionary; - NSMutableDictionary *counters = threadDict[threadKey]; - NSCountedSet *functionNamesCounter = counters[localObjectKey]; - return functionNamesCounter.count > 0 ? functionNamesCounter.allObjects : nil; -} -@end -#endif // DEBUG && (!defined(NS_BLOCK_ASSERTIONS) || GTMSESSION_ASSERT_AS_LOG) -GTM_ASSUME_NONNULL_END diff --git a/Pods/GTMSessionFetcher/Source/GTMSessionFetcherLogging.h b/Pods/GTMSessionFetcher/Source/GTMSessionFetcherLogging.h @@ -1,112 +0,0 @@ -/* Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "GTMSessionFetcher.h" - -// GTM HTTP Logging -// -// All traffic using GTMSessionFetcher can be easily logged. Call -// -// [GTMSessionFetcher setLoggingEnabled:YES]; -// -// to begin generating log files. -// -// Unless explicitly set by the application using +setLoggingDirectory:, -// logs are put into a default directory, located at: -// * macOS: ~/Desktop/GTMHTTPDebugLogs -// * iOS simulator: ~/GTMHTTPDebugLogs (in application sandbox) -// * iOS device: ~/Documents/GTMHTTPDebugLogs (in application sandbox) -// -// Tip: use the Finder's "Sort By Date" to find the most recent logs. -// -// Each run of an application gets a separate set of log files. An html -// file is generated to simplify browsing the run's http transactions. -// The html file includes javascript links for inline viewing of uploaded -// and downloaded data. -// -// A symlink is created in the logs folder to simplify finding the html file -// for the latest run of the application; the symlink is called -// -// AppName_http_log_newest.html -// -// For better viewing of XML logs, use Camino or Firefox rather than Safari. -// -// Each fetcher may be given a comment to be inserted as a label in the logs, -// such as -// [fetcher setCommentWithFormat:@"retrieve item %@", itemName]; -// -// Projects may define STRIP_GTM_FETCH_LOGGING to remove logging code. - -#if !STRIP_GTM_FETCH_LOGGING - -@interface GTMSessionFetcher (GTMSessionFetcherLogging) - -// Note: on macOS the default logs directory is ~/Desktop/GTMHTTPDebugLogs; on -// iOS simulators it will be the ~/GTMHTTPDebugLogs (in the app sandbox); on -// iOS devices it will be in ~/Documents/GTMHTTPDebugLogs (in the app sandbox). -// These directories will be created as needed, and are excluded from backups -// to iCloud and iTunes. -// -// If a custom directory is set, the directory should already exist. It is -// the application's responsibility to exclude any custom directory from -// backups, if desired. -+ (void)setLoggingDirectory:(NSString *)path; -+ (NSString *)loggingDirectory; - -// client apps can turn logging on and off -+ (void)setLoggingEnabled:(BOOL)isLoggingEnabled; -+ (BOOL)isLoggingEnabled; - -// client apps can turn off logging to a file if they want to only check -// the fetcher's log property -+ (void)setLoggingToFileEnabled:(BOOL)isLoggingToFileEnabled; -+ (BOOL)isLoggingToFileEnabled; - -// client apps can optionally specify process name and date string used in -// log file names -+ (void)setLoggingProcessName:(NSString *)processName; -+ (NSString *)loggingProcessName; - -+ (void)setLoggingDateStamp:(NSString *)dateStamp; -+ (NSString *)loggingDateStamp; - -// client apps can specify the directory for the log for this specific run, -// typically to match the directory used by another fetcher class, like: -// -// [GTMSessionFetcher setLogDirectoryForCurrentRun:[GTMHTTPFetcher logDirectoryForCurrentRun]]; -// -// Setting this overrides the logging directory, process name, and date stamp when writing -// the log file. -+ (void)setLogDirectoryForCurrentRun:(NSString *)logDirectoryForCurrentRun; -+ (NSString *)logDirectoryForCurrentRun; - -// Prunes old log directories that have not been modified since the provided date. -// This will not delete the current run's log directory. -+ (void)deleteLogDirectoriesOlderThanDate:(NSDate *)date; - -// internal; called by fetcher -- (void)logFetchWithError:(NSError *)error; -- (NSInputStream *)loggedInputStreamForInputStream:(NSInputStream *)inputStream; -- (GTMSessionFetcherBodyStreamProvider)loggedStreamProviderForStreamProvider: - (GTMSessionFetcherBodyStreamProvider)streamProvider; - -// internal; accessors useful for viewing logs -+ (NSString *)processNameLogPrefix; -+ (NSString *)symlinkNameSuffix; -+ (NSString *)htmlFileName; - -@end - -#endif // !STRIP_GTM_FETCH_LOGGING diff --git a/Pods/GTMSessionFetcher/Source/GTMSessionFetcherLogging.m b/Pods/GTMSessionFetcher/Source/GTMSessionFetcherLogging.m @@ -1,982 +0,0 @@ -/* Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -#include <sys/stat.h> -#include <unistd.h> - -#import "GTMSessionFetcherLogging.h" - -#ifndef STRIP_GTM_FETCH_LOGGING - #error GTMSessionFetcher headers should have defaulted this if it wasn't already defined. -#endif - -#if !STRIP_GTM_FETCH_LOGGING - -// Sensitive credential strings are replaced in logs with _snip_ -// -// Apps that must see the contents of sensitive tokens can set this to 1 -#ifndef SKIP_GTM_FETCH_LOGGING_SNIPPING -#define SKIP_GTM_FETCH_LOGGING_SNIPPING 0 -#endif - -// If GTMReadMonitorInputStream is available, it can be used for -// capturing uploaded streams of data -// -// We locally declare methods of GTMReadMonitorInputStream so we -// do not need to import the header, as some projects may not have it available -#if !GTMSESSION_BUILD_COMBINED_SOURCES -@interface GTMReadMonitorInputStream : NSInputStream - -+ (instancetype)inputStreamWithStream:(NSInputStream *)input; - -@property (assign) id readDelegate; -@property (assign) SEL readSelector; - -@end -#else -@class GTMReadMonitorInputStream; -#endif // !GTMSESSION_BUILD_COMBINED_SOURCES - -@interface GTMSessionFetcher (GTMHTTPFetcherLoggingUtilities) - -+ (NSString *)headersStringForDictionary:(NSDictionary *)dict; -+ (NSString *)snipSubstringOfString:(NSString *)originalStr - betweenStartString:(NSString *)startStr - endString:(NSString *)endStr; -- (void)inputStream:(GTMReadMonitorInputStream *)stream - readIntoBuffer:(void *)buffer - length:(int64_t)length; - -@end - -@implementation GTMSessionFetcher (GTMSessionFetcherLogging) - -// fetchers come and fetchers go, but statics are forever -static BOOL gIsLoggingEnabled = NO; -static BOOL gIsLoggingToFile = YES; -static NSString *gLoggingDirectoryPath = nil; -static NSString *gLogDirectoryForCurrentRun = nil; -static NSString *gLoggingDateStamp = nil; -static NSString *gLoggingProcessName = nil; - -+ (void)setLoggingDirectory:(NSString *)path { - gLoggingDirectoryPath = [path copy]; -} - -+ (NSString *)loggingDirectory { - if (!gLoggingDirectoryPath) { - NSArray *paths = nil; -#if TARGET_IPHONE_SIMULATOR - // default to a directory called GTMHTTPDebugLogs into a sandbox-safe - // directory that a developer can find easily, the application home - paths = @[ NSHomeDirectory() ]; -#elif TARGET_OS_IPHONE - // Neither ~/Desktop nor ~/Home is writable on an actual iOS, watchOS, or tvOS device. - // Put it in ~/Documents. - paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); -#else - // default to a directory called GTMHTTPDebugLogs in the desktop folder - paths = NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, NSUserDomainMask, YES); -#endif - - NSString *desktopPath = paths.firstObject; - if (desktopPath) { - NSString *const kGTMLogFolderName = @"GTMHTTPDebugLogs"; - NSString *logsFolderPath = [desktopPath stringByAppendingPathComponent:kGTMLogFolderName]; - - NSFileManager *fileMgr = [NSFileManager defaultManager]; - BOOL isDir; - BOOL doesFolderExist = [fileMgr fileExistsAtPath:logsFolderPath isDirectory:&isDir]; - if (!doesFolderExist) { - // make the directory - doesFolderExist = [fileMgr createDirectoryAtPath:logsFolderPath - withIntermediateDirectories:YES - attributes:nil - error:NULL]; - if (doesFolderExist) { - // The directory has been created. Exclude it from backups. - NSURL *pathURL = [NSURL fileURLWithPath:logsFolderPath isDirectory:YES]; - [pathURL setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:NULL]; - } - } - - if (doesFolderExist) { - // it's there; store it in the global - gLoggingDirectoryPath = [logsFolderPath copy]; - } - } - } - return gLoggingDirectoryPath; -} - -+ (void)setLogDirectoryForCurrentRun:(NSString *)logDirectoryForCurrentRun { - // Set the path for this run's logs. - gLogDirectoryForCurrentRun = [logDirectoryForCurrentRun copy]; -} - -+ (NSString *)logDirectoryForCurrentRun { - // make a directory for this run's logs, like SyncProto_logs_10-16_01-56-58PM - if (gLogDirectoryForCurrentRun) return gLogDirectoryForCurrentRun; - - NSString *parentDir = [self loggingDirectory]; - NSString *logNamePrefix = [self processNameLogPrefix]; - NSString *dateStamp = [self loggingDateStamp]; - NSString *dirName = [NSString stringWithFormat:@"%@%@", logNamePrefix, dateStamp]; - NSString *logDirectory = [parentDir stringByAppendingPathComponent:dirName]; - - if (gIsLoggingToFile) { - NSFileManager *fileMgr = [NSFileManager defaultManager]; - // Be sure that the first time this app runs, it's not writing to a preexisting folder - static BOOL gShouldReuseFolder = NO; - if (!gShouldReuseFolder) { - gShouldReuseFolder = YES; - NSString *origLogDir = logDirectory; - for (int ctr = 2; ctr < 20; ++ctr) { - if (![fileMgr fileExistsAtPath:logDirectory]) break; - - // append a digit - logDirectory = [origLogDir stringByAppendingFormat:@"_%d", ctr]; - } - } - if (![fileMgr createDirectoryAtPath:logDirectory - withIntermediateDirectories:YES - attributes:nil - error:NULL]) return nil; - } - gLogDirectoryForCurrentRun = logDirectory; - - return gLogDirectoryForCurrentRun; -} - -+ (void)setLoggingEnabled:(BOOL)isLoggingEnabled { - gIsLoggingEnabled = isLoggingEnabled; -} - -+ (BOOL)isLoggingEnabled { - return gIsLoggingEnabled; -} - -+ (void)setLoggingToFileEnabled:(BOOL)isLoggingToFileEnabled { - gIsLoggingToFile = isLoggingToFileEnabled; -} - -+ (BOOL)isLoggingToFileEnabled { - return gIsLoggingToFile; -} - -+ (void)setLoggingProcessName:(NSString *)processName { - gLoggingProcessName = [processName copy]; -} - -+ (NSString *)loggingProcessName { - // get the process name (once per run) replacing spaces with underscores - if (!gLoggingProcessName) { - NSString *procName = [[NSProcessInfo processInfo] processName]; - gLoggingProcessName = [procName stringByReplacingOccurrencesOfString:@" " withString:@"_"]; - } - return gLoggingProcessName; -} - -+ (void)setLoggingDateStamp:(NSString *)dateStamp { - gLoggingDateStamp = [dateStamp copy]; -} - -+ (NSString *)loggingDateStamp { - // We'll pick one date stamp per run, so a run that starts at a later second - // will get a unique results html file - if (!gLoggingDateStamp) { - // produce a string like 08-21_01-41-23PM - - NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; - [formatter setFormatterBehavior:NSDateFormatterBehavior10_4]; - [formatter setDateFormat:@"M-dd_hh-mm-ssa"]; - - gLoggingDateStamp = [formatter stringFromDate:[NSDate date]]; - } - return gLoggingDateStamp; -} - -+ (NSString *)processNameLogPrefix { - static NSString *gPrefix = nil; - if (!gPrefix) { - NSString *processName = [self loggingProcessName]; - gPrefix = [[NSString alloc] initWithFormat:@"%@_log_", processName]; - } - return gPrefix; -} - -+ (NSString *)symlinkNameSuffix { - return @"_log_newest.html"; -} - -+ (NSString *)htmlFileName { - return @"aperçu_http_log.html"; -} - -+ (void)deleteLogDirectoriesOlderThanDate:(NSDate *)cutoffDate { - NSFileManager *fileMgr = [NSFileManager defaultManager]; - NSURL *parentDir = [NSURL fileURLWithPath:[[self class] loggingDirectory]]; - NSURL *logDirectoryForCurrentRun = - [NSURL fileURLWithPath:[[self class] logDirectoryForCurrentRun]]; - NSError *error; - NSArray *contents = [fileMgr contentsOfDirectoryAtURL:parentDir - includingPropertiesForKeys:@[ NSURLContentModificationDateKey ] - options:0 - error:&error]; - for (NSURL *itemURL in contents) { - if ([itemURL isEqual:logDirectoryForCurrentRun]) continue; - - NSDate *modDate; - if ([itemURL getResourceValue:&modDate - forKey:NSURLContentModificationDateKey - error:&error]) { - if ([modDate compare:cutoffDate] == NSOrderedAscending) { - if (![fileMgr removeItemAtURL:itemURL error:&error]) { - NSLog(@"deleteLogDirectoriesOlderThanDate failed to delete %@: %@", - itemURL.path, error); - } - } - } else { - NSLog(@"deleteLogDirectoriesOlderThanDate failed to get mod date of %@: %@", - itemURL.path, error); - } - } -} - -// formattedStringFromData returns a prettyprinted string for XML or JSON input, -// and a plain string for other input data -- (NSString *)formattedStringFromData:(NSData *)inputData - contentType:(NSString *)contentType - JSON:(NSDictionary **)outJSON { - if (!inputData) return nil; - - // if the content type is JSON and we have the parsing class available, use that - if ([contentType hasPrefix:@"application/json"] && inputData.length > 5) { - // convert from JSON string to NSObjects and back to a formatted string - NSMutableDictionary *obj = [NSJSONSerialization JSONObjectWithData:inputData - options:NSJSONReadingMutableContainers - error:NULL]; - if (obj) { - if (outJSON) *outJSON = obj; - if ([obj isKindOfClass:[NSMutableDictionary class]]) { - // for security and privacy, omit OAuth 2 response access and refresh tokens - if ([obj valueForKey:@"refresh_token"] != nil) { - [obj setObject:@"_snip_" forKey:@"refresh_token"]; - } - if ([obj valueForKey:@"access_token"] != nil) { - [obj setObject:@"_snip_" forKey:@"access_token"]; - } - } - NSData *data = [NSJSONSerialization dataWithJSONObject:obj - options:NSJSONWritingPrettyPrinted - error:NULL]; - if (data) { - NSString *jsonStr = [[NSString alloc] initWithData:data - encoding:NSUTF8StringEncoding]; - return jsonStr; - } - } - } - -#if !TARGET_OS_IPHONE && !GTM_SKIP_LOG_XMLFORMAT - // verify that this data starts with the bytes indicating XML - - NSString *const kXMLLintPath = @"/usr/bin/xmllint"; - static BOOL gHasCheckedAvailability = NO; - static BOOL gIsXMLLintAvailable = NO; - - if (!gHasCheckedAvailability) { - gIsXMLLintAvailable = [[NSFileManager defaultManager] fileExistsAtPath:kXMLLintPath]; - gHasCheckedAvailability = YES; - } - if (gIsXMLLintAvailable - && inputData.length > 5 - && strncmp(inputData.bytes, "<?xml", 5) == 0) { - - // call xmllint to format the data - NSTask *task = [[NSTask alloc] init]; - [task setLaunchPath:kXMLLintPath]; - - // use the dash argument to specify stdin as the source file - [task setArguments:@[ @"--format", @"-" ]]; - [task setEnvironment:@{}]; - - NSPipe *inputPipe = [NSPipe pipe]; - NSPipe *outputPipe = [NSPipe pipe]; - [task setStandardInput:inputPipe]; - [task setStandardOutput:outputPipe]; - - [task launch]; - - [[inputPipe fileHandleForWriting] writeData:inputData]; - [[inputPipe fileHandleForWriting] closeFile]; - - // drain the stdout before waiting for the task to exit - NSData *formattedData = [[outputPipe fileHandleForReading] readDataToEndOfFile]; - - [task waitUntilExit]; - - int status = [task terminationStatus]; - if (status == 0 && formattedData.length > 0) { - // success - inputData = formattedData; - } - } -#else - // we can't call external tasks on the iPhone; leave the XML unformatted -#endif - - NSString *dataStr = [[NSString alloc] initWithData:inputData - encoding:NSUTF8StringEncoding]; - return dataStr; -} - -// stringFromStreamData creates a string given the supplied data -// -// If NSString can create a UTF-8 string from the data, then that is returned. -// -// Otherwise, this routine tries to find a MIME boundary at the beginning of the data block, and -// uses that to break up the data into parts. Each part will be used to try to make a UTF-8 string. -// For parts that fail, a replacement string showing the part header and <<n bytes>> is supplied -// in place of the binary data. - -- (NSString *)stringFromStreamData:(NSData *)data - contentType:(NSString *)contentType { - - if (!data) return nil; - - // optimistically, see if the whole data block is UTF-8 - NSString *streamDataStr = [self formattedStringFromData:data - contentType:contentType - JSON:NULL]; - if (streamDataStr) return streamDataStr; - - // Munge a buffer by replacing non-ASCII bytes with underscores, and turn that munged buffer an - // NSString. That gives us a string we can use with NSScanner. - NSMutableData *mutableData = [NSMutableData dataWithData:data]; - unsigned char *bytes = (unsigned char *)mutableData.mutableBytes; - - for (unsigned int idx = 0; idx < mutableData.length; ++idx) { - if (bytes[idx] > 0x7F || bytes[idx] == 0) { - bytes[idx] = '_'; - } - } - - NSString *mungedStr = [[NSString alloc] initWithData:mutableData - encoding:NSUTF8StringEncoding]; - if (mungedStr) { - - // scan for the boundary string - NSString *boundary = nil; - NSScanner *scanner = [NSScanner scannerWithString:mungedStr]; - - if ([scanner scanUpToString:@"\r\n" intoString:&boundary] - && [boundary hasPrefix:@"--"]) { - - // we found a boundary string; use it to divide the string into parts - NSArray *mungedParts = [mungedStr componentsSeparatedByString:boundary]; - - // look at each munged part in the original string, and try to convert those into UTF-8 - NSMutableArray *origParts = [NSMutableArray array]; - NSUInteger offset = 0; - for (NSString *mungedPart in mungedParts) { - NSUInteger partSize = mungedPart.length; - NSData *origPartData = [data subdataWithRange:NSMakeRange(offset, partSize)]; - NSString *origPartStr = [[NSString alloc] initWithData:origPartData - encoding:NSUTF8StringEncoding]; - if (origPartStr) { - // we could make this original part into UTF-8; use the string - [origParts addObject:origPartStr]; - } else { - // this part can't be made into UTF-8; scan the header, if we can - NSString *header = nil; - NSScanner *headerScanner = [NSScanner scannerWithString:mungedPart]; - if (![headerScanner scanUpToString:@"\r\n\r\n" intoString:&header]) { - // we couldn't find a header - header = @""; - } - // make a part string with the header and <<n bytes>> - NSString *binStr = [NSString stringWithFormat:@"\r%@\r<<%lu bytes>>\r", - header, (long)(partSize - header.length)]; - [origParts addObject:binStr]; - } - offset += partSize + boundary.length; - } - // rejoin the original parts - streamDataStr = [origParts componentsJoinedByString:boundary]; - } - } - if (!streamDataStr) { - // give up; just make a string showing the uploaded bytes - streamDataStr = [NSString stringWithFormat:@"<<%u bytes>>", (unsigned int)data.length]; - } - return streamDataStr; -} - -// logFetchWithError is called following a successful or failed fetch attempt -// -// This method does all the work for appending to and creating log files - -- (void)logFetchWithError:(NSError *)error { - if (![[self class] isLoggingEnabled]) return; - NSString *logDirectory = [[self class] logDirectoryForCurrentRun]; - if (!logDirectory) return; - NSString *processName = [[self class] loggingProcessName]; - - // TODO: add Javascript to display response data formatted in hex - - // each response's NSData goes into its own xml or txt file, though all responses for this run of - // the app share a main html file. This counter tracks all fetch responses for this app run. - // - // we'll use a local variable since this routine may be reentered while waiting for XML formatting - // to be completed by an external task - static int gResponseCounter = 0; - int responseCounter = ++gResponseCounter; - - NSURLResponse *response = [self response]; - NSDictionary *responseHeaders = [self responseHeaders]; - NSString *responseDataStr = nil; - NSDictionary *responseJSON = nil; - - // if there's response data, decide what kind of file to put it in based on the first bytes of the - // file or on the mime type supplied by the server - NSString *responseMIMEType = [response MIMEType]; - BOOL isResponseImage = NO; - - // file name for an image data file - NSString *responseDataFileName = nil; - - int64_t responseDataLength = self.downloadedLength; - if (responseDataLength > 0) { - NSData *downloadedData = self.downloadedData; - if (downloadedData == nil - && responseDataLength > 0 - && responseDataLength < 20000 - && self.destinationFileURL) { - // There's a download file that's not too big, so get the data to display from the downloaded - // file. - NSURL *destinationURL = self.destinationFileURL; - downloadedData = [NSData dataWithContentsOfURL:destinationURL]; - } - NSString *responseType = [responseHeaders valueForKey:@"Content-Type"]; - responseDataStr = [self formattedStringFromData:downloadedData - contentType:responseType - JSON:&responseJSON]; - NSString *responseDataExtn = nil; - NSData *dataToWrite = nil; - if (responseDataStr) { - // we were able to make a UTF-8 string from the response data - if ([responseMIMEType isEqual:@"application/atom+xml"] - || [responseMIMEType hasSuffix:@"/xml"]) { - responseDataExtn = @"xml"; - dataToWrite = [responseDataStr dataUsingEncoding:NSUTF8StringEncoding]; - } - } else if ([responseMIMEType isEqual:@"image/jpeg"]) { - responseDataExtn = @"jpg"; - dataToWrite = downloadedData; - isResponseImage = YES; - } else if ([responseMIMEType isEqual:@"image/gif"]) { - responseDataExtn = @"gif"; - dataToWrite = downloadedData; - isResponseImage = YES; - } else if ([responseMIMEType isEqual:@"image/png"]) { - responseDataExtn = @"png"; - dataToWrite = downloadedData; - isResponseImage = YES; - } else { - // add more non-text types here - } - // if we have an extension, save the raw data in a file with that extension - if (responseDataExtn && dataToWrite) { - // generate a response file base name like - NSString *responseBaseName = [NSString stringWithFormat:@"fetch_%d_response", responseCounter]; - responseDataFileName = [responseBaseName stringByAppendingPathExtension:responseDataExtn]; - NSString *responseDataFilePath = [logDirectory stringByAppendingPathComponent:responseDataFileName]; - - NSError *downloadedError = nil; - if (gIsLoggingToFile && ![dataToWrite writeToFile:responseDataFilePath - options:0 - error:&downloadedError]) { - NSLog(@"%@ logging write error:%@ (%@)", [self class], downloadedError, responseDataFileName); - } - } - } - // we'll have one main html file per run of the app - NSString *htmlName = [[self class] htmlFileName]; - NSString *htmlPath =[logDirectory stringByAppendingPathComponent:htmlName]; - - // if the html file exists (from logging previous fetches) we don't need - // to re-write the header or the scripts - NSFileManager *fileMgr = [NSFileManager defaultManager]; - BOOL didFileExist = [fileMgr fileExistsAtPath:htmlPath]; - - NSMutableString* outputHTML = [NSMutableString string]; - - // we need a header to say we'll have UTF-8 text - if (!didFileExist) { - [outputHTML appendFormat:@"<html><head><meta http-equiv=\"content-type\" " - "content=\"text/html; charset=UTF-8\"><title>%@ HTTP fetch log %@</title>", - processName, [[self class] loggingDateStamp]]; - } - // now write the visible html elements - NSString *copyableFileName = [NSString stringWithFormat:@"fetch_%d.txt", responseCounter]; - - NSDate *now = [NSDate date]; - // write the date & time, the comment, and the link to the plain-text (copyable) log - [outputHTML appendFormat:@"<b>%@ &nbsp;&nbsp;&nbsp;&nbsp; ", now]; - - NSString *comment = [self comment]; - if (comment.length > 0) { - [outputHTML appendFormat:@"%@ &nbsp;&nbsp;&nbsp;&nbsp; ", comment]; - } - [outputHTML appendFormat:@"</b><a href='%@'><i>request/response log</i></a><br>", copyableFileName]; - NSTimeInterval elapsed = -self.initialBeginFetchDate.timeIntervalSinceNow; - [outputHTML appendFormat:@"elapsed: %5.3fsec<br>", elapsed]; - - // write the request URL - NSURLRequest *request = self.request; - NSString *requestMethod = request.HTTPMethod; - NSURL *requestURL = request.URL; - - // Save the request URL for next time in case this redirects. - NSString *redirectedFromURLString = [self.redirectedFromURL absoluteString]; - self.redirectedFromURL = [requestURL copy]; - if (redirectedFromURLString) { - [outputHTML appendFormat:@"<FONT COLOR='#990066'><i>redirected from %@</i></FONT><br>", - redirectedFromURLString]; - } - [outputHTML appendFormat:@"<b>request:</b> %@ <code>%@</code><br>\n", requestMethod, requestURL]; - - // write the request headers - NSDictionary *requestHeaders = request.allHTTPHeaderFields; - NSUInteger numberOfRequestHeaders = requestHeaders.count; - if (numberOfRequestHeaders > 0) { - // Indicate if the request is authorized; warn if the request is authorized but non-SSL - NSString *auth = [requestHeaders objectForKey:@"Authorization"]; - NSString *headerDetails = @""; - if (auth) { - BOOL isInsecure = [[requestURL scheme] isEqual:@"http"]; - if (isInsecure) { - // 26A0 = ⚠ - headerDetails = - @"&nbsp;&nbsp;&nbsp;<i>authorized, non-SSL</i><FONT COLOR='#FF00FF'> &#x26A0;</FONT> "; - } else { - headerDetails = @"&nbsp;&nbsp;&nbsp;<i>authorized</i>"; - } - } - NSString *cookiesHdr = [requestHeaders objectForKey:@"Cookie"]; - if (cookiesHdr) { - headerDetails = [headerDetails stringByAppendingString:@"&nbsp;&nbsp;&nbsp;<i>cookies</i>"]; - } - NSString *matchHdr = [requestHeaders objectForKey:@"If-Match"]; - if (matchHdr) { - headerDetails = [headerDetails stringByAppendingString:@"&nbsp;&nbsp;&nbsp;<i>if-match</i>"]; - } - matchHdr = [requestHeaders objectForKey:@"If-None-Match"]; - if (matchHdr) { - headerDetails = [headerDetails stringByAppendingString:@"&nbsp;&nbsp;&nbsp;<i>if-none-match</i>"]; - } - [outputHTML appendFormat:@"&nbsp;&nbsp; headers: %d %@<br>", - (int)numberOfRequestHeaders, headerDetails]; - } else { - [outputHTML appendFormat:@"&nbsp;&nbsp; headers: none<br>"]; - } - // write the request post data - NSData *bodyData = nil; - NSData *loggedStreamData = self.loggedStreamData; - if (loggedStreamData) { - bodyData = loggedStreamData; - } else { - bodyData = self.bodyData; - if (bodyData == nil) { - bodyData = self.request.HTTPBody; - } - } - uint64_t bodyDataLength = bodyData.length; - - if (bodyData.length == 0) { - // If the data is in a body upload file URL, read that in if it's not huge. - NSURL *bodyFileURL = self.bodyFileURL; - if (bodyFileURL) { - NSNumber *fileSizeNum = nil; - NSError *fileSizeError = nil; - if ([bodyFileURL getResourceValue:&fileSizeNum - forKey:NSURLFileSizeKey - error:&fileSizeError]) { - bodyDataLength = [fileSizeNum unsignedLongLongValue]; - if (bodyDataLength > 0 && bodyDataLength < 50000) { - bodyData = [NSData dataWithContentsOfURL:bodyFileURL - options:NSDataReadingUncached - error:&fileSizeError]; - } - } - } - } - NSString *bodyDataStr = nil; - NSString *postType = [requestHeaders valueForKey:@"Content-Type"]; - - if (bodyDataLength > 0) { - [outputHTML appendFormat:@"&nbsp;&nbsp; data: %llu bytes, <code>%@</code><br>\n", - bodyDataLength, postType ? postType : @"(no type)"]; - NSString *logRequestBody = self.logRequestBody; - if (logRequestBody) { - bodyDataStr = [logRequestBody copy]; - self.logRequestBody = nil; - } else { - bodyDataStr = [self stringFromStreamData:bodyData - contentType:postType]; - if (bodyDataStr) { - // remove OAuth 2 client secret and refresh token - bodyDataStr = [[self class] snipSubstringOfString:bodyDataStr - betweenStartString:@"client_secret=" - endString:@"&"]; - bodyDataStr = [[self class] snipSubstringOfString:bodyDataStr - betweenStartString:@"refresh_token=" - endString:@"&"]; - // remove ClientLogin password - bodyDataStr = [[self class] snipSubstringOfString:bodyDataStr - betweenStartString:@"&Passwd=" - endString:@"&"]; - } - } - } else { - // no post data - } - // write the response status, MIME type, URL - NSInteger status = [self statusCode]; - if (response) { - NSString *statusString = @""; - if (status != 0) { - if (status == 200 || status == 201) { - statusString = [NSString stringWithFormat:@"%ld", (long)status]; - - // report any JSON-RPC error - if ([responseJSON isKindOfClass:[NSDictionary class]]) { - NSDictionary *jsonError = [responseJSON objectForKey:@"error"]; - if ([jsonError isKindOfClass:[NSDictionary class]]) { - NSString *jsonCode = [[jsonError valueForKey:@"code"] description]; - NSString *jsonMessage = [jsonError valueForKey:@"message"]; - if (jsonCode || jsonMessage) { - // 2691 = ⚑ - NSString *const jsonErrFmt = - @"&nbsp;&nbsp;&nbsp;<i>JSON error:</i> <FONT COLOR='#FF00FF'>%@ %@ &nbsp;&#x2691;</FONT>"; - statusString = [statusString stringByAppendingFormat:jsonErrFmt, - jsonCode ? jsonCode : @"", - jsonMessage ? jsonMessage : @""]; - } - } - } - } else { - // purple for anything other than 200 or 201 - NSString *flag = status >= 400 ? @"&nbsp;&#x2691;" : @""; // 2691 = ⚑ - NSString *explanation = [NSHTTPURLResponse localizedStringForStatusCode:status]; - NSString *const statusFormat = @"<FONT COLOR='#FF00FF'>%ld %@ %@</FONT>"; - statusString = [NSString stringWithFormat:statusFormat, (long)status, explanation, flag]; - } - } - // show the response URL only if it's different from the request URL - NSString *responseURLStr = @""; - NSURL *responseURL = response.URL; - - if (responseURL && ![responseURL isEqual:request.URL]) { - NSString *const responseURLFormat = - @"<FONT COLOR='#FF00FF'>response URL:</FONT> <code>%@</code><br>\n"; - responseURLStr = [NSString stringWithFormat:responseURLFormat, [responseURL absoluteString]]; - } - [outputHTML appendFormat:@"<b>response:</b>&nbsp;&nbsp;status %@<br>\n%@", - statusString, responseURLStr]; - // Write the response headers - NSUInteger numberOfResponseHeaders = responseHeaders.count; - if (numberOfResponseHeaders > 0) { - // Indicate if the server is setting cookies - NSString *cookiesSet = [responseHeaders valueForKey:@"Set-Cookie"]; - NSString *cookiesStr = - cookiesSet ? @"&nbsp;&nbsp;<FONT COLOR='#990066'><i>sets cookies</i></FONT>" : @""; - // Indicate if the server is redirecting - NSString *location = [responseHeaders valueForKey:@"Location"]; - BOOL isRedirect = status >= 300 && status <= 399 && location != nil; - NSString *redirectsStr = - isRedirect ? @"&nbsp;&nbsp;<FONT COLOR='#990066'><i>redirects</i></FONT>" : @""; - [outputHTML appendFormat:@"&nbsp;&nbsp; headers: %d %@ %@<br>\n", - (int)numberOfResponseHeaders, cookiesStr, redirectsStr]; - } else { - [outputHTML appendString:@"&nbsp;&nbsp; headers: none<br>\n"]; - } - } - // error - if (error) { - [outputHTML appendFormat:@"<b>Error:</b> %@ <br>\n", error.description]; - } - // Write the response data - if (responseDataFileName) { - if (isResponseImage) { - // Make a small inline image that links to the full image file - [outputHTML appendFormat:@"&nbsp;&nbsp; data: %lld bytes, <code>%@</code><br>", - responseDataLength, responseMIMEType]; - NSString *const fmt = - @"<a href=\"%@\"><img src='%@' alt='image' style='border:solid thin;max-height:32'></a>\n"; - [outputHTML appendFormat:fmt, responseDataFileName, responseDataFileName]; - } else { - // The response data was XML; link to the xml file - NSString *const fmt = - @"&nbsp;&nbsp; data: %lld bytes, <code>%@</code>&nbsp;&nbsp;&nbsp;<i><a href=\"%@\">%@</a></i>\n"; - [outputHTML appendFormat:fmt, responseDataLength, responseMIMEType, - responseDataFileName, [responseDataFileName pathExtension]]; - } - } else { - // The response data was not an image; just show the length and MIME type - [outputHTML appendFormat:@"&nbsp;&nbsp; data: %lld bytes, <code>%@</code>\n", - responseDataLength, responseMIMEType ? responseMIMEType : @"(no response type)"]; - } - // Make a single string of the request and response, suitable for copying - // to the clipboard and pasting into a bug report - NSMutableString *copyable = [NSMutableString string]; - if (comment) { - [copyable appendFormat:@"%@\n\n", comment]; - } - [copyable appendFormat:@"%@ elapsed: %5.3fsec\n", now, elapsed]; - if (redirectedFromURLString) { - [copyable appendFormat:@"Redirected from %@\n", redirectedFromURLString]; - } - [copyable appendFormat:@"Request: %@ %@\n", requestMethod, requestURL]; - if (requestHeaders.count > 0) { - [copyable appendFormat:@"Request headers:\n%@\n", - [[self class] headersStringForDictionary:requestHeaders]]; - } - if (bodyDataLength > 0) { - [copyable appendFormat:@"Request body: (%llu bytes)\n", bodyDataLength]; - if (bodyDataStr) { - [copyable appendFormat:@"%@\n", bodyDataStr]; - } - [copyable appendString:@"\n"]; - } - if (response) { - [copyable appendFormat:@"Response: status %d\n", (int) status]; - [copyable appendFormat:@"Response headers:\n%@\n", - [[self class] headersStringForDictionary:responseHeaders]]; - [copyable appendFormat:@"Response body: (%lld bytes)\n", responseDataLength]; - if (responseDataLength > 0) { - NSString *logResponseBody = self.logResponseBody; - if (logResponseBody) { - // The user has provided the response body text. - responseDataStr = [logResponseBody copy]; - self.logResponseBody = nil; - } - if (responseDataStr != nil) { - [copyable appendFormat:@"%@\n", responseDataStr]; - } else { - // Even though it's redundant, we'll put in text to indicate that all the bytes are binary. - if (self.destinationFileURL) { - [copyable appendFormat:@"<<%lld bytes>> to file %@\n", - responseDataLength, self.destinationFileURL.path]; - } else { - [copyable appendFormat:@"<<%lld bytes>>\n", responseDataLength]; - } - } - } - } - if (error) { - [copyable appendFormat:@"Error: %@\n", error]; - } - // Save to log property before adding the separator - self.log = copyable; - - [copyable appendString:@"-----------------------------------------------------------\n"]; - - // Write the copyable version to another file (linked to at the top of the html file, above) - // - // Ideally, something to just copy this to the clipboard like - // <span onCopy='window.event.clipboardData.setData(\"Text\", - // \"copyable stuff\");return false;'>Copy here.</span>" - // would work everywhere, but it only works in Safari as of 8/2010 - if (gIsLoggingToFile) { - NSString *parentDir = [[self class] loggingDirectory]; - NSString *copyablePath = [logDirectory stringByAppendingPathComponent:copyableFileName]; - NSError *copyableError = nil; - if (![copyable writeToFile:copyablePath - atomically:NO - encoding:NSUTF8StringEncoding - error:&copyableError]) { - // Error writing to file - NSLog(@"%@ logging write error:%@ (%@)", [self class], copyableError, copyablePath); - } - [outputHTML appendString:@"<br><hr><p>"]; - - // Append the HTML to the main output file - const char* htmlBytes = outputHTML.UTF8String; - NSOutputStream *stream = [NSOutputStream outputStreamToFileAtPath:htmlPath - append:YES]; - [stream open]; - [stream write:(const uint8_t *) htmlBytes maxLength:strlen(htmlBytes)]; - [stream close]; - - // Make a symlink to the latest html - NSString *const symlinkNameSuffix = [[self class] symlinkNameSuffix]; - NSString *symlinkName = [processName stringByAppendingString:symlinkNameSuffix]; - NSString *symlinkPath = [parentDir stringByAppendingPathComponent:symlinkName]; - - [fileMgr removeItemAtPath:symlinkPath error:NULL]; - [fileMgr createSymbolicLinkAtPath:symlinkPath - withDestinationPath:htmlPath - error:NULL]; -#if TARGET_OS_IPHONE - static BOOL gReportedLoggingPath = NO; - if (!gReportedLoggingPath) { - gReportedLoggingPath = YES; - NSLog(@"GTMSessionFetcher logging to \"%@\"", parentDir); - } -#endif - } -} - -- (NSInputStream *)loggedInputStreamForInputStream:(NSInputStream *)inputStream { - if (!inputStream) return nil; - if (![GTMSessionFetcher isLoggingEnabled]) return inputStream; - - [self clearLoggedStreamData]; // Clear any previous data. - Class monitorClass = NSClassFromString(@"GTMReadMonitorInputStream"); - if (!monitorClass) { - NSString const *str = @"<<Uploaded stream log unavailable without GTMReadMonitorInputStream>>"; - NSData *stringData = [str dataUsingEncoding:NSUTF8StringEncoding]; - [self appendLoggedStreamData:stringData]; - return inputStream; - } - inputStream = [monitorClass inputStreamWithStream:inputStream]; - - GTMReadMonitorInputStream *readMonitorInputStream = (GTMReadMonitorInputStream *)inputStream; - [readMonitorInputStream setReadDelegate:self]; - SEL readSel = @selector(inputStream:readIntoBuffer:length:); - [readMonitorInputStream setReadSelector:readSel]; - - return inputStream; -} - -- (GTMSessionFetcherBodyStreamProvider)loggedStreamProviderForStreamProvider: - (GTMSessionFetcherBodyStreamProvider)streamProvider { - if (!streamProvider) return nil; - if (![GTMSessionFetcher isLoggingEnabled]) return streamProvider; - - [self clearLoggedStreamData]; // Clear any previous data. - Class monitorClass = NSClassFromString(@"GTMReadMonitorInputStream"); - if (!monitorClass) { - NSString const *str = @"<<Uploaded stream log unavailable without GTMReadMonitorInputStream>>"; - NSData *stringData = [str dataUsingEncoding:NSUTF8StringEncoding]; - [self appendLoggedStreamData:stringData]; - return streamProvider; - } - GTMSessionFetcherBodyStreamProvider loggedStreamProvider = - ^(GTMSessionFetcherBodyStreamProviderResponse response) { - streamProvider(^(NSInputStream *bodyStream) { - bodyStream = [self loggedInputStreamForInputStream:bodyStream]; - response(bodyStream); - }); - }; - return loggedStreamProvider; -} - -@end - -@implementation GTMSessionFetcher (GTMSessionFetcherLoggingUtilities) - -- (void)inputStream:(GTMReadMonitorInputStream *)stream - readIntoBuffer:(void *)buffer - length:(int64_t)length { - // append the captured data - NSData *data = [NSData dataWithBytesNoCopy:buffer - length:(NSUInteger)length - freeWhenDone:NO]; - [self appendLoggedStreamData:data]; -} - -#pragma mark Fomatting Utilities - -+ (NSString *)snipSubstringOfString:(NSString *)originalStr - betweenStartString:(NSString *)startStr - endString:(NSString *)endStr { -#if SKIP_GTM_FETCH_LOGGING_SNIPPING - return originalStr; -#else - if (!originalStr) return nil; - - // Find the start string, and replace everything between it - // and the end string (or the end of the original string) with "_snip_" - NSRange startRange = [originalStr rangeOfString:startStr]; - if (startRange.location == NSNotFound) return originalStr; - - // We found the start string - NSUInteger originalLength = originalStr.length; - NSUInteger startOfTarget = NSMaxRange(startRange); - NSRange targetAndRest = NSMakeRange(startOfTarget, originalLength - startOfTarget); - NSRange endRange = [originalStr rangeOfString:endStr - options:0 - range:targetAndRest]; - NSRange replaceRange; - if (endRange.location == NSNotFound) { - // Found no end marker so replace to end of string - replaceRange = targetAndRest; - } else { - // Replace up to the endStr - replaceRange = NSMakeRange(startOfTarget, endRange.location - startOfTarget); - } - NSString *result = [originalStr stringByReplacingCharactersInRange:replaceRange - withString:@"_snip_"]; - return result; -#endif // SKIP_GTM_FETCH_LOGGING_SNIPPING -} - -+ (NSString *)headersStringForDictionary:(NSDictionary *)dict { - // Format the dictionary in http header style, like - // Accept: application/json - // Cache-Control: no-cache - // Content-Type: application/json; charset=utf-8 - // - // Pad the key names, but not beyond 16 chars, since long custom header - // keys just create too much whitespace - NSArray *keys = [dict.allKeys sortedArrayUsingSelector:@selector(compare:)]; - - NSMutableString *str = [NSMutableString string]; - for (NSString *key in keys) { - NSString *value = [dict valueForKey:key]; - if ([key isEqual:@"Authorization"]) { - // Remove OAuth 1 token - value = [[self class] snipSubstringOfString:value - betweenStartString:@"oauth_token=\"" - endString:@"\""]; - - // Remove OAuth 2 bearer token (draft 16, and older form) - value = [[self class] snipSubstringOfString:value - betweenStartString:@"Bearer " - endString:@"\n"]; - value = [[self class] snipSubstringOfString:value - betweenStartString:@"OAuth " - endString:@"\n"]; - - // Remove Google ClientLogin - value = [[self class] snipSubstringOfString:value - betweenStartString:@"GoogleLogin auth=" - endString:@"\n"]; - } - [str appendFormat:@" %@: %@\n", key, value]; - } - return str; -} - -@end - -#endif // !STRIP_GTM_FETCH_LOGGING diff --git a/Pods/GTMSessionFetcher/Source/GTMSessionFetcherService.h b/Pods/GTMSessionFetcher/Source/GTMSessionFetcherService.h @@ -1,193 +0,0 @@ -/* Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// For best performance and convenient usage, fetchers should be generated by a common -// GTMSessionFetcherService instance, like -// -// _fetcherService = [[GTMSessionFetcherService alloc] init]; -// GTMSessionFetcher* myFirstFetcher = [_fetcherService fetcherWithRequest:request1]; -// GTMSessionFetcher* mySecondFetcher = [_fetcherService fetcherWithRequest:request2]; - -#import "GTMSessionFetcher.h" - -GTM_ASSUME_NONNULL_BEGIN - -// Notifications. - -// This notification indicates a reusable session has become invalid. It is intended mainly for the -// service's unit tests. -// -// The notification object is the fetcher service. -// The invalid session is provided via the userInfo kGTMSessionFetcherServiceSessionKey key. -extern NSString *const kGTMSessionFetcherServiceSessionBecameInvalidNotification; -extern NSString *const kGTMSessionFetcherServiceSessionKey; - -@interface GTMSessionFetcherService : NSObject<GTMSessionFetcherServiceProtocol> - -// Queues of delayed and running fetchers. Each dictionary contains arrays -// of GTMSessionFetcher *fetchers, keyed by NSString *host -@property(atomic, strong, readonly, GTM_NULLABLE) GTM_NSDictionaryOf(NSString *, NSArray *) *delayedFetchersByHost; -@property(atomic, strong, readonly, GTM_NULLABLE) GTM_NSDictionaryOf(NSString *, NSArray *) *runningFetchersByHost; - -// A max value of 0 means no fetchers should be delayed. -// The default limit is 10 simultaneous fetchers targeting each host. -// This does not apply to fetchers whose useBackgroundSession property is YES. Since services are -// not resurrected on an app relaunch, delayed fetchers would effectively be abandoned. -@property(atomic, assign) NSUInteger maxRunningFetchersPerHost; - -// Properties to be applied to each fetcher; see GTMSessionFetcher.h for descriptions -@property(atomic, strong, GTM_NULLABLE) NSURLSessionConfiguration *configuration; -@property(atomic, copy, GTM_NULLABLE) GTMSessionFetcherConfigurationBlock configurationBlock; -@property(atomic, strong, GTM_NULLABLE) NSHTTPCookieStorage *cookieStorage; -@property(atomic, strong, GTM_NULL_RESETTABLE) dispatch_queue_t callbackQueue; -@property(atomic, copy, GTM_NULLABLE) GTMSessionFetcherChallengeBlock challengeBlock; -@property(atomic, strong, GTM_NULLABLE) NSURLCredential *credential; -@property(atomic, strong) NSURLCredential *proxyCredential; -@property(atomic, copy, GTM_NULLABLE) GTM_NSArrayOf(NSString *) *allowedInsecureSchemes; -@property(atomic, assign) BOOL allowLocalhostRequest; -@property(atomic, assign) BOOL allowInvalidServerCertificates; -@property(atomic, assign, getter=isRetryEnabled) BOOL retryEnabled; -@property(atomic, copy, GTM_NULLABLE) GTMSessionFetcherRetryBlock retryBlock; -@property(atomic, assign) NSTimeInterval maxRetryInterval; -@property(atomic, assign) NSTimeInterval minRetryInterval; -@property(atomic, copy, GTM_NULLABLE) GTM_NSDictionaryOf(NSString *, id) *properties; - -#if GTM_BACKGROUND_TASK_FETCHING -@property(atomic, assign) BOOL skipBackgroundTask; -#endif - -// A default useragent of GTMFetcherStandardUserAgentString(nil) will be given to each fetcher -// created by this service unless the request already has a user-agent header set. -// This default will be added starting with builds with the SDKs for OS X 10.11 and iOS 9. -// -// To use the configuration's default user agent, set this property to nil. -@property(atomic, copy, GTM_NULLABLE) NSString *userAgent; - -// The authorizer to attach to the created fetchers. If a specific fetcher should -// not authorize its requests, the fetcher's authorizer property may be set to nil -// before the fetch begins. -@property(atomic, strong, GTM_NULLABLE) id<GTMFetcherAuthorizationProtocol> authorizer; - -// Delegate queue used by the session when calling back to the fetcher. The default -// is the main queue. Changing this does not affect the queue used to call back to the -// application; that is specified by the callbackQueue property above. -@property(atomic, strong, GTM_NULL_RESETTABLE) NSOperationQueue *sessionDelegateQueue; - -// When enabled, indicates the same session should be used by subsequent fetchers. -// -// This is enabled by default. -@property(atomic, assign) BOOL reuseSession; - -// Sets the delay until an unused session is invalidated. -// The default interval is 60 seconds. -// -// If the interval is set to 0, then any reused session is not invalidated except by -// explicitly invoking -resetSession. Be aware that setting the interval to 0 thus -// causes the session's delegate to be retained until the session is explicitly reset. -@property(atomic, assign) NSTimeInterval unusedSessionTimeout; - -// If shouldReuseSession is enabled, this will force creation of a new session when future -// fetchers begin. -- (void)resetSession; - -// Create a fetcher -// -// These methods will return a fetcher. If successfully created, the connection -// will hold a strong reference to it for the life of the connection as well. -// So the caller doesn't have to hold onto the fetcher explicitly unless they -// want to be able to monitor or cancel it. -- (GTMSessionFetcher *)fetcherWithRequest:(NSURLRequest *)request; -- (GTMSessionFetcher *)fetcherWithURL:(NSURL *)requestURL; -- (GTMSessionFetcher *)fetcherWithURLString:(NSString *)requestURLString; - -// Common method for fetcher creation. -// -// -fetcherWithRequest:fetcherClass: may be overridden to customize creation of -// fetchers. This is the ONLY method in the GTMSessionFetcher library intended to -// be overridden. -- (id)fetcherWithRequest:(NSURLRequest *)request - fetcherClass:(Class)fetcherClass; - -- (BOOL)isDelayingFetcher:(GTMSessionFetcher *)fetcher; - -- (NSUInteger)numberOfFetchers; // running + delayed fetchers -- (NSUInteger)numberOfRunningFetchers; -- (NSUInteger)numberOfDelayedFetchers; - -// Return a list of all running or delayed fetchers. This includes fetchers created -// by the service which have been started and have not yet stopped. -// -// Returns an array of fetcher objects, or nil if none. -- (GTM_NULLABLE GTM_NSArrayOf(GTMSessionFetcher *) *)issuedFetchers; - -// Search for running or delayed fetchers with the specified URL. -// -// Returns an array of fetcher objects found, or nil if none found. -- (GTM_NULLABLE GTM_NSArrayOf(GTMSessionFetcher *) *)issuedFetchersWithRequestURL:(NSURL *)requestURL; - -- (void)stopAllFetchers; - -// Methods for use by the fetcher class only. -- (GTM_NULLABLE NSURLSession *)session; -- (GTM_NULLABLE NSURLSession *)sessionForFetcherCreation; -- (GTM_NULLABLE id<NSURLSessionDelegate>)sessionDelegate; -- (GTM_NULLABLE NSDate *)stoppedAllFetchersDate; - -// The testBlock can inspect its fetcher parameter's request property to -// determine which fetcher is being faked. -@property(atomic, copy, GTM_NULLABLE) GTMSessionFetcherTestBlock testBlock; - -@end - -@interface GTMSessionFetcherService (TestingSupport) - -// Convenience methods to create a fetcher service for testing. -// -// Fetchers generated by this mock fetcher service will not perform any -// network operation, but will invoke callbacks and provide the supplied data -// or error to the completion handler. -// -// You can make more customized mocks by setting the test block property of the service -// or fetcher; the test block can inspect the fetcher's request or other properties. -// -// See the description of the testBlock property below. -+ (instancetype)mockFetcherServiceWithFakedData:(GTM_NULLABLE NSData *)fakedDataOrNil - fakedError:(GTM_NULLABLE NSError *)fakedErrorOrNil; -+ (instancetype)mockFetcherServiceWithFakedData:(GTM_NULLABLE NSData *)fakedDataOrNil - fakedResponse:(NSHTTPURLResponse *)fakedResponse - fakedError:(GTM_NULLABLE NSError *)fakedErrorOrNil; - -// Spin the run loop and discard events (or, if not on the main thread, just sleep the thread) -// until all running and delayed fetchers have completed. -// -// This is only for use in testing or in tools without a user interface. -// -// Synchronous fetches should never be done by shipping apps; they are -// sufficient reason for rejection from the app store. -// -// Returns NO if timed out. -- (BOOL)waitForCompletionOfAllFetchersWithTimeout:(NSTimeInterval)timeoutInSeconds; - -@end - -@interface GTMSessionFetcherService (BackwardsCompatibilityOnly) - -// Clients using GTMSessionFetcher should set the cookie storage explicitly themselves. -// This method is just for compatibility with the old fetcher. -@property(atomic, assign) NSInteger cookieStorageMethod; - -@end - -GTM_ASSUME_NONNULL_END diff --git a/Pods/GTMSessionFetcher/Source/GTMSessionFetcherService.m b/Pods/GTMSessionFetcher/Source/GTMSessionFetcherService.m @@ -1,1365 +0,0 @@ -/* Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -#import "GTMSessionFetcherService.h" - -NSString *const kGTMSessionFetcherServiceSessionBecameInvalidNotification - = @"kGTMSessionFetcherServiceSessionBecameInvalidNotification"; -NSString *const kGTMSessionFetcherServiceSessionKey - = @"kGTMSessionFetcherServiceSessionKey"; - -#if !GTMSESSION_BUILD_COMBINED_SOURCES -@interface GTMSessionFetcher (ServiceMethods) -- (BOOL)beginFetchMayDelay:(BOOL)mayDelay - mayAuthorize:(BOOL)mayAuthorize; -@end -#endif // !GTMSESSION_BUILD_COMBINED_SOURCES - -@interface GTMSessionFetcherService () - -@property(atomic, strong, readwrite) NSDictionary *delayedFetchersByHost; -@property(atomic, strong, readwrite) NSDictionary *runningFetchersByHost; - -@end - -// Since NSURLSession doesn't support a separate delegate per task (!), instances of this -// class serve as a session delegate trampoline. -// -// This class maps a session's tasks to fetchers, and resends delegate messages to the task's -// fetcher. -@interface GTMSessionFetcherSessionDelegateDispatcher : NSObject<NSURLSessionDelegate> - -// The session for the tasks in this dispatcher's task-to-fetcher map. -@property(atomic) NSURLSession *session; - -// The timer interval for invalidating a session that has no active tasks. -@property(atomic) NSTimeInterval discardInterval; - -// The current discard timer. -@property(atomic, readonly) NSTimer *discardTimer; - - -- (instancetype)initWithParentService:(GTMSessionFetcherService *)parentService - sessionDiscardInterval:(NSTimeInterval)discardInterval; - -- (void)setFetcher:(GTMSessionFetcher *)fetcher - forTask:(NSURLSessionTask *)task; -- (void)removeFetcher:(GTMSessionFetcher *)fetcher; - -// Before using a session, tells the delegate dispatcher to stop the discard timer. -- (void)startSessionUsage; - -// When abandoning a delegate dispatcher, we want to avoid the session retaining -// the delegate after tasks complete. -- (void)abandon; - -@end - - -@implementation GTMSessionFetcherService { - NSMutableDictionary *_delayedFetchersByHost; - NSMutableDictionary *_runningFetchersByHost; - NSUInteger _maxRunningFetchersPerHost; - - // When this ivar is nil, the service will not reuse sessions. - GTMSessionFetcherSessionDelegateDispatcher *_delegateDispatcher; - - // Fetchers will wait on this if another fetcher is creating the shared NSURLSession. - dispatch_semaphore_t _sessionCreationSemaphore; - - dispatch_queue_t _callbackQueue; - NSOperationQueue *_delegateQueue; - NSHTTPCookieStorage *_cookieStorage; - NSString *_userAgent; - NSTimeInterval _timeout; - - NSURLCredential *_credential; // Username & password. - NSURLCredential *_proxyCredential; // Credential supplied to proxy servers. - - NSInteger _cookieStorageMethod; - - id<GTMFetcherAuthorizationProtocol> _authorizer; - - // For waitForCompletionOfAllFetchersWithTimeout: we need to wait on stopped fetchers since - // they've not yet finished invoking their queued callbacks. This array is nil except when - // waiting on fetchers. - NSMutableArray *_stoppedFetchersToWaitFor; - - // For fetchers that enqueued their callbacks before stopAllFetchers was called on the service, - // set a barrier so the callbacks know to bail out. - NSDate *_stoppedAllFetchersDate; -} - -@synthesize maxRunningFetchersPerHost = _maxRunningFetchersPerHost, - configuration = _configuration, - configurationBlock = _configurationBlock, - cookieStorage = _cookieStorage, - userAgent = _userAgent, - challengeBlock = _challengeBlock, - credential = _credential, - proxyCredential = _proxyCredential, - allowedInsecureSchemes = _allowedInsecureSchemes, - allowLocalhostRequest = _allowLocalhostRequest, - allowInvalidServerCertificates = _allowInvalidServerCertificates, - retryEnabled = _retryEnabled, - retryBlock = _retryBlock, - maxRetryInterval = _maxRetryInterval, - minRetryInterval = _minRetryInterval, - properties = _properties, - unusedSessionTimeout = _unusedSessionTimeout, - testBlock = _testBlock; - -#if GTM_BACKGROUND_TASK_FETCHING -@synthesize skipBackgroundTask = _skipBackgroundTask; -#endif - -- (instancetype)init { - self = [super init]; - if (self) { - _delayedFetchersByHost = [[NSMutableDictionary alloc] init]; - _runningFetchersByHost = [[NSMutableDictionary alloc] init]; - _maxRunningFetchersPerHost = 10; - _cookieStorageMethod = -1; - _unusedSessionTimeout = 60.0; - _delegateDispatcher = - [[GTMSessionFetcherSessionDelegateDispatcher alloc] initWithParentService:self - sessionDiscardInterval:_unusedSessionTimeout]; - _callbackQueue = dispatch_get_main_queue(); - - _delegateQueue = [[NSOperationQueue alloc] init]; - _delegateQueue.maxConcurrentOperationCount = 1; - _delegateQueue.name = @"com.google.GTMSessionFetcher.NSURLSessionDelegateQueue"; - - _sessionCreationSemaphore = dispatch_semaphore_create(1); - - // Starting with the SDKs for OS X 10.11/iOS 9, the service has a default useragent. - // Apps can remove this and get the default system "CFNetwork" useragent by setting the - // fetcher service's userAgent property to nil. -#if (!TARGET_OS_IPHONE && defined(MAC_OS_X_VERSION_10_11) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11) \ - || (TARGET_OS_IPHONE && defined(__IPHONE_9_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0) - _userAgent = GTMFetcherStandardUserAgentString(nil); -#endif - } - return self; -} - -- (void)dealloc { - [self detachAuthorizer]; - [_delegateDispatcher abandon]; -} - -#pragma mark Generate a new fetcher - -// Clients may override this method. Clients should not override any other library methods. -- (id)fetcherWithRequest:(NSURLRequest *)request - fetcherClass:(Class)fetcherClass { - GTMSessionFetcher *fetcher = [[fetcherClass alloc] initWithRequest:request - configuration:self.configuration]; - fetcher.callbackQueue = self.callbackQueue; - fetcher.sessionDelegateQueue = self.sessionDelegateQueue; - fetcher.challengeBlock = self.challengeBlock; - fetcher.credential = self.credential; - fetcher.proxyCredential = self.proxyCredential; - fetcher.authorizer = self.authorizer; - fetcher.cookieStorage = self.cookieStorage; - fetcher.allowedInsecureSchemes = self.allowedInsecureSchemes; - fetcher.allowLocalhostRequest = self.allowLocalhostRequest; - fetcher.allowInvalidServerCertificates = self.allowInvalidServerCertificates; - fetcher.configurationBlock = self.configurationBlock; - fetcher.retryEnabled = self.retryEnabled; - fetcher.retryBlock = self.retryBlock; - fetcher.maxRetryInterval = self.maxRetryInterval; - fetcher.minRetryInterval = self.minRetryInterval; - fetcher.properties = self.properties; - fetcher.service = self; - if (self.cookieStorageMethod >= 0) { - [fetcher setCookieStorageMethod:self.cookieStorageMethod]; - } - -#if GTM_BACKGROUND_TASK_FETCHING - fetcher.skipBackgroundTask = self.skipBackgroundTask; -#endif - - NSString *userAgent = self.userAgent; - if (userAgent.length > 0 - && [request valueForHTTPHeaderField:@"User-Agent"] == nil) { - [fetcher setRequestValue:userAgent - forHTTPHeaderField:@"User-Agent"]; - } - fetcher.testBlock = self.testBlock; - - return fetcher; -} - -- (GTMSessionFetcher *)fetcherWithRequest:(NSURLRequest *)request { - return [self fetcherWithRequest:request - fetcherClass:[GTMSessionFetcher class]]; -} - -- (GTMSessionFetcher *)fetcherWithURL:(NSURL *)requestURL { - return [self fetcherWithRequest:[NSURLRequest requestWithURL:requestURL]]; -} - -- (GTMSessionFetcher *)fetcherWithURLString:(NSString *)requestURLString { - NSURL *url = [NSURL URLWithString:requestURLString]; - return [self fetcherWithURL:url]; -} - -// Returns a session for the fetcher's host, or nil. -- (NSURLSession *)session { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - NSURLSession *session = _delegateDispatcher.session; - return session; - } -} - -// Returns a session for the fetcher's host, or nil. For shared sessions, this -// waits on a semaphore, blocking other fetchers while the caller creates the -// session if needed. -- (NSURLSession *)sessionForFetcherCreation { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - if (!_delegateDispatcher) { - // This fetcher is creating a non-shared session, so skip the semaphore usage. - return nil; - } - } - - // Wait if another fetcher is currently creating a session; avoid waiting - // inside the @synchronized block, as that can deadlock. - dispatch_semaphore_wait(_sessionCreationSemaphore, DISPATCH_TIME_FOREVER); - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - // Before getting the NSURLSession for task creation, it is - // important to invalidate and nil out the session discard timer; otherwise - // the session can be invalidated between when it is returned to the - // fetcher, and when the fetcher attempts to create its NSURLSessionTask. - [_delegateDispatcher startSessionUsage]; - - NSURLSession *session = _delegateDispatcher.session; - if (session) { - // The calling fetcher will receive a preexisting session, so - // we can allow other fetchers to create a session. - dispatch_semaphore_signal(_sessionCreationSemaphore); - } else { - // No existing session was obtained, so the calling fetcher will create the session; - // it *must* invoke fetcherDidCreateSession: to signal the dispatcher's semaphore after - // the session has been created (or fails to be created) to avoid a hang. - } - return session; - } -} - -- (id<NSURLSessionDelegate>)sessionDelegate { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _delegateDispatcher; - } -} - -#pragma mark Queue Management - -- (void)addRunningFetcher:(GTMSessionFetcher *)fetcher - forHost:(NSString *)host { - // Add to the array of running fetchers for this host, creating the array if needed. - NSMutableArray *runningForHost = [_runningFetchersByHost objectForKey:host]; - if (runningForHost == nil) { - runningForHost = [NSMutableArray arrayWithObject:fetcher]; - [_runningFetchersByHost setObject:runningForHost forKey:host]; - } else { - [runningForHost addObject:fetcher]; - } -} - -- (void)addDelayedFetcher:(GTMSessionFetcher *)fetcher - forHost:(NSString *)host { - // Add to the array of delayed fetchers for this host, creating the array if needed. - NSMutableArray *delayedForHost = [_delayedFetchersByHost objectForKey:host]; - if (delayedForHost == nil) { - delayedForHost = [NSMutableArray arrayWithObject:fetcher]; - [_delayedFetchersByHost setObject:delayedForHost forKey:host]; - } else { - [delayedForHost addObject:fetcher]; - } -} - -- (BOOL)isDelayingFetcher:(GTMSessionFetcher *)fetcher { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - NSString *host = fetcher.request.URL.host; - if (host == nil) { - return NO; - } - NSArray *delayedForHost = [_delayedFetchersByHost objectForKey:host]; - NSUInteger idx = [delayedForHost indexOfObjectIdenticalTo:fetcher]; - BOOL isDelayed = (delayedForHost != nil) && (idx != NSNotFound); - return isDelayed; - } -} - -- (BOOL)fetcherShouldBeginFetching:(GTMSessionFetcher *)fetcher { - // Entry point from the fetcher - NSURL *requestURL = fetcher.request.URL; - NSString *host = requestURL.host; - - // Addresses "file:///path" case where localhost is the implicit host. - if (host.length == 0 && [requestURL isFileURL]) { - host = @"localhost"; - } - - if (host.length == 0) { - // Data URIs legitimately have no host, reject other hostless URLs. - GTMSESSION_ASSERT_DEBUG([[requestURL scheme] isEqual:@"data"], @"%@ lacks host", fetcher); - return YES; - } - - BOOL shouldBeginResult; - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - NSMutableArray *runningForHost = [_runningFetchersByHost objectForKey:host]; - if (runningForHost != nil - && [runningForHost indexOfObjectIdenticalTo:fetcher] != NSNotFound) { - GTMSESSION_ASSERT_DEBUG(NO, @"%@ was already running", fetcher); - return YES; - } - - BOOL shouldRunNow = (fetcher.usingBackgroundSession - || _maxRunningFetchersPerHost == 0 - || _maxRunningFetchersPerHost > - [[self class] numberOfNonBackgroundSessionFetchers:runningForHost]); - if (shouldRunNow) { - [self addRunningFetcher:fetcher forHost:host]; - shouldBeginResult = YES; - } else { - [self addDelayedFetcher:fetcher forHost:host]; - shouldBeginResult = NO; - } - } // @synchronized(self) - - // We'll save the host that serves as the key for this fetcher's array - // to avoid any chance of the underlying request changing, stranding - // the fetcher in the wrong array - fetcher.serviceHost = host; - - return shouldBeginResult; -} - -- (void)startFetcher:(GTMSessionFetcher *)fetcher { - [fetcher beginFetchMayDelay:NO - mayAuthorize:YES]; -} - -// Internal utility. Returns a fetcher's delegate if it's a dispatcher, or nil if the fetcher -// is its own delegate and has no dispatcher. -- (GTMSessionFetcherSessionDelegateDispatcher *)delegateDispatcherForFetcher:(GTMSessionFetcher *)fetcher { - GTMSessionCheckNotSynchronized(self); - - NSURLSession *fetcherSession = fetcher.session; - if (fetcherSession) { - id<NSURLSessionDelegate> fetcherDelegate = fetcherSession.delegate; - BOOL hasDispatcher = (fetcherDelegate != nil && fetcherDelegate != fetcher); - if (hasDispatcher) { - GTMSESSION_ASSERT_DEBUG([fetcherDelegate isKindOfClass:[GTMSessionFetcherSessionDelegateDispatcher class]], - @"Fetcher delegate class: %@", [fetcherDelegate class]); - return (GTMSessionFetcherSessionDelegateDispatcher *)fetcherDelegate; - } - } - return nil; -} - -- (void)fetcherDidCreateSession:(GTMSessionFetcher *)fetcher { - if (fetcher.canShareSession) { - NSURLSession *fetcherSession = fetcher.session; - GTMSESSION_ASSERT_DEBUG(fetcherSession != nil, @"Fetcher missing its session: %@", fetcher); - - GTMSessionFetcherSessionDelegateDispatcher *delegateDispatcher = - [self delegateDispatcherForFetcher:fetcher]; - if (delegateDispatcher) { - GTMSESSION_ASSERT_DEBUG(delegateDispatcher.session == nil, - @"Fetcher made an extra session: %@", fetcher); - - // Save this fetcher's session. - delegateDispatcher.session = fetcherSession; - - // Allow other fetchers to request this session now. - dispatch_semaphore_signal(_sessionCreationSemaphore); - } - } -} - -- (void)fetcherDidBeginFetching:(GTMSessionFetcher *)fetcher { - // If this fetcher has a separate delegate with a shared session, then - // this fetcher should be added to the delegate's map of tasks to fetchers. - GTMSessionFetcherSessionDelegateDispatcher *delegateDispatcher = - [self delegateDispatcherForFetcher:fetcher]; - if (delegateDispatcher) { - GTMSESSION_ASSERT_DEBUG(fetcher.canShareSession, - @"Inappropriate shared session: %@", fetcher); - - // There should already be a session, from this or a previous fetcher. - // - // Sanity check that the fetcher's session is the delegate's shared session. - NSURLSession *sharedSession = delegateDispatcher.session; - NSURLSession *fetcherSession = fetcher.session; - GTMSESSION_ASSERT_DEBUG(sharedSession != nil, @"Missing delegate session: %@", fetcher); - GTMSESSION_ASSERT_DEBUG(fetcherSession == sharedSession, - @"Inconsistent session: %@ %@ (shared: %@)", - fetcher, fetcherSession, sharedSession); - - if (sharedSession != nil && fetcherSession == sharedSession) { - NSURLSessionTask *task = fetcher.sessionTask; - GTMSESSION_ASSERT_DEBUG(task != nil, @"Missing session task: %@", fetcher); - - if (task) { - [delegateDispatcher setFetcher:fetcher - forTask:task]; - } - } - } -} - -- (void)stopFetcher:(GTMSessionFetcher *)fetcher { - [fetcher stopFetching]; -} - -- (void)fetcherDidStop:(GTMSessionFetcher *)fetcher { - // Entry point from the fetcher - NSString *host = fetcher.serviceHost; - if (!host) { - // fetcher has been stopped previously - return; - } - - // This removeFetcher: invocation is a fallback; typically, fetchers are removed from the task - // map when the task completes. - GTMSessionFetcherSessionDelegateDispatcher *delegateDispatcher = - [self delegateDispatcherForFetcher:fetcher]; - [delegateDispatcher removeFetcher:fetcher]; - - NSMutableArray *fetchersToStart; - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - // If a test is waiting for all fetchers to stop, it needs to wait for this one - // to invoke its callbacks on the callback queue. - [_stoppedFetchersToWaitFor addObject:fetcher]; - - NSMutableArray *runningForHost = [_runningFetchersByHost objectForKey:host]; - [runningForHost removeObject:fetcher]; - - NSMutableArray *delayedForHost = [_delayedFetchersByHost objectForKey:host]; - [delayedForHost removeObject:fetcher]; - - while (delayedForHost.count > 0 - && [[self class] numberOfNonBackgroundSessionFetchers:runningForHost] - < _maxRunningFetchersPerHost) { - // Start another delayed fetcher running, scanning for the minimum - // priority value, defaulting to FIFO for equal priorities - GTMSessionFetcher *nextFetcher = nil; - for (GTMSessionFetcher *delayedFetcher in delayedForHost) { - if (nextFetcher == nil - || delayedFetcher.servicePriority < nextFetcher.servicePriority) { - nextFetcher = delayedFetcher; - } - } - - if (nextFetcher) { - [self addRunningFetcher:nextFetcher forHost:host]; - runningForHost = [_runningFetchersByHost objectForKey:host]; - - [delayedForHost removeObjectIdenticalTo:nextFetcher]; - - if (!fetchersToStart) { - fetchersToStart = [NSMutableArray array]; - } - [fetchersToStart addObject:nextFetcher]; - } - } - - if (runningForHost.count == 0) { - // None left; remove the empty array - [_runningFetchersByHost removeObjectForKey:host]; - } - - if (delayedForHost.count == 0) { - [_delayedFetchersByHost removeObjectForKey:host]; - } - } // @synchronized(self) - - // Start fetchers outside of the synchronized block to avoid a deadlock. - for (GTMSessionFetcher *nextFetcher in fetchersToStart) { - [self startFetcher:nextFetcher]; - } - - // The fetcher is no longer in the running or the delayed array, - // so remove its host and thread properties - fetcher.serviceHost = nil; -} - -- (NSUInteger)numberOfFetchers { - NSUInteger running = [self numberOfRunningFetchers]; - NSUInteger delayed = [self numberOfDelayedFetchers]; - return running + delayed; -} - -- (NSUInteger)numberOfRunningFetchers { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - NSUInteger sum = 0; - for (NSString *host in _runningFetchersByHost) { - NSArray *fetchers = [_runningFetchersByHost objectForKey:host]; - sum += fetchers.count; - } - return sum; - } -} - -- (NSUInteger)numberOfDelayedFetchers { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - NSUInteger sum = 0; - for (NSString *host in _delayedFetchersByHost) { - NSArray *fetchers = [_delayedFetchersByHost objectForKey:host]; - sum += fetchers.count; - } - return sum; - } -} - -- (NSArray *)issuedFetchers { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - NSMutableArray *allFetchers = [NSMutableArray array]; - void (^accumulateFetchers)(id, id, BOOL *) = ^(NSString *host, - NSArray *fetchersForHost, - BOOL *stop) { - [allFetchers addObjectsFromArray:fetchersForHost]; - }; - [_runningFetchersByHost enumerateKeysAndObjectsUsingBlock:accumulateFetchers]; - [_delayedFetchersByHost enumerateKeysAndObjectsUsingBlock:accumulateFetchers]; - - GTMSESSION_ASSERT_DEBUG(allFetchers.count == [NSSet setWithArray:allFetchers].count, - @"Fetcher appears multiple times\n running: %@\n delayed: %@", - _runningFetchersByHost, _delayedFetchersByHost); - - return allFetchers.count > 0 ? allFetchers : nil; - } -} - -- (NSArray *)issuedFetchersWithRequestURL:(NSURL *)requestURL { - NSString *host = requestURL.host; - if (host.length == 0) return nil; - - NSURL *targetURL = [requestURL absoluteURL]; - - NSArray *allFetchers = [self issuedFetchers]; - NSIndexSet *indexes = [allFetchers indexesOfObjectsPassingTest:^BOOL(GTMSessionFetcher *fetcher, - NSUInteger idx, - BOOL *stop) { - NSURL *fetcherURL = [fetcher.request.URL absoluteURL]; - return [fetcherURL isEqual:targetURL]; - }]; - - NSArray *result = nil; - if (indexes.count > 0) { - result = [allFetchers objectsAtIndexes:indexes]; - } - return result; -} - -- (void)stopAllFetchers { - NSArray *delayedFetchersByHost; - NSArray *runningFetchersByHost; - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - // Set the time barrier so fetchers know not to call back even if - // the stop calls below occur after the fetchers naturally - // stopped and so were removed from _runningFetchersByHost, - // but while the callbacks were already enqueued before stopAllFetchers - // was invoked. - _stoppedAllFetchersDate = [[NSDate alloc] init]; - - // Remove fetchers from the delayed list to avoid fetcherDidStop: from - // starting more fetchers running as a side effect of stopping one - delayedFetchersByHost = _delayedFetchersByHost.allValues; - [_delayedFetchersByHost removeAllObjects]; - - runningFetchersByHost = _runningFetchersByHost.allValues; - [_runningFetchersByHost removeAllObjects]; - } - - for (NSArray *delayedForHost in delayedFetchersByHost) { - for (GTMSessionFetcher *fetcher in delayedForHost) { - [self stopFetcher:fetcher]; - } - } - - for (NSArray *runningForHost in runningFetchersByHost) { - for (GTMSessionFetcher *fetcher in runningForHost) { - [self stopFetcher:fetcher]; - } - } -} - -- (NSDate *)stoppedAllFetchersDate { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _stoppedAllFetchersDate; - } -} - -#pragma mark Accessors - -- (BOOL)reuseSession { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _delegateDispatcher != nil; - } -} - -- (void)setReuseSession:(BOOL)shouldReuse { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - BOOL wasReusing = (_delegateDispatcher != nil); - if (shouldReuse != wasReusing) { - [self abandonDispatcher]; - if (shouldReuse) { - _delegateDispatcher = - [[GTMSessionFetcherSessionDelegateDispatcher alloc] initWithParentService:self - sessionDiscardInterval:_unusedSessionTimeout]; - } else { - _delegateDispatcher = nil; - } - } - } -} - -- (void)resetSession { - GTMSessionCheckNotSynchronized(self); - dispatch_semaphore_wait(_sessionCreationSemaphore, DISPATCH_TIME_FOREVER); - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - [self resetSessionInternal]; - } - - dispatch_semaphore_signal(_sessionCreationSemaphore); -} - -- (void)resetSessionInternal { - GTMSessionCheckSynchronized(self); - - // The old dispatchers may be retained as delegates of any ongoing sessions by those sessions. - if (_delegateDispatcher) { - [self abandonDispatcher]; - _delegateDispatcher = - [[GTMSessionFetcherSessionDelegateDispatcher alloc] initWithParentService:self - sessionDiscardInterval:_unusedSessionTimeout]; - } -} - -- (void)resetSessionForDispatcherDiscardTimer:(NSTimer *)timer { - GTMSessionCheckNotSynchronized(self); - - dispatch_semaphore_wait(_sessionCreationSemaphore, DISPATCH_TIME_FOREVER); - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (_delegateDispatcher.discardTimer == timer) { - // If the delegate dispatcher's current discardTimer is the same object as the timer - // that fired, no fetcher has recently attempted to start using the session by calling - // startSessionUsage, which invalidates and nils out the timer. - [self resetSessionInternal]; - } else { - // A fetcher has invalidated the timer between its triggering and now, potentially - // meaning a fetcher has requested access to the NSURLSession, and may be in the process - // of starting a new task. The dispatcher should not be abandoned, as this can lead - // to a race condition between calling -finishTasksAndInvalidate on the NSURLSession - // and the fetcher attempting to create a new task. - } - } - - dispatch_semaphore_signal(_sessionCreationSemaphore); -} - -- (NSTimeInterval)unusedSessionTimeout { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _unusedSessionTimeout; - } -} - -- (void)setUnusedSessionTimeout:(NSTimeInterval)timeout { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _unusedSessionTimeout = timeout; - _delegateDispatcher.discardInterval = timeout; - } -} - -// This method should be called inside of @synchronized(self) -- (void)abandonDispatcher { - GTMSessionCheckSynchronized(self); - [_delegateDispatcher abandon]; -} - -- (NSDictionary *)runningFetchersByHost { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return [_runningFetchersByHost copy]; - } -} - -- (void)setRunningFetchersByHost:(NSDictionary *)dict { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _runningFetchersByHost = [dict mutableCopy]; - } -} - -- (NSDictionary *)delayedFetchersByHost { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return [_delayedFetchersByHost copy]; - } -} - -- (void)setDelayedFetchersByHost:(NSDictionary *)dict { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _delayedFetchersByHost = [dict mutableCopy]; - } -} - -- (id<GTMFetcherAuthorizationProtocol>)authorizer { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _authorizer; - } -} - -- (void)setAuthorizer:(id<GTMFetcherAuthorizationProtocol>)obj { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (obj != _authorizer) { - [self detachAuthorizer]; - } - - _authorizer = obj; - } - - // Use the fetcher service for the authorization fetches if the auth - // object supports fetcher services - if ([obj respondsToSelector:@selector(setFetcherService:)]) { -#if GTM_USE_SESSION_FETCHER - [obj setFetcherService:self]; -#else - [obj setFetcherService:(id)self]; -#endif - } -} - -// This should be called inside a @synchronized(self) block except during dealloc. -- (void)detachAuthorizer { - // This method is called by the fetcher service's dealloc and setAuthorizer: - // methods; do not override. - // - // The fetcher service retains the authorizer, and the authorizer has a - // weak pointer to the fetcher service (a non-zeroing pointer for - // compatibility with iOS 4 and Mac OS X 10.5/10.6.) - // - // When this fetcher service no longer uses the authorizer, we want to remove - // the authorizer's dependence on the fetcher service. Authorizers can still - // function without a fetcher service. - if ([_authorizer respondsToSelector:@selector(fetcherService)]) { - id authFetcherService = [_authorizer fetcherService]; - if (authFetcherService == self) { - [_authorizer setFetcherService:nil]; - } - } -} - -- (dispatch_queue_t GTM_NONNULL_TYPE)callbackQueue { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _callbackQueue; - } // @synchronized(self) -} - -- (void)setCallbackQueue:(dispatch_queue_t GTM_NULLABLE_TYPE)queue { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _callbackQueue = queue ?: dispatch_get_main_queue(); - } // @synchronized(self) -} - -- (NSOperationQueue * GTM_NONNULL_TYPE)sessionDelegateQueue { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _delegateQueue; - } // @synchronized(self) -} - -- (void)setSessionDelegateQueue:(NSOperationQueue * GTM_NULLABLE_TYPE)queue { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _delegateQueue = queue ?: [NSOperationQueue mainQueue]; - } // @synchronized(self) -} - -- (NSOperationQueue *)delegateQueue { - // Provided for compatibility with the old fetcher service. The gtm-oauth2 code respects - // any custom delegate queue for calling the app. - return nil; -} - -+ (NSUInteger)numberOfNonBackgroundSessionFetchers:(NSArray *)fetchers { - NSUInteger sum = 0; - for (GTMSessionFetcher *fetcher in fetchers) { - if (!fetcher.usingBackgroundSession) { - ++sum; - } - } - return sum; -} - -@end - -@implementation GTMSessionFetcherService (TestingSupport) - -+ (instancetype)mockFetcherServiceWithFakedData:(NSData *)fakedDataOrNil - fakedError:(NSError *)fakedErrorOrNil { -#if !GTM_DISABLE_FETCHER_TEST_BLOCK - NSURL *url = [NSURL URLWithString:@"http://example.invalid"]; - NSHTTPURLResponse *fakedResponse = - [[NSHTTPURLResponse alloc] initWithURL:url - statusCode:(fakedErrorOrNil ? 500 : 200) - HTTPVersion:@"HTTP/1.1" - headerFields:nil]; - return [self mockFetcherServiceWithFakedData:fakedDataOrNil - fakedResponse:fakedResponse - fakedError:fakedErrorOrNil]; -#else - GTMSESSION_ASSERT_DEBUG(0, @"Test blocks disabled"); - return nil; -#endif // GTM_DISABLE_FETCHER_TEST_BLOCK -} - -+ (instancetype)mockFetcherServiceWithFakedData:(NSData *)fakedDataOrNil - fakedResponse:(NSHTTPURLResponse *)fakedResponse - fakedError:(NSError *)fakedErrorOrNil { -#if !GTM_DISABLE_FETCHER_TEST_BLOCK - GTMSessionFetcherService *service = [[self alloc] init]; - service.allowedInsecureSchemes = @[ @"http" ]; - service.testBlock = ^(GTMSessionFetcher *fetcherToTest, - GTMSessionFetcherTestResponse testResponse) { - testResponse(fakedResponse, fakedDataOrNil, fakedErrorOrNil); - }; - return service; -#else - GTMSESSION_ASSERT_DEBUG(0, @"Test blocks disabled"); - return nil; -#endif // GTM_DISABLE_FETCHER_TEST_BLOCK -} - -#pragma mark Synchronous Wait for Unit Testing - -- (BOOL)waitForCompletionOfAllFetchersWithTimeout:(NSTimeInterval)timeoutInSeconds { - NSDate *giveUpDate = [NSDate dateWithTimeIntervalSinceNow:timeoutInSeconds]; - _stoppedFetchersToWaitFor = [NSMutableArray array]; - - BOOL shouldSpinRunLoop = [NSThread isMainThread]; - const NSTimeInterval kSpinInterval = 0.001; - BOOL didTimeOut = NO; - while (([self numberOfFetchers] > 0 || _stoppedFetchersToWaitFor.count > 0)) { - didTimeOut = [giveUpDate timeIntervalSinceNow] < 0; - if (didTimeOut) break; - - GTMSessionFetcher *stoppedFetcher = _stoppedFetchersToWaitFor.firstObject; - if (stoppedFetcher) { - [_stoppedFetchersToWaitFor removeObject:stoppedFetcher]; - [stoppedFetcher waitForCompletionWithTimeout:10.0 * kSpinInterval]; - } - - if (shouldSpinRunLoop) { - NSDate *stopDate = [NSDate dateWithTimeIntervalSinceNow:kSpinInterval]; - [[NSRunLoop currentRunLoop] runUntilDate:stopDate]; - } else { - [NSThread sleepForTimeInterval:kSpinInterval]; - } - } - _stoppedFetchersToWaitFor = nil; - - return !didTimeOut; -} - -@end - -@implementation GTMSessionFetcherService (BackwardsCompatibilityOnly) - -- (NSInteger)cookieStorageMethod { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _cookieStorageMethod; - } -} - -- (void)setCookieStorageMethod:(NSInteger)cookieStorageMethod { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _cookieStorageMethod = cookieStorageMethod; - } -} - -@end - -@implementation GTMSessionFetcherSessionDelegateDispatcher { - __weak GTMSessionFetcherService *_parentService; - NSURLSession *_session; - - // The task map maps NSURLSessionTasks to GTMSessionFetchers - NSMutableDictionary *_taskToFetcherMap; - // The discard timer will invalidate sessions after the session's last task completes. - NSTimer *_discardTimer; - NSTimeInterval _discardInterval; -} - -@synthesize discardInterval = _discardInterval, - session = _session; - -- (instancetype)init { - [self doesNotRecognizeSelector:_cmd]; - return nil; -} - -- (instancetype)initWithParentService:(GTMSessionFetcherService *)parentService - sessionDiscardInterval:(NSTimeInterval)discardInterval { - self = [super init]; - if (self) { - _discardInterval = discardInterval; - _parentService = parentService; - } - return self; -} - -- (NSString *)description { - return [NSString stringWithFormat:@"%@ %p %@ %@", - [self class], self, - _session ?: @"<no session>", - _taskToFetcherMap.count > 0 ? _taskToFetcherMap : @"<no tasks>"]; -} - -- (NSTimer *)discardTimer { - GTMSessionCheckNotSynchronized(self); - @synchronized(self) { - return _discardTimer; - } -} - -// This method should be called inside of a @synchronized(self) block. -- (void)startDiscardTimer { - GTMSessionCheckSynchronized(self); - [_discardTimer invalidate]; - _discardTimer = nil; - if (_discardInterval > 0) { - _discardTimer = [NSTimer timerWithTimeInterval:_discardInterval - target:self - selector:@selector(discardTimerFired:) - userInfo:nil - repeats:NO]; - [_discardTimer setTolerance:(_discardInterval / 10)]; - [[NSRunLoop mainRunLoop] addTimer:_discardTimer forMode:NSRunLoopCommonModes]; - } -} - -// This method should be called inside of a @synchronized(self) block. -- (void)destroyDiscardTimer { - GTMSessionCheckSynchronized(self); - [_discardTimer invalidate]; - _discardTimer = nil; -} - -- (void)discardTimerFired:(NSTimer *)timer { - GTMSessionFetcherService *service; - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - NSUInteger numberOfTasks = _taskToFetcherMap.count; - if (numberOfTasks == 0) { - service = _parentService; - } - } - - // Inform the service that the discard timer has fired, and should check whether the - // service can abandon us. -resetSession cannot be called directly, as there is a - // race condition that must be guarded against with the NSURLSession being returned - // from sessionForFetcherCreation outside other locks. The service can take steps - // to prevent resetting the session if that has occurred. - // - // The service must be called from outside the @synchronized block. - [service resetSessionForDispatcherDiscardTimer:timer]; -} - -- (void)abandon { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - [self destroySessionAndTimer]; - } -} - -- (void)startSessionUsage { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - [self destroyDiscardTimer]; - } -} - -// This method should be called inside of a @synchronized(self) block. -- (void)destroySessionAndTimer { - GTMSessionCheckSynchronized(self); - [self destroyDiscardTimer]; - - // Break any retain cycle from the session holding the delegate. - [_session finishTasksAndInvalidate]; - - // Immediately clear the session so no new task may be issued with it. - // - // The _taskToFetcherMap needs to stay valid until the outstanding tasks finish. - _session = nil; -} - -- (void)setFetcher:(GTMSessionFetcher *)fetcher forTask:(NSURLSessionTask *)task { - GTMSESSION_ASSERT_DEBUG(fetcher != nil, @"missing fetcher"); - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (_taskToFetcherMap == nil) { - _taskToFetcherMap = [[NSMutableDictionary alloc] init]; - } - - if (fetcher) { - [_taskToFetcherMap setObject:fetcher forKey:task]; - [self destroyDiscardTimer]; - } - } -} - -- (void)removeFetcher:(GTMSessionFetcher *)fetcher { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - // Typically, a fetcher should be removed when its task invokes - // URLSession:task:didCompleteWithError:. - // - // When fetching with a testBlock, though, the task completed delegate - // method may not be invoked, requiring cleanup here. - NSArray *tasks = [_taskToFetcherMap allKeysForObject:fetcher]; - GTMSESSION_ASSERT_DEBUG(tasks.count <= 1, @"fetcher task not unmapped: %@", tasks); - [_taskToFetcherMap removeObjectsForKeys:tasks]; - - if (_taskToFetcherMap.count == 0) { - [self startDiscardTimer]; - } - } -} - -// This helper method provides synchronized access to the task map for the delegate -// methods below. -- (id)fetcherForTask:(NSURLSessionTask *)task { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return [_taskToFetcherMap objectForKey:task]; - } -} - -- (void)removeTaskFromMap:(NSURLSessionTask *)task { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - [_taskToFetcherMap removeObjectForKey:task]; - } -} - -- (void)setSession:(NSURLSession *)session { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _session = session; - } -} - -- (NSURLSession *)session { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _session; - } -} - -- (NSTimeInterval)discardInterval { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _discardInterval; - } -} - -- (void)setDiscardInterval:(NSTimeInterval)interval { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _discardInterval = interval; - } -} - -// NSURLSessionDelegate protocol methods. - -// - (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session; -// -// TODO(seh): How do we route this to an appropriate fetcher? - - -- (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(NSError *)error { - GTM_LOG_SESSION_DELEGATE(@"%@ %p URLSession:%@ didBecomeInvalidWithError:%@", - [self class], self, session, error); - NSDictionary *localTaskToFetcherMap; - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _session = nil; - - localTaskToFetcherMap = [_taskToFetcherMap copy]; - } - - // Any "suspended" tasks may not have received callbacks from NSURLSession when the session - // completes; we'll call them now. - [localTaskToFetcherMap enumerateKeysAndObjectsUsingBlock:^(NSURLSessionTask *task, - GTMSessionFetcher *fetcher, - BOOL *stop) { - if (fetcher.session == session) { - // Our delegate method URLSession:task:didCompleteWithError: will rely on - // _taskToFetcherMap so that should still contain this fetcher. - NSError *canceledError = [NSError errorWithDomain:NSURLErrorDomain - code:NSURLErrorCancelled - userInfo:nil]; - [self URLSession:session task:task didCompleteWithError:canceledError]; - } else { - GTMSESSION_ASSERT_DEBUG(0, @"Unexpected session in fetcher: %@ has %@ (expected %@)", - fetcher, fetcher.session, session); - } - }]; - - // Our tests rely on this notification to know the session discard timer fired. - NSDictionary *userInfo = @{ kGTMSessionFetcherServiceSessionKey : session }; - NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - [nc postNotificationName:kGTMSessionFetcherServiceSessionBecameInvalidNotification - object:_parentService - userInfo:userInfo]; -} - - -#pragma mark - NSURLSessionTaskDelegate - -// NSURLSessionTaskDelegate protocol methods. -// -// We won't test here if the fetcher responds to these since we only want this -// class to implement the same delegate methods the fetcher does (so NSURLSession's -// tests for respondsToSelector: will have the same result whether the session -// delegate is the fetcher or this dispatcher.) - -- (void)URLSession:(NSURLSession *)session - task:(NSURLSessionTask *)task -willPerformHTTPRedirection:(NSHTTPURLResponse *)response - newRequest:(NSURLRequest *)request - completionHandler:(void (^)(NSURLRequest *))completionHandler { - id<NSURLSessionTaskDelegate> fetcher = [self fetcherForTask:task]; - [fetcher URLSession:session - task:task -willPerformHTTPRedirection:response - newRequest:request - completionHandler:completionHandler]; -} - -- (void)URLSession:(NSURLSession *)session - task:(NSURLSessionTask *)task -didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge - completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))handler { - id<NSURLSessionTaskDelegate> fetcher = [self fetcherForTask:task]; - [fetcher URLSession:session - task:task - didReceiveChallenge:challenge - completionHandler:handler]; -} - -- (void)URLSession:(NSURLSession *)session - task:(NSURLSessionTask *)task - needNewBodyStream:(void (^)(NSInputStream *bodyStream))handler { - id<NSURLSessionTaskDelegate> fetcher = [self fetcherForTask:task]; - [fetcher URLSession:session - task:task - needNewBodyStream:handler]; -} - -- (void)URLSession:(NSURLSession *)session - task:(NSURLSessionTask *)task - didSendBodyData:(int64_t)bytesSent - totalBytesSent:(int64_t)totalBytesSent -totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend { - id<NSURLSessionTaskDelegate> fetcher = [self fetcherForTask:task]; - [fetcher URLSession:session - task:task - didSendBodyData:bytesSent - totalBytesSent:totalBytesSent -totalBytesExpectedToSend:totalBytesExpectedToSend]; -} - -- (void)URLSession:(NSURLSession *)session - task:(NSURLSessionTask *)task -didCompleteWithError:(NSError *)error { - id<NSURLSessionTaskDelegate> fetcher = [self fetcherForTask:task]; - - // This is the usual way tasks are removed from the task map. - [self removeTaskFromMap:task]; - - [fetcher URLSession:session - task:task - didCompleteWithError:error]; -} - -// NSURLSessionDataDelegate protocol methods. - -- (void)URLSession:(NSURLSession *)session - dataTask:(NSURLSessionDataTask *)dataTask -didReceiveResponse:(NSURLResponse *)response - completionHandler:(void (^)(NSURLSessionResponseDisposition))handler { - id<NSURLSessionDataDelegate> fetcher = [self fetcherForTask:dataTask]; - [fetcher URLSession:session - dataTask:dataTask - didReceiveResponse:response - completionHandler:handler]; -} - -- (void)URLSession:(NSURLSession *)session - dataTask:(NSURLSessionDataTask *)dataTask -didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask { - id<NSURLSessionDataDelegate> fetcher = [self fetcherForTask:dataTask]; - GTMSESSION_ASSERT_DEBUG(fetcher != nil, @"Missing fetcher for %@", dataTask); - [self removeTaskFromMap:dataTask]; - if (fetcher) { - GTMSESSION_ASSERT_DEBUG([fetcher isKindOfClass:[GTMSessionFetcher class]], - @"Expecting GTMSessionFetcher"); - [self setFetcher:(GTMSessionFetcher *)fetcher forTask:downloadTask]; - } - - [fetcher URLSession:session - dataTask:dataTask -didBecomeDownloadTask:downloadTask]; -} - -- (void)URLSession:(NSURLSession *)session - dataTask:(NSURLSessionDataTask *)dataTask - didReceiveData:(NSData *)data { - id<NSURLSessionDataDelegate> fetcher = [self fetcherForTask:dataTask]; - [fetcher URLSession:session - dataTask:dataTask - didReceiveData:data]; -} - -- (void)URLSession:(NSURLSession *)session - dataTask:(NSURLSessionDataTask *)dataTask - willCacheResponse:(NSCachedURLResponse *)proposedResponse - completionHandler:(void (^)(NSCachedURLResponse *))handler { - id<NSURLSessionDataDelegate> fetcher = [self fetcherForTask:dataTask]; - [fetcher URLSession:session - dataTask:dataTask - willCacheResponse:proposedResponse - completionHandler:handler]; -} - -// NSURLSessionDownloadDelegate protocol methods. - -- (void)URLSession:(NSURLSession *)session - downloadTask:(NSURLSessionDownloadTask *)downloadTask -didFinishDownloadingToURL:(NSURL *)location { - id<NSURLSessionDownloadDelegate> fetcher = [self fetcherForTask:downloadTask]; - [fetcher URLSession:session - downloadTask:downloadTask -didFinishDownloadingToURL:location]; -} - -- (void)URLSession:(NSURLSession *)session - downloadTask:(NSURLSessionDownloadTask *)downloadTask - didWriteData:(int64_t)bytesWritten - totalBytesWritten:(int64_t)totalWritten -totalBytesExpectedToWrite:(int64_t)totalExpected { - id<NSURLSessionDownloadDelegate> fetcher = [self fetcherForTask:downloadTask]; - [fetcher URLSession:session - downloadTask:downloadTask - didWriteData:bytesWritten - totalBytesWritten:totalWritten -totalBytesExpectedToWrite:totalExpected]; -} - -- (void)URLSession:(NSURLSession *)session - downloadTask:(NSURLSessionDownloadTask *)downloadTask - didResumeAtOffset:(int64_t)fileOffset -expectedTotalBytes:(int64_t)expectedTotalBytes { - id<NSURLSessionDownloadDelegate> fetcher = [self fetcherForTask:downloadTask]; - [fetcher URLSession:session - downloadTask:downloadTask - didResumeAtOffset:fileOffset - expectedTotalBytes:expectedTotalBytes]; -} - -@end diff --git a/Pods/GTMSessionFetcher/Source/GTMSessionUploadFetcher.h b/Pods/GTMSessionFetcher/Source/GTMSessionUploadFetcher.h @@ -1,166 +0,0 @@ -/* Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// GTMSessionUploadFetcher implements Google's resumable upload protocol. - -// -// This subclass of GTMSessionFetcher simulates the series of fetches -// needed for chunked upload as a single fetch operation. -// -// Protocol document: TBD -// -// To the client, the only fetcher that exists is this class; the subsidiary -// fetchers needed for uploading chunks are not visible (though the most recent -// chunk fetcher may be accessed via the -activeFetcher or -chunkFetcher methods, and -// -responseHeaders and -statusCode reflect results from the most recent chunk -// fetcher.) -// -// Chunk fetchers are discarded as soon as they have completed. -// -// The protocol also allows for a cancellation notification request to be sent to the -// server to allow discarding of the currently uploaded data and this will be sent -// automatically upon calling stopFetching if the upload has already started. -// -// Note: Unlike the fetcher superclass, the methods of GTMSessionUploadFetcher should -// only be used from the main thread until further work is done to make this subclass -// thread-safe. - -#import "GTMSessionFetcher.h" -#import "GTMSessionFetcherService.h" - -GTM_ASSUME_NONNULL_BEGIN - -// The value to use for file size parameters when the file size is not yet known. -extern int64_t const kGTMSessionUploadFetcherUnknownFileSize; - -// Unless an application knows it needs a smaller chunk size, it should use the standard -// chunk size, which sends the entire file as a single chunk to minimize upload overhead. -// Setting an explicit chunk size that comfortably fits in memory is advisable for large -// uploads. -extern int64_t const kGTMSessionUploadFetcherStandardChunkSize; - -// When uploading requires data buffer allocations (such as uploading from an NSData or -// an NSFileHandle) this is the maximum buffer size that will be created by the fetcher. -extern int64_t const kGTMSessionUploadFetcherMaximumDemandBufferSize; - -// Notification that the upload location URL was provided by the server. -extern NSString *const kGTMSessionFetcherUploadLocationObtainedNotification; - -// Block to provide data during uploads. -// -// Response data may be allocated with dataWithBytesNoCopy:length:freeWhenDone: for efficiency, -// and released after the response block returns. -// -// If the length of the file being uploaded is unknown or already set, send -// kGTMSessionUploadFetcherUnknownFileSize for |fullUploadLength|. Otherwise, set |fullUploadLength| -// to its proper value. -// -// Pass nil as the data (and optionally an NSError) for a failure. -typedef void (^GTMSessionUploadFetcherDataProviderResponse)(NSData * GTM_NULLABLE_TYPE data, - int64_t fullUploadLength, - NSError * GTM_NULLABLE_TYPE error); -// Do not call the response with an NSData object with less data than the requested length unless -// you are passing the fullUploadLength to the fetcher for the first time and it is the last chunk -// of data in the file being uploaded. -typedef void (^GTMSessionUploadFetcherDataProvider)(int64_t offset, int64_t length, - GTMSessionUploadFetcherDataProviderResponse response); - -// Block to be notified about the final status of the cancellation request started in stopFetching. -// -// |fetcher| will be the cancel request that was sent to the server, or nil if stopFetching is not -// going to send a cancel request. If |fetcher| is provided, the other parameters correspond to the -// completion handler of the cancellation request fetcher. -typedef void (^GTMSessionUploadFetcherCancellationHandler)( - GTMSessionFetcher * GTM_NULLABLE_TYPE fetcher, - NSData * GTM_NULLABLE_TYPE data, - NSError * GTM_NULLABLE_TYPE error); - -@interface GTMSessionUploadFetcher : GTMSessionFetcher - -// Create an upload fetcher specifying either the request or the resume location URL, -// then set an upload data source using one of these: -// -// setUploadFileURL: -// setUploadDataLength:provider: -// setUploadFileHandle: -// setUploadData: - -+ (instancetype)uploadFetcherWithRequest:(NSURLRequest *)request - uploadMIMEType:(NSString *)uploadMIMEType - chunkSize:(int64_t)chunkSize - fetcherService:(GTM_NULLABLE GTMSessionFetcherService *)fetcherServiceOrNil; - -+ (instancetype)uploadFetcherWithLocation:(NSURL * GTM_NULLABLE_TYPE)uploadLocationURL - uploadMIMEType:(NSString *)uploadMIMEType - chunkSize:(int64_t)chunkSize - fetcherService:(GTM_NULLABLE GTMSessionFetcherService *)fetcherServiceOrNil; - -// Allows dataProviders for files of unknown length. Pass kGTMSessionUploadFetcherUnknownFileSize as -// |fullLength| if the length is unknown. -- (void)setUploadDataLength:(int64_t)fullLength - provider:(GTM_NULLABLE GTMSessionUploadFetcherDataProvider)block; - -+ (NSArray *)uploadFetchersForBackgroundSessions; -+ (GTM_NULLABLE instancetype)uploadFetcherForSessionIdentifier:(NSString *)sessionIdentifier; - -- (void)pauseFetching; -- (void)resumeFetching; -- (BOOL)isPaused; - -@property(atomic, strong, GTM_NULLABLE) NSURL *uploadLocationURL; -@property(atomic, strong, GTM_NULLABLE) NSData *uploadData; -@property(atomic, strong, GTM_NULLABLE) NSURL *uploadFileURL; -@property(atomic, strong, GTM_NULLABLE) NSFileHandle *uploadFileHandle; -@property(atomic, copy, readonly, GTM_NULLABLE) GTMSessionUploadFetcherDataProvider uploadDataProvider; -@property(atomic, copy) NSString *uploadMIMEType; -@property(atomic, assign) int64_t chunkSize; -@property(atomic, readonly, assign) int64_t currentOffset; - -// The fetcher for the current data chunk, if any -@property(atomic, strong, GTM_NULLABLE) GTMSessionFetcher *chunkFetcher; - -// The active fetcher is the current chunk fetcher, or the upload fetcher itself -// if no chunk fetcher has yet been created. -@property(atomic, readonly) GTMSessionFetcher *activeFetcher; - -// The last request made by an active fetcher. Useful for testing. -@property(atomic, readonly, GTM_NULLABLE) NSURLRequest *lastChunkRequest; - -// The status code from the most recently-completed fetch. -@property(atomic, assign) NSInteger statusCode; - -// Invoked as part of the stop fetching process. Invoked immediately if there is no upload in -// progress, otherwise invoked with the results of the attempt to notify the server that the -// upload will not continue. -// -// Unlike other callbacks, since this is related specifically to the stopFetching flow it is not -// cleared by stopFetching. It will instead clear itself after it is invoked or if the completion -// has occured before stopFetching is called. -@property(atomic, copy, GTM_NULLABLE) GTMSessionUploadFetcherCancellationHandler - cancellationHandler; - -// Exposed for testing only. -@property(atomic, readonly, GTM_NULLABLE) dispatch_queue_t delegateCallbackQueue; -@property(atomic, readonly, GTM_NULLABLE) GTMSessionFetcherCompletionHandler delegateCompletionHandler; - -@end - -@interface GTMSessionFetcher (GTMSessionUploadFetcherMethods) - -@property(readonly, GTM_NULLABLE) GTMSessionUploadFetcher *parentUploadFetcher; - -@end - -GTM_ASSUME_NONNULL_END diff --git a/Pods/GTMSessionFetcher/Source/GTMSessionUploadFetcher.m b/Pods/GTMSessionFetcher/Source/GTMSessionUploadFetcher.m @@ -1,1954 +0,0 @@ -/* Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -#import "GTMSessionUploadFetcher.h" - -static NSString *const kGTMSessionIdentifierIsUploadChunkFetcherMetadataKey = @"_upChunk"; -static NSString *const kGTMSessionIdentifierUploadFileURLMetadataKey = @"_upFileURL"; -static NSString *const kGTMSessionIdentifierUploadFileLengthMetadataKey = @"_upFileLen"; -static NSString *const kGTMSessionIdentifierUploadLocationURLMetadataKey = @"_upLocURL"; -static NSString *const kGTMSessionIdentifierUploadMIMETypeMetadataKey = @"_uploadMIME"; -static NSString *const kGTMSessionIdentifierUploadChunkSizeMetadataKey = @"_upChSize"; -static NSString *const kGTMSessionIdentifierUploadCurrentOffsetMetadataKey = @"_upOffset"; - -static NSString *const kGTMSessionHeaderXGoogUploadChunkGranularity = @"X-Goog-Upload-Chunk-Granularity"; -static NSString *const kGTMSessionHeaderXGoogUploadCommand = @"X-Goog-Upload-Command"; -static NSString *const kGTMSessionHeaderXGoogUploadContentLength = @"X-Goog-Upload-Content-Length"; -static NSString *const kGTMSessionHeaderXGoogUploadContentType = @"X-Goog-Upload-Content-Type"; -static NSString *const kGTMSessionHeaderXGoogUploadOffset = @"X-Goog-Upload-Offset"; -static NSString *const kGTMSessionHeaderXGoogUploadProtocol = @"X-Goog-Upload-Protocol"; -static NSString *const kGTMSessionXGoogUploadProtocolResumable = @"resumable"; -static NSString *const kGTMSessionHeaderXGoogUploadSizeReceived = @"X-Goog-Upload-Size-Received"; -static NSString *const kGTMSessionHeaderXGoogUploadStatus = @"X-Goog-Upload-Status"; -static NSString *const kGTMSessionHeaderXGoogUploadURL = @"X-Goog-Upload-URL"; - -// Property of chunk fetchers identifying the parent upload fetcher. Non-retained NSValue. -static NSString *const kGTMSessionUploadFetcherChunkParentKey = @"_uploadFetcherChunkParent"; - -int64_t const kGTMSessionUploadFetcherUnknownFileSize = -1; - -int64_t const kGTMSessionUploadFetcherStandardChunkSize = (int64_t)LLONG_MAX; - -#if TARGET_OS_IPHONE -int64_t const kGTMSessionUploadFetcherMaximumDemandBufferSize = 10 * 1024 * 1024; // 10 MB for iOS, watchOS, tvOS -#else -int64_t const kGTMSessionUploadFetcherMaximumDemandBufferSize = 100 * 1024 * 1024; // 100 MB for macOS -#endif - -typedef NS_ENUM(NSUInteger, GTMSessionUploadFetcherStatus) { - kStatusUnknown, - kStatusActive, - kStatusFinal, - kStatusCancelled, -}; - -NSString *const kGTMSessionFetcherUploadLocationObtainedNotification = - @"kGTMSessionFetcherUploadLocationObtainedNotification"; - -#if !GTMSESSION_BUILD_COMBINED_SOURCES -@interface GTMSessionFetcher (ProtectedMethods) - -// Access to non-public method on the parent fetcher class. -- (void)stopFetchReleasingCallbacks:(BOOL)shouldReleaseCallbacks; -- (void)createSessionIdentifierWithMetadata:(NSDictionary *)metadata; -- (GTMSessionFetcherCompletionHandler)completionHandlerWithTarget:(id)target - didFinishSelector:(SEL)finishedSelector; -- (void)invokeOnCallbackQueue:(dispatch_queue_t)callbackQueue - afterUserStopped:(BOOL)afterStopped - block:(void (^)(void))block; -- (NSTimer *)retryTimer; -- (void)beginFetchForRetry; - -@property(readwrite, strong) NSData *downloadedData; -- (void)releaseCallbacks; - -- (NSInteger)statusCodeUnsynchronized; - -- (BOOL)userStoppedFetching; - -@end -#endif // !GTMSESSION_BUILD_COMBINED_SOURCES - -@interface GTMSessionUploadFetcher () - -// Changing readonly to readwrite. -@property(atomic, strong, readwrite) NSURLRequest *lastChunkRequest; -@property(atomic, readwrite, assign) int64_t currentOffset; - -// Internal properties. -@property(strong, atomic, GTM_NULLABLE) GTMSessionFetcher *fetcherInFlight; // Synchronized on self. - -@property(assign, atomic, getter=isSubdataGenerating) BOOL subdataGenerating; -@property(assign, atomic) BOOL shouldInitiateOffsetQuery; -@property(assign, atomic) int64_t uploadGranularity; - -@end - -@implementation GTMSessionUploadFetcher { - GTMSessionFetcher *_chunkFetcher; - - // We'll call through to the delegate's completion handler. - GTMSessionFetcherCompletionHandler _delegateCompletionHandler; - dispatch_queue_t _delegateCallbackQueue; - - // The initial fetch's body length and bytes actually sent are - // needed for calculating progress during subsequent chunk uploads - int64_t _initialBodyLength; - int64_t _initialBodySent; - - // The upload server address for the chunks of this upload session. - NSURL *_uploadLocationURL; - - // _uploadData, _uploadDataProvider, or _uploadFileHandle may be set, but only one. - NSData *_uploadData; - NSFileHandle *_uploadFileHandle; - GTMSessionUploadFetcherDataProvider _uploadDataProvider; - NSURL *_uploadFileURL; - int64_t _uploadFileLength; - NSString *_uploadMIMEType; - int64_t _chunkSize; - int64_t _uploadGranularity; - BOOL _isPaused; - BOOL _isRestartedUpload; - BOOL _shouldInitiateOffsetQuery; - - // Tied to useBackgroundSession property, since this property is applicable to chunk fetchers. - BOOL _useBackgroundSessionOnChunkFetchers; - - // We keep the latest offset into the upload data just for progress reporting. - int64_t _currentOffset; - - NSDictionary *_recentChunkReponseHeaders; - NSInteger _recentChunkStatusCode; - - // For waiting, we need to know the fetcher in flight, if any, and if subdata generation - // is in progress. - GTMSessionFetcher *_fetcherInFlight; - BOOL _isSubdataGenerating; - BOOL _isCancelInFlight; - - GTMSessionUploadFetcherCancellationHandler _cancellationHandler; -} - -+ (void)load { - [self uploadFetchersForBackgroundSessions]; -} - -+ (instancetype)uploadFetcherWithRequest:(NSURLRequest *)request - uploadMIMEType:(NSString *)uploadMIMEType - chunkSize:(int64_t)chunkSize - fetcherService:(GTMSessionFetcherService *)fetcherService { - GTMSessionUploadFetcher *fetcher = [self uploadFetcherWithRequest:request - fetcherService:fetcherService]; - [fetcher setLocationURL:nil - uploadMIMEType:uploadMIMEType - chunkSize:chunkSize]; - return fetcher; -} - -+ (instancetype)uploadFetcherWithLocation:(NSURL * GTM_NULLABLE_TYPE)uploadLocationURL - uploadMIMEType:(NSString *)uploadMIMEType - chunkSize:(int64_t)chunkSize - fetcherService:(GTMSessionFetcherService *)fetcherService { - GTMSessionUploadFetcher *fetcher = [self uploadFetcherWithRequest:nil - fetcherService:fetcherService]; - [fetcher setLocationURL:uploadLocationURL - uploadMIMEType:uploadMIMEType - chunkSize:chunkSize]; - return fetcher; -} - -+ (instancetype)uploadFetcherForSessionIdentifierMetadata:(NSDictionary *)metadata { - GTMSESSION_ASSERT_DEBUG( - [metadata[kGTMSessionIdentifierIsUploadChunkFetcherMetadataKey] boolValue], - @"Session identifier metadata is not for an upload fetcher: %@", metadata); - - NSNumber *uploadFileLengthNum = metadata[kGTMSessionIdentifierUploadFileLengthMetadataKey]; - GTMSESSION_ASSERT_DEBUG(uploadFileLengthNum != nil, - @"Session metadata missing an UploadFileSize"); - if (uploadFileLengthNum == nil) return nil; - - int64_t uploadFileLength = [uploadFileLengthNum longLongValue]; - GTMSESSION_ASSERT_DEBUG(uploadFileLength >= 0, @"Session metadata UploadFileSize is unknown"); - - NSString *uploadFileURLString = metadata[kGTMSessionIdentifierUploadFileURLMetadataKey]; - GTMSESSION_ASSERT_DEBUG(uploadFileURLString, @"Session metadata missing an UploadFileURL"); - if (uploadFileURLString == nil) return nil; - - NSURL *uploadFileURL = [NSURL URLWithString:uploadFileURLString]; - // There used to be a call here to NSURL checkResourceIsReachableAndReturnError: to check for the - // existence of the file (also tried NSFileManager fileExistsAtPath:). We've determined - // empirically that the check can fail at startup even when the upload file does in fact exist. - // For now, we'll go ahead and restore the background upload fetcher. If the file doesn't exist, - // it will fail later. - - NSString *uploadLocationURLString = metadata[kGTMSessionIdentifierUploadLocationURLMetadataKey]; - NSURL *uploadLocationURL = - uploadLocationURLString ? [NSURL URLWithString:uploadLocationURLString] : nil; - - NSString *uploadMIMEType = - metadata[kGTMSessionIdentifierUploadMIMETypeMetadataKey]; - int64_t uploadChunkSize = - [metadata[kGTMSessionIdentifierUploadChunkSizeMetadataKey] longLongValue]; - if (uploadChunkSize <= 0) { - uploadChunkSize = kGTMSessionUploadFetcherStandardChunkSize; - } - int64_t currentOffset = - [metadata[kGTMSessionIdentifierUploadCurrentOffsetMetadataKey] longLongValue]; - GTMSESSION_ASSERT_DEBUG(currentOffset <= uploadFileLength, - @"CurrentOffset (%lld) exceeds UploadFileSize (%lld)", - currentOffset, uploadFileLength); - if (currentOffset > uploadFileLength) return nil; - - GTMSessionUploadFetcher *uploadFetcher = [self uploadFetcherWithLocation:uploadLocationURL - uploadMIMEType:uploadMIMEType - chunkSize:uploadChunkSize - fetcherService:nil]; - // Set the upload file length before setting the upload file URL tries to determine the length. - [uploadFetcher setUploadFileLength:uploadFileLength]; - - uploadFetcher.uploadFileURL = uploadFileURL; - uploadFetcher.sessionUserInfo = metadata; - uploadFetcher.useBackgroundSession = YES; - uploadFetcher.currentOffset = currentOffset; - uploadFetcher.delegateCallbackQueue = uploadFetcher.callbackQueue; - uploadFetcher.allowedInsecureSchemes = @[ @"http" ]; // Allowed on restored upload fetcher. - return uploadFetcher; -} - -+ (instancetype)uploadFetcherWithRequest:(NSURLRequest *)request - fetcherService:(GTMSessionFetcherService *)fetcherService { - // Internal utility method for instantiating fetchers - GTMSessionUploadFetcher *fetcher; - if ([fetcherService isKindOfClass:[GTMSessionFetcherService class]]) { - fetcher = [fetcherService fetcherWithRequest:request - fetcherClass:self]; - } else { - fetcher = [self fetcherWithRequest:request]; - } - fetcher.useBackgroundSession = YES; - return fetcher; -} - -+ (NSPointerArray *)uploadFetcherPointerArrayForBackgroundSessions { - static NSPointerArray *gUploadFetcherPointerArrayForBackgroundSessions = nil; - - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - gUploadFetcherPointerArrayForBackgroundSessions = [NSPointerArray weakObjectsPointerArray]; - }); - return gUploadFetcherPointerArrayForBackgroundSessions; -} - -+ (instancetype)uploadFetcherForSessionIdentifier:(NSString *)sessionIdentifier { - GTMSESSION_ASSERT_DEBUG(sessionIdentifier != nil, @"Invalid session identifier"); - NSArray *uploadFetchersForBackgroundSessions = [self uploadFetchersForBackgroundSessions]; - for (GTMSessionUploadFetcher *uploadFetcher in uploadFetchersForBackgroundSessions) { - if ([uploadFetcher.chunkFetcher.sessionIdentifier isEqual:sessionIdentifier]) { - return uploadFetcher; - } - } - return nil; -} - -+ (NSArray *)uploadFetchersForBackgroundSessions { - // Collect the background session upload fetchers that are still in memory. - NSPointerArray *uploadFetcherPointerArray = [self uploadFetcherPointerArrayForBackgroundSessions]; - [uploadFetcherPointerArray compact]; - NSMutableSet *restoredSessionIdentifiers = [[NSMutableSet alloc] init]; - NSMutableArray *uploadFetchers = [[NSMutableArray alloc] init]; - for (GTMSessionUploadFetcher *uploadFetcher in uploadFetcherPointerArray) { - NSString *sessionIdentifier = uploadFetcher.chunkFetcher.sessionIdentifier; - if (sessionIdentifier) { - [restoredSessionIdentifiers addObject:sessionIdentifier]; - [uploadFetchers addObject:uploadFetcher]; - } - } - - // The system may have other ongoing background upload sessions. Restore upload fetchers for those - // too. - NSArray *fetchers = [GTMSessionFetcher fetchersForBackgroundSessions]; - for (GTMSessionFetcher *fetcher in fetchers) { - NSString *sessionIdentifier = fetcher.sessionIdentifier; - if (!sessionIdentifier || [restoredSessionIdentifiers containsObject:sessionIdentifier]) { - continue; - } - NSDictionary *sessionIdentifierMetadata = [fetcher sessionIdentifierMetadata]; - if (sessionIdentifierMetadata == nil) { - continue; - } - if (![sessionIdentifierMetadata[kGTMSessionIdentifierIsUploadChunkFetcherMetadataKey] boolValue]) { - continue; - } - GTMSessionUploadFetcher *uploadFetcher = - [self uploadFetcherForSessionIdentifierMetadata:sessionIdentifierMetadata]; - if (uploadFetcher == nil) { - // Something went wrong with this upload fetcher, so kill the restored chunk fetcher. - [fetcher stopFetching]; - continue; - } - [uploadFetchers addObject:uploadFetcher]; - uploadFetcher->_chunkFetcher = fetcher; - uploadFetcher->_fetcherInFlight = fetcher; - [uploadFetcher attachSendProgressBlockToChunkFetcher:fetcher]; - fetcher.completionHandler = - [fetcher completionHandlerWithTarget:uploadFetcher - didFinishSelector:@selector(chunkFetcher:finishedWithData:error:)]; - - GTMSESSION_LOG_DEBUG(@"%@ restoring upload fetcher %@ for chunk fetcher %@", - [self class], uploadFetcher, fetcher); - } - return uploadFetchers; -} - -- (void)setUploadData:(NSData *)data { - BOOL changed = NO; - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (_uploadData != data) { - _uploadData = data; - changed = YES; - } - } - if (changed) { - [self setupRequestHeaders]; - } -} - -- (NSData *)uploadData { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _uploadData; - } -} - -- (void)setUploadFileHandle:(NSFileHandle *)fh { - BOOL changed = NO; - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (_uploadFileHandle != fh) { - _uploadFileHandle = fh; - changed = YES; - } - } - if (changed) { - [self setupRequestHeaders]; - } -} - -- (NSFileHandle *)uploadFileHandle { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _uploadFileHandle; - } -} - -- (void)setUploadFileURL:(NSURL *)uploadURL { - BOOL changed = NO; - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (_uploadFileURL != uploadURL) { - _uploadFileURL = uploadURL; - changed = YES; - } - } - if (changed) { - [self setupRequestHeaders]; - } -} - -- (NSURL *)uploadFileURL { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _uploadFileURL; - } -} - -- (void)setUploadFileLength:(int64_t)fullLength { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (_uploadFileLength == kGTMSessionUploadFetcherUnknownFileSize && - fullLength != kGTMSessionUploadFetcherUnknownFileSize) { - _uploadFileLength = fullLength; - } - } -} - -- (void)setUploadDataLength:(int64_t)fullLength - provider:(GTMSessionUploadFetcherDataProvider)block { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _uploadDataProvider = [block copy]; - _uploadFileLength = fullLength; - } - [self setupRequestHeaders]; -} - -- (GTMSessionUploadFetcherDataProvider)uploadDataProvider { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _uploadDataProvider; - } -} - - -- (void)setUploadMIMEType:(NSString *)uploadMIMEType { - GTMSESSION_ASSERT_DEBUG(0, @"TODO: disallow setUploadMIMEType by making declaration readonly"); - // (and uploadMIMEType, chunksize, currentOffset) - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _uploadMIMEType = uploadMIMEType; - } -} - -- (NSString *)uploadMIMEType { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _uploadMIMEType; - } -} - -- (void)setChunkSize:(int64_t)chunkSize { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _chunkSize = chunkSize; - } -} - -- (int64_t)chunkSize { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _chunkSize; - } -} - -- (void)setupRequestHeaders { - GTMSessionCheckNotSynchronized(self); - -#if DEBUG - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - int hasData = (_uploadData != nil) ? 1 : 0; - int hasFileHandle = (_uploadFileHandle != nil) ? 1 : 0; - int hasFileURL = (_uploadFileURL != nil) ? 1 : 0; - int hasUploadDataProvider = (_uploadDataProvider != nil) ? 1 : 0; - int numberOfSources = hasData + hasFileHandle + hasFileURL + hasUploadDataProvider; - #pragma unused(numberOfSources) - GTMSESSION_ASSERT_DEBUG(numberOfSources == 1, - @"Need just one upload source (%d)", numberOfSources); - } // @synchronized(self) -#endif - - // Add our custom headers to the initial request indicating the data - // type and total size to be delivered later in the chunk requests. - NSMutableURLRequest *mutableRequest = [self.request mutableCopy]; - - GTMSESSION_ASSERT_DEBUG((mutableRequest == nil) != (_uploadLocationURL == nil), - @"Request and location are mutually exclusive"); - if (!mutableRequest) return; - - [mutableRequest setValue:kGTMSessionXGoogUploadProtocolResumable - forHTTPHeaderField:kGTMSessionHeaderXGoogUploadProtocol]; - [mutableRequest setValue:@"start" - forHTTPHeaderField:kGTMSessionHeaderXGoogUploadCommand]; - [mutableRequest setValue:_uploadMIMEType - forHTTPHeaderField:kGTMSessionHeaderXGoogUploadContentType]; - [mutableRequest setValue:@([self fullUploadLength]).stringValue - forHTTPHeaderField:kGTMSessionHeaderXGoogUploadContentLength]; - - NSString *method = mutableRequest.HTTPMethod; - if (method == nil || [method caseInsensitiveCompare:@"GET"] == NSOrderedSame) { - [mutableRequest setHTTPMethod:@"POST"]; - } - - // Ensure the user agent header identifies this to the upload server as a - // GTMSessionUploadFetcher client. The /1 can be incremented in the unlikely circumstance - // we need to make a bug fix in the client that the server can recognize. - NSString *const kUserAgentStub = @"(GTMSUF/1)"; - NSString *userAgent = [mutableRequest valueForHTTPHeaderField:@"User-Agent"]; - if (userAgent == nil - || [userAgent rangeOfString:kUserAgentStub].location == NSNotFound) { - if (userAgent.length == 0) { - userAgent = GTMFetcherStandardUserAgentString(nil); - } - userAgent = [userAgent stringByAppendingFormat:@" %@", kUserAgentStub]; - [mutableRequest setValue:userAgent forHTTPHeaderField:@"User-Agent"]; - } - [self setRequest:mutableRequest]; -} - -- (void)setLocationURL:(NSURL * GTM_NULLABLE_TYPE)location - uploadMIMEType:(NSString *)uploadMIMEType - chunkSize:(int64_t)chunkSize { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - GTMSESSION_ASSERT_DEBUG(chunkSize > 0, @"chunk size is zero"); - - // When resuming an upload, set the known upload target URL. - _uploadLocationURL = location; - - _uploadMIMEType = uploadMIMEType; - _chunkSize = chunkSize; - - // Indicate that we've not yet determined the file handle's length - _uploadFileLength = kGTMSessionUploadFetcherUnknownFileSize; - - // Indicate that we've not yet determined the upload fetcher status - _recentChunkStatusCode = -1; - - // If this is restarting an upload begun by another fetcher, - // the location is specified but the request is nil - _isRestartedUpload = (location != nil); - } // @synchronized(self) -} - -- (int64_t)fullUploadLength { - int64_t result; - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (_uploadData) { - result = (int64_t)_uploadData.length; - } else { - if (_uploadFileLength == kGTMSessionUploadFetcherUnknownFileSize) { - if (_uploadFileHandle) { - // First time through, seek to end to determine file length - _uploadFileLength = (int64_t)[_uploadFileHandle seekToEndOfFile]; - } else if (_uploadDataProvider) { - // _uploadFileLength is set when the _uploadDataProvider is set. - GTMSESSION_ASSERT_DEBUG(_uploadFileLength >= 0, @"No uploadDataProvider length set"); - } else { - NSNumber *filesizeNum; - NSError *valueError; - if ([_uploadFileURL getResourceValue:&filesizeNum - forKey:NSURLFileSizeKey - error:&valueError]) { - _uploadFileLength = filesizeNum.longLongValue; - } else { - GTMSESSION_ASSERT_DEBUG(NO, @"Cannot get file size: %@\n %@", - valueError, _uploadFileURL.path); - _uploadFileLength = 0; - } - } - } - result = _uploadFileLength; - } - } // @synchronized(self) - return result; -} - -// Make a subdata of the upload data. -- (void)generateChunkSubdataWithOffset:(int64_t)offset - length:(int64_t)length - response:(GTMSessionUploadFetcherDataProviderResponse)response { - GTMSessionUploadFetcherDataProvider uploadDataProvider = self.uploadDataProvider; - if (uploadDataProvider) { - uploadDataProvider(offset, length, response); - return; - } - - NSData *uploadData = self.uploadData; - if (uploadData) { - // NSData provided. - NSData *resultData; - if (offset == 0 && length == (int64_t)uploadData.length) { - resultData = uploadData; - } else { - int64_t dataLength = (int64_t)uploadData.length; - // Ensure our range is valid. b/18007814 - if (offset + length > dataLength) { - NSString *errorMessage = [NSString stringWithFormat: - @"Range invalid for upload data. offset: %lld\tlength: %lld\tdataLength: %lld", - offset, length, dataLength]; - GTMSESSION_ASSERT_DEBUG(NO, @"%@", errorMessage); - response(nil, - kGTMSessionUploadFetcherUnknownFileSize, - [self uploadChunkUnavailableErrorWithDescription:errorMessage]); - return; - } - NSRange range = NSMakeRange((NSUInteger)offset, (NSUInteger)length); - - @try { - resultData = [uploadData subdataWithRange:range]; - } - @catch (NSException *exception) { - NSString *errorMessage = exception.description; - GTMSESSION_ASSERT_DEBUG(NO, @"%@", errorMessage); - response(nil, - kGTMSessionUploadFetcherUnknownFileSize, - [self uploadChunkUnavailableErrorWithDescription:errorMessage]); - return; - } - } - response(resultData, kGTMSessionUploadFetcherUnknownFileSize, nil); - return; - } - NSURL *uploadFileURL = self.uploadFileURL; - if (uploadFileURL) { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - [self generateChunkSubdataFromFileURL:uploadFileURL - offset:offset - length:length - response:response]; - }); - return; - } - GTMSESSION_ASSERT_DEBUG(_uploadFileHandle, @"Unexpectedly missing upload data package"); - NSFileHandle *uploadFileHandle = self.uploadFileHandle; - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - [self generateChunkSubdataFromFileHandle:uploadFileHandle - offset:offset - length:length - response:response]; - }); -} - -- (void)generateChunkSubdataFromFileHandle:(NSFileHandle *)fileHandle - offset:(int64_t)offset - length:(int64_t)length - response:(GTMSessionUploadFetcherDataProviderResponse)response { - NSData *resultData; - NSError *error; - @try { - [fileHandle seekToFileOffset:(unsigned long long)offset]; - resultData = [fileHandle readDataOfLength:(NSUInteger)length]; - } - @catch (NSException *exception) { - GTMSESSION_ASSERT_DEBUG(NO, @"uploadFileHandle failed to read, %@", exception); - error = [self uploadChunkUnavailableErrorWithDescription:exception.description]; - } - // The response always re-dispatches to the main thread, so we skip doing that here. - response(resultData, kGTMSessionUploadFetcherUnknownFileSize, error); -} - -- (void)generateChunkSubdataFromFileURL:(NSURL *)fileURL - offset:(int64_t)offset - length:(int64_t)length - response:(GTMSessionUploadFetcherDataProviderResponse)response { - GTMSessionCheckNotSynchronized(self); - - NSData *resultData; - NSError *error; - int64_t fullUploadLength = [self fullUploadLength]; - NSData *mappedData = - [NSData dataWithContentsOfURL:fileURL - options:NSDataReadingMappedAlways + NSDataReadingUncached - error:&error]; - if (!mappedData) { - // We could not create an NSData by memory-mapping the file. -#if TARGET_IPHONE_SIMULATOR - // NSTemporaryDirectory() can differ in the simulator between app restarts, - // yet the contents for the new path remains unchanged, so try the latest temp path. - if ([error.domain isEqual:NSCocoaErrorDomain] && (error.code == NSFileReadNoSuchFileError)) { - NSString *filename = [fileURL lastPathComponent]; - NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:filename]; - NSURL *newFileURL = [NSURL fileURLWithPath:filePath]; - if (![newFileURL isEqual:fileURL]) { - [self generateChunkSubdataFromFileURL:newFileURL - offset:offset - length:length - response:response]; - return; - } - } -#endif - - // If the file is just too large to create an NSData for, or if for some other reason we can't - // map it, create an NSFileHandle instead to read a subset into an NSData. -#if DEBUG - NSNumber *fileSizeNum; - BOOL hasFileSize = [fileURL getResourceValue:&fileSizeNum forKey:NSURLFileSizeKey error:NULL]; - GTMSESSION_LOG_DEBUG(@"Note: uploadFileURL is falling back to creating upload chunks by reading" - @" an NSFileHandle since uploadFileURL failed to map the upload file," - @" file size %@, %@", - hasFileSize ? fileSizeNum : @"unknown", error); -#endif - - NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingFromURL:fileURL - error:&error]; - if (fileHandle != nil) { - [self generateChunkSubdataFromFileHandle:fileHandle - offset:offset - length:length - response:response]; - return; - } - GTMSESSION_ASSERT_DEBUG(NO, @"uploadFileURL failed to read, %@", error); - // Fall through with the error. - } else { - // Successfully created an NSData by memory-mapping the file. - if ((NSUInteger)(offset + length) > mappedData.length) { - NSString *errorMessage = [NSString stringWithFormat: - @"Range invalid for upload data. offset: %lld\tlength: %lld\tdataLength: %lld\texpected UploadLength: %lld", - offset, length, (long long)mappedData.length, fullUploadLength]; - GTMSESSION_ASSERT_DEBUG(NO, @"%@", errorMessage); - response(nil, - kGTMSessionUploadFetcherUnknownFileSize, - [self uploadChunkUnavailableErrorWithDescription:errorMessage]); - return; - } - if (offset > 0 || length < fullUploadLength) { - NSRange range = NSMakeRange((NSUInteger)offset, (NSUInteger)length); - resultData = [mappedData subdataWithRange:range]; - } else { - resultData = mappedData; - } - } - // The response always re-dispatches to the main thread, so we skip re-dispatching here. - response(resultData, kGTMSessionUploadFetcherUnknownFileSize, error); -} - -- (NSError *)uploadChunkUnavailableErrorWithDescription:(NSString *)description { - // The description in the userInfo is intended as a clue to programmers, not - // for client code to examine or rely on. - NSDictionary *userInfo = @{ @"description" : description }; - return [NSError errorWithDomain:kGTMSessionFetcherErrorDomain - code:GTMSessionFetcherErrorUploadChunkUnavailable - userInfo:userInfo]; -} - -- (NSError *)prematureFailureErrorWithUserInfo:(NSDictionary *)userInfo { - // An error for if we get an unexpected status from the upload server or - // otherwise cannot continue. This is an issue beyond the upload protocol; - // there's no way the client can do anything useful except give up. - NSError *error = [NSError errorWithDomain:kGTMSessionFetcherStatusDomain - code:501 // Not implemented - userInfo:userInfo]; - return error; -} - -+ (GTMSessionUploadFetcherStatus)uploadStatusFromResponseHeaders:(NSDictionary *)responseHeaders { - NSString *statusString = [responseHeaders objectForKey:kGTMSessionHeaderXGoogUploadStatus]; - if ([statusString isEqual:@"active"]) { - return kStatusActive; - } - if ([statusString isEqual:@"final"]) { - return kStatusFinal; - } - if ([statusString isEqual:@"cancelled"]) { - return kStatusCancelled; - } - return kStatusUnknown; -} - -#pragma mark Method overrides affecting the initial fetch only - -- (void)setCompletionHandler:(GTMSessionFetcherCompletionHandler)handler { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _delegateCompletionHandler = handler; - } -} - -- (void)setDelegateCallbackQueue:(dispatch_queue_t GTM_NULLABLE_TYPE)queue { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _delegateCallbackQueue = queue; - } -} - -- (dispatch_queue_t GTM_NULLABLE_TYPE)delegateCallbackQueue { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _delegateCallbackQueue; - } -} - -- (BOOL)isRestartedUpload { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _isRestartedUpload; - } -} - -- (GTMSessionFetcher * GTM_NULLABLE_TYPE)chunkFetcher { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _chunkFetcher; - } -} - -- (void)setChunkFetcher:(GTMSessionFetcher * GTM_NULLABLE_TYPE)fetcher { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _chunkFetcher = fetcher; - } -} - -- (void)setFetcherInFlight:(GTMSessionFetcher * GTM_NULLABLE_TYPE)fetcher { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _fetcherInFlight = fetcher; - } -} - -- (GTMSessionFetcher * GTM_NULLABLE_TYPE)fetcherInFlight { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _fetcherInFlight; - } -} - -- (void)setCancellationHandler:(GTMSessionUploadFetcherCancellationHandler GTM_NULLABLE_TYPE) - cancellationHandler { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _cancellationHandler = cancellationHandler; - } -} - -- (GTMSessionUploadFetcherCancellationHandler GTM_NULLABLE_TYPE)cancellationHandler { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _cancellationHandler; - } -} - -- (void)beginFetchForRetry { - GTMSessionCheckNotSynchronized(self); - - // Override the superclass to reset the initial body length and fetcher-in-flight, - // then call the superclass implementation. - [self setInitialBodyLength:[self bodyLength]]; - - GTMSESSION_ASSERT_DEBUG(self.fetcherInFlight == nil, @"unexpected fetcher in flight: %@", - self.fetcherInFlight); - self.fetcherInFlight = self; - [super beginFetchForRetry]; -} - -- (void)beginFetchWithCompletionHandler:(GTMSessionFetcherCompletionHandler)handler { - GTMSessionCheckNotSynchronized(self); - - [self setInitialBodyLength:[self bodyLength]]; - - // We'll hold onto the superclass's callback queue so we can invoke the handler - // even after the superclass has released the queue and its callback handler, as - // happens during auth failure. - [self setDelegateCallbackQueue:self.callbackQueue]; - self.completionHandler = handler; - - if ([self isRestartedUpload]) { - // When restarting an upload, we know the destination location for chunk fetches, - // but we need to query to find the initial offset. - if (![self isPaused]) { - [self sendQueryForUploadOffsetWithFetcherProperties:self.properties]; - } - return; - } - // We don't want to call into the client's completion block immediately - // after the finish of the initial connection (the delegate is called only - // when uploading finishes), so we substitute our own completion block to be - // called when the initial connection finishes - GTMSESSION_ASSERT_DEBUG(self.fetcherInFlight == nil, @"unexpected fetcher in flight: %@", - self.fetcherInFlight); - - self.fetcherInFlight = self; - [super beginFetchWithCompletionHandler:^(NSData *data, NSError *error) { - self.fetcherInFlight = nil; - // callback - - BOOL hasTestBlock = (self.testBlock != nil); - if (![self isRestartedUpload] && !hasTestBlock) { - if (error == nil) { - [self beginChunkFetches]; - } else { - if ([self retryTimer] == nil) { - [self invokeFinalCallbackWithData:nil - error:error - shouldInvalidateLocation:YES]; - } - } - } else { - // If there was no initial request, then this fetch is resuming some - // other uploadFetcher's initial request, and the superclass's connection - // is never used, so at this point we call the user's actual completion - // block. - if (!hasTestBlock) { - [self invokeFinalCallbackWithData:data - error:error - shouldInvalidateLocation:YES]; - } else { - // There was a test block, so we won't do chunk fetches, but we simulate obtaining - // the data to be uploaded from the upload data provider block or the file handle, - // and then call back. - [self generateChunkSubdataWithOffset:0 - length:[self fullUploadLength] - response:^(NSData *generateData, int64_t fullUploadLength, NSError *generateError) { - [self invokeFinalCallbackWithData:data - error:error - shouldInvalidateLocation:YES]; - }]; - } - } - }]; -} - -- (void)beginChunkFetches { - GTMSessionCheckNotSynchronized(self); - -#if DEBUG - // The initial response of the resumable upload protocol should have an - // empty body - // - // This assert typically happens because the upload create/edit link URL was - // not supplied with the request, and the server is thus expecting a non- - // resumable request/response. - if (self.downloadedData.length > 0) { - NSData *downloadedData = self.downloadedData; - NSString *str = [[NSString alloc] initWithData:downloadedData - encoding:NSUTF8StringEncoding]; - #pragma unused(str) - GTMSESSION_ASSERT_DEBUG(NO, @"unexpected response data (uploading to the wrong URL?)\n%@", str); - } -#endif - - // We need to get the upload URL from the location header to continue. - NSDictionary *responseHeaders = [self responseHeaders]; - - [self retrieveUploadChunkGranularityFromResponseHeaders:responseHeaders]; - - GTMSessionUploadFetcherStatus uploadStatus = - [[self class] uploadStatusFromResponseHeaders:responseHeaders]; - GTMSESSION_ASSERT_DEBUG(uploadStatus != kStatusUnknown, - @"beginChunkFetches has unexpected upload status for headers %@", responseHeaders); - - BOOL isPrematureStop = (uploadStatus == kStatusFinal) || (uploadStatus == kStatusCancelled); - - NSString *uploadLocationURLStr = [responseHeaders objectForKey:kGTMSessionHeaderXGoogUploadURL]; - BOOL hasUploadLocation = (uploadLocationURLStr.length > 0); - - if (isPrematureStop || !hasUploadLocation) { - GTMSESSION_ASSERT_DEBUG(NO, @"Premature failure: upload-status:\"%@\" location:%@", - [responseHeaders objectForKey:kGTMSessionHeaderXGoogUploadStatus], uploadLocationURLStr); - // We cannot continue since we do not know the location to use - // as our upload destination. - NSDictionary *userInfo = nil; - NSData *downloadedData = self.downloadedData; - if (downloadedData.length > 0) { - userInfo = @{ kGTMSessionFetcherStatusDataKey : downloadedData }; - } - NSError *failureError = [self prematureFailureErrorWithUserInfo:userInfo]; - [self invokeFinalCallbackWithData:nil - error:failureError - shouldInvalidateLocation:YES]; - return; - } - - self.uploadLocationURL = [NSURL URLWithString:uploadLocationURLStr]; - - NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - [nc postNotificationName:kGTMSessionFetcherUploadLocationObtainedNotification - object:self]; - - // we've now sent all of the initial post body data, so we need to include - // its size in future progress indicator callbacks - [self setInitialBodySent:[self initialBodyLength]]; - - // just in case the user paused us during the initial fetch... - if (![self isPaused]) { - [self uploadNextChunkWithOffset:0]; - } -} - -- (void)URLSession:(NSURLSession *)session - task:(NSURLSessionTask *)task - didSendBodyData:(int64_t)bytesSent - totalBytesSent:(int64_t)totalBytesSent - totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend { - // Overrides the superclass. - [self invokeDelegateWithDidSendBytes:bytesSent - totalBytesSent:totalBytesSent - totalBytesExpectedToSend:totalBytesExpectedToSend + [self fullUploadLength]]; -} - -- (BOOL)shouldReleaseCallbacksUponCompletion { - // Overrides the superclass. - - // We don't want the superclass to release the delegate and callback - // blocks once the initial fetch has finished - // - // This is invoked for only successful completion of the connection; - // an error always will invoke and release the callbacks - return NO; -} - -- (void)invokeFinalCallbackWithData:(NSData *)data - error:(NSError *)error - shouldInvalidateLocation:(BOOL)shouldInvalidateLocation { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (shouldInvalidateLocation) { - _uploadLocationURL = nil; - } - - dispatch_queue_t queue = _delegateCallbackQueue; - GTMSessionFetcherCompletionHandler handler = _delegateCompletionHandler; - if (queue && handler) { - [self invokeOnCallbackQueue:queue - afterUserStopped:NO - block:^{ - handler(data, error); - }]; - } - } // @synchronized(self) - - [self releaseUploadAndBaseCallbacks:!self.userStoppedFetching]; -} - -- (void)releaseUploadAndBaseCallbacks:(BOOL)shouldReleaseCancellation { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _delegateCallbackQueue = nil; - _delegateCompletionHandler = nil; - _uploadDataProvider = nil; - if (shouldReleaseCancellation) { - _cancellationHandler = nil; - } - } - - // Release the base class's callbacks, too, if needed. - [self releaseCallbacks]; -} - -- (void)stopFetchReleasingCallbacks:(BOOL)shouldReleaseCallbacks { - GTMSessionCheckNotSynchronized(self); - - // Clear _fetcherInFlight when stopped. Moved from stopFetching, since that's a public method, - // where this method does the work. Fixes issue clearing value when retryBlock included. - GTMSessionFetcher *fetcherInFlight = self.fetcherInFlight; - if (fetcherInFlight == self) { - self.fetcherInFlight = nil; - } - - [super stopFetchReleasingCallbacks:shouldReleaseCallbacks]; - - if (shouldReleaseCallbacks) { - [self releaseUploadAndBaseCallbacks:NO]; - } -} - -#pragma mark Chunk fetching methods - -- (void)uploadNextChunkWithOffset:(int64_t)offset { - // use the properties in each chunk fetcher - NSDictionary *props = [self properties]; - - [self uploadNextChunkWithOffset:offset - fetcherProperties:props]; -} - -- (void)sendQueryForUploadOffsetWithFetcherProperties:(NSDictionary *)props { - GTMSessionFetcher *queryFetcher = [self uploadFetcherWithProperties:props - isQueryFetch:YES]; - queryFetcher.bodyData = [NSData data]; - - NSString *originalComment = self.comment; - [queryFetcher setCommentWithFormat:@"%@ (query offset)", - originalComment ? originalComment : @"upload"]; - - [queryFetcher setRequestValue:@"query" forHTTPHeaderField:kGTMSessionHeaderXGoogUploadCommand]; - - self.fetcherInFlight = queryFetcher; - [queryFetcher beginFetchWithDelegate:self - didFinishSelector:@selector(queryFetcher:finishedWithData:error:)]; -} - -- (void)queryFetcher:(GTMSessionFetcher *)queryFetcher - finishedWithData:(NSData *)data - error:(NSError *)error { - self.fetcherInFlight = nil; - - NSDictionary *responseHeaders = [queryFetcher responseHeaders]; - NSString *sizeReceivedHeader; - - GTMSessionUploadFetcherStatus uploadStatus = - [[self class] uploadStatusFromResponseHeaders:responseHeaders]; - GTMSESSION_ASSERT_DEBUG(uploadStatus != kStatusUnknown || error != nil, - @"query fetcher completion has unexpected upload status for headers %@", responseHeaders); - - if (error == nil) { - sizeReceivedHeader = [responseHeaders objectForKey:kGTMSessionHeaderXGoogUploadSizeReceived]; - - if (uploadStatus == kStatusCancelled || - (uploadStatus == kStatusActive && sizeReceivedHeader == nil)) { - NSDictionary *userInfo = nil; - if (data.length > 0) { - userInfo = @{ kGTMSessionFetcherStatusDataKey : data }; - } - error = [self prematureFailureErrorWithUserInfo:userInfo]; - } - } - - if (error == nil) { - int64_t offset = [sizeReceivedHeader longLongValue]; - int64_t fullUploadLength = [self fullUploadLength]; - if (uploadStatus == kStatusFinal || - (offset >= fullUploadLength && - fullUploadLength != kGTMSessionUploadFetcherUnknownFileSize)) { - // Handle we're done - [self chunkFetcher:queryFetcher finishedWithData:data error:nil]; - } else { - [self retrieveUploadChunkGranularityFromResponseHeaders:responseHeaders]; - [self uploadNextChunkWithOffset:offset]; - } - } else { - // Handle query error - [self chunkFetcher:queryFetcher finishedWithData:data error:error]; - } -} - -- (void)sendCancelUploadWithFetcherProperties:(NSDictionary *)props { - @synchronized(self) { - _isCancelInFlight = YES; - } - GTMSessionFetcher *cancelFetcher = [self uploadFetcherWithProperties:props - isQueryFetch:YES]; - cancelFetcher.bodyData = [NSData data]; - - NSString *originalComment = self.comment; - [cancelFetcher setCommentWithFormat:@"%@ (cancel)", - originalComment ? originalComment : @"upload"]; - - [cancelFetcher setRequestValue:@"cancel" forHTTPHeaderField:kGTMSessionHeaderXGoogUploadCommand]; - - self.fetcherInFlight = cancelFetcher; - [cancelFetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error) { - self.fetcherInFlight = nil; - if (![self triggerCancellationHandlerForFetch:cancelFetcher data:data error:error]) { - if (error) { - GTMSESSION_LOG_DEBUG(@"cancelFetcher %@", error); - } - } - @synchronized(self) { - self->_isCancelInFlight = NO; - } - }]; -} - -- (void)uploadNextChunkWithOffset:(int64_t)offset - fetcherProperties:(NSDictionary *)props { - GTMSessionCheckNotSynchronized(self); - - // Example chunk headers: - // X-Goog-Upload-Command: upload, finalize - // X-Goog-Upload-Offset: 0 - // Content-Length: 2000000 - // Content-Type: image/jpeg - // - // {bytes 0-1999999} - - // The chunk upload URL requires no authentication header. - GTMSessionFetcher *chunkFetcher = [self uploadFetcherWithProperties:props - isQueryFetch:NO]; - [self attachSendProgressBlockToChunkFetcher:chunkFetcher]; - int64_t chunkSize = [self updateChunkFetcher:chunkFetcher - forChunkAtOffset:offset]; - BOOL isUploadingFileURL = (self.uploadFileURL != nil); - int64_t fullUploadLength = [self fullUploadLength]; - - // The chunk size may have changed, so determine again if we're uploading the full file. - BOOL isUploadingFullFile = (offset == 0 && - fullUploadLength != kGTMSessionUploadFetcherUnknownFileSize && - chunkSize >= fullUploadLength); - if (isUploadingFullFile && isUploadingFileURL) { - // The data is the full upload file URL. - chunkFetcher.bodyFileURL = self.uploadFileURL; - [self beginChunkFetcher:chunkFetcher - offset:offset]; - } else { - // Make an NSData for the subset for this upload chunk. - self.subdataGenerating = YES; - [self generateChunkSubdataWithOffset:offset - length:chunkSize - response:^(NSData *chunkData, int64_t uploadFileLength, NSError *chunkError) { - // The subdata methods may leave us on a background thread. - dispatch_async(dispatch_get_main_queue(), ^{ - self.subdataGenerating = NO; - - // dont allow the updating of fileLength for uploads not using a data provider as they - // should know the file length before the upload starts. - if (self->_uploadDataProvider != nil && uploadFileLength > 0) { - [self setUploadFileLength:uploadFileLength]; - // Update the command and content-length headers if this is the last chunk to be sent. - if (offset + chunkSize >= uploadFileLength) { - int64_t updatedChunkSize = [self updateChunkFetcher:chunkFetcher - forChunkAtOffset:offset]; - if (updatedChunkSize == 0) { - // Calling beginChunkFetcher early when there is no more data to send allows us to - // properly handle nil chunkData below without having to account for the case where - // we are just finalizing the file. - chunkFetcher.bodyData = [[NSData alloc] init]; - [self beginChunkFetcher:chunkFetcher - offset:offset]; - return; - } - } - } - - if (chunkData == nil) { - NSError *responseError = chunkError; - if (!responseError) { - responseError = [self uploadChunkUnavailableErrorWithDescription:@"chunkData is nil"]; - } - [self invokeFinalCallbackWithData:nil - error:responseError - shouldInvalidateLocation:YES]; - return; - } - - BOOL didWriteFile = NO; - if (isUploadingFileURL) { - // Make a temporary file with the data subset. - NSString *tempName = - [NSString stringWithFormat:@"GTMUpload_temp_%@", [[NSUUID UUID] UUIDString]]; - NSString *tempPath = [NSTemporaryDirectory() stringByAppendingPathComponent:tempName]; - NSError *writeError; - didWriteFile = [chunkData writeToFile:tempPath - options:NSDataWritingAtomic - error:&writeError]; - if (didWriteFile) { - chunkFetcher.bodyFileURL = [NSURL fileURLWithPath:tempPath]; - } else { - GTMSESSION_LOG_DEBUG(@"writeToFile failed: %@\n%@", writeError, tempPath); - } - } - if (!didWriteFile) { - chunkFetcher.bodyData = [chunkData copy]; - } - [self beginChunkFetcher:chunkFetcher - offset:offset]; - }); - }]; - } -} - -- (void)beginChunkFetcher:(GTMSessionFetcher *)chunkFetcher - offset:(int64_t)offset { - - // Track the current offset for progress reporting - self.currentOffset = offset; - - // Hang on to the fetcher in case we need to cancel it. We set these before beginning the - // chunk fetch so the observers notified of chunk fetches can inspect the upload fetcher to - // match to the chunk. - self.chunkFetcher = chunkFetcher; - self.fetcherInFlight = chunkFetcher; - - // Update the last chunk request, including any request headers. - self.lastChunkRequest = chunkFetcher.request; - - [chunkFetcher beginFetchWithDelegate:self - didFinishSelector:@selector(chunkFetcher:finishedWithData:error:)]; -} - -- (void)attachSendProgressBlockToChunkFetcher:(GTMSessionFetcher *)chunkFetcher { - chunkFetcher.sendProgressBlock = ^(int64_t bytesSent, int64_t totalBytesSent, - int64_t totalBytesExpectedToSend) { - // The total bytes expected include the initial body and the full chunked - // data, independent of how big this fetcher's chunk is. - int64_t initialBodySent = [self bodyLength]; // TODO(grobbins) use [self initialBodySent] - int64_t totalSent = initialBodySent + self.currentOffset + totalBytesSent; - int64_t totalExpected = initialBodySent + [self fullUploadLength]; - - [self invokeDelegateWithDidSendBytes:bytesSent - totalBytesSent:totalSent - totalBytesExpectedToSend:totalExpected]; - }; -} - -- (NSDictionary *)uploadSessionIdentifierMetadata { - NSMutableDictionary *metadata = [NSMutableDictionary dictionary]; - metadata[kGTMSessionIdentifierIsUploadChunkFetcherMetadataKey] = @YES; - GTMSESSION_ASSERT_DEBUG(self.uploadFileURL, - @"Invalid upload fetcher to create session identifier for metadata"); - metadata[kGTMSessionIdentifierUploadFileURLMetadataKey] = [self.uploadFileURL absoluteString]; - metadata[kGTMSessionIdentifierUploadFileLengthMetadataKey] = @([self fullUploadLength]); - - if (self.uploadLocationURL) { - metadata[kGTMSessionIdentifierUploadLocationURLMetadataKey] = - [self.uploadLocationURL absoluteString]; - } - if (self.uploadMIMEType) { - metadata[kGTMSessionIdentifierUploadMIMETypeMetadataKey] = self.uploadMIMEType; - } - metadata[kGTMSessionIdentifierUploadChunkSizeMetadataKey] = @(self.chunkSize); - metadata[kGTMSessionIdentifierUploadCurrentOffsetMetadataKey] = @(self.currentOffset); - return metadata; -} - -- (GTMSessionFetcher *)uploadFetcherWithProperties:(NSDictionary *)properties - isQueryFetch:(BOOL)isQueryFetch { - GTMSessionCheckNotSynchronized(self); - - // Common code to make a request for a query command or for a chunk upload. - NSURL *uploadLocationURL = self.uploadLocationURL; - NSMutableURLRequest *chunkRequest = [NSMutableURLRequest requestWithURL:uploadLocationURL]; - [chunkRequest setHTTPMethod:@"PUT"]; - - // copy the user-agent from the original connection - // n.b. that self.request is nil for upload fetchers created with an existing upload location - // URL. - NSURLRequest *origRequest = self.request; - NSString *userAgent = [origRequest valueForHTTPHeaderField:@"User-Agent"]; - if (userAgent.length > 0) { - [chunkRequest setValue:userAgent forHTTPHeaderField:@"User-Agent"]; - } - - [chunkRequest setValue:kGTMSessionXGoogUploadProtocolResumable - forHTTPHeaderField:kGTMSessionHeaderXGoogUploadProtocol]; - - // To avoid timeouts when debugging, copy the timeout of the initial fetcher. - NSTimeInterval origTimeout = [origRequest timeoutInterval]; - [chunkRequest setTimeoutInterval:origTimeout]; - - // - // Make a new chunk fetcher. - // - GTMSessionFetcher *chunkFetcher = [GTMSessionFetcher fetcherWithRequest:chunkRequest]; - chunkFetcher.callbackQueue = self.callbackQueue; - chunkFetcher.sessionUserInfo = self.sessionUserInfo; - chunkFetcher.configurationBlock = self.configurationBlock; - chunkFetcher.allowedInsecureSchemes = self.allowedInsecureSchemes; - chunkFetcher.allowLocalhostRequest = self.allowLocalhostRequest; - chunkFetcher.allowInvalidServerCertificates = self.allowInvalidServerCertificates; - chunkFetcher.useUploadTask = !isQueryFetch; - - if (self.uploadFileURL && !isQueryFetch && self.useBackgroundSession) { - [chunkFetcher createSessionIdentifierWithMetadata:[self uploadSessionIdentifierMetadata]]; - } - - // Give the chunk fetcher the same properties as the previous chunk fetcher - chunkFetcher.properties = [properties mutableCopy]; - [chunkFetcher setProperty:[NSValue valueWithNonretainedObject:self] - forKey:kGTMSessionUploadFetcherChunkParentKey]; - - // copy other fetcher settings to the new fetcher - chunkFetcher.retryEnabled = self.retryEnabled; - chunkFetcher.maxRetryInterval = self.maxRetryInterval; - - if ([self isRetryEnabled]) { - // We interpose our own retry method both so we can change the request to ask the server to - // tell us where to resume the chunk. - chunkFetcher.retryBlock = ^(BOOL suggestedWillRetry, NSError *chunkError, - GTMSessionFetcherRetryResponse response) { - void (^finish)(BOOL) = ^(BOOL shouldRetry){ - // We'll retry by sending an offset query. - if (shouldRetry) { - self.shouldInitiateOffsetQuery = !isQueryFetch; - - // We don't know what our actual offset is anymore, but the server will tell us. - self.currentOffset = 0; - } - // We don't actually want to retry this specific fetcher. - response(NO); - }; - - GTMSessionFetcherRetryBlock retryBlock = self.retryBlock; - if (retryBlock) { - // Ask the client, then call the finish block above. - retryBlock(suggestedWillRetry, chunkError, finish); - } else { - finish(suggestedWillRetry); - } - }; - } - - return chunkFetcher; -} - -- (void)chunkFetcher:(GTMSessionFetcher *)chunkFetcher - finishedWithData:(NSData *)data - error:(NSError *)error { - BOOL hasDestroyedOldChunkFetcher = NO; - self.fetcherInFlight = nil; - - NSDictionary *responseHeaders = [chunkFetcher responseHeaders]; - GTMSessionUploadFetcherStatus uploadStatus = - [[self class] uploadStatusFromResponseHeaders:responseHeaders]; - GTMSESSION_ASSERT_DEBUG(uploadStatus != kStatusUnknown - || error != nil - || self.wasCreatedFromBackgroundSession, - @"chunk fetcher completion has kStatusUnknown upload status for headers %@ fetcher %@", - responseHeaders, self); - BOOL isUploadStatusStopped = (uploadStatus == kStatusFinal || uploadStatus == kStatusCancelled); - - // Check if the fetcher was actually querying. If it failed, do not retry, - // as it would enter an infinite retry loop. - NSString *uploadCommand = - chunkFetcher.request.allHTTPHeaderFields[kGTMSessionHeaderXGoogUploadCommand]; - BOOL isQueryFetch = [uploadCommand isEqual:@"query"]; - - // TODO - // Maybe here we can check to see if the request had x goog content length set. (the file length one). - int64_t previousContentLength = - [[chunkFetcher.request valueForHTTPHeaderField:@"Content-Length"] longLongValue]; - // The Content-Length header may not be present if the chunk fetcher was recreated from - // a background session. - BOOL hasKnownChunkSize = (previousContentLength > 0); - BOOL needsQuery = (!hasKnownChunkSize && !isUploadStatusStopped); - - if (error || (needsQuery && !isQueryFetch)) { - NSInteger status = error.code; - - // Status 4xx indicates a bad offset in the Google upload protocol. However, do not retry status - // 404 per spec, nor if the upload size appears to have been zero (since the server will just - // keep asking us to retry.) - if (self.shouldInitiateOffsetQuery || - (needsQuery && !isQueryFetch) || - ([error.domain isEqual:kGTMSessionFetcherStatusDomain] && - status >= 400 && status <= 499 && - status != 404 && - uploadStatus == kStatusActive && - previousContentLength > 0)) { - self.shouldInitiateOffsetQuery = NO; - [self destroyChunkFetcher]; - hasDestroyedOldChunkFetcher = YES; - [self sendQueryForUploadOffsetWithFetcherProperties:chunkFetcher.properties]; - } else { - // Some unexpected status has occurred; handle it as we would a regular - // object fetcher failure. - [self invokeFinalCallbackWithData:data - error:error - shouldInvalidateLocation:NO]; - } - } else { - // The chunk has uploaded successfully. - int64_t newOffset = self.currentOffset + previousContentLength; -#if DEBUG - // Verify that if we think all of the uploading data has been sent, the server responded with - // the "final" upload status. - BOOL hasUploadAllData = (newOffset == [self fullUploadLength]); - BOOL isFinalStatus = (uploadStatus == kStatusFinal); - #pragma unused(hasUploadAllData,isFinalStatus) - GTMSESSION_ASSERT_DEBUG(hasUploadAllData == isFinalStatus || !hasKnownChunkSize, - @"uploadStatus:%@ newOffset:%lld (%lld + %lld) fullUploadLength:%lld" - @" chunkFetcher:%@ requestHeaders:%@ responseHeaders:%@", - [responseHeaders objectForKey:kGTMSessionHeaderXGoogUploadStatus], - newOffset, self.currentOffset, previousContentLength, - [self fullUploadLength], - chunkFetcher, chunkFetcher.request.allHTTPHeaderFields, - responseHeaders); -#endif - if (isUploadStatusStopped || (_currentOffset > _uploadFileLength && _uploadFileLength > 0)) { - // This was the last chunk. - if (error == nil && uploadStatus == kStatusCancelled) { - // Report cancelled status as an error. - NSDictionary *userInfo = nil; - if (data.length > 0) { - userInfo = @{ kGTMSessionFetcherStatusDataKey : data }; - } - data = nil; - error = [self prematureFailureErrorWithUserInfo:userInfo]; - } else { - // The upload is in final status. - // - // Take the chunk fetcher's data as the superclass data. - self.downloadedData = data; - self.statusCode = chunkFetcher.statusCode; - } - - // we're done - [self invokeFinalCallbackWithData:data - error:error - shouldInvalidateLocation:YES]; - } else { - // Start the next chunk. - self.currentOffset = newOffset; - - // We want to destroy this chunk fetcher before creating the next one, but - // we want to pass on its properties - NSDictionary *props = [chunkFetcher properties]; - - // We no longer need to be able to cancel this chunkFetcher. Destroy it - // before we create a new chunk fetcher. - [self destroyChunkFetcher]; - hasDestroyedOldChunkFetcher = YES; - - [self uploadNextChunkWithOffset:newOffset - fetcherProperties:props]; - } - } - if (!hasDestroyedOldChunkFetcher) { - [self destroyChunkFetcher]; - } -} - -- (void)destroyChunkFetcher { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (_fetcherInFlight == _chunkFetcher) { - _fetcherInFlight = nil; - } - - [_chunkFetcher stopFetching]; - - NSURL *chunkFileURL = _chunkFetcher.bodyFileURL; - BOOL wasTemporaryUploadFile = ![chunkFileURL isEqual:_uploadFileURL]; - if (wasTemporaryUploadFile) { - NSError *error; - [[NSFileManager defaultManager] removeItemAtURL:chunkFileURL - error:&error]; - if (error) { - GTMSESSION_LOG_DEBUG(@"removingItemAtURL failed: %@\n%@", error, chunkFileURL); - } - } - - _recentChunkReponseHeaders = _chunkFetcher.responseHeaders; - - // To avoid retain cycles, remove all properties except the parent identifier. - _chunkFetcher.properties = - @{ kGTMSessionUploadFetcherChunkParentKey : [NSValue valueWithNonretainedObject:self] }; - - _chunkFetcher.retryBlock = nil; - _chunkFetcher.sendProgressBlock = nil; - _chunkFetcher = nil; - } // @synchronized(self) -} - -// This method calculates the proper values to pass to the client's send progress block. -// -// The actual total bytes sent include the initial body sent, plus the -// offset into the batched data prior to the current chunk fetcher - -- (void)invokeDelegateWithDidSendBytes:(int64_t)bytesSent - totalBytesSent:(int64_t)totalBytesSent - totalBytesExpectedToSend:(int64_t)totalBytesExpected { - GTMSessionCheckNotSynchronized(self); - - // Ensure the chunk fetcher survives the callback in case the user pauses the upload process. - __block GTMSessionFetcher *holdFetcher = self.chunkFetcher; - - [self invokeOnCallbackQueue:self.delegateCallbackQueue - afterUserStopped:NO - block:^{ - GTMSessionFetcherSendProgressBlock sendProgressBlock = self.sendProgressBlock; - if (sendProgressBlock) { - sendProgressBlock(bytesSent, totalBytesSent, totalBytesExpected); - } - holdFetcher = nil; - }]; -} - -- (void)retrieveUploadChunkGranularityFromResponseHeaders:(NSDictionary *)responseHeaders { - GTMSessionCheckNotSynchronized(self); - - // Standard granularity for Google uploads is 256K. - NSString *chunkGranularityHeader = - [responseHeaders objectForKey:kGTMSessionHeaderXGoogUploadChunkGranularity]; - self.uploadGranularity = chunkGranularityHeader.longLongValue; -} - -#pragma mark - - -- (BOOL)isPaused { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _isPaused; - } // @synchronized(self) -} - -- (void)pauseFetching { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _isPaused = YES; - } // @synchronized(self) - - // Pausing just means stopping the current chunk from uploading; - // when we resume, we will send a query request to the server to - // figure out what bytes to resume sending. - // - // We won't try to cancel the initial data upload, but rather will check - // for being paused in beginChunkFetches. - [self destroyChunkFetcher]; -} - -- (void)resumeFetching { - BOOL wasPaused; - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - wasPaused = _isPaused; - _isPaused = NO; - } // @synchronized(self) - - if (wasPaused) { - [self sendQueryForUploadOffsetWithFetcherProperties:self.properties]; - } -} - -- (void)stopFetching { - // Overrides the superclass - [self destroyChunkFetcher]; - - // If we think the server is waiting for more data, then tell it there won't be more. - if (self.uploadLocationURL) { - [self sendCancelUploadWithFetcherProperties:[self properties]]; - self.uploadLocationURL = nil; - } else { - [self invokeOnCallbackQueue:self.callbackQueue - afterUserStopped:YES - block:^{ - // Repeated calls to stopFetching may cause this path to be reached despite having sent a real - // cancel request, check here to ensure that the cancellation handler invocation which fires - // will definitely be for the real request sent previously. - @synchronized(self) { - if (self->_isCancelInFlight) { - return; - } - } - [self triggerCancellationHandlerForFetch:nil data:nil error:nil]; - }]; - } - - [super stopFetching]; -} - -// Fires the cancellation handler, returning whether there was a handler to be fired. -- (BOOL)triggerCancellationHandlerForFetch:(GTMSessionFetcher *)fetcher - data:(NSData *)data - error:(NSError *)error { - GTMSessionUploadFetcherCancellationHandler handler = self.cancellationHandler; - if (handler) { - handler(fetcher, data, error); - self.cancellationHandler = nil; - return YES; - } - return NO; -} - -#pragma mark - - -- (int64_t)updateChunkFetcher:(GTMSessionFetcher *)chunkFetcher - forChunkAtOffset:(int64_t)offset { - BOOL isUploadingFileURL = (self.uploadFileURL != nil); - - // Upload another chunk, meeting server-required granularity. - int64_t chunkSize = self.chunkSize; - - int64_t fullUploadLength = [self fullUploadLength]; - BOOL isFileLengthKnown = fullUploadLength >= 0; - - BOOL isUploadingFullFile = (offset == 0 && isFileLengthKnown && chunkSize >= fullUploadLength); - if (!isUploadingFileURL || !isUploadingFullFile) { - // We're not uploading the entire file and given the file URL. Since we'll be - // allocating a subdata block for a chunk, we need to bound it to something that - // won't blow the process's memory. - if (chunkSize > kGTMSessionUploadFetcherMaximumDemandBufferSize) { - chunkSize = kGTMSessionUploadFetcherMaximumDemandBufferSize; - } - } - - int64_t granularity = self.uploadGranularity; - if (granularity > 0) { - if (chunkSize < granularity) { - chunkSize = granularity; - } else { - chunkSize = chunkSize - (chunkSize % granularity); - } - } - - GTMSESSION_ASSERT_DEBUG(offset < fullUploadLength || fullUploadLength == 0, - @"offset %lld exceeds data length %lld", offset, fullUploadLength); - - if (granularity > 0) { - offset = offset - (offset % granularity); - } - - // If the chunk size is bigger than the remaining data, or else - // it's close enough in size to the remaining data that we'd rather - // avoid having a whole extra http fetch for the leftover bit, then make - // this chunk size exactly match the remaining data size - NSString *command; - int64_t thisChunkSize = chunkSize; - - BOOL isChunkTooBig = (thisChunkSize >= (fullUploadLength - offset)); - BOOL isChunkAlmostBigEnough = (fullUploadLength - offset - 2500 < thisChunkSize); - BOOL isFinalChunk = (isChunkTooBig || isChunkAlmostBigEnough) && isFileLengthKnown; - if (isFinalChunk) { - thisChunkSize = fullUploadLength - offset; - if (thisChunkSize > 0) { - command = @"upload, finalize"; - } else { - command = @"finalize"; - } - } else { - command = @"upload"; - } - NSString *lengthStr = @(thisChunkSize).stringValue; - NSString *offsetStr = @(offset).stringValue; - - [chunkFetcher setRequestValue:command forHTTPHeaderField:kGTMSessionHeaderXGoogUploadCommand]; - [chunkFetcher setRequestValue:lengthStr forHTTPHeaderField:@"Content-Length"]; - [chunkFetcher setRequestValue:offsetStr forHTTPHeaderField:kGTMSessionHeaderXGoogUploadOffset]; - if (_uploadFileLength != kGTMSessionUploadFetcherUnknownFileSize) { - [chunkFetcher setRequestValue:@([self fullUploadLength]).stringValue - forHTTPHeaderField:kGTMSessionHeaderXGoogUploadContentLength]; - } - - // Append the range of bytes in this chunk to the fetcher comment. - NSString *baseComment = self.comment; - [chunkFetcher setCommentWithFormat:@"%@ (%lld-%lld)", - baseComment ? baseComment : @"upload", offset, MAX(0, offset + thisChunkSize - 1)]; - - return thisChunkSize; -} - -// Public properties. -@synthesize currentOffset = _currentOffset, - delegateCompletionHandler = _delegateCompletionHandler, - chunkFetcher = _chunkFetcher, - lastChunkRequest = _lastChunkRequest, - subdataGenerating = _subdataGenerating, - shouldInitiateOffsetQuery = _shouldInitiateOffsetQuery, - uploadGranularity = _uploadGranularity; - -// Internal properties. -@dynamic fetcherInFlight; -@dynamic activeFetcher; -@dynamic statusCode; -@dynamic delegateCallbackQueue; - -+ (void)removePointer:(void *)pointer fromPointerArray:(NSPointerArray *)pointerArray { - for (NSUInteger index = 0, count = pointerArray.count; index < count; ++index) { - void *pointerAtIndex = [pointerArray pointerAtIndex:index]; - if (pointerAtIndex == pointer) { - [pointerArray removePointerAtIndex:index]; - return; - } - } -} - -- (BOOL)useBackgroundSession { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _useBackgroundSessionOnChunkFetchers; - } // @synchronized(self -} - -- (void)setUseBackgroundSession:(BOOL)useBackgroundSession { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (_useBackgroundSessionOnChunkFetchers != useBackgroundSession) { - _useBackgroundSessionOnChunkFetchers = useBackgroundSession; - NSPointerArray *uploadFetcherPointerArrayForBackgroundSessions = - [[self class] uploadFetcherPointerArrayForBackgroundSessions]; - if (_useBackgroundSessionOnChunkFetchers) { - [uploadFetcherPointerArrayForBackgroundSessions addPointer:(__bridge void *)self]; - } else { - [[self class] removePointer:(__bridge void *)self - fromPointerArray:uploadFetcherPointerArrayForBackgroundSessions]; - } - } - } // @synchronized(self -} - -- (BOOL)canFetchWithBackgroundSession { - // The initial upload fetcher is always a foreground session; the - // useBackgroundSession property will apply only to chunk fetchers, - // not to queries. - return NO; -} - -- (NSDictionary *)responseHeaders { - GTMSessionCheckNotSynchronized(self); - // Overrides the superclass - - // If asked for the fetcher's response, use the most recent chunk fetcher's response, - // since the original request's response lacks useful information like the actual - // Content-Type. - NSDictionary *dict = self.chunkFetcher.responseHeaders; - if (dict) { - return dict; - } - - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - if (_recentChunkReponseHeaders) { - return _recentChunkReponseHeaders; - } - } // @synchronized(self - - // No chunk fetcher yet completed, so return whatever we have from the initial fetch. - return [super responseHeaders]; -} - -- (NSInteger)statusCodeUnsynchronized { - GTMSessionCheckSynchronized(self); - - if (_recentChunkStatusCode != -1) { - // Overrides the superclass to indicate status appropriate to the initial - // or latest chunk fetch - return _recentChunkStatusCode; - } else { - return [super statusCodeUnsynchronized]; - } -} - - -- (void)setStatusCode:(NSInteger)val { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _recentChunkStatusCode = val; - } -} - -- (int64_t)initialBodyLength { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _initialBodyLength; - } -} - -- (void)setInitialBodyLength:(int64_t)length { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _initialBodyLength = length; - } -} - -- (int64_t)initialBodySent { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _initialBodySent; - } -} - -- (void)setInitialBodySent:(int64_t)length { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _initialBodySent = length; - } -} - -- (NSURL *)uploadLocationURL { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - return _uploadLocationURL; - } -} - -- (void)setUploadLocationURL:(NSURL *)locationURL { - @synchronized(self) { - GTMSessionMonitorSynchronized(self); - - _uploadLocationURL = locationURL; - } -} - -- (GTMSessionFetcher *)activeFetcher { - GTMSessionFetcher *result = self.fetcherInFlight; - if (result) return result; - - return self; -} - -- (BOOL)isFetching { - // If there is an active chunk fetcher, then the upload fetcher is considered - // to still be fetching. - if (self.fetcherInFlight != nil) return YES; - - return [super isFetching]; -} - -- (BOOL)waitForCompletionWithTimeout:(NSTimeInterval)timeoutInSeconds { - NSDate *timeoutDate = [NSDate dateWithTimeIntervalSinceNow:timeoutInSeconds]; - - while (self.fetcherInFlight || self.subdataGenerating) { - if ([timeoutDate timeIntervalSinceNow] < 0) return NO; - - if (self.subdataGenerating) { - // Allow time for subdata generation. - NSDate *stopDate = [NSDate dateWithTimeIntervalSinceNow:0.001]; - [[NSRunLoop currentRunLoop] runUntilDate:stopDate]; - } else { - // Wait for any chunk or query fetchers that still have pending callbacks or - // notifications. - BOOL timedOut; - - if (self.fetcherInFlight == self) { - timedOut = ![super waitForCompletionWithTimeout:timeoutInSeconds]; - } else { - timedOut = ![self.fetcherInFlight waitForCompletionWithTimeout:timeoutInSeconds]; - } - if (timedOut) return NO; - } - } - return YES; -} - -@end - -@implementation GTMSessionFetcher (GTMSessionUploadFetcherMethods) - -- (GTMSessionUploadFetcher *)parentUploadFetcher { - NSValue *property = [self propertyForKey:kGTMSessionUploadFetcherChunkParentKey]; - if (!property) return nil; - - GTMSessionUploadFetcher *uploadFetcher = property.nonretainedObjectValue; - - GTMSESSION_ASSERT_DEBUG([uploadFetcher isKindOfClass:[GTMSessionUploadFetcher class]], - @"Unexpected parent upload fetcher class: %@", [uploadFetcher class]); - return uploadFetcher; -} - -@end diff --git a/Pods/GoogleAPIClientForREST/LICENSE b/Pods/GoogleAPIClientForREST/LICENSE @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Pods/GoogleAPIClientForREST/README.md b/Pods/GoogleAPIClientForREST/README.md @@ -1,48 +0,0 @@ -# Google APIs Client Library for Objective-C for REST # - -**Project site** <https://github.com/google/google-api-objectivec-client-for-rest><br> -**Discussion group** <http://groups.google.com/group/google-api-objectivec-client> - -[![Build Status](https://travis-ci.org/google/google-api-objectivec-client-for-rest.svg?branch=master)](https://travis-ci.org/google/google-api-objectivec-client-for-rest) - -Written by Google, this library is a flexible and efficient Objective-C -framework for accessing JSON APIs. - -This is the recommended library for accessing JSON-based Google APIs for iOS and -Mac OS X applications. The library is compatible with applications built for -iOS 7 and later, and Mac OS X 10.9 and later. - -**To get started** with Google APIs and the Objective-C client library, Read the -[wiki](https://github.com/google/google-api-objectivec-client-for-rest/wiki). -See -[BuildingTheLibrary](https://github.com/google/google-api-objectivec-client-for-rest/wiki/BuildingTheLibrary) -for how to add the library to a Mac or iPhone application project, it covers -directly adding sources or using CocoaPods. Study the -[example applications](https://github.com/google/google-api-objectivec-client-for-rest/tree/master/Examples). - -Generated interfaces for Google APIs are in the -[GeneratedServices folder](https://github.com/google/google-api-objectivec-client-for-rest/tree/master/Source/GeneratedServices). - -In addition to the pre generated classes included with the library, you can -generate your own source for other services that have a -[discovery document](https://developers.google.com/discovery/v1/reference/apis#resource-representations) -by using the -[ServiceGenerator](https://github.com/google/google-api-objectivec-client-for-rest/wiki/ServiceGenerator). - -**If you have a problem** or want a new feature to be included in the library, -please join the -[discussion group](http://groups.google.com/group/google-api-objectivec-client). -Be sure to include -[http logs](https://github.com/google/google-api-objectivec-client-for-rest/wiki#logging-http-server-traffic) -for requests and responses when posting questions. Bugs may also be submitted -on the [issues list](https://github.com/google/google-api-objectivec-client-for-rest/issues). - -**Externally-included projects**: The library includes code from the separate -projects [GTM Session Fetcher](https://github.com/google/gtm-session-fetcher), -[GTMAppAuth](https://github.com/google/GTMAppAuth). - -**Google Data APIs**: The much older library for XML-based APIs is -[still available](https://github.com/google/gdata-objectivec-client). - -Other useful classes for Mac and iOS developers are available in the -[Google Toolbox for Mac](https://github.com/google/google-toolbox-for-mac). diff --git a/Pods/GoogleAPIClientForREST/Source/GTLRDefines.h b/Pods/GoogleAPIClientForREST/Source/GTLRDefines.h @@ -1,109 +0,0 @@ -/* Copyright (c) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// -// GTLRDefines.h -// - -// Ensure Apple's conditionals we depend on are defined. -#import <TargetConditionals.h> -#import <AvailabilityMacros.h> - -// These can be redefined via a prefix if you are prefixing symbols to prefix -// the names used in strings. Something like: -// #define _HELPER(x) "MyPrefix" #x -// #define GTLR_CLASSNAME_STR(x) @_HELPER(x) -// #define GTLR_CLASSNAME_CSTR(x) _HELPER(x) -#ifndef GTLR_CLASSNAME_STR - #define _GTLR_CLASSNAME_HELPER(x) #x - #define GTLR_CLASSNAME_STR(x) @_GTLR_CLASSNAME_HELPER(x) - #define GTLR_CLASSNAME_CSTR(x) _GTLR_CLASSNAME_HELPER(x) -#endif - -// Provide a common definition for externing constants/functions -#if defined(__cplusplus) - #define GTLR_EXTERN extern "C" -#else - #define GTLR_EXTERN extern -#endif - -// -// GTLR_ASSERT defaults to bridging to NSAssert. This macro exists just in case -// it needs to be remapped. -// GTLR_DEBUG_ASSERT is similar, but compiles in only for debug builds -// - -#ifndef GTLR_ASSERT - // NSCAssert to avoid capturing self if used in a block. - #define GTLR_ASSERT(condition, ...) NSCAssert(condition, __VA_ARGS__) -#endif // GTLR_ASSERT - -#ifndef GTLR_DEBUG_ASSERT - #if DEBUG && !defined(NS_BLOCK_ASSERTIONS) - #define GTLR_DEBUG_ASSERT(condition, ...) GTLR_ASSERT(condition, __VA_ARGS__) - #elif DEBUG - // In DEBUG builds with assertions blocked, log to avoid unused variable warnings. - #define GTLR_DEBUG_ASSERT(condition, ...) if (!(condition)) { NSLog(__VA_ARGS__); } - #else - #define GTLR_DEBUG_ASSERT(condition, ...) do { } while (0) - #endif -#endif - -#ifndef GTLR_DEBUG_LOG - #if DEBUG - #define GTLR_DEBUG_LOG(...) NSLog(__VA_ARGS__) - #else - #define GTLR_DEBUG_LOG(...) do { } while (0) - #endif -#endif - -#ifndef GTLR_DEBUG_ASSERT_CURRENT_QUEUE - #define GTLR_ASSERT_CURRENT_QUEUE_DEBUG(targetQueue) \ - GTLR_DEBUG_ASSERT(0 == strcmp(GTLR_QUEUE_NAME(targetQueue), \ - GTLR_QUEUE_NAME(DISPATCH_CURRENT_QUEUE_LABEL)), \ - @"Current queue is %s (expected %s)", \ - GTLR_QUEUE_NAME(DISPATCH_CURRENT_QUEUE_LABEL), \ - GTLR_QUEUE_NAME(targetQueue)) - - #define GTLR_QUEUE_NAME(queue) \ - (strlen(dispatch_queue_get_label(queue)) > 0 ? dispatch_queue_get_label(queue) : "unnamed") -#endif // GTLR_ASSERT_CURRENT_QUEUE_DEBUG - -// Sanity check the min versions. - -#if (defined(TARGET_OS_TV) && TARGET_OS_TV) || (defined(TARGET_OS_WATCH) && TARGET_OS_WATCH) - // No min checks for these two. -#elif TARGET_OS_IPHONE - #if !defined(__IPHONE_9_0) || (__IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_9_0) - #error "This project expects to be compiled with the iOS 9.0 SDK (or later)." - #endif - #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0 - #error "The minimum supported iOS version is 7.0." - #endif -#elif TARGET_OS_MAC - #if !defined(MAC_OS_X_VERSION_10_10) || (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_10) - #error "This project expects to be compiled with the OS X 10.10 SDK (or later)." - #endif - #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9 - #error "The minimum supported OS X version is 10.9." - #endif -#else - #error "Unknown target platform." -#endif - -// Version marker used to validate the generated sources against the library -// version. The will be changed any time the library makes a change that means -// past sources need to be regenerated. -#define GTLR_RUNTIME_VERSION 3000 diff --git a/Pods/GoogleAPIClientForREST/Source/GeneratedServices/Sheets/GTLRSheets.h b/Pods/GoogleAPIClientForREST/Source/GeneratedServices/Sheets/GTLRSheets.h @@ -1,13 +0,0 @@ -// NOTE: This file was generated by the ServiceGenerator. - -// ---------------------------------------------------------------------------- -// API: -// Google Sheets API (sheets/v4) -// Description: -// Reads and writes Google Sheets. -// Documentation: -// https://developers.google.com/sheets/ - -#import "GTLRSheetsObjects.h" -#import "GTLRSheetsQuery.h" -#import "GTLRSheetsService.h" diff --git a/Pods/GoogleAPIClientForREST/Source/GeneratedServices/Sheets/GTLRSheetsObjects.h b/Pods/GoogleAPIClientForREST/Source/GeneratedServices/Sheets/GTLRSheetsObjects.h @@ -1,9245 +0,0 @@ -// NOTE: This file was generated by the ServiceGenerator. - -// ---------------------------------------------------------------------------- -// API: -// Google Sheets API (sheets/v4) -// Description: -// Reads and writes Google Sheets. -// Documentation: -// https://developers.google.com/sheets/ - -#if GTLR_BUILT_AS_FRAMEWORK - #import "GTLR/GTLRObject.h" -#else - #import "GTLRObject.h" -#endif - -#if GTLR_RUNTIME_VERSION != 3000 -#error This file was generated by a different version of ServiceGenerator which is incompatible with this GTLR library source. -#endif - -@class GTLRSheets_AddBandingRequest; -@class GTLRSheets_AddBandingResponse; -@class GTLRSheets_AddChartRequest; -@class GTLRSheets_AddChartResponse; -@class GTLRSheets_AddConditionalFormatRuleRequest; -@class GTLRSheets_AddDimensionGroupRequest; -@class GTLRSheets_AddDimensionGroupResponse; -@class GTLRSheets_AddFilterViewRequest; -@class GTLRSheets_AddFilterViewResponse; -@class GTLRSheets_AddNamedRangeRequest; -@class GTLRSheets_AddNamedRangeResponse; -@class GTLRSheets_AddProtectedRangeRequest; -@class GTLRSheets_AddProtectedRangeResponse; -@class GTLRSheets_AddSheetRequest; -@class GTLRSheets_AddSheetResponse; -@class GTLRSheets_AppendCellsRequest; -@class GTLRSheets_AppendDimensionRequest; -@class GTLRSheets_AutoFillRequest; -@class GTLRSheets_AutoResizeDimensionsRequest; -@class GTLRSheets_BandedRange; -@class GTLRSheets_BandingProperties; -@class GTLRSheets_BasicChartAxis; -@class GTLRSheets_BasicChartDomain; -@class GTLRSheets_BasicChartSeries; -@class GTLRSheets_BasicChartSpec; -@class GTLRSheets_BasicFilter; -@class GTLRSheets_BasicFilter_Criteria; -@class GTLRSheets_BooleanCondition; -@class GTLRSheets_BooleanRule; -@class GTLRSheets_Border; -@class GTLRSheets_Borders; -@class GTLRSheets_BubbleChartSpec; -@class GTLRSheets_CandlestickChartSpec; -@class GTLRSheets_CandlestickData; -@class GTLRSheets_CandlestickDomain; -@class GTLRSheets_CandlestickSeries; -@class GTLRSheets_CellData; -@class GTLRSheets_CellFormat; -@class GTLRSheets_ChartData; -@class GTLRSheets_ChartSourceRange; -@class GTLRSheets_ChartSpec; -@class GTLRSheets_ClearBasicFilterRequest; -@class GTLRSheets_Color; -@class GTLRSheets_ConditionalFormatRule; -@class GTLRSheets_ConditionValue; -@class GTLRSheets_CopyPasteRequest; -@class GTLRSheets_CreateDeveloperMetadataRequest; -@class GTLRSheets_CreateDeveloperMetadataResponse; -@class GTLRSheets_CutPasteRequest; -@class GTLRSheets_DataFilter; -@class GTLRSheets_DataFilterValueRange; -@class GTLRSheets_DataValidationRule; -@class GTLRSheets_DateTimeRule; -@class GTLRSheets_DeleteBandingRequest; -@class GTLRSheets_DeleteConditionalFormatRuleRequest; -@class GTLRSheets_DeleteConditionalFormatRuleResponse; -@class GTLRSheets_DeleteDeveloperMetadataRequest; -@class GTLRSheets_DeleteDeveloperMetadataResponse; -@class GTLRSheets_DeleteDimensionGroupRequest; -@class GTLRSheets_DeleteDimensionGroupResponse; -@class GTLRSheets_DeleteDimensionRequest; -@class GTLRSheets_DeleteEmbeddedObjectRequest; -@class GTLRSheets_DeleteFilterViewRequest; -@class GTLRSheets_DeleteNamedRangeRequest; -@class GTLRSheets_DeleteProtectedRangeRequest; -@class GTLRSheets_DeleteRangeRequest; -@class GTLRSheets_DeleteSheetRequest; -@class GTLRSheets_DeveloperMetadata; -@class GTLRSheets_DeveloperMetadataLocation; -@class GTLRSheets_DeveloperMetadataLookup; -@class GTLRSheets_DimensionGroup; -@class GTLRSheets_DimensionProperties; -@class GTLRSheets_DimensionRange; -@class GTLRSheets_DuplicateFilterViewRequest; -@class GTLRSheets_DuplicateFilterViewResponse; -@class GTLRSheets_DuplicateSheetRequest; -@class GTLRSheets_DuplicateSheetResponse; -@class GTLRSheets_Editors; -@class GTLRSheets_EmbeddedChart; -@class GTLRSheets_EmbeddedObjectPosition; -@class GTLRSheets_ErrorValue; -@class GTLRSheets_ExtendedValue; -@class GTLRSheets_FilterCriteria; -@class GTLRSheets_FilterView; -@class GTLRSheets_FilterView_Criteria; -@class GTLRSheets_FindReplaceRequest; -@class GTLRSheets_FindReplaceResponse; -@class GTLRSheets_GradientRule; -@class GTLRSheets_GridCoordinate; -@class GTLRSheets_GridData; -@class GTLRSheets_GridProperties; -@class GTLRSheets_GridRange; -@class GTLRSheets_HistogramChartSpec; -@class GTLRSheets_HistogramRule; -@class GTLRSheets_HistogramSeries; -@class GTLRSheets_InsertDimensionRequest; -@class GTLRSheets_InsertRangeRequest; -@class GTLRSheets_InterpolationPoint; -@class GTLRSheets_IterativeCalculationSettings; -@class GTLRSheets_LineStyle; -@class GTLRSheets_ManualRule; -@class GTLRSheets_ManualRuleGroup; -@class GTLRSheets_MatchedDeveloperMetadata; -@class GTLRSheets_MatchedValueRange; -@class GTLRSheets_MergeCellsRequest; -@class GTLRSheets_MoveDimensionRequest; -@class GTLRSheets_NamedRange; -@class GTLRSheets_NumberFormat; -@class GTLRSheets_OrgChartSpec; -@class GTLRSheets_OverlayPosition; -@class GTLRSheets_Padding; -@class GTLRSheets_PasteDataRequest; -@class GTLRSheets_PieChartSpec; -@class GTLRSheets_PivotFilterCriteria; -@class GTLRSheets_PivotGroup; -@class GTLRSheets_PivotGroupRule; -@class GTLRSheets_PivotGroupSortValueBucket; -@class GTLRSheets_PivotGroupValueMetadata; -@class GTLRSheets_PivotTable; -@class GTLRSheets_PivotTable_Criteria; -@class GTLRSheets_PivotValue; -@class GTLRSheets_ProtectedRange; -@class GTLRSheets_RandomizeRangeRequest; -@class GTLRSheets_RepeatCellRequest; -@class GTLRSheets_Request; -@class GTLRSheets_Response; -@class GTLRSheets_RowData; -@class GTLRSheets_SetBasicFilterRequest; -@class GTLRSheets_SetDataValidationRequest; -@class GTLRSheets_Sheet; -@class GTLRSheets_SheetProperties; -@class GTLRSheets_SortRangeRequest; -@class GTLRSheets_SortSpec; -@class GTLRSheets_SourceAndDestination; -@class GTLRSheets_Spreadsheet; -@class GTLRSheets_SpreadsheetProperties; -@class GTLRSheets_TextFormat; -@class GTLRSheets_TextFormatRun; -@class GTLRSheets_TextPosition; -@class GTLRSheets_TextRotation; -@class GTLRSheets_TextToColumnsRequest; -@class GTLRSheets_TreemapChartColorScale; -@class GTLRSheets_TreemapChartSpec; -@class GTLRSheets_UnmergeCellsRequest; -@class GTLRSheets_UpdateBandingRequest; -@class GTLRSheets_UpdateBordersRequest; -@class GTLRSheets_UpdateCellsRequest; -@class GTLRSheets_UpdateChartSpecRequest; -@class GTLRSheets_UpdateConditionalFormatRuleRequest; -@class GTLRSheets_UpdateConditionalFormatRuleResponse; -@class GTLRSheets_UpdateDeveloperMetadataRequest; -@class GTLRSheets_UpdateDeveloperMetadataResponse; -@class GTLRSheets_UpdateDimensionGroupRequest; -@class GTLRSheets_UpdateDimensionPropertiesRequest; -@class GTLRSheets_UpdateEmbeddedObjectPositionRequest; -@class GTLRSheets_UpdateEmbeddedObjectPositionResponse; -@class GTLRSheets_UpdateFilterViewRequest; -@class GTLRSheets_UpdateNamedRangeRequest; -@class GTLRSheets_UpdateProtectedRangeRequest; -@class GTLRSheets_UpdateSheetPropertiesRequest; -@class GTLRSheets_UpdateSpreadsheetPropertiesRequest; -@class GTLRSheets_UpdateValuesByDataFilterResponse; -@class GTLRSheets_UpdateValuesResponse; -@class GTLRSheets_ValueRange; -@class GTLRSheets_WaterfallChartColumnStyle; -@class GTLRSheets_WaterfallChartCustomSubtotal; -@class GTLRSheets_WaterfallChartDomain; -@class GTLRSheets_WaterfallChartSeries; -@class GTLRSheets_WaterfallChartSpec; - -// Generated comments include content from the discovery document; avoid them -// causing warnings since clang's checks are some what arbitrary. -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdocumentation" - -NS_ASSUME_NONNULL_BEGIN - -// ---------------------------------------------------------------------------- -// Constants - For some of the classes' properties below. - -// ---------------------------------------------------------------------------- -// GTLRSheets_AppendDimensionRequest.dimension - -/** - * Operates on the columns of a sheet. - * - * Value: "COLUMNS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_AppendDimensionRequest_Dimension_Columns; -/** - * The default value, do not use. - * - * Value: "DIMENSION_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_AppendDimensionRequest_Dimension_DimensionUnspecified; -/** - * Operates on the rows of a sheet. - * - * Value: "ROWS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_AppendDimensionRequest_Dimension_Rows; - -// ---------------------------------------------------------------------------- -// GTLRSheets_BasicChartAxis.position - -/** - * Default value, do not use. - * - * Value: "BASIC_CHART_AXIS_POSITION_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartAxis_Position_BasicChartAxisPositionUnspecified; -/** - * The axis rendered at the bottom of a chart. - * For most charts, this is the standard major axis. - * For bar charts, this is a minor axis. - * - * Value: "BOTTOM_AXIS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartAxis_Position_BottomAxis; -/** - * The axis rendered at the left of a chart. - * For most charts, this is a minor axis. - * For bar charts, this is the standard major axis. - * - * Value: "LEFT_AXIS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartAxis_Position_LeftAxis; -/** - * The axis rendered at the right of a chart. - * For most charts, this is a minor axis. - * For bar charts, this is an unusual major axis. - * - * Value: "RIGHT_AXIS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartAxis_Position_RightAxis; - -// ---------------------------------------------------------------------------- -// GTLRSheets_BasicChartSeries.targetAxis - -/** - * Default value, do not use. - * - * Value: "BASIC_CHART_AXIS_POSITION_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSeries_TargetAxis_BasicChartAxisPositionUnspecified; -/** - * The axis rendered at the bottom of a chart. - * For most charts, this is the standard major axis. - * For bar charts, this is a minor axis. - * - * Value: "BOTTOM_AXIS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSeries_TargetAxis_BottomAxis; -/** - * The axis rendered at the left of a chart. - * For most charts, this is a minor axis. - * For bar charts, this is the standard major axis. - * - * Value: "LEFT_AXIS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSeries_TargetAxis_LeftAxis; -/** - * The axis rendered at the right of a chart. - * For most charts, this is a minor axis. - * For bar charts, this is an unusual major axis. - * - * Value: "RIGHT_AXIS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSeries_TargetAxis_RightAxis; - -// ---------------------------------------------------------------------------- -// GTLRSheets_BasicChartSeries.type - -/** - * An <a href="/chart/interactive/docs/gallery/areachart">area chart</a>. - * - * Value: "AREA" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSeries_Type_Area; -/** - * A <a href="/chart/interactive/docs/gallery/barchart">bar chart</a>. - * - * Value: "BAR" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSeries_Type_Bar; -/** - * Default value, do not use. - * - * Value: "BASIC_CHART_TYPE_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSeries_Type_BasicChartTypeUnspecified; -/** - * A <a href="/chart/interactive/docs/gallery/columnchart">column chart</a>. - * - * Value: "COLUMN" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSeries_Type_Column; -/** - * A <a href="/chart/interactive/docs/gallery/combochart">combo chart</a>. - * - * Value: "COMBO" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSeries_Type_Combo; -/** - * A <a href="/chart/interactive/docs/gallery/linechart">line chart</a>. - * - * Value: "LINE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSeries_Type_Line; -/** - * A <a href="/chart/interactive/docs/gallery/scatterchart">scatter - * chart</a>. - * - * Value: "SCATTER" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSeries_Type_Scatter; -/** - * A <a href="/chart/interactive/docs/gallery/steppedareachart">stepped area - * chart</a>. - * - * Value: "STEPPED_AREA" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSeries_Type_SteppedArea; - -// ---------------------------------------------------------------------------- -// GTLRSheets_BasicChartSpec.chartType - -/** - * An <a href="/chart/interactive/docs/gallery/areachart">area chart</a>. - * - * Value: "AREA" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSpec_ChartType_Area; -/** - * A <a href="/chart/interactive/docs/gallery/barchart">bar chart</a>. - * - * Value: "BAR" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSpec_ChartType_Bar; -/** - * Default value, do not use. - * - * Value: "BASIC_CHART_TYPE_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSpec_ChartType_BasicChartTypeUnspecified; -/** - * A <a href="/chart/interactive/docs/gallery/columnchart">column chart</a>. - * - * Value: "COLUMN" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSpec_ChartType_Column; -/** - * A <a href="/chart/interactive/docs/gallery/combochart">combo chart</a>. - * - * Value: "COMBO" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSpec_ChartType_Combo; -/** - * A <a href="/chart/interactive/docs/gallery/linechart">line chart</a>. - * - * Value: "LINE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSpec_ChartType_Line; -/** - * A <a href="/chart/interactive/docs/gallery/scatterchart">scatter - * chart</a>. - * - * Value: "SCATTER" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSpec_ChartType_Scatter; -/** - * A <a href="/chart/interactive/docs/gallery/steppedareachart">stepped area - * chart</a>. - * - * Value: "STEPPED_AREA" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSpec_ChartType_SteppedArea; - -// ---------------------------------------------------------------------------- -// GTLRSheets_BasicChartSpec.compareMode - -/** - * Default value, do not use. - * - * Value: "BASIC_CHART_COMPARE_MODE_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSpec_CompareMode_BasicChartCompareModeUnspecified; -/** - * All data elements with the same category (e.g., domain value) are - * highlighted and shown in the tooltip. - * - * Value: "CATEGORY" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSpec_CompareMode_Category; -/** - * Only the focused data element is highlighted and shown in the tooltip. - * - * Value: "DATUM" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSpec_CompareMode_Datum; - -// ---------------------------------------------------------------------------- -// GTLRSheets_BasicChartSpec.legendPosition - -/** - * Default value, do not use. - * - * Value: "BASIC_CHART_LEGEND_POSITION_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSpec_LegendPosition_BasicChartLegendPositionUnspecified; -/** - * The legend is rendered on the bottom of the chart. - * - * Value: "BOTTOM_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSpec_LegendPosition_BottomLegend; -/** - * The legend is rendered on the left of the chart. - * - * Value: "LEFT_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSpec_LegendPosition_LeftLegend; -/** - * No legend is rendered. - * - * Value: "NO_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSpec_LegendPosition_NoLegend; -/** - * The legend is rendered on the right of the chart. - * - * Value: "RIGHT_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSpec_LegendPosition_RightLegend; -/** - * The legend is rendered on the top of the chart. - * - * Value: "TOP_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSpec_LegendPosition_TopLegend; - -// ---------------------------------------------------------------------------- -// GTLRSheets_BasicChartSpec.stackedType - -/** - * Default value, do not use. - * - * Value: "BASIC_CHART_STACKED_TYPE_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSpec_StackedType_BasicChartStackedTypeUnspecified; -/** - * Series are not stacked. - * - * Value: "NOT_STACKED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSpec_StackedType_NotStacked; -/** - * Vertical stacks are stretched to reach the top of the chart, with - * values laid out as percentages of each other. - * - * Value: "PERCENT_STACKED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSpec_StackedType_PercentStacked; -/** - * Series values are stacked, each value is rendered vertically beginning - * from the top of the value below it. - * - * Value: "STACKED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BasicChartSpec_StackedType_Stacked; - -// ---------------------------------------------------------------------------- -// GTLRSheets_BatchGetValuesByDataFilterRequest.dateTimeRenderOption - -/** - * Instructs date, time, datetime, and duration fields to be output - * as strings in their given number format (which is dependent - * on the spreadsheet locale). - * - * Value: "FORMATTED_STRING" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchGetValuesByDataFilterRequest_DateTimeRenderOption_FormattedString; -/** - * Instructs date, time, datetime, and duration fields to be output - * as doubles in "serial number" format, as popularized by Lotus 1-2-3. - * The whole number portion of the value (left of the decimal) counts - * the days since December 30th 1899. The fractional portion (right of - * the decimal) counts the time as a fraction of the day. For example, - * January 1st 1900 at noon would be 2.5, 2 because it's 2 days after - * December 30st 1899, and .5 because noon is half a day. February 1st - * 1900 at 3pm would be 33.625. This correctly treats the year 1900 as - * not a leap year. - * - * Value: "SERIAL_NUMBER" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchGetValuesByDataFilterRequest_DateTimeRenderOption_SerialNumber; - -// ---------------------------------------------------------------------------- -// GTLRSheets_BatchGetValuesByDataFilterRequest.majorDimension - -/** - * Operates on the columns of a sheet. - * - * Value: "COLUMNS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchGetValuesByDataFilterRequest_MajorDimension_Columns; -/** - * The default value, do not use. - * - * Value: "DIMENSION_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchGetValuesByDataFilterRequest_MajorDimension_DimensionUnspecified; -/** - * Operates on the rows of a sheet. - * - * Value: "ROWS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchGetValuesByDataFilterRequest_MajorDimension_Rows; - -// ---------------------------------------------------------------------------- -// GTLRSheets_BatchGetValuesByDataFilterRequest.valueRenderOption - -/** - * Values will be calculated & formatted in the reply according to the - * cell's formatting. Formatting is based on the spreadsheet's locale, - * not the requesting user's locale. - * For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, - * then `A2` would return `"$1.23"`. - * - * Value: "FORMATTED_VALUE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchGetValuesByDataFilterRequest_ValueRenderOption_FormattedValue; -/** - * Values will not be calculated. The reply will include the formulas. - * For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, - * then A2 would return `"=A1"`. - * - * Value: "FORMULA" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchGetValuesByDataFilterRequest_ValueRenderOption_Formula; -/** - * Values will be calculated, but not formatted in the reply. - * For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, - * then `A2` would return the number `1.23`. - * - * Value: "UNFORMATTED_VALUE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchGetValuesByDataFilterRequest_ValueRenderOption_UnformattedValue; - -// ---------------------------------------------------------------------------- -// GTLRSheets_BatchUpdateValuesByDataFilterRequest.responseDateTimeRenderOption - -/** - * Instructs date, time, datetime, and duration fields to be output - * as strings in their given number format (which is dependent - * on the spreadsheet locale). - * - * Value: "FORMATTED_STRING" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ResponseDateTimeRenderOption_FormattedString; -/** - * Instructs date, time, datetime, and duration fields to be output - * as doubles in "serial number" format, as popularized by Lotus 1-2-3. - * The whole number portion of the value (left of the decimal) counts - * the days since December 30th 1899. The fractional portion (right of - * the decimal) counts the time as a fraction of the day. For example, - * January 1st 1900 at noon would be 2.5, 2 because it's 2 days after - * December 30st 1899, and .5 because noon is half a day. February 1st - * 1900 at 3pm would be 33.625. This correctly treats the year 1900 as - * not a leap year. - * - * Value: "SERIAL_NUMBER" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ResponseDateTimeRenderOption_SerialNumber; - -// ---------------------------------------------------------------------------- -// GTLRSheets_BatchUpdateValuesByDataFilterRequest.responseValueRenderOption - -/** - * Values will be calculated & formatted in the reply according to the - * cell's formatting. Formatting is based on the spreadsheet's locale, - * not the requesting user's locale. - * For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, - * then `A2` would return `"$1.23"`. - * - * Value: "FORMATTED_VALUE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ResponseValueRenderOption_FormattedValue; -/** - * Values will not be calculated. The reply will include the formulas. - * For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, - * then A2 would return `"=A1"`. - * - * Value: "FORMULA" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ResponseValueRenderOption_Formula; -/** - * Values will be calculated, but not formatted in the reply. - * For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, - * then `A2` would return the number `1.23`. - * - * Value: "UNFORMATTED_VALUE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ResponseValueRenderOption_UnformattedValue; - -// ---------------------------------------------------------------------------- -// GTLRSheets_BatchUpdateValuesByDataFilterRequest.valueInputOption - -/** - * Default input value. This value must not be used. - * - * Value: "INPUT_VALUE_OPTION_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ValueInputOption_InputValueOptionUnspecified; -/** - * The values the user has entered will not be parsed and will be stored - * as-is. - * - * Value: "RAW" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ValueInputOption_Raw; -/** - * The values will be parsed as if the user typed them into the UI. - * Numbers will stay as numbers, but strings may be converted to numbers, - * dates, etc. following the same rules that are applied when entering - * text into a cell via the Google Sheets UI. - * - * Value: "USER_ENTERED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ValueInputOption_UserEntered; - -// ---------------------------------------------------------------------------- -// GTLRSheets_BatchUpdateValuesRequest.responseDateTimeRenderOption - -/** - * Instructs date, time, datetime, and duration fields to be output - * as strings in their given number format (which is dependent - * on the spreadsheet locale). - * - * Value: "FORMATTED_STRING" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchUpdateValuesRequest_ResponseDateTimeRenderOption_FormattedString; -/** - * Instructs date, time, datetime, and duration fields to be output - * as doubles in "serial number" format, as popularized by Lotus 1-2-3. - * The whole number portion of the value (left of the decimal) counts - * the days since December 30th 1899. The fractional portion (right of - * the decimal) counts the time as a fraction of the day. For example, - * January 1st 1900 at noon would be 2.5, 2 because it's 2 days after - * December 30st 1899, and .5 because noon is half a day. February 1st - * 1900 at 3pm would be 33.625. This correctly treats the year 1900 as - * not a leap year. - * - * Value: "SERIAL_NUMBER" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchUpdateValuesRequest_ResponseDateTimeRenderOption_SerialNumber; - -// ---------------------------------------------------------------------------- -// GTLRSheets_BatchUpdateValuesRequest.responseValueRenderOption - -/** - * Values will be calculated & formatted in the reply according to the - * cell's formatting. Formatting is based on the spreadsheet's locale, - * not the requesting user's locale. - * For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, - * then `A2` would return `"$1.23"`. - * - * Value: "FORMATTED_VALUE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchUpdateValuesRequest_ResponseValueRenderOption_FormattedValue; -/** - * Values will not be calculated. The reply will include the formulas. - * For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, - * then A2 would return `"=A1"`. - * - * Value: "FORMULA" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchUpdateValuesRequest_ResponseValueRenderOption_Formula; -/** - * Values will be calculated, but not formatted in the reply. - * For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, - * then `A2` would return the number `1.23`. - * - * Value: "UNFORMATTED_VALUE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchUpdateValuesRequest_ResponseValueRenderOption_UnformattedValue; - -// ---------------------------------------------------------------------------- -// GTLRSheets_BatchUpdateValuesRequest.valueInputOption - -/** - * Default input value. This value must not be used. - * - * Value: "INPUT_VALUE_OPTION_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchUpdateValuesRequest_ValueInputOption_InputValueOptionUnspecified; -/** - * The values the user has entered will not be parsed and will be stored - * as-is. - * - * Value: "RAW" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchUpdateValuesRequest_ValueInputOption_Raw; -/** - * The values will be parsed as if the user typed them into the UI. - * Numbers will stay as numbers, but strings may be converted to numbers, - * dates, etc. following the same rules that are applied when entering - * text into a cell via the Google Sheets UI. - * - * Value: "USER_ENTERED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BatchUpdateValuesRequest_ValueInputOption_UserEntered; - -// ---------------------------------------------------------------------------- -// GTLRSheets_BooleanCondition.type - -/** - * The cell's value must be empty. - * Supported by conditional formatting and filters. - * Requires no ConditionValues. - * - * Value: "BLANK" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_Blank; -/** - * The cell's value must be TRUE/FALSE or in the list of condition values. - * Supported by data validation. - * Renders as a cell checkbox. - * Supports zero, one or two ConditionValues. No - * values indicates the cell must be TRUE or FALSE, where TRUE renders as - * checked and FALSE renders as unchecked. One value indicates the cell - * will render as checked when it contains that value and unchecked when it - * is blank. Two values indicate that the cell will render as checked when - * it contains the first value and unchecked when it contains the second - * value. For example, ["Yes","No"] indicates that the cell will render a - * checked box when it has the value "Yes" and an unchecked box when it has - * the value "No". - * - * Value: "BOOLEAN" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_Boolean; -/** - * The default value, do not use. - * - * Value: "CONDITION_TYPE_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_ConditionTypeUnspecified; -/** - * The condition's formula must evaluate to true. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue. - * - * Value: "CUSTOM_FORMULA" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_CustomFormula; -/** - * The cell's value must be after the date of the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue - * that may be a relative date. - * - * Value: "DATE_AFTER" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_DateAfter; -/** - * The cell's value must be before the date of the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue - * that may be a relative date. - * - * Value: "DATE_BEFORE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_DateBefore; -/** - * The cell's value must be between the dates of the two condition values. - * Supported by data validation. - * Requires exactly two ConditionValues. - * - * Value: "DATE_BETWEEN" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_DateBetween; -/** - * The cell's value must be the same date as the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue. - * - * Value: "DATE_EQ" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_DateEq; -/** - * The cell's value must be a date. - * Supported by data validation. - * Requires no ConditionValues. - * - * Value: "DATE_IS_VALID" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_DateIsValid; -/** - * The cell's value must be outside the dates of the two condition values. - * Supported by data validation. - * Requires exactly two ConditionValues. - * - * Value: "DATE_NOT_BETWEEN" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_DateNotBetween; -/** - * The cell's value must be on or after the date of the condition's value. - * Supported by data validation. - * Requires a single ConditionValue - * that may be a relative date. - * - * Value: "DATE_ON_OR_AFTER" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_DateOnOrAfter; -/** - * The cell's value must be on or before the date of the condition's value. - * Supported by data validation. - * Requires a single ConditionValue - * that may be a relative date. - * - * Value: "DATE_ON_OR_BEFORE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_DateOnOrBefore; -/** - * The cell's value must not be empty. - * Supported by conditional formatting and filters. - * Requires no ConditionValues. - * - * Value: "NOT_BLANK" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_NotBlank; -/** - * The cell's value must be between the two condition values. - * Supported by data validation, conditional formatting and filters. - * Requires exactly two ConditionValues. - * - * Value: "NUMBER_BETWEEN" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_NumberBetween; -/** - * The cell's value must be equal to the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue. - * - * Value: "NUMBER_EQ" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_NumberEq; -/** - * The cell's value must be greater than the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue. - * - * Value: "NUMBER_GREATER" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_NumberGreater; -/** - * The cell's value must be greater than or equal to the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue. - * - * Value: "NUMBER_GREATER_THAN_EQ" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_NumberGreaterThanEq; -/** - * The cell's value must be less than the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue. - * - * Value: "NUMBER_LESS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_NumberLess; -/** - * The cell's value must be less than or equal to the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue. - * - * Value: "NUMBER_LESS_THAN_EQ" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_NumberLessThanEq; -/** - * The cell's value must not be between the two condition values. - * Supported by data validation, conditional formatting and filters. - * Requires exactly two ConditionValues. - * - * Value: "NUMBER_NOT_BETWEEN" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_NumberNotBetween; -/** - * The cell's value must be not equal to the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue. - * - * Value: "NUMBER_NOT_EQ" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_NumberNotEq; -/** - * The cell's value must be in the list of condition values. - * Supported by data validation. - * Supports any number of condition values, - * one per item in the list. - * Formulas are not supported in the values. - * - * Value: "ONE_OF_LIST" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_OneOfList; -/** - * The cell's value must be listed in the grid in condition value's range. - * Supported by data validation. - * Requires a single ConditionValue, - * and the value must be a valid range in A1 notation. - * - * Value: "ONE_OF_RANGE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_OneOfRange; -/** - * The cell's value must contain the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue. - * - * Value: "TEXT_CONTAINS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_TextContains; -/** - * The cell's value must end with the condition's value. - * Supported by conditional formatting and filters. - * Requires a single ConditionValue. - * - * Value: "TEXT_ENDS_WITH" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_TextEndsWith; -/** - * The cell's value must be exactly the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue. - * - * Value: "TEXT_EQ" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_TextEq; -/** - * The cell's value must be a valid email address. - * Supported by data validation. - * Requires no ConditionValues. - * - * Value: "TEXT_IS_EMAIL" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_TextIsEmail; -/** - * The cell's value must be a valid URL. - * Supported by data validation. - * Requires no ConditionValues. - * - * Value: "TEXT_IS_URL" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_TextIsUrl; -/** - * The cell's value must not contain the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue. - * - * Value: "TEXT_NOT_CONTAINS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_TextNotContains; -/** - * The cell's value must start with the condition's value. - * Supported by conditional formatting and filters. - * Requires a single ConditionValue. - * - * Value: "TEXT_STARTS_WITH" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BooleanCondition_Type_TextStartsWith; - -// ---------------------------------------------------------------------------- -// GTLRSheets_Border.style - -/** - * The border is dashed. - * - * Value: "DASHED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_Border_Style_Dashed; -/** - * The border is dotted. - * - * Value: "DOTTED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_Border_Style_Dotted; -/** - * The border is two solid lines. - * - * Value: "DOUBLE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_Border_Style_Double; -/** - * No border. - * Used only when updating a border in order to erase it. - * - * Value: "NONE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_Border_Style_None; -/** - * The border is a thin solid line. - * - * Value: "SOLID" - */ -GTLR_EXTERN NSString * const kGTLRSheets_Border_Style_Solid; -/** - * The border is a medium solid line. - * - * Value: "SOLID_MEDIUM" - */ -GTLR_EXTERN NSString * const kGTLRSheets_Border_Style_SolidMedium; -/** - * The border is a thick solid line. - * - * Value: "SOLID_THICK" - */ -GTLR_EXTERN NSString * const kGTLRSheets_Border_Style_SolidThick; -/** - * The style is not specified. Do not use this. - * - * Value: "STYLE_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_Border_Style_StyleUnspecified; - -// ---------------------------------------------------------------------------- -// GTLRSheets_BubbleChartSpec.legendPosition - -/** - * The legend is rendered on the bottom of the chart. - * - * Value: "BOTTOM_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BubbleChartSpec_LegendPosition_BottomLegend; -/** - * Default value, do not use. - * - * Value: "BUBBLE_CHART_LEGEND_POSITION_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BubbleChartSpec_LegendPosition_BubbleChartLegendPositionUnspecified; -/** - * The legend is rendered inside the chart area. - * - * Value: "INSIDE_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BubbleChartSpec_LegendPosition_InsideLegend; -/** - * The legend is rendered on the left of the chart. - * - * Value: "LEFT_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BubbleChartSpec_LegendPosition_LeftLegend; -/** - * No legend is rendered. - * - * Value: "NO_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BubbleChartSpec_LegendPosition_NoLegend; -/** - * The legend is rendered on the right of the chart. - * - * Value: "RIGHT_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BubbleChartSpec_LegendPosition_RightLegend; -/** - * The legend is rendered on the top of the chart. - * - * Value: "TOP_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_BubbleChartSpec_LegendPosition_TopLegend; - -// ---------------------------------------------------------------------------- -// GTLRSheets_CellFormat.horizontalAlignment - -/** - * The text is explicitly aligned to the center of the cell. - * - * Value: "CENTER" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CellFormat_HorizontalAlignment_Center; -/** - * The horizontal alignment is not specified. Do not use this. - * - * Value: "HORIZONTAL_ALIGN_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CellFormat_HorizontalAlignment_HorizontalAlignUnspecified; -/** - * The text is explicitly aligned to the left of the cell. - * - * Value: "LEFT" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CellFormat_HorizontalAlignment_Left; -/** - * The text is explicitly aligned to the right of the cell. - * - * Value: "RIGHT" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CellFormat_HorizontalAlignment_Right; - -// ---------------------------------------------------------------------------- -// GTLRSheets_CellFormat.hyperlinkDisplayType - -/** - * The default value: the hyperlink is rendered. Do not use this. - * - * Value: "HYPERLINK_DISPLAY_TYPE_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CellFormat_HyperlinkDisplayType_HyperlinkDisplayTypeUnspecified; -/** - * A hyperlink should be explicitly rendered. - * - * Value: "LINKED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CellFormat_HyperlinkDisplayType_Linked; -/** - * A hyperlink should not be rendered. - * - * Value: "PLAIN_TEXT" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CellFormat_HyperlinkDisplayType_PlainText; - -// ---------------------------------------------------------------------------- -// GTLRSheets_CellFormat.textDirection - -/** - * The text direction of left-to-right was set by the user. - * - * Value: "LEFT_TO_RIGHT" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CellFormat_TextDirection_LeftToRight; -/** - * The text direction of right-to-left was set by the user. - * - * Value: "RIGHT_TO_LEFT" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CellFormat_TextDirection_RightToLeft; -/** - * The text direction is not specified. Do not use this. - * - * Value: "TEXT_DIRECTION_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CellFormat_TextDirection_TextDirectionUnspecified; - -// ---------------------------------------------------------------------------- -// GTLRSheets_CellFormat.verticalAlignment - -/** - * The text is explicitly aligned to the bottom of the cell. - * - * Value: "BOTTOM" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CellFormat_VerticalAlignment_Bottom; -/** - * The text is explicitly aligned to the middle of the cell. - * - * Value: "MIDDLE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CellFormat_VerticalAlignment_Middle; -/** - * The text is explicitly aligned to the top of the cell. - * - * Value: "TOP" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CellFormat_VerticalAlignment_Top; -/** - * The vertical alignment is not specified. Do not use this. - * - * Value: "VERTICAL_ALIGN_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CellFormat_VerticalAlignment_VerticalAlignUnspecified; - -// ---------------------------------------------------------------------------- -// GTLRSheets_CellFormat.wrapStrategy - -/** - * Lines that are longer than the cell width will be clipped. - * The text will never wrap to the next line unless the user manually - * inserts a new line. - * Example: - * | First sentence. | - * | Manual newline t| <- Text is clipped - * | Next newline. | - * - * Value: "CLIP" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CellFormat_WrapStrategy_Clip; -/** - * This wrap strategy represents the old Google Sheets wrap strategy where - * words that are longer than a line are clipped rather than broken. This - * strategy is not supported on all platforms and is being phased out. - * Example: - * | Cell has a | - * | loooooooooo| <- Word is clipped. - * | word. | - * - * Value: "LEGACY_WRAP" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CellFormat_WrapStrategy_LegacyWrap; -/** - * Lines that are longer than the cell width will be written in the next - * cell over, so long as that cell is empty. If the next cell over is - * non-empty, this behaves the same as CLIP. The text will never wrap - * to the next line unless the user manually inserts a new line. - * Example: - * | First sentence. | - * | Manual newline that is very long. <- Text continues into next cell - * | Next newline. | - * - * Value: "OVERFLOW_CELL" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CellFormat_WrapStrategy_OverflowCell; -/** - * Words that are longer than a line are wrapped at the character level - * rather than clipped. - * Example: - * | Cell has a | - * | loooooooooo| <- Word is broken. - * | ong word. | - * - * Value: "WRAP" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CellFormat_WrapStrategy_Wrap; -/** - * The default value, do not use. - * - * Value: "WRAP_STRATEGY_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CellFormat_WrapStrategy_WrapStrategyUnspecified; - -// ---------------------------------------------------------------------------- -// GTLRSheets_ChartSpec.hiddenDimensionStrategy - -/** - * Default value, do not use. - * - * Value: "CHART_HIDDEN_DIMENSION_STRATEGY_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ChartSpec_HiddenDimensionStrategy_ChartHiddenDimensionStrategyUnspecified; -/** - * Charts will not skip any hidden rows or columns. - * - * Value: "SHOW_ALL" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ChartSpec_HiddenDimensionStrategy_ShowAll; -/** - * Charts will skip hidden columns only. - * - * Value: "SKIP_HIDDEN_COLUMNS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ChartSpec_HiddenDimensionStrategy_SkipHiddenColumns; -/** - * Charts will skip hidden rows only. - * - * Value: "SKIP_HIDDEN_ROWS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ChartSpec_HiddenDimensionStrategy_SkipHiddenRows; -/** - * Charts will skip hidden rows and columns. - * - * Value: "SKIP_HIDDEN_ROWS_AND_COLUMNS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ChartSpec_HiddenDimensionStrategy_SkipHiddenRowsAndColumns; - -// ---------------------------------------------------------------------------- -// GTLRSheets_ConditionValue.relativeDate - -/** - * The value is one month before today. - * - * Value: "PAST_MONTH" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ConditionValue_RelativeDate_PastMonth; -/** - * The value is one week before today. - * - * Value: "PAST_WEEK" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ConditionValue_RelativeDate_PastWeek; -/** - * The value is one year before today. - * - * Value: "PAST_YEAR" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ConditionValue_RelativeDate_PastYear; -/** - * Default value, do not use. - * - * Value: "RELATIVE_DATE_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ConditionValue_RelativeDate_RelativeDateUnspecified; -/** - * The value is today. - * - * Value: "TODAY" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ConditionValue_RelativeDate_Today; -/** - * The value is tomorrow. - * - * Value: "TOMORROW" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ConditionValue_RelativeDate_Tomorrow; -/** - * The value is yesterday. - * - * Value: "YESTERDAY" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ConditionValue_RelativeDate_Yesterday; - -// ---------------------------------------------------------------------------- -// GTLRSheets_CopyPasteRequest.pasteOrientation - -/** - * Paste normally. - * - * Value: "NORMAL" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CopyPasteRequest_PasteOrientation_Normal; -/** - * Paste transposed, where all rows become columns and vice versa. - * - * Value: "TRANSPOSE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CopyPasteRequest_PasteOrientation_Transpose; - -// ---------------------------------------------------------------------------- -// GTLRSheets_CopyPasteRequest.pasteType - -/** - * Paste the conditional formatting rules only. - * - * Value: "PASTE_CONDITIONAL_FORMATTING" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CopyPasteRequest_PasteType_PasteConditionalFormatting; -/** - * Paste the data validation only. - * - * Value: "PASTE_DATA_VALIDATION" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CopyPasteRequest_PasteType_PasteDataValidation; -/** - * Paste the format and data validation only. - * - * Value: "PASTE_FORMAT" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CopyPasteRequest_PasteType_PasteFormat; -/** - * Paste the formulas only. - * - * Value: "PASTE_FORMULA" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CopyPasteRequest_PasteType_PasteFormula; -/** - * Like PASTE_NORMAL but without borders. - * - * Value: "PASTE_NO_BORDERS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CopyPasteRequest_PasteType_PasteNoBorders; -/** - * Paste values, formulas, formats, and merges. - * - * Value: "PASTE_NORMAL" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CopyPasteRequest_PasteType_PasteNormal; -/** - * Paste the values ONLY without formats, formulas, or merges. - * - * Value: "PASTE_VALUES" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CopyPasteRequest_PasteType_PasteValues; - -// ---------------------------------------------------------------------------- -// GTLRSheets_CutPasteRequest.pasteType - -/** - * Paste the conditional formatting rules only. - * - * Value: "PASTE_CONDITIONAL_FORMATTING" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CutPasteRequest_PasteType_PasteConditionalFormatting; -/** - * Paste the data validation only. - * - * Value: "PASTE_DATA_VALIDATION" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CutPasteRequest_PasteType_PasteDataValidation; -/** - * Paste the format and data validation only. - * - * Value: "PASTE_FORMAT" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CutPasteRequest_PasteType_PasteFormat; -/** - * Paste the formulas only. - * - * Value: "PASTE_FORMULA" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CutPasteRequest_PasteType_PasteFormula; -/** - * Like PASTE_NORMAL but without borders. - * - * Value: "PASTE_NO_BORDERS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CutPasteRequest_PasteType_PasteNoBorders; -/** - * Paste values, formulas, formats, and merges. - * - * Value: "PASTE_NORMAL" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CutPasteRequest_PasteType_PasteNormal; -/** - * Paste the values ONLY without formats, formulas, or merges. - * - * Value: "PASTE_VALUES" - */ -GTLR_EXTERN NSString * const kGTLRSheets_CutPasteRequest_PasteType_PasteValues; - -// ---------------------------------------------------------------------------- -// GTLRSheets_DataFilterValueRange.majorDimension - -/** - * Operates on the columns of a sheet. - * - * Value: "COLUMNS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DataFilterValueRange_MajorDimension_Columns; -/** - * The default value, do not use. - * - * Value: "DIMENSION_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DataFilterValueRange_MajorDimension_DimensionUnspecified; -/** - * Operates on the rows of a sheet. - * - * Value: "ROWS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DataFilterValueRange_MajorDimension_Rows; - -// ---------------------------------------------------------------------------- -// GTLRSheets_DateTimeRule.type - -/** - * The default type, do not use. - * - * Value: "DATE_TIME_RULE_TYPE_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DateTimeRule_Type_DateTimeRuleTypeUnspecified; -/** - * Group dates by day and month, for example 22-Nov. The month is - * translated based on the spreadsheet locale. - * - * Value: "DAY_MONTH" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DateTimeRule_Type_DayMonth; -/** - * Group dates by day of month, from 1 to 31. - * - * Value: "DAY_OF_MONTH" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DateTimeRule_Type_DayOfMonth; -/** - * Group dates by day of week, for example Sunday. The days of the week will - * be translated based on the spreadsheet locale. - * - * Value: "DAY_OF_WEEK" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DateTimeRule_Type_DayOfWeek; -/** - * Group dates by day of year, from 1 to 366. Note that dates after Feb. 29 - * fall in different buckets in leap years than in non-leap years. - * - * Value: "DAY_OF_YEAR" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DateTimeRule_Type_DayOfYear; -/** - * Group dates by hour using a 24-hour system, from 0 to 23. - * - * Value: "HOUR" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DateTimeRule_Type_Hour; -/** - * Group dates by hour and minute using a 24-hour system, for example 19:45. - * - * Value: "HOUR_MINUTE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DateTimeRule_Type_HourMinute; -/** - * Group dates by hour and minute using a 12-hour system, for example 7:45 - * PM. The AM/PM designation is translated based on the spreadsheet - * locale. - * - * Value: "HOUR_MINUTE_AMPM" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DateTimeRule_Type_HourMinuteAmpm; -/** - * Group dates by minute, from 0 to 59. - * - * Value: "MINUTE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DateTimeRule_Type_Minute; -/** - * Group dates by month, for example Nov. The month is translated based - * on the spreadsheet locale. - * - * Value: "MONTH" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DateTimeRule_Type_Month; -/** - * Group dates by quarter, for example Q1 (which represents Jan-Mar). - * - * Value: "QUARTER" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DateTimeRule_Type_Quarter; -/** - * Group dates by second, from 0 to 59. - * - * Value: "SECOND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DateTimeRule_Type_Second; -/** - * Group dates by year, for example 2008. - * - * Value: "YEAR" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DateTimeRule_Type_Year; -/** - * Group dates by year and month, for example 2008-Nov. The month is - * translated based on the spreadsheet locale. - * - * Value: "YEAR_MONTH" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DateTimeRule_Type_YearMonth; -/** - * Group dates by year, month, and day, for example 2008-11-22. - * - * Value: "YEAR_MONTH_DAY" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DateTimeRule_Type_YearMonthDay; -/** - * Group dates by year and quarter, for example 2008 Q4. - * - * Value: "YEAR_QUARTER" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DateTimeRule_Type_YearQuarter; - -// ---------------------------------------------------------------------------- -// GTLRSheets_DeleteRangeRequest.shiftDimension - -/** - * Operates on the columns of a sheet. - * - * Value: "COLUMNS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DeleteRangeRequest_ShiftDimension_Columns; -/** - * The default value, do not use. - * - * Value: "DIMENSION_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DeleteRangeRequest_ShiftDimension_DimensionUnspecified; -/** - * Operates on the rows of a sheet. - * - * Value: "ROWS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DeleteRangeRequest_ShiftDimension_Rows; - -// ---------------------------------------------------------------------------- -// GTLRSheets_DeveloperMetadata.visibility - -/** - * Default value. - * - * Value: "DEVELOPER_METADATA_VISIBILITY_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DeveloperMetadata_Visibility_DeveloperMetadataVisibilityUnspecified; -/** - * Document-visible metadata is accessible from any developer project with - * access to the document. - * - * Value: "DOCUMENT" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DeveloperMetadata_Visibility_Document; -/** - * Project-visible metadata is only visible to and accessible by the developer - * project that created the metadata. - * - * Value: "PROJECT" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DeveloperMetadata_Visibility_Project; - -// ---------------------------------------------------------------------------- -// GTLRSheets_DeveloperMetadataLocation.locationType - -/** - * Developer metadata associated on an entire column dimension. - * - * Value: "COLUMN" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DeveloperMetadataLocation_LocationType_Column; -/** - * Default value. - * - * Value: "DEVELOPER_METADATA_LOCATION_TYPE_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DeveloperMetadataLocation_LocationType_DeveloperMetadataLocationTypeUnspecified; -/** - * Developer metadata associated on an entire row dimension. - * - * Value: "ROW" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DeveloperMetadataLocation_LocationType_Row; -/** - * Developer metadata associated on an entire sheet. - * - * Value: "SHEET" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DeveloperMetadataLocation_LocationType_Sheet; -/** - * Developer metadata associated on the entire spreadsheet. - * - * Value: "SPREADSHEET" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DeveloperMetadataLocation_LocationType_Spreadsheet; - -// ---------------------------------------------------------------------------- -// GTLRSheets_DeveloperMetadataLookup.locationMatchingStrategy - -/** - * Default value. This value must not be used. - * - * Value: "DEVELOPER_METADATA_LOCATION_MATCHING_STRATEGY_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DeveloperMetadataLookup_LocationMatchingStrategy_DeveloperMetadataLocationMatchingStrategyUnspecified; -/** - * Indicates that a specified location should be matched exactly. For - * example, if row three were specified as a location this matching strategy - * would only match developer metadata also associated on row three. Metadata - * associated on other locations would not be considered. - * - * Value: "EXACT_LOCATION" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DeveloperMetadataLookup_LocationMatchingStrategy_ExactLocation; -/** - * Indicates that a specified location should match that exact location as - * well as any intersecting locations. For example, if row three were - * specified as a location this matching strategy would match developer - * metadata associated on row three as well as metadata associated on - * locations that intersect row three. If, for instance, there was developer - * metadata associated on column B, this matching strategy would also match - * that location because column B intersects row three. - * - * Value: "INTERSECTING_LOCATION" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DeveloperMetadataLookup_LocationMatchingStrategy_IntersectingLocation; - -// ---------------------------------------------------------------------------- -// GTLRSheets_DeveloperMetadataLookup.locationType - -/** - * Developer metadata associated on an entire column dimension. - * - * Value: "COLUMN" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DeveloperMetadataLookup_LocationType_Column; -/** - * Default value. - * - * Value: "DEVELOPER_METADATA_LOCATION_TYPE_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DeveloperMetadataLookup_LocationType_DeveloperMetadataLocationTypeUnspecified; -/** - * Developer metadata associated on an entire row dimension. - * - * Value: "ROW" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DeveloperMetadataLookup_LocationType_Row; -/** - * Developer metadata associated on an entire sheet. - * - * Value: "SHEET" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DeveloperMetadataLookup_LocationType_Sheet; -/** - * Developer metadata associated on the entire spreadsheet. - * - * Value: "SPREADSHEET" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DeveloperMetadataLookup_LocationType_Spreadsheet; - -// ---------------------------------------------------------------------------- -// GTLRSheets_DeveloperMetadataLookup.visibility - -/** - * Default value. - * - * Value: "DEVELOPER_METADATA_VISIBILITY_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DeveloperMetadataLookup_Visibility_DeveloperMetadataVisibilityUnspecified; -/** - * Document-visible metadata is accessible from any developer project with - * access to the document. - * - * Value: "DOCUMENT" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DeveloperMetadataLookup_Visibility_Document; -/** - * Project-visible metadata is only visible to and accessible by the developer - * project that created the metadata. - * - * Value: "PROJECT" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DeveloperMetadataLookup_Visibility_Project; - -// ---------------------------------------------------------------------------- -// GTLRSheets_DimensionRange.dimension - -/** - * Operates on the columns of a sheet. - * - * Value: "COLUMNS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DimensionRange_Dimension_Columns; -/** - * The default value, do not use. - * - * Value: "DIMENSION_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DimensionRange_Dimension_DimensionUnspecified; -/** - * Operates on the rows of a sheet. - * - * Value: "ROWS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_DimensionRange_Dimension_Rows; - -// ---------------------------------------------------------------------------- -// GTLRSheets_ErrorValue.type - -/** - * Corresponds to the `#DIV/0` error. - * - * Value: "DIVIDE_BY_ZERO" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ErrorValue_Type_DivideByZero; -/** - * Corresponds to the `#ERROR!` error. - * - * Value: "ERROR" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ErrorValue_Type_Error; -/** - * The default error type, do not use this. - * - * Value: "ERROR_TYPE_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ErrorValue_Type_ErrorTypeUnspecified; -/** - * Corresponds to the `Loading...` state. - * - * Value: "LOADING" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ErrorValue_Type_Loading; -/** - * Corresponds to the `#N/A` error. - * - * Value: "N_A" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ErrorValue_Type_NA; -/** - * Corresponds to the `#NAME?` error. - * - * Value: "NAME" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ErrorValue_Type_Name; -/** - * Corresponds to the `#NULL!` error. - * - * Value: "NULL_VALUE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ErrorValue_Type_NullValue; -/** - * Corresponds to the `#NUM`! error. - * - * Value: "NUM" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ErrorValue_Type_Num; -/** - * Corresponds to the `#REF!` error. - * - * Value: "REF" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ErrorValue_Type_Ref; -/** - * Corresponds to the `#VALUE!` error. - * - * Value: "VALUE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ErrorValue_Type_Value; - -// ---------------------------------------------------------------------------- -// GTLRSheets_HistogramChartSpec.legendPosition - -/** - * The legend is rendered on the bottom of the chart. - * - * Value: "BOTTOM_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_HistogramChartSpec_LegendPosition_BottomLegend; -/** - * Default value, do not use. - * - * Value: "HISTOGRAM_CHART_LEGEND_POSITION_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_HistogramChartSpec_LegendPosition_HistogramChartLegendPositionUnspecified; -/** - * The legend is rendered inside the chart area. - * - * Value: "INSIDE_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_HistogramChartSpec_LegendPosition_InsideLegend; -/** - * The legend is rendered on the left of the chart. - * - * Value: "LEFT_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_HistogramChartSpec_LegendPosition_LeftLegend; -/** - * No legend is rendered. - * - * Value: "NO_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_HistogramChartSpec_LegendPosition_NoLegend; -/** - * The legend is rendered on the right of the chart. - * - * Value: "RIGHT_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_HistogramChartSpec_LegendPosition_RightLegend; -/** - * The legend is rendered on the top of the chart. - * - * Value: "TOP_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_HistogramChartSpec_LegendPosition_TopLegend; - -// ---------------------------------------------------------------------------- -// GTLRSheets_InsertRangeRequest.shiftDimension - -/** - * Operates on the columns of a sheet. - * - * Value: "COLUMNS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_InsertRangeRequest_ShiftDimension_Columns; -/** - * The default value, do not use. - * - * Value: "DIMENSION_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_InsertRangeRequest_ShiftDimension_DimensionUnspecified; -/** - * Operates on the rows of a sheet. - * - * Value: "ROWS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_InsertRangeRequest_ShiftDimension_Rows; - -// ---------------------------------------------------------------------------- -// GTLRSheets_InterpolationPoint.type - -/** - * The default value, do not use. - * - * Value: "INTERPOLATION_POINT_TYPE_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_InterpolationPoint_Type_InterpolationPointTypeUnspecified; -/** - * The interpolation point uses the maximum value in the - * cells over the range of the conditional format. - * - * Value: "MAX" - */ -GTLR_EXTERN NSString * const kGTLRSheets_InterpolationPoint_Type_Max; -/** - * The interpolation point uses the minimum value in the - * cells over the range of the conditional format. - * - * Value: "MIN" - */ -GTLR_EXTERN NSString * const kGTLRSheets_InterpolationPoint_Type_Min; -/** - * The interpolation point uses exactly the value in - * InterpolationPoint.value. - * - * Value: "NUMBER" - */ -GTLR_EXTERN NSString * const kGTLRSheets_InterpolationPoint_Type_Number; -/** - * The interpolation point is the given percentage over - * all the cells in the range of the conditional format. - * This is equivalent to NUMBER if the value was: - * `=(MAX(FLATTEN(range)) * (value / 100)) - * + (MIN(FLATTEN(range)) * (1 - (value / 100)))` - * (where errors in the range are ignored when flattening). - * - * Value: "PERCENT" - */ -GTLR_EXTERN NSString * const kGTLRSheets_InterpolationPoint_Type_Percent; -/** - * The interpolation point is the given percentile - * over all the cells in the range of the conditional format. - * This is equivalent to NUMBER if the value was: - * `=PERCENTILE(FLATTEN(range), value / 100)` - * (where errors in the range are ignored when flattening). - * - * Value: "PERCENTILE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_InterpolationPoint_Type_Percentile; - -// ---------------------------------------------------------------------------- -// GTLRSheets_LineStyle.type - -/** - * A custom dash for a line. Modifying the exact custom dash style is - * currently unsupported. - * - * Value: "CUSTOM" - */ -GTLR_EXTERN NSString * const kGTLRSheets_LineStyle_Type_Custom; -/** - * A dotted line. - * - * Value: "DOTTED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_LineStyle_Type_Dotted; -/** - * No dash type, which is equivalent to a non-visible line. - * - * Value: "INVISIBLE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_LineStyle_Type_Invisible; -/** - * Default value, do not use. - * - * Value: "LINE_DASH_TYPE_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_LineStyle_Type_LineDashTypeUnspecified; -/** - * A dashed line where the dashes have "long" length. - * - * Value: "LONG_DASHED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_LineStyle_Type_LongDashed; -/** - * A line that alternates between a "long" dash and a dot. - * - * Value: "LONG_DASHED_DOTTED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_LineStyle_Type_LongDashedDotted; -/** - * A dashed line where the dashes have "medium" length. - * - * Value: "MEDIUM_DASHED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_LineStyle_Type_MediumDashed; -/** - * A line that alternates between a "medium" dash and a dot. - * - * Value: "MEDIUM_DASHED_DOTTED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_LineStyle_Type_MediumDashedDotted; -/** - * A solid line. - * - * Value: "SOLID" - */ -GTLR_EXTERN NSString * const kGTLRSheets_LineStyle_Type_Solid; - -// ---------------------------------------------------------------------------- -// GTLRSheets_MergeCellsRequest.mergeType - -/** - * Create a single merge from the range - * - * Value: "MERGE_ALL" - */ -GTLR_EXTERN NSString * const kGTLRSheets_MergeCellsRequest_MergeType_MergeAll; -/** - * Create a merge for each column in the range - * - * Value: "MERGE_COLUMNS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_MergeCellsRequest_MergeType_MergeColumns; -/** - * Create a merge for each row in the range - * - * Value: "MERGE_ROWS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_MergeCellsRequest_MergeType_MergeRows; - -// ---------------------------------------------------------------------------- -// GTLRSheets_NumberFormat.type - -/** - * Currency formatting, e.g `$1,000.12` - * - * Value: "CURRENCY" - */ -GTLR_EXTERN NSString * const kGTLRSheets_NumberFormat_Type_Currency; -/** - * Date formatting, e.g `9/26/2008` - * - * Value: "DATE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_NumberFormat_Type_Date; -/** - * Date+Time formatting, e.g `9/26/08 15:59:00` - * - * Value: "DATE_TIME" - */ -GTLR_EXTERN NSString * const kGTLRSheets_NumberFormat_Type_DateTime; -/** - * Number formatting, e.g, `1,000.12` - * - * Value: "NUMBER" - */ -GTLR_EXTERN NSString * const kGTLRSheets_NumberFormat_Type_Number; -/** - * The number format is not specified - * and is based on the contents of the cell. - * Do not explicitly use this. - * - * Value: "NUMBER_FORMAT_TYPE_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_NumberFormat_Type_NumberFormatTypeUnspecified; -/** - * Percent formatting, e.g `10.12%` - * - * Value: "PERCENT" - */ -GTLR_EXTERN NSString * const kGTLRSheets_NumberFormat_Type_Percent; -/** - * Scientific number formatting, e.g `1.01E+03` - * - * Value: "SCIENTIFIC" - */ -GTLR_EXTERN NSString * const kGTLRSheets_NumberFormat_Type_Scientific; -/** - * Text formatting, e.g `1000.12` - * - * Value: "TEXT" - */ -GTLR_EXTERN NSString * const kGTLRSheets_NumberFormat_Type_Text; -/** - * Time formatting, e.g `3:59:00 PM` - * - * Value: "TIME" - */ -GTLR_EXTERN NSString * const kGTLRSheets_NumberFormat_Type_Time; - -// ---------------------------------------------------------------------------- -// GTLRSheets_OrgChartSpec.nodeSize - -/** - * The large org chart node size. - * - * Value: "LARGE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_OrgChartSpec_NodeSize_Large; -/** - * The medium org chart node size. - * - * Value: "MEDIUM" - */ -GTLR_EXTERN NSString * const kGTLRSheets_OrgChartSpec_NodeSize_Medium; -/** - * Default value, do not use. - * - * Value: "ORG_CHART_LABEL_SIZE_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_OrgChartSpec_NodeSize_OrgChartLabelSizeUnspecified; -/** - * The small org chart node size. - * - * Value: "SMALL" - */ -GTLR_EXTERN NSString * const kGTLRSheets_OrgChartSpec_NodeSize_Small; - -// ---------------------------------------------------------------------------- -// GTLRSheets_PasteDataRequest.type - -/** - * Paste the conditional formatting rules only. - * - * Value: "PASTE_CONDITIONAL_FORMATTING" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PasteDataRequest_Type_PasteConditionalFormatting; -/** - * Paste the data validation only. - * - * Value: "PASTE_DATA_VALIDATION" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PasteDataRequest_Type_PasteDataValidation; -/** - * Paste the format and data validation only. - * - * Value: "PASTE_FORMAT" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PasteDataRequest_Type_PasteFormat; -/** - * Paste the formulas only. - * - * Value: "PASTE_FORMULA" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PasteDataRequest_Type_PasteFormula; -/** - * Like PASTE_NORMAL but without borders. - * - * Value: "PASTE_NO_BORDERS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PasteDataRequest_Type_PasteNoBorders; -/** - * Paste values, formulas, formats, and merges. - * - * Value: "PASTE_NORMAL" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PasteDataRequest_Type_PasteNormal; -/** - * Paste the values ONLY without formats, formulas, or merges. - * - * Value: "PASTE_VALUES" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PasteDataRequest_Type_PasteValues; - -// ---------------------------------------------------------------------------- -// GTLRSheets_PieChartSpec.legendPosition - -/** - * The legend is rendered on the bottom of the chart. - * - * Value: "BOTTOM_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PieChartSpec_LegendPosition_BottomLegend; -/** - * Each pie slice has a label attached to it. - * - * Value: "LABELED_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PieChartSpec_LegendPosition_LabeledLegend; -/** - * The legend is rendered on the left of the chart. - * - * Value: "LEFT_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PieChartSpec_LegendPosition_LeftLegend; -/** - * No legend is rendered. - * - * Value: "NO_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PieChartSpec_LegendPosition_NoLegend; -/** - * Default value, do not use. - * - * Value: "PIE_CHART_LEGEND_POSITION_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PieChartSpec_LegendPosition_PieChartLegendPositionUnspecified; -/** - * The legend is rendered on the right of the chart. - * - * Value: "RIGHT_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PieChartSpec_LegendPosition_RightLegend; -/** - * The legend is rendered on the top of the chart. - * - * Value: "TOP_LEGEND" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PieChartSpec_LegendPosition_TopLegend; - -// ---------------------------------------------------------------------------- -// GTLRSheets_PivotGroup.sortOrder - -/** - * Sort ascending. - * - * Value: "ASCENDING" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotGroup_SortOrder_Ascending; -/** - * Sort descending. - * - * Value: "DESCENDING" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotGroup_SortOrder_Descending; -/** - * Default value, do not use this. - * - * Value: "SORT_ORDER_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotGroup_SortOrder_SortOrderUnspecified; - -// ---------------------------------------------------------------------------- -// GTLRSheets_PivotTable.valueLayout - -/** - * Values are laid out horizontally (as columns). - * - * Value: "HORIZONTAL" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotTable_ValueLayout_Horizontal; -/** - * Values are laid out vertically (as rows). - * - * Value: "VERTICAL" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotTable_ValueLayout_Vertical; - -// ---------------------------------------------------------------------------- -// GTLRSheets_PivotValue.calculatedDisplayType - -/** - * Shows the pivot values as percentage of the column total values. - * - * Value: "PERCENT_OF_COLUMN_TOTAL" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotValue_CalculatedDisplayType_PercentOfColumnTotal; -/** - * Shows the pivot values as percentage of the grand total values. - * - * Value: "PERCENT_OF_GRAND_TOTAL" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotValue_CalculatedDisplayType_PercentOfGrandTotal; -/** - * Shows the pivot values as percentage of the row total values. - * - * Value: "PERCENT_OF_ROW_TOTAL" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotValue_CalculatedDisplayType_PercentOfRowTotal; -/** - * Default value, do not use. - * - * Value: "PIVOT_VALUE_CALCULATED_DISPLAY_TYPE_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotValue_CalculatedDisplayType_PivotValueCalculatedDisplayTypeUnspecified; - -// ---------------------------------------------------------------------------- -// GTLRSheets_PivotValue.summarizeFunction - -/** - * Corresponds to the `AVERAGE` function. - * - * Value: "AVERAGE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Average; -/** - * Corresponds to the `COUNT` function. - * - * Value: "COUNT" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Count; -/** - * Corresponds to the `COUNTA` function. - * - * Value: "COUNTA" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Counta; -/** - * Corresponds to the `COUNTUNIQUE` function. - * - * Value: "COUNTUNIQUE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Countunique; -/** - * Indicates the formula should be used as-is. - * Only valid if PivotValue.formula was set. - * - * Value: "CUSTOM" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Custom; -/** - * Corresponds to the `MAX` function. - * - * Value: "MAX" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Max; -/** - * Corresponds to the `MEDIAN` function. - * - * Value: "MEDIAN" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Median; -/** - * Corresponds to the `MIN` function. - * - * Value: "MIN" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Min; -/** - * The default, do not use. - * - * Value: "PIVOT_STANDARD_VALUE_FUNCTION_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotValue_SummarizeFunction_PivotStandardValueFunctionUnspecified; -/** - * Corresponds to the `PRODUCT` function. - * - * Value: "PRODUCT" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Product; -/** - * Corresponds to the `STDEV` function. - * - * Value: "STDEV" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Stdev; -/** - * Corresponds to the `STDEVP` function. - * - * Value: "STDEVP" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Stdevp; -/** - * Corresponds to the `SUM` function. - * - * Value: "SUM" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Sum; -/** - * Corresponds to the `VAR` function. - * - * Value: "VAR" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Var; -/** - * Corresponds to the `VARP` function. - * - * Value: "VARP" - */ -GTLR_EXTERN NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Varp; - -// ---------------------------------------------------------------------------- -// GTLRSheets_SheetProperties.sheetType - -/** - * The sheet is a grid. - * - * Value: "GRID" - */ -GTLR_EXTERN NSString * const kGTLRSheets_SheetProperties_SheetType_Grid; -/** - * The sheet has no grid and instead has an object like a chart or image. - * - * Value: "OBJECT" - */ -GTLR_EXTERN NSString * const kGTLRSheets_SheetProperties_SheetType_Object; -/** - * Default value, do not use. - * - * Value: "SHEET_TYPE_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_SheetProperties_SheetType_SheetTypeUnspecified; - -// ---------------------------------------------------------------------------- -// GTLRSheets_SortSpec.sortOrder - -/** - * Sort ascending. - * - * Value: "ASCENDING" - */ -GTLR_EXTERN NSString * const kGTLRSheets_SortSpec_SortOrder_Ascending; -/** - * Sort descending. - * - * Value: "DESCENDING" - */ -GTLR_EXTERN NSString * const kGTLRSheets_SortSpec_SortOrder_Descending; -/** - * Default value, do not use this. - * - * Value: "SORT_ORDER_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_SortSpec_SortOrder_SortOrderUnspecified; - -// ---------------------------------------------------------------------------- -// GTLRSheets_SourceAndDestination.dimension - -/** - * Operates on the columns of a sheet. - * - * Value: "COLUMNS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_SourceAndDestination_Dimension_Columns; -/** - * The default value, do not use. - * - * Value: "DIMENSION_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_SourceAndDestination_Dimension_DimensionUnspecified; -/** - * Operates on the rows of a sheet. - * - * Value: "ROWS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_SourceAndDestination_Dimension_Rows; - -// ---------------------------------------------------------------------------- -// GTLRSheets_SpreadsheetProperties.autoRecalc - -/** - * Volatile functions are updated on every change and hourly. - * - * Value: "HOUR" - */ -GTLR_EXTERN NSString * const kGTLRSheets_SpreadsheetProperties_AutoRecalc_Hour; -/** - * Volatile functions are updated on every change and every minute. - * - * Value: "MINUTE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_SpreadsheetProperties_AutoRecalc_Minute; -/** - * Volatile functions are updated on every change. - * - * Value: "ON_CHANGE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_SpreadsheetProperties_AutoRecalc_OnChange; -/** - * Default value. This value must not be used. - * - * Value: "RECALCULATION_INTERVAL_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_SpreadsheetProperties_AutoRecalc_RecalculationIntervalUnspecified; - -// ---------------------------------------------------------------------------- -// GTLRSheets_TextPosition.horizontalAlignment - -/** - * The text is explicitly aligned to the center of the cell. - * - * Value: "CENTER" - */ -GTLR_EXTERN NSString * const kGTLRSheets_TextPosition_HorizontalAlignment_Center; -/** - * The horizontal alignment is not specified. Do not use this. - * - * Value: "HORIZONTAL_ALIGN_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_TextPosition_HorizontalAlignment_HorizontalAlignUnspecified; -/** - * The text is explicitly aligned to the left of the cell. - * - * Value: "LEFT" - */ -GTLR_EXTERN NSString * const kGTLRSheets_TextPosition_HorizontalAlignment_Left; -/** - * The text is explicitly aligned to the right of the cell. - * - * Value: "RIGHT" - */ -GTLR_EXTERN NSString * const kGTLRSheets_TextPosition_HorizontalAlignment_Right; - -// ---------------------------------------------------------------------------- -// GTLRSheets_TextToColumnsRequest.delimiterType - -/** - * Automatically detect columns. - * - * Value: "AUTODETECT" - */ -GTLR_EXTERN NSString * const kGTLRSheets_TextToColumnsRequest_DelimiterType_Autodetect; -/** - * "," - * - * Value: "COMMA" - */ -GTLR_EXTERN NSString * const kGTLRSheets_TextToColumnsRequest_DelimiterType_Comma; -/** - * A custom value as defined in delimiter. - * - * Value: "CUSTOM" - */ -GTLR_EXTERN NSString * const kGTLRSheets_TextToColumnsRequest_DelimiterType_Custom; -/** - * Default value. This value must not be used. - * - * Value: "DELIMITER_TYPE_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_TextToColumnsRequest_DelimiterType_DelimiterTypeUnspecified; -/** - * "." - * - * Value: "PERIOD" - */ -GTLR_EXTERN NSString * const kGTLRSheets_TextToColumnsRequest_DelimiterType_Period; -/** - * ";" - * - * Value: "SEMICOLON" - */ -GTLR_EXTERN NSString * const kGTLRSheets_TextToColumnsRequest_DelimiterType_Semicolon; -/** - * " " - * - * Value: "SPACE" - */ -GTLR_EXTERN NSString * const kGTLRSheets_TextToColumnsRequest_DelimiterType_Space; - -// ---------------------------------------------------------------------------- -// GTLRSheets_ValueRange.majorDimension - -/** - * Operates on the columns of a sheet. - * - * Value: "COLUMNS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ValueRange_MajorDimension_Columns; -/** - * The default value, do not use. - * - * Value: "DIMENSION_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ValueRange_MajorDimension_DimensionUnspecified; -/** - * Operates on the rows of a sheet. - * - * Value: "ROWS" - */ -GTLR_EXTERN NSString * const kGTLRSheets_ValueRange_MajorDimension_Rows; - -// ---------------------------------------------------------------------------- -// GTLRSheets_WaterfallChartSpec.stackedType - -/** - * Series will spread out along the horizontal axis. - * - * Value: "SEQUENTIAL" - */ -GTLR_EXTERN NSString * const kGTLRSheets_WaterfallChartSpec_StackedType_Sequential; -/** - * Values corresponding to the same domain (horizontal axis) value will be - * stacked vertically. - * - * Value: "STACKED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_WaterfallChartSpec_StackedType_Stacked; -/** - * Default value, do not use. - * - * Value: "WATERFALL_STACKED_TYPE_UNSPECIFIED" - */ -GTLR_EXTERN NSString * const kGTLRSheets_WaterfallChartSpec_StackedType_WaterfallStackedTypeUnspecified; - -/** - * Adds a new banded range to the spreadsheet. - */ -@interface GTLRSheets_AddBandingRequest : GTLRObject - -/** - * The banded range to add. The bandedRangeId - * field is optional; if one is not set, an id will be randomly generated. (It - * is an error to specify the ID of a range that already exists.) - */ -@property(nonatomic, strong, nullable) GTLRSheets_BandedRange *bandedRange; - -@end - - -/** - * The result of adding a banded range. - */ -@interface GTLRSheets_AddBandingResponse : GTLRObject - -/** The banded range that was added. */ -@property(nonatomic, strong, nullable) GTLRSheets_BandedRange *bandedRange; - -@end - - -/** - * Adds a chart to a sheet in the spreadsheet. - */ -@interface GTLRSheets_AddChartRequest : GTLRObject - -/** - * The chart that should be added to the spreadsheet, including the position - * where it should be placed. The chartId - * field is optional; if one is not set, an id will be randomly generated. (It - * is an error to specify the ID of a chart that already exists.) - */ -@property(nonatomic, strong, nullable) GTLRSheets_EmbeddedChart *chart; - -@end - - -/** - * The result of adding a chart to a spreadsheet. - */ -@interface GTLRSheets_AddChartResponse : GTLRObject - -/** The newly added chart. */ -@property(nonatomic, strong, nullable) GTLRSheets_EmbeddedChart *chart; - -@end - - -/** - * Adds a new conditional format rule at the given index. - * All subsequent rules' indexes are incremented. - */ -@interface GTLRSheets_AddConditionalFormatRuleRequest : GTLRObject - -/** - * The zero-based index where the rule should be inserted. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *index; - -/** The rule to add. */ -@property(nonatomic, strong, nullable) GTLRSheets_ConditionalFormatRule *rule; - -@end - - -/** - * Creates a group over the specified range. - * If the requested range is a superset of the range of an existing group G, - * then the depth of G is incremented and this new group G' has the - * depth of that group. For example, a group [C:D, depth 1] + [B:E] results in - * groups [B:E, depth 1] and [C:D, depth 2]. - * If the requested range is a subset of the range of an existing group G, - * then the depth of the new group G' becomes one greater than the depth of G. - * For example, a group [B:E, depth 1] + [C:D] results in groups [B:E, depth 1] - * and [C:D, depth 2]. - * If the requested range starts before and ends within, or starts within and - * ends after, the range of an existing group G, then the range of the existing - * group G becomes the union of the ranges, and the new group G' has - * depth one greater than the depth of G and range as the intersection of the - * ranges. For example, a group [B:D, depth 1] + [C:E] results in groups [B:E, - * depth 1] and [C:D, depth 2]. - */ -@interface GTLRSheets_AddDimensionGroupRequest : GTLRObject - -/** The range over which to create a group. */ -@property(nonatomic, strong, nullable) GTLRSheets_DimensionRange *range; - -@end - - -/** - * The result of adding a group. - */ -@interface GTLRSheets_AddDimensionGroupResponse : GTLRObject - -/** All groups of a dimension after adding a group to that dimension. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_DimensionGroup *> *dimensionGroups; - -@end - - -/** - * Adds a filter view. - */ -@interface GTLRSheets_AddFilterViewRequest : GTLRObject - -/** - * The filter to add. The filterViewId - * field is optional; if one is not set, an id will be randomly generated. (It - * is an error to specify the ID of a filter that already exists.) - */ -@property(nonatomic, strong, nullable) GTLRSheets_FilterView *filter; - -@end - - -/** - * The result of adding a filter view. - */ -@interface GTLRSheets_AddFilterViewResponse : GTLRObject - -/** The newly added filter view. */ -@property(nonatomic, strong, nullable) GTLRSheets_FilterView *filter; - -@end - - -/** - * Adds a named range to the spreadsheet. - */ -@interface GTLRSheets_AddNamedRangeRequest : GTLRObject - -/** - * The named range to add. The namedRangeId - * field is optional; if one is not set, an id will be randomly generated. (It - * is an error to specify the ID of a range that already exists.) - */ -@property(nonatomic, strong, nullable) GTLRSheets_NamedRange *namedRange; - -@end - - -/** - * The result of adding a named range. - */ -@interface GTLRSheets_AddNamedRangeResponse : GTLRObject - -/** The named range to add. */ -@property(nonatomic, strong, nullable) GTLRSheets_NamedRange *namedRange; - -@end - - -/** - * Adds a new protected range. - */ -@interface GTLRSheets_AddProtectedRangeRequest : GTLRObject - -/** - * The protected range to be added. The - * protectedRangeId field is optional; if - * one is not set, an id will be randomly generated. (It is an error to - * specify the ID of a range that already exists.) - */ -@property(nonatomic, strong, nullable) GTLRSheets_ProtectedRange *protectedRange; - -@end - - -/** - * The result of adding a new protected range. - */ -@interface GTLRSheets_AddProtectedRangeResponse : GTLRObject - -/** The newly added protected range. */ -@property(nonatomic, strong, nullable) GTLRSheets_ProtectedRange *protectedRange; - -@end - - -/** - * Adds a new sheet. - * When a sheet is added at a given index, - * all subsequent sheets' indexes are incremented. - * To add an object sheet, use AddChartRequest instead and specify - * EmbeddedObjectPosition.sheetId or - * EmbeddedObjectPosition.newSheet. - */ -@interface GTLRSheets_AddSheetRequest : GTLRObject - -/** - * The properties the new sheet should have. - * All properties are optional. - * The sheetId field is optional; if one is not - * set, an id will be randomly generated. (It is an error to specify the ID - * of a sheet that already exists.) - */ -@property(nonatomic, strong, nullable) GTLRSheets_SheetProperties *properties; - -@end - - -/** - * The result of adding a sheet. - */ -@interface GTLRSheets_AddSheetResponse : GTLRObject - -/** The properties of the newly added sheet. */ -@property(nonatomic, strong, nullable) GTLRSheets_SheetProperties *properties; - -@end - - -/** - * Adds new cells after the last row with data in a sheet, - * inserting new rows into the sheet if necessary. - */ -@interface GTLRSheets_AppendCellsRequest : GTLRObject - -/** - * The fields of CellData that should be updated. - * At least one field must be specified. - * The root is the CellData; 'row.values.' should not be specified. - * A single `"*"` can be used as short-hand for listing every field. - * - * String format is a comma-separated list of fields. - */ -@property(nonatomic, copy, nullable) NSString *fields; - -/** The data to append. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_RowData *> *rows; - -/** - * The sheet ID to append the data to. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *sheetId; - -@end - - -/** - * Appends rows or columns to the end of a sheet. - */ -@interface GTLRSheets_AppendDimensionRequest : GTLRObject - -/** - * Whether rows or columns should be appended. - * - * Likely values: - * @arg @c kGTLRSheets_AppendDimensionRequest_Dimension_Columns Operates on - * the columns of a sheet. (Value: "COLUMNS") - * @arg @c kGTLRSheets_AppendDimensionRequest_Dimension_DimensionUnspecified - * The default value, do not use. (Value: "DIMENSION_UNSPECIFIED") - * @arg @c kGTLRSheets_AppendDimensionRequest_Dimension_Rows Operates on the - * rows of a sheet. (Value: "ROWS") - */ -@property(nonatomic, copy, nullable) NSString *dimension; - -/** - * The number of rows or columns to append. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *length; - -/** - * The sheet to append rows or columns to. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *sheetId; - -@end - - -/** - * The response when updating a range of values in a spreadsheet. - */ -@interface GTLRSheets_AppendValuesResponse : GTLRObject - -/** The spreadsheet the updates were applied to. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * The range (in A1 notation) of the table that values are being appended to - * (before the values were appended). - * Empty if no table was found. - */ -@property(nonatomic, copy, nullable) NSString *tableRange; - -/** Information about the updates that were applied. */ -@property(nonatomic, strong, nullable) GTLRSheets_UpdateValuesResponse *updates; - -@end - - -/** - * Fills in more data based on existing data. - */ -@interface GTLRSheets_AutoFillRequest : GTLRObject - -/** - * The range to autofill. This will examine the range and detect - * the location that has data and automatically fill that data - * in to the rest of the range. - */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *range; - -/** - * The source and destination areas to autofill. - * This explicitly lists the source of the autofill and where to - * extend that data. - */ -@property(nonatomic, strong, nullable) GTLRSheets_SourceAndDestination *sourceAndDestination; - -/** - * True if we should generate data with the "alternate" series. - * This differs based on the type and amount of source data. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *useAlternateSeries; - -@end - - -/** - * Automatically resizes one or more dimensions based on the contents - * of the cells in that dimension. - */ -@interface GTLRSheets_AutoResizeDimensionsRequest : GTLRObject - -/** The dimensions to automatically resize. */ -@property(nonatomic, strong, nullable) GTLRSheets_DimensionRange *dimensions; - -@end - - -/** - * A banded (alternating colors) range in a sheet. - */ -@interface GTLRSheets_BandedRange : GTLRObject - -/** - * The id of the banded range. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *bandedRangeId; - -/** - * Properties for column bands. These properties are applied on a column- - * by-column basis throughout all the columns in the range. At least one of - * row_properties or column_properties must be specified. - */ -@property(nonatomic, strong, nullable) GTLRSheets_BandingProperties *columnProperties; - -/** The range over which these properties are applied. */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *range; - -/** - * Properties for row bands. These properties are applied on a row-by-row - * basis throughout all the rows in the range. At least one of - * row_properties or column_properties must be specified. - */ -@property(nonatomic, strong, nullable) GTLRSheets_BandingProperties *rowProperties; - -@end - - -/** - * Properties referring a single dimension (either row or column). If both - * BandedRange.row_properties and BandedRange.column_properties are - * set, the fill colors are applied to cells according to the following rules: - * * header_color and footer_color take priority over band colors. - * * first_band_color takes priority over second_band_color. - * * row_properties takes priority over column_properties. - * For example, the first row color takes priority over the first column - * color, but the first column color takes priority over the second row color. - * Similarly, the row header takes priority over the column header in the - * top left cell, but the column header takes priority over the first row - * color if the row header is not set. - */ -@interface GTLRSheets_BandingProperties : GTLRObject - -/** The first color that is alternating. (Required) */ -@property(nonatomic, strong, nullable) GTLRSheets_Color *firstBandColor; - -/** - * The color of the last row or column. If this field is not set, the last - * row or column will be filled with either first_band_color or - * second_band_color, depending on the color of the previous row or - * column. - */ -@property(nonatomic, strong, nullable) GTLRSheets_Color *footerColor; - -/** - * The color of the first row or column. If this field is set, the first - * row or column will be filled with this color and the colors will - * alternate between first_band_color and second_band_color starting - * from the second row or column. Otherwise, the first row or column will be - * filled with first_band_color and the colors will proceed to alternate - * as they normally would. - */ -@property(nonatomic, strong, nullable) GTLRSheets_Color *headerColor; - -/** The second color that is alternating. (Required) */ -@property(nonatomic, strong, nullable) GTLRSheets_Color *secondBandColor; - -@end - - -/** - * An axis of the chart. - * A chart may not have more than one axis per - * axis position. - */ -@interface GTLRSheets_BasicChartAxis : GTLRObject - -/** - * The format of the title. - * Only valid if the axis is not associated with the domain. - */ -@property(nonatomic, strong, nullable) GTLRSheets_TextFormat *format; - -/** - * The position of this axis. - * - * Likely values: - * @arg @c kGTLRSheets_BasicChartAxis_Position_BasicChartAxisPositionUnspecified - * Default value, do not use. (Value: - * "BASIC_CHART_AXIS_POSITION_UNSPECIFIED") - * @arg @c kGTLRSheets_BasicChartAxis_Position_BottomAxis The axis rendered - * at the bottom of a chart. - * For most charts, this is the standard major axis. - * For bar charts, this is a minor axis. (Value: "BOTTOM_AXIS") - * @arg @c kGTLRSheets_BasicChartAxis_Position_LeftAxis The axis rendered at - * the left of a chart. - * For most charts, this is a minor axis. - * For bar charts, this is the standard major axis. (Value: "LEFT_AXIS") - * @arg @c kGTLRSheets_BasicChartAxis_Position_RightAxis The axis rendered at - * the right of a chart. - * For most charts, this is a minor axis. - * For bar charts, this is an unusual major axis. (Value: "RIGHT_AXIS") - */ -@property(nonatomic, copy, nullable) NSString *position; - -/** - * The title of this axis. If set, this overrides any title inferred - * from headers of the data. - */ -@property(nonatomic, copy, nullable) NSString *title; - -/** The axis title text position. */ -@property(nonatomic, strong, nullable) GTLRSheets_TextPosition *titleTextPosition; - -@end - - -/** - * The domain of a chart. - * For example, if charting stock prices over time, this would be the date. - */ -@interface GTLRSheets_BasicChartDomain : GTLRObject - -/** - * The data of the domain. For example, if charting stock prices over time, - * this is the data representing the dates. - */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartData *domain; - -/** - * True to reverse the order of the domain values (horizontal axis). - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *reversed; - -@end - - -/** - * A single series of data in a chart. - * For example, if charting stock prices over time, multiple series may exist, - * one for the "Open Price", "High Price", "Low Price" and "Close Price". - */ -@interface GTLRSheets_BasicChartSeries : GTLRObject - -/** - * The color for elements (i.e. bars, lines, points) associated with this - * series. If empty, a default color is used. - */ -@property(nonatomic, strong, nullable) GTLRSheets_Color *color; - -/** - * The line style of this series. Valid only if the - * chartType is AREA, - * LINE, or SCATTER. - * COMBO charts are also supported if the - * series chart type is - * AREA or LINE. - */ -@property(nonatomic, strong, nullable) GTLRSheets_LineStyle *lineStyle; - -/** The data being visualized in this chart series. */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartData *series; - -/** - * The minor axis that will specify the range of values for this series. - * For example, if charting stocks over time, the "Volume" series - * may want to be pinned to the right with the prices pinned to the left, - * because the scale of trading volume is different than the scale of - * prices. - * It is an error to specify an axis that isn't a valid minor axis - * for the chart's type. - * - * Likely values: - * @arg @c kGTLRSheets_BasicChartSeries_TargetAxis_BasicChartAxisPositionUnspecified - * Default value, do not use. (Value: - * "BASIC_CHART_AXIS_POSITION_UNSPECIFIED") - * @arg @c kGTLRSheets_BasicChartSeries_TargetAxis_BottomAxis The axis - * rendered at the bottom of a chart. - * For most charts, this is the standard major axis. - * For bar charts, this is a minor axis. (Value: "BOTTOM_AXIS") - * @arg @c kGTLRSheets_BasicChartSeries_TargetAxis_LeftAxis The axis rendered - * at the left of a chart. - * For most charts, this is a minor axis. - * For bar charts, this is the standard major axis. (Value: "LEFT_AXIS") - * @arg @c kGTLRSheets_BasicChartSeries_TargetAxis_RightAxis The axis - * rendered at the right of a chart. - * For most charts, this is a minor axis. - * For bar charts, this is an unusual major axis. (Value: "RIGHT_AXIS") - */ -@property(nonatomic, copy, nullable) NSString *targetAxis; - -/** - * The type of this series. Valid only if the - * chartType is - * COMBO. - * Different types will change the way the series is visualized. - * Only LINE, AREA, - * and COLUMN are supported. - * - * Likely values: - * @arg @c kGTLRSheets_BasicChartSeries_Type_Area An - * <a href="/chart/interactive/docs/gallery/areachart">area chart</a>. - * (Value: "AREA") - * @arg @c kGTLRSheets_BasicChartSeries_Type_Bar A - * <a href="/chart/interactive/docs/gallery/barchart">bar chart</a>. - * (Value: "BAR") - * @arg @c kGTLRSheets_BasicChartSeries_Type_BasicChartTypeUnspecified - * Default value, do not use. (Value: "BASIC_CHART_TYPE_UNSPECIFIED") - * @arg @c kGTLRSheets_BasicChartSeries_Type_Column A - * <a href="/chart/interactive/docs/gallery/columnchart">column - * chart</a>. (Value: "COLUMN") - * @arg @c kGTLRSheets_BasicChartSeries_Type_Combo A - * <a href="/chart/interactive/docs/gallery/combochart">combo chart</a>. - * (Value: "COMBO") - * @arg @c kGTLRSheets_BasicChartSeries_Type_Line A - * <a href="/chart/interactive/docs/gallery/linechart">line chart</a>. - * (Value: "LINE") - * @arg @c kGTLRSheets_BasicChartSeries_Type_Scatter A - * <a href="/chart/interactive/docs/gallery/scatterchart">scatter - * chart</a>. (Value: "SCATTER") - * @arg @c kGTLRSheets_BasicChartSeries_Type_SteppedArea A - * <a href="/chart/interactive/docs/gallery/steppedareachart">stepped - * area - * chart</a>. (Value: "STEPPED_AREA") - */ -@property(nonatomic, copy, nullable) NSString *type; - -@end - - -/** - * The specification for a basic chart. See BasicChartType for the list - * of charts this supports. - */ -@interface GTLRSheets_BasicChartSpec : GTLRObject - -/** The axis on the chart. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_BasicChartAxis *> *axis; - -/** - * The type of the chart. - * - * Likely values: - * @arg @c kGTLRSheets_BasicChartSpec_ChartType_Area An - * <a href="/chart/interactive/docs/gallery/areachart">area chart</a>. - * (Value: "AREA") - * @arg @c kGTLRSheets_BasicChartSpec_ChartType_Bar A - * <a href="/chart/interactive/docs/gallery/barchart">bar chart</a>. - * (Value: "BAR") - * @arg @c kGTLRSheets_BasicChartSpec_ChartType_BasicChartTypeUnspecified - * Default value, do not use. (Value: "BASIC_CHART_TYPE_UNSPECIFIED") - * @arg @c kGTLRSheets_BasicChartSpec_ChartType_Column A - * <a href="/chart/interactive/docs/gallery/columnchart">column - * chart</a>. (Value: "COLUMN") - * @arg @c kGTLRSheets_BasicChartSpec_ChartType_Combo A - * <a href="/chart/interactive/docs/gallery/combochart">combo chart</a>. - * (Value: "COMBO") - * @arg @c kGTLRSheets_BasicChartSpec_ChartType_Line A - * <a href="/chart/interactive/docs/gallery/linechart">line chart</a>. - * (Value: "LINE") - * @arg @c kGTLRSheets_BasicChartSpec_ChartType_Scatter A - * <a href="/chart/interactive/docs/gallery/scatterchart">scatter - * chart</a>. (Value: "SCATTER") - * @arg @c kGTLRSheets_BasicChartSpec_ChartType_SteppedArea A - * <a href="/chart/interactive/docs/gallery/steppedareachart">stepped - * area - * chart</a>. (Value: "STEPPED_AREA") - */ -@property(nonatomic, copy, nullable) NSString *chartType; - -/** - * The behavior of tooltips and data highlighting when hovering on data and - * chart area. - * - * Likely values: - * @arg @c kGTLRSheets_BasicChartSpec_CompareMode_BasicChartCompareModeUnspecified - * Default value, do not use. (Value: - * "BASIC_CHART_COMPARE_MODE_UNSPECIFIED") - * @arg @c kGTLRSheets_BasicChartSpec_CompareMode_Category All data elements - * with the same category (e.g., domain value) are - * highlighted and shown in the tooltip. (Value: "CATEGORY") - * @arg @c kGTLRSheets_BasicChartSpec_CompareMode_Datum Only the focused data - * element is highlighted and shown in the tooltip. (Value: "DATUM") - */ -@property(nonatomic, copy, nullable) NSString *compareMode; - -/** - * The domain of data this is charting. - * Only a single domain is supported. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_BasicChartDomain *> *domains; - -/** - * The number of rows or columns in the data that are "headers". - * If not set, Google Sheets will guess how many rows are headers based - * on the data. - * (Note that BasicChartAxis.title may override the axis title - * inferred from the header values.) - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *headerCount; - -/** - * If some values in a series are missing, gaps may appear in the chart (e.g, - * segments of lines in a line chart will be missing). To eliminate these - * gaps set this to true. - * Applies to Line, Area, and Combo charts. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *interpolateNulls; - -/** - * The position of the chart legend. - * - * Likely values: - * @arg @c kGTLRSheets_BasicChartSpec_LegendPosition_BasicChartLegendPositionUnspecified - * Default value, do not use. (Value: - * "BASIC_CHART_LEGEND_POSITION_UNSPECIFIED") - * @arg @c kGTLRSheets_BasicChartSpec_LegendPosition_BottomLegend The legend - * is rendered on the bottom of the chart. (Value: "BOTTOM_LEGEND") - * @arg @c kGTLRSheets_BasicChartSpec_LegendPosition_LeftLegend The legend is - * rendered on the left of the chart. (Value: "LEFT_LEGEND") - * @arg @c kGTLRSheets_BasicChartSpec_LegendPosition_NoLegend No legend is - * rendered. (Value: "NO_LEGEND") - * @arg @c kGTLRSheets_BasicChartSpec_LegendPosition_RightLegend The legend - * is rendered on the right of the chart. (Value: "RIGHT_LEGEND") - * @arg @c kGTLRSheets_BasicChartSpec_LegendPosition_TopLegend The legend is - * rendered on the top of the chart. (Value: "TOP_LEGEND") - */ -@property(nonatomic, copy, nullable) NSString *legendPosition; - -/** - * Gets whether all lines should be rendered smooth or straight by default. - * Applies to Line charts. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *lineSmoothing; - -/** The data this chart is visualizing. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_BasicChartSeries *> *series; - -/** - * The stacked type for charts that support vertical stacking. - * Applies to Area, Bar, Column, Combo, and Stepped Area charts. - * - * Likely values: - * @arg @c kGTLRSheets_BasicChartSpec_StackedType_BasicChartStackedTypeUnspecified - * Default value, do not use. (Value: - * "BASIC_CHART_STACKED_TYPE_UNSPECIFIED") - * @arg @c kGTLRSheets_BasicChartSpec_StackedType_NotStacked Series are not - * stacked. (Value: "NOT_STACKED") - * @arg @c kGTLRSheets_BasicChartSpec_StackedType_PercentStacked Vertical - * stacks are stretched to reach the top of the chart, with - * values laid out as percentages of each other. (Value: - * "PERCENT_STACKED") - * @arg @c kGTLRSheets_BasicChartSpec_StackedType_Stacked Series values are - * stacked, each value is rendered vertically beginning - * from the top of the value below it. (Value: "STACKED") - */ -@property(nonatomic, copy, nullable) NSString *stackedType; - -/** - * True to make the chart 3D. - * Applies to Bar and Column charts. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *threeDimensional; - -@end - - -/** - * The default filter associated with a sheet. - */ -@interface GTLRSheets_BasicFilter : GTLRObject - -/** - * The criteria for showing/hiding values per column. - * The map's key is the column index, and the value is the criteria for - * that column. - */ -@property(nonatomic, strong, nullable) GTLRSheets_BasicFilter_Criteria *criteria; - -/** The range the filter covers. */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *range; - -/** - * The sort order per column. Later specifications are used when values - * are equal in the earlier specifications. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_SortSpec *> *sortSpecs; - -@end - - -/** - * The criteria for showing/hiding values per column. - * The map's key is the column index, and the value is the criteria for - * that column. - * - * @note This class is documented as having more properties of - * GTLRSheets_FilterCriteria. Use @c -additionalJSONKeys and @c - * -additionalPropertyForName: to get the list of properties and then - * fetch them; or @c -additionalProperties to fetch them all at once. - */ -@interface GTLRSheets_BasicFilter_Criteria : GTLRObject -@end - - -/** - * The request for clearing more than one range selected by a - * DataFilter in a spreadsheet. - */ -@interface GTLRSheets_BatchClearValuesByDataFilterRequest : GTLRObject - -/** The DataFilters used to determine which ranges to clear. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_DataFilter *> *dataFilters; - -@end - - -/** - * The response when clearing a range of values selected with - * DataFilters in a spreadsheet. - */ -@interface GTLRSheets_BatchClearValuesByDataFilterResponse : GTLRObject - -/** - * The ranges that were cleared, in A1 notation. - * (If the requests were for an unbounded range or a ranger larger - * than the bounds of the sheet, this will be the actual ranges - * that were cleared, bounded to the sheet's limits.) - */ -@property(nonatomic, strong, nullable) NSArray<NSString *> *clearedRanges; - -/** The spreadsheet the updates were applied to. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -@end - - -/** - * The request for clearing more than one range of values in a spreadsheet. - */ -@interface GTLRSheets_BatchClearValuesRequest : GTLRObject - -/** The ranges to clear, in A1 notation. */ -@property(nonatomic, strong, nullable) NSArray<NSString *> *ranges; - -@end - - -/** - * The response when clearing a range of values in a spreadsheet. - */ -@interface GTLRSheets_BatchClearValuesResponse : GTLRObject - -/** - * The ranges that were cleared, in A1 notation. - * (If the requests were for an unbounded range or a ranger larger - * than the bounds of the sheet, this will be the actual ranges - * that were cleared, bounded to the sheet's limits.) - */ -@property(nonatomic, strong, nullable) NSArray<NSString *> *clearedRanges; - -/** The spreadsheet the updates were applied to. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -@end - - -/** - * The request for retrieving a range of values in a spreadsheet selected by a - * set of DataFilters. - */ -@interface GTLRSheets_BatchGetValuesByDataFilterRequest : GTLRObject - -/** - * The data filters used to match the ranges of values to retrieve. Ranges - * that match any of the specified data filters will be included in the - * response. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_DataFilter *> *dataFilters; - -/** - * How dates, times, and durations should be represented in the output. - * This is ignored if value_render_option is - * FORMATTED_VALUE. - * The default dateTime render option is [DateTimeRenderOption.SERIAL_NUMBER]. - * - * Likely values: - * @arg @c kGTLRSheets_BatchGetValuesByDataFilterRequest_DateTimeRenderOption_FormattedString - * Instructs date, time, datetime, and duration fields to be output - * as strings in their given number format (which is dependent - * on the spreadsheet locale). (Value: "FORMATTED_STRING") - * @arg @c kGTLRSheets_BatchGetValuesByDataFilterRequest_DateTimeRenderOption_SerialNumber - * Instructs date, time, datetime, and duration fields to be output - * as doubles in "serial number" format, as popularized by Lotus 1-2-3. - * The whole number portion of the value (left of the decimal) counts - * the days since December 30th 1899. The fractional portion (right of - * the decimal) counts the time as a fraction of the day. For example, - * January 1st 1900 at noon would be 2.5, 2 because it's 2 days after - * December 30st 1899, and .5 because noon is half a day. February 1st - * 1900 at 3pm would be 33.625. This correctly treats the year 1900 as - * not a leap year. (Value: "SERIAL_NUMBER") - */ -@property(nonatomic, copy, nullable) NSString *dateTimeRenderOption; - -/** - * The major dimension that results should use. - * For example, if the spreadsheet data is: `A1=1,B1=2,A2=3,B2=4`, - * then a request that selects that range and sets `majorDimension=ROWS` will - * return `[[1,2],[3,4]]`, - * whereas a request that sets `majorDimension=COLUMNS` will return - * `[[1,3],[2,4]]`. - * - * Likely values: - * @arg @c kGTLRSheets_BatchGetValuesByDataFilterRequest_MajorDimension_Columns - * Operates on the columns of a sheet. (Value: "COLUMNS") - * @arg @c kGTLRSheets_BatchGetValuesByDataFilterRequest_MajorDimension_DimensionUnspecified - * The default value, do not use. (Value: "DIMENSION_UNSPECIFIED") - * @arg @c kGTLRSheets_BatchGetValuesByDataFilterRequest_MajorDimension_Rows - * Operates on the rows of a sheet. (Value: "ROWS") - */ -@property(nonatomic, copy, nullable) NSString *majorDimension; - -/** - * How values should be represented in the output. - * The default render option is ValueRenderOption.FORMATTED_VALUE. - * - * Likely values: - * @arg @c kGTLRSheets_BatchGetValuesByDataFilterRequest_ValueRenderOption_FormattedValue - * Values will be calculated & formatted in the reply according to the - * cell's formatting. Formatting is based on the spreadsheet's locale, - * not the requesting user's locale. - * For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as - * currency, - * then `A2` would return `"$1.23"`. (Value: "FORMATTED_VALUE") - * @arg @c kGTLRSheets_BatchGetValuesByDataFilterRequest_ValueRenderOption_Formula - * Values will not be calculated. The reply will include the formulas. - * For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as - * currency, - * then A2 would return `"=A1"`. (Value: "FORMULA") - * @arg @c kGTLRSheets_BatchGetValuesByDataFilterRequest_ValueRenderOption_UnformattedValue - * Values will be calculated, but not formatted in the reply. - * For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as - * currency, - * then `A2` would return the number `1.23`. (Value: "UNFORMATTED_VALUE") - */ -@property(nonatomic, copy, nullable) NSString *valueRenderOption; - -@end - - -/** - * The response when retrieving more than one range of values in a spreadsheet - * selected by DataFilters. - */ -@interface GTLRSheets_BatchGetValuesByDataFilterResponse : GTLRObject - -/** The ID of the spreadsheet the data was retrieved from. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** The requested values with the list of data filters that matched them. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_MatchedValueRange *> *valueRanges; - -@end - - -/** - * The response when retrieving more than one range of values in a spreadsheet. - */ -@interface GTLRSheets_BatchGetValuesResponse : GTLRObject - -/** The ID of the spreadsheet the data was retrieved from. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * The requested values. The order of the ValueRanges is the same as the - * order of the requested ranges. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_ValueRange *> *valueRanges; - -@end - - -/** - * The request for updating any aspect of a spreadsheet. - */ -@interface GTLRSheets_BatchUpdateSpreadsheetRequest : GTLRObject - -/** - * Determines if the update response should include the spreadsheet - * resource. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *includeSpreadsheetInResponse; - -/** - * A list of updates to apply to the spreadsheet. - * Requests will be applied in the order they are specified. - * If any request is not valid, no requests will be applied. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_Request *> *requests; - -/** - * True if grid data should be returned. Meaningful only if - * if include_spreadsheet_in_response is 'true'. - * This parameter is ignored if a field mask was set in the request. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *responseIncludeGridData; - -/** - * Limits the ranges included in the response spreadsheet. - * Meaningful only if include_spreadsheet_response is 'true'. - */ -@property(nonatomic, strong, nullable) NSArray<NSString *> *responseRanges; - -@end - - -/** - * The reply for batch updating a spreadsheet. - */ -@interface GTLRSheets_BatchUpdateSpreadsheetResponse : GTLRObject - -/** - * The reply of the updates. This maps 1:1 with the updates, although - * replies to some requests may be empty. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_Response *> *replies; - -/** The spreadsheet the updates were applied to. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * The spreadsheet after updates were applied. This is only set if - * [BatchUpdateSpreadsheetRequest.include_spreadsheet_in_response] is `true`. - */ -@property(nonatomic, strong, nullable) GTLRSheets_Spreadsheet *updatedSpreadsheet; - -@end - - -/** - * The request for updating more than one range of values in a spreadsheet. - */ -@interface GTLRSheets_BatchUpdateValuesByDataFilterRequest : GTLRObject - -/** - * The new values to apply to the spreadsheet. If more than one range is - * matched by the specified DataFilter the specified values will be - * applied to all of those ranges. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_DataFilterValueRange *> *data; - -/** - * Determines if the update response should include the values - * of the cells that were updated. By default, responses - * do not include the updated values. The `updatedData` field within - * each of the BatchUpdateValuesResponse.responses will contain - * the updated values. If the range to write was larger than than the range - * actually written, the response will include all values in the requested - * range (excluding trailing empty rows and columns). - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *includeValuesInResponse; - -/** - * Determines how dates, times, and durations in the response should be - * rendered. This is ignored if response_value_render_option is - * FORMATTED_VALUE. - * The default dateTime render option is - * DateTimeRenderOption.SERIAL_NUMBER. - * - * Likely values: - * @arg @c kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ResponseDateTimeRenderOption_FormattedString - * Instructs date, time, datetime, and duration fields to be output - * as strings in their given number format (which is dependent - * on the spreadsheet locale). (Value: "FORMATTED_STRING") - * @arg @c kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ResponseDateTimeRenderOption_SerialNumber - * Instructs date, time, datetime, and duration fields to be output - * as doubles in "serial number" format, as popularized by Lotus 1-2-3. - * The whole number portion of the value (left of the decimal) counts - * the days since December 30th 1899. The fractional portion (right of - * the decimal) counts the time as a fraction of the day. For example, - * January 1st 1900 at noon would be 2.5, 2 because it's 2 days after - * December 30st 1899, and .5 because noon is half a day. February 1st - * 1900 at 3pm would be 33.625. This correctly treats the year 1900 as - * not a leap year. (Value: "SERIAL_NUMBER") - */ -@property(nonatomic, copy, nullable) NSString *responseDateTimeRenderOption; - -/** - * Determines how values in the response should be rendered. - * The default render option is ValueRenderOption.FORMATTED_VALUE. - * - * Likely values: - * @arg @c kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ResponseValueRenderOption_FormattedValue - * Values will be calculated & formatted in the reply according to the - * cell's formatting. Formatting is based on the spreadsheet's locale, - * not the requesting user's locale. - * For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as - * currency, - * then `A2` would return `"$1.23"`. (Value: "FORMATTED_VALUE") - * @arg @c kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ResponseValueRenderOption_Formula - * Values will not be calculated. The reply will include the formulas. - * For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as - * currency, - * then A2 would return `"=A1"`. (Value: "FORMULA") - * @arg @c kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ResponseValueRenderOption_UnformattedValue - * Values will be calculated, but not formatted in the reply. - * For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as - * currency, - * then `A2` would return the number `1.23`. (Value: "UNFORMATTED_VALUE") - */ -@property(nonatomic, copy, nullable) NSString *responseValueRenderOption; - -/** - * How the input data should be interpreted. - * - * Likely values: - * @arg @c kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ValueInputOption_InputValueOptionUnspecified - * Default input value. This value must not be used. (Value: - * "INPUT_VALUE_OPTION_UNSPECIFIED") - * @arg @c kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ValueInputOption_Raw - * The values the user has entered will not be parsed and will be stored - * as-is. (Value: "RAW") - * @arg @c kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ValueInputOption_UserEntered - * The values will be parsed as if the user typed them into the UI. - * Numbers will stay as numbers, but strings may be converted to numbers, - * dates, etc. following the same rules that are applied when entering - * text into a cell via the Google Sheets UI. (Value: "USER_ENTERED") - */ -@property(nonatomic, copy, nullable) NSString *valueInputOption; - -@end - - -/** - * The response when updating a range of values in a spreadsheet. - */ -@interface GTLRSheets_BatchUpdateValuesByDataFilterResponse : GTLRObject - -/** The response for each range updated. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_UpdateValuesByDataFilterResponse *> *responses; - -/** The spreadsheet the updates were applied to. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * The total number of cells updated. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *totalUpdatedCells; - -/** - * The total number of columns where at least one cell in the column was - * updated. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *totalUpdatedColumns; - -/** - * The total number of rows where at least one cell in the row was updated. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *totalUpdatedRows; - -/** - * The total number of sheets where at least one cell in the sheet was - * updated. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *totalUpdatedSheets; - -@end - - -/** - * The request for updating more than one range of values in a spreadsheet. - */ -@interface GTLRSheets_BatchUpdateValuesRequest : GTLRObject - -/** The new values to apply to the spreadsheet. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_ValueRange *> *data; - -/** - * Determines if the update response should include the values - * of the cells that were updated. By default, responses - * do not include the updated values. The `updatedData` field within - * each of the BatchUpdateValuesResponse.responses will contain - * the updated values. If the range to write was larger than than the range - * actually written, the response will include all values in the requested - * range (excluding trailing empty rows and columns). - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *includeValuesInResponse; - -/** - * Determines how dates, times, and durations in the response should be - * rendered. This is ignored if response_value_render_option is - * FORMATTED_VALUE. - * The default dateTime render option is - * DateTimeRenderOption.SERIAL_NUMBER. - * - * Likely values: - * @arg @c kGTLRSheets_BatchUpdateValuesRequest_ResponseDateTimeRenderOption_FormattedString - * Instructs date, time, datetime, and duration fields to be output - * as strings in their given number format (which is dependent - * on the spreadsheet locale). (Value: "FORMATTED_STRING") - * @arg @c kGTLRSheets_BatchUpdateValuesRequest_ResponseDateTimeRenderOption_SerialNumber - * Instructs date, time, datetime, and duration fields to be output - * as doubles in "serial number" format, as popularized by Lotus 1-2-3. - * The whole number portion of the value (left of the decimal) counts - * the days since December 30th 1899. The fractional portion (right of - * the decimal) counts the time as a fraction of the day. For example, - * January 1st 1900 at noon would be 2.5, 2 because it's 2 days after - * December 30st 1899, and .5 because noon is half a day. February 1st - * 1900 at 3pm would be 33.625. This correctly treats the year 1900 as - * not a leap year. (Value: "SERIAL_NUMBER") - */ -@property(nonatomic, copy, nullable) NSString *responseDateTimeRenderOption; - -/** - * Determines how values in the response should be rendered. - * The default render option is ValueRenderOption.FORMATTED_VALUE. - * - * Likely values: - * @arg @c kGTLRSheets_BatchUpdateValuesRequest_ResponseValueRenderOption_FormattedValue - * Values will be calculated & formatted in the reply according to the - * cell's formatting. Formatting is based on the spreadsheet's locale, - * not the requesting user's locale. - * For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as - * currency, - * then `A2` would return `"$1.23"`. (Value: "FORMATTED_VALUE") - * @arg @c kGTLRSheets_BatchUpdateValuesRequest_ResponseValueRenderOption_Formula - * Values will not be calculated. The reply will include the formulas. - * For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as - * currency, - * then A2 would return `"=A1"`. (Value: "FORMULA") - * @arg @c kGTLRSheets_BatchUpdateValuesRequest_ResponseValueRenderOption_UnformattedValue - * Values will be calculated, but not formatted in the reply. - * For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as - * currency, - * then `A2` would return the number `1.23`. (Value: "UNFORMATTED_VALUE") - */ -@property(nonatomic, copy, nullable) NSString *responseValueRenderOption; - -/** - * How the input data should be interpreted. - * - * Likely values: - * @arg @c kGTLRSheets_BatchUpdateValuesRequest_ValueInputOption_InputValueOptionUnspecified - * Default input value. This value must not be used. (Value: - * "INPUT_VALUE_OPTION_UNSPECIFIED") - * @arg @c kGTLRSheets_BatchUpdateValuesRequest_ValueInputOption_Raw The - * values the user has entered will not be parsed and will be stored - * as-is. (Value: "RAW") - * @arg @c kGTLRSheets_BatchUpdateValuesRequest_ValueInputOption_UserEntered - * The values will be parsed as if the user typed them into the UI. - * Numbers will stay as numbers, but strings may be converted to numbers, - * dates, etc. following the same rules that are applied when entering - * text into a cell via the Google Sheets UI. (Value: "USER_ENTERED") - */ -@property(nonatomic, copy, nullable) NSString *valueInputOption; - -@end - - -/** - * The response when updating a range of values in a spreadsheet. - */ -@interface GTLRSheets_BatchUpdateValuesResponse : GTLRObject - -/** - * One UpdateValuesResponse per requested range, in the same order as - * the requests appeared. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_UpdateValuesResponse *> *responses; - -/** The spreadsheet the updates were applied to. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * The total number of cells updated. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *totalUpdatedCells; - -/** - * The total number of columns where at least one cell in the column was - * updated. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *totalUpdatedColumns; - -/** - * The total number of rows where at least one cell in the row was updated. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *totalUpdatedRows; - -/** - * The total number of sheets where at least one cell in the sheet was - * updated. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *totalUpdatedSheets; - -@end - - -/** - * A condition that can evaluate to true or false. - * BooleanConditions are used by conditional formatting, - * data validation, and the criteria in filters. - */ -@interface GTLRSheets_BooleanCondition : GTLRObject - -/** - * The type of condition. - * - * Likely values: - * @arg @c kGTLRSheets_BooleanCondition_Type_Blank The cell's value must be - * empty. - * Supported by conditional formatting and filters. - * Requires no ConditionValues. (Value: "BLANK") - * @arg @c kGTLRSheets_BooleanCondition_Type_Boolean The cell's value must be - * TRUE/FALSE or in the list of condition values. - * Supported by data validation. - * Renders as a cell checkbox. - * Supports zero, one or two ConditionValues. No - * values indicates the cell must be TRUE or FALSE, where TRUE renders as - * checked and FALSE renders as unchecked. One value indicates the cell - * will render as checked when it contains that value and unchecked when - * it - * is blank. Two values indicate that the cell will render as checked - * when - * it contains the first value and unchecked when it contains the second - * value. For example, ["Yes","No"] indicates that the cell will render a - * checked box when it has the value "Yes" and an unchecked box when it - * has - * the value "No". (Value: "BOOLEAN") - * @arg @c kGTLRSheets_BooleanCondition_Type_ConditionTypeUnspecified The - * default value, do not use. (Value: "CONDITION_TYPE_UNSPECIFIED") - * @arg @c kGTLRSheets_BooleanCondition_Type_CustomFormula The condition's - * formula must evaluate to true. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue. (Value: "CUSTOM_FORMULA") - * @arg @c kGTLRSheets_BooleanCondition_Type_DateAfter The cell's value must - * be after the date of the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue - * that may be a relative date. (Value: "DATE_AFTER") - * @arg @c kGTLRSheets_BooleanCondition_Type_DateBefore The cell's value must - * be before the date of the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue - * that may be a relative date. (Value: "DATE_BEFORE") - * @arg @c kGTLRSheets_BooleanCondition_Type_DateBetween The cell's value - * must be between the dates of the two condition values. - * Supported by data validation. - * Requires exactly two ConditionValues. (Value: "DATE_BETWEEN") - * @arg @c kGTLRSheets_BooleanCondition_Type_DateEq The cell's value must be - * the same date as the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue. (Value: "DATE_EQ") - * @arg @c kGTLRSheets_BooleanCondition_Type_DateIsValid The cell's value - * must be a date. - * Supported by data validation. - * Requires no ConditionValues. (Value: "DATE_IS_VALID") - * @arg @c kGTLRSheets_BooleanCondition_Type_DateNotBetween The cell's value - * must be outside the dates of the two condition values. - * Supported by data validation. - * Requires exactly two ConditionValues. (Value: "DATE_NOT_BETWEEN") - * @arg @c kGTLRSheets_BooleanCondition_Type_DateOnOrAfter The cell's value - * must be on or after the date of the condition's value. - * Supported by data validation. - * Requires a single ConditionValue - * that may be a relative date. (Value: "DATE_ON_OR_AFTER") - * @arg @c kGTLRSheets_BooleanCondition_Type_DateOnOrBefore The cell's value - * must be on or before the date of the condition's value. - * Supported by data validation. - * Requires a single ConditionValue - * that may be a relative date. (Value: "DATE_ON_OR_BEFORE") - * @arg @c kGTLRSheets_BooleanCondition_Type_NotBlank The cell's value must - * not be empty. - * Supported by conditional formatting and filters. - * Requires no ConditionValues. (Value: "NOT_BLANK") - * @arg @c kGTLRSheets_BooleanCondition_Type_NumberBetween The cell's value - * must be between the two condition values. - * Supported by data validation, conditional formatting and filters. - * Requires exactly two ConditionValues. (Value: "NUMBER_BETWEEN") - * @arg @c kGTLRSheets_BooleanCondition_Type_NumberEq The cell's value must - * be equal to the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue. (Value: "NUMBER_EQ") - * @arg @c kGTLRSheets_BooleanCondition_Type_NumberGreater The cell's value - * must be greater than the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue. (Value: "NUMBER_GREATER") - * @arg @c kGTLRSheets_BooleanCondition_Type_NumberGreaterThanEq The cell's - * value must be greater than or equal to the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue. (Value: "NUMBER_GREATER_THAN_EQ") - * @arg @c kGTLRSheets_BooleanCondition_Type_NumberLess The cell's value must - * be less than the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue. (Value: "NUMBER_LESS") - * @arg @c kGTLRSheets_BooleanCondition_Type_NumberLessThanEq The cell's - * value must be less than or equal to the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue. (Value: "NUMBER_LESS_THAN_EQ") - * @arg @c kGTLRSheets_BooleanCondition_Type_NumberNotBetween The cell's - * value must not be between the two condition values. - * Supported by data validation, conditional formatting and filters. - * Requires exactly two ConditionValues. (Value: "NUMBER_NOT_BETWEEN") - * @arg @c kGTLRSheets_BooleanCondition_Type_NumberNotEq The cell's value - * must be not equal to the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue. (Value: "NUMBER_NOT_EQ") - * @arg @c kGTLRSheets_BooleanCondition_Type_OneOfList The cell's value must - * be in the list of condition values. - * Supported by data validation. - * Supports any number of condition values, - * one per item in the list. - * Formulas are not supported in the values. (Value: "ONE_OF_LIST") - * @arg @c kGTLRSheets_BooleanCondition_Type_OneOfRange The cell's value must - * be listed in the grid in condition value's range. - * Supported by data validation. - * Requires a single ConditionValue, - * and the value must be a valid range in A1 notation. (Value: - * "ONE_OF_RANGE") - * @arg @c kGTLRSheets_BooleanCondition_Type_TextContains The cell's value - * must contain the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue. (Value: "TEXT_CONTAINS") - * @arg @c kGTLRSheets_BooleanCondition_Type_TextEndsWith The cell's value - * must end with the condition's value. - * Supported by conditional formatting and filters. - * Requires a single ConditionValue. (Value: "TEXT_ENDS_WITH") - * @arg @c kGTLRSheets_BooleanCondition_Type_TextEq The cell's value must be - * exactly the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue. (Value: "TEXT_EQ") - * @arg @c kGTLRSheets_BooleanCondition_Type_TextIsEmail The cell's value - * must be a valid email address. - * Supported by data validation. - * Requires no ConditionValues. (Value: "TEXT_IS_EMAIL") - * @arg @c kGTLRSheets_BooleanCondition_Type_TextIsUrl The cell's value must - * be a valid URL. - * Supported by data validation. - * Requires no ConditionValues. (Value: "TEXT_IS_URL") - * @arg @c kGTLRSheets_BooleanCondition_Type_TextNotContains The cell's value - * must not contain the condition's value. - * Supported by data validation, conditional formatting and filters. - * Requires a single ConditionValue. (Value: "TEXT_NOT_CONTAINS") - * @arg @c kGTLRSheets_BooleanCondition_Type_TextStartsWith The cell's value - * must start with the condition's value. - * Supported by conditional formatting and filters. - * Requires a single ConditionValue. (Value: "TEXT_STARTS_WITH") - */ -@property(nonatomic, copy, nullable) NSString *type; - -/** - * The values of the condition. The number of supported values depends - * on the condition type. Some support zero values, - * others one or two values, - * and ConditionType.ONE_OF_LIST supports an arbitrary number of values. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_ConditionValue *> *values; - -@end - - -/** - * A rule that may or may not match, depending on the condition. - */ -@interface GTLRSheets_BooleanRule : GTLRObject - -/** - * The condition of the rule. If the condition evaluates to true, - * the format is applied. - */ -@property(nonatomic, strong, nullable) GTLRSheets_BooleanCondition *condition; - -/** - * The format to apply. - * Conditional formatting can only apply a subset of formatting: - * bold, italic, - * strikethrough, - * foreground color & - * background color. - */ -@property(nonatomic, strong, nullable) GTLRSheets_CellFormat *format; - -@end - - -/** - * A border along a cell. - */ -@interface GTLRSheets_Border : GTLRObject - -/** The color of the border. */ -@property(nonatomic, strong, nullable) GTLRSheets_Color *color; - -/** - * The style of the border. - * - * Likely values: - * @arg @c kGTLRSheets_Border_Style_Dashed The border is dashed. (Value: - * "DASHED") - * @arg @c kGTLRSheets_Border_Style_Dotted The border is dotted. (Value: - * "DOTTED") - * @arg @c kGTLRSheets_Border_Style_Double The border is two solid lines. - * (Value: "DOUBLE") - * @arg @c kGTLRSheets_Border_Style_None No border. - * Used only when updating a border in order to erase it. (Value: "NONE") - * @arg @c kGTLRSheets_Border_Style_Solid The border is a thin solid line. - * (Value: "SOLID") - * @arg @c kGTLRSheets_Border_Style_SolidMedium The border is a medium solid - * line. (Value: "SOLID_MEDIUM") - * @arg @c kGTLRSheets_Border_Style_SolidThick The border is a thick solid - * line. (Value: "SOLID_THICK") - * @arg @c kGTLRSheets_Border_Style_StyleUnspecified The style is not - * specified. Do not use this. (Value: "STYLE_UNSPECIFIED") - */ -@property(nonatomic, copy, nullable) NSString *style; - -/** - * The width of the border, in pixels. - * Deprecated; the width is determined by the "style" field. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *width; - -@end - - -/** - * The borders of the cell. - */ -@interface GTLRSheets_Borders : GTLRObject - -/** The bottom border of the cell. */ -@property(nonatomic, strong, nullable) GTLRSheets_Border *bottom; - -/** The left border of the cell. */ -@property(nonatomic, strong, nullable) GTLRSheets_Border *left; - -/** The right border of the cell. */ -@property(nonatomic, strong, nullable) GTLRSheets_Border *right; - -/** The top border of the cell. */ -@property(nonatomic, strong, nullable) GTLRSheets_Border *top; - -@end - - -/** - * A <a href="/chart/interactive/docs/gallery/bubblechart">bubble chart</a>. - */ -@interface GTLRSheets_BubbleChartSpec : GTLRObject - -/** The bubble border color. */ -@property(nonatomic, strong, nullable) GTLRSheets_Color *bubbleBorderColor; - -/** The data containing the bubble labels. These do not need to be unique. */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartData *bubbleLabels; - -/** - * The max radius size of the bubbles, in pixels. - * If specified, the field must be a positive value. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *bubbleMaxRadiusSize; - -/** - * The minimum radius size of the bubbles, in pixels. - * If specific, the field must be a positive value. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *bubbleMinRadiusSize; - -/** - * The opacity of the bubbles between 0 and 1.0. - * 0 is fully transparent and 1 is fully opaque. - * - * Uses NSNumber of floatValue. - */ -@property(nonatomic, strong, nullable) NSNumber *bubbleOpacity; - -/** - * The data contianing the bubble sizes. Bubble sizes are used to draw - * the bubbles at different sizes relative to each other. - * If specified, group_ids must also be specified. This field is - * optional. - */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartData *bubbleSizes; - -/** - * The format of the text inside the bubbles. - * Underline and Strikethrough are not supported. - */ -@property(nonatomic, strong, nullable) GTLRSheets_TextFormat *bubbleTextStyle; - -/** - * The data containing the bubble x-values. These values locate the bubbles - * in the chart horizontally. - */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartData *domain; - -/** - * The data containing the bubble group IDs. All bubbles with the same group - * ID are drawn in the same color. If bubble_sizes is specified then - * this field must also be specified but may contain blank values. - * This field is optional. - */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartData *groupIds; - -/** - * Where the legend of the chart should be drawn. - * - * Likely values: - * @arg @c kGTLRSheets_BubbleChartSpec_LegendPosition_BottomLegend The legend - * is rendered on the bottom of the chart. (Value: "BOTTOM_LEGEND") - * @arg @c kGTLRSheets_BubbleChartSpec_LegendPosition_BubbleChartLegendPositionUnspecified - * Default value, do not use. (Value: - * "BUBBLE_CHART_LEGEND_POSITION_UNSPECIFIED") - * @arg @c kGTLRSheets_BubbleChartSpec_LegendPosition_InsideLegend The legend - * is rendered inside the chart area. (Value: "INSIDE_LEGEND") - * @arg @c kGTLRSheets_BubbleChartSpec_LegendPosition_LeftLegend The legend - * is rendered on the left of the chart. (Value: "LEFT_LEGEND") - * @arg @c kGTLRSheets_BubbleChartSpec_LegendPosition_NoLegend No legend is - * rendered. (Value: "NO_LEGEND") - * @arg @c kGTLRSheets_BubbleChartSpec_LegendPosition_RightLegend The legend - * is rendered on the right of the chart. (Value: "RIGHT_LEGEND") - * @arg @c kGTLRSheets_BubbleChartSpec_LegendPosition_TopLegend The legend is - * rendered on the top of the chart. (Value: "TOP_LEGEND") - */ -@property(nonatomic, copy, nullable) NSString *legendPosition; - -/** - * The data contianing the bubble y-values. These values locate the bubbles - * in the chart vertically. - */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartData *series; - -@end - - -/** - * A <a href="/chart/interactive/docs/gallery/candlestickchart">candlestick - * chart</a>. - */ -@interface GTLRSheets_CandlestickChartSpec : GTLRObject - -/** - * The Candlestick chart data. - * Only one CandlestickData is supported. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_CandlestickData *> *data; - -/** - * The domain data (horizontal axis) for the candlestick chart. String data - * will be treated as discrete labels, other data will be treated as - * continuous values. - */ -@property(nonatomic, strong, nullable) GTLRSheets_CandlestickDomain *domain; - -@end - - -/** - * The Candlestick chart data, each containing the low, open, close, and high - * values for a series. - */ -@interface GTLRSheets_CandlestickData : GTLRObject - -/** - * The range data (vertical axis) for the close/final value for each candle. - * This is the top of the candle body. If greater than the open value the - * candle will be filled. Otherwise the candle will be hollow. - */ -@property(nonatomic, strong, nullable) GTLRSheets_CandlestickSeries *closeSeries; - -/** - * The range data (vertical axis) for the high/maximum value for each - * candle. This is the top of the candle's center line. - */ -@property(nonatomic, strong, nullable) GTLRSheets_CandlestickSeries *highSeries; - -/** - * The range data (vertical axis) for the low/minimum value for each candle. - * This is the bottom of the candle's center line. - */ -@property(nonatomic, strong, nullable) GTLRSheets_CandlestickSeries *lowSeries; - -/** - * The range data (vertical axis) for the open/initial value for each - * candle. This is the bottom of the candle body. If less than the close - * value the candle will be filled. Otherwise the candle will be hollow. - */ -@property(nonatomic, strong, nullable) GTLRSheets_CandlestickSeries *openSeries; - -@end - - -/** - * The domain of a CandlestickChart. - */ -@interface GTLRSheets_CandlestickDomain : GTLRObject - -/** The data of the CandlestickDomain. */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartData *data; - -/** - * True to reverse the order of the domain values (horizontal axis). - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *reversed; - -@end - - -/** - * The series of a CandlestickData. - */ -@interface GTLRSheets_CandlestickSeries : GTLRObject - -/** The data of the CandlestickSeries. */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartData *data; - -@end - - -/** - * Data about a specific cell. - */ -@interface GTLRSheets_CellData : GTLRObject - -/** - * A data validation rule on the cell, if any. - * When writing, the new data validation rule will overwrite any prior rule. - */ -@property(nonatomic, strong, nullable) GTLRSheets_DataValidationRule *dataValidation; - -/** - * The effective format being used by the cell. - * This includes the results of applying any conditional formatting and, - * if the cell contains a formula, the computed number format. - * If the effective format is the default format, effective format will - * not be written. - * This field is read-only. - */ -@property(nonatomic, strong, nullable) GTLRSheets_CellFormat *effectiveFormat; - -/** - * The effective value of the cell. For cells with formulas, this is - * the calculated value. For cells with literals, this is - * the same as the user_entered_value. - * This field is read-only. - */ -@property(nonatomic, strong, nullable) GTLRSheets_ExtendedValue *effectiveValue; - -/** - * The formatted value of the cell. - * This is the value as it's shown to the user. - * This field is read-only. - */ -@property(nonatomic, copy, nullable) NSString *formattedValue; - -/** - * A hyperlink this cell points to, if any. - * This field is read-only. (To set it, use a `=HYPERLINK` formula - * in the userEnteredValue.formulaValue - * field.) - */ -@property(nonatomic, copy, nullable) NSString *hyperlink; - -/** Any note on the cell. */ -@property(nonatomic, copy, nullable) NSString *note; - -/** - * A pivot table anchored at this cell. The size of pivot table itself - * is computed dynamically based on its data, grouping, filters, values, - * etc. Only the top-left cell of the pivot table contains the pivot table - * definition. The other cells will contain the calculated values of the - * results of the pivot in their effective_value fields. - */ -@property(nonatomic, strong, nullable) GTLRSheets_PivotTable *pivotTable; - -/** - * Runs of rich text applied to subsections of the cell. Runs are only valid - * on user entered strings, not formulas, bools, or numbers. - * Runs start at specific indexes in the text and continue until the next - * run. Properties of a run will continue unless explicitly changed - * in a subsequent run (and properties of the first run will continue - * the properties of the cell unless explicitly changed). - * When writing, the new runs will overwrite any prior runs. When writing a - * new user_entered_value, previous runs are erased. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_TextFormatRun *> *textFormatRuns; - -/** - * The format the user entered for the cell. - * When writing, the new format will be merged with the existing format. - */ -@property(nonatomic, strong, nullable) GTLRSheets_CellFormat *userEnteredFormat; - -/** - * The value the user entered in the cell. e.g, `1234`, `'Hello'`, or `=NOW()` - * Note: Dates, Times and DateTimes are represented as doubles in - * serial number format. - */ -@property(nonatomic, strong, nullable) GTLRSheets_ExtendedValue *userEnteredValue; - -@end - - -/** - * The format of a cell. - */ -@interface GTLRSheets_CellFormat : GTLRObject - -/** The background color of the cell. */ -@property(nonatomic, strong, nullable) GTLRSheets_Color *backgroundColor; - -/** The borders of the cell. */ -@property(nonatomic, strong, nullable) GTLRSheets_Borders *borders; - -/** - * The horizontal alignment of the value in the cell. - * - * Likely values: - * @arg @c kGTLRSheets_CellFormat_HorizontalAlignment_Center The text is - * explicitly aligned to the center of the cell. (Value: "CENTER") - * @arg @c kGTLRSheets_CellFormat_HorizontalAlignment_HorizontalAlignUnspecified - * The horizontal alignment is not specified. Do not use this. (Value: - * "HORIZONTAL_ALIGN_UNSPECIFIED") - * @arg @c kGTLRSheets_CellFormat_HorizontalAlignment_Left The text is - * explicitly aligned to the left of the cell. (Value: "LEFT") - * @arg @c kGTLRSheets_CellFormat_HorizontalAlignment_Right The text is - * explicitly aligned to the right of the cell. (Value: "RIGHT") - */ -@property(nonatomic, copy, nullable) NSString *horizontalAlignment; - -/** - * How a hyperlink, if it exists, should be displayed in the cell. - * - * Likely values: - * @arg @c kGTLRSheets_CellFormat_HyperlinkDisplayType_HyperlinkDisplayTypeUnspecified - * The default value: the hyperlink is rendered. Do not use this. (Value: - * "HYPERLINK_DISPLAY_TYPE_UNSPECIFIED") - * @arg @c kGTLRSheets_CellFormat_HyperlinkDisplayType_Linked A hyperlink - * should be explicitly rendered. (Value: "LINKED") - * @arg @c kGTLRSheets_CellFormat_HyperlinkDisplayType_PlainText A hyperlink - * should not be rendered. (Value: "PLAIN_TEXT") - */ -@property(nonatomic, copy, nullable) NSString *hyperlinkDisplayType; - -/** - * A format describing how number values should be represented to the user. - */ -@property(nonatomic, strong, nullable) GTLRSheets_NumberFormat *numberFormat; - -/** The padding of the cell. */ -@property(nonatomic, strong, nullable) GTLRSheets_Padding *padding; - -/** - * The direction of the text in the cell. - * - * Likely values: - * @arg @c kGTLRSheets_CellFormat_TextDirection_LeftToRight The text - * direction of left-to-right was set by the user. (Value: - * "LEFT_TO_RIGHT") - * @arg @c kGTLRSheets_CellFormat_TextDirection_RightToLeft The text - * direction of right-to-left was set by the user. (Value: - * "RIGHT_TO_LEFT") - * @arg @c kGTLRSheets_CellFormat_TextDirection_TextDirectionUnspecified The - * text direction is not specified. Do not use this. (Value: - * "TEXT_DIRECTION_UNSPECIFIED") - */ -@property(nonatomic, copy, nullable) NSString *textDirection; - -/** The format of the text in the cell (unless overridden by a format run). */ -@property(nonatomic, strong, nullable) GTLRSheets_TextFormat *textFormat; - -/** The rotation applied to text in a cell */ -@property(nonatomic, strong, nullable) GTLRSheets_TextRotation *textRotation; - -/** - * The vertical alignment of the value in the cell. - * - * Likely values: - * @arg @c kGTLRSheets_CellFormat_VerticalAlignment_Bottom The text is - * explicitly aligned to the bottom of the cell. (Value: "BOTTOM") - * @arg @c kGTLRSheets_CellFormat_VerticalAlignment_Middle The text is - * explicitly aligned to the middle of the cell. (Value: "MIDDLE") - * @arg @c kGTLRSheets_CellFormat_VerticalAlignment_Top The text is - * explicitly aligned to the top of the cell. (Value: "TOP") - * @arg @c kGTLRSheets_CellFormat_VerticalAlignment_VerticalAlignUnspecified - * The vertical alignment is not specified. Do not use this. (Value: - * "VERTICAL_ALIGN_UNSPECIFIED") - */ -@property(nonatomic, copy, nullable) NSString *verticalAlignment; - -/** - * The wrap strategy for the value in the cell. - * - * Likely values: - * @arg @c kGTLRSheets_CellFormat_WrapStrategy_Clip Lines that are longer - * than the cell width will be clipped. - * The text will never wrap to the next line unless the user manually - * inserts a new line. - * Example: - * | First sentence. | - * | Manual newline t| <- Text is clipped - * | Next newline. | (Value: "CLIP") - * @arg @c kGTLRSheets_CellFormat_WrapStrategy_LegacyWrap This wrap strategy - * represents the old Google Sheets wrap strategy where - * words that are longer than a line are clipped rather than broken. This - * strategy is not supported on all platforms and is being phased out. - * Example: - * | Cell has a | - * | loooooooooo| <- Word is clipped. - * | word. | (Value: "LEGACY_WRAP") - * @arg @c kGTLRSheets_CellFormat_WrapStrategy_OverflowCell Lines that are - * longer than the cell width will be written in the next - * cell over, so long as that cell is empty. If the next cell over is - * non-empty, this behaves the same as CLIP. The text will never wrap - * to the next line unless the user manually inserts a new line. - * Example: - * | First sentence. | - * | Manual newline that is very long. <- Text continues into next cell - * | Next newline. | (Value: "OVERFLOW_CELL") - * @arg @c kGTLRSheets_CellFormat_WrapStrategy_Wrap Words that are longer - * than a line are wrapped at the character level - * rather than clipped. - * Example: - * | Cell has a | - * | loooooooooo| <- Word is broken. - * | ong word. | (Value: "WRAP") - * @arg @c kGTLRSheets_CellFormat_WrapStrategy_WrapStrategyUnspecified The - * default value, do not use. (Value: "WRAP_STRATEGY_UNSPECIFIED") - */ -@property(nonatomic, copy, nullable) NSString *wrapStrategy; - -@end - - -/** - * The data included in a domain or series. - */ -@interface GTLRSheets_ChartData : GTLRObject - -/** The source ranges of the data. */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartSourceRange *sourceRange; - -@end - - -/** - * Source ranges for a chart. - */ -@interface GTLRSheets_ChartSourceRange : GTLRObject - -/** - * The ranges of data for a series or domain. - * Exactly one dimension must have a length of 1, - * and all sources in the list must have the same dimension - * with length 1. - * The domain (if it exists) & all series must have the same number - * of source ranges. If using more than one source range, then the source - * range at a given offset must be in order and contiguous across the domain - * and series. - * For example, these are valid configurations: - * domain sources: A1:A5 - * series1 sources: B1:B5 - * series2 sources: D6:D10 - * domain sources: A1:A5, C10:C12 - * series1 sources: B1:B5, D10:D12 - * series2 sources: C1:C5, E10:E12 - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_GridRange *> *sources; - -@end - - -/** - * The specifications of a chart. - */ -@interface GTLRSheets_ChartSpec : GTLRObject - -/** - * The alternative text that describes the chart. This is often used - * for accessibility. - */ -@property(nonatomic, copy, nullable) NSString *altText; - -/** - * The background color of the entire chart. - * Not applicable to Org charts. - */ -@property(nonatomic, strong, nullable) GTLRSheets_Color *backgroundColor; - -/** - * A basic chart specification, can be one of many kinds of charts. - * See BasicChartType for the list of all - * charts this supports. - */ -@property(nonatomic, strong, nullable) GTLRSheets_BasicChartSpec *basicChart; - -/** A bubble chart specification. */ -@property(nonatomic, strong, nullable) GTLRSheets_BubbleChartSpec *bubbleChart; - -/** A candlestick chart specification. */ -@property(nonatomic, strong, nullable) GTLRSheets_CandlestickChartSpec *candlestickChart; - -/** - * The name of the font to use by default for all chart text (e.g. title, - * axis labels, legend). If a font is specified for a specific part of the - * chart it will override this font name. - */ -@property(nonatomic, copy, nullable) NSString *fontName; - -/** - * Determines how the charts will use hidden rows or columns. - * - * Likely values: - * @arg @c kGTLRSheets_ChartSpec_HiddenDimensionStrategy_ChartHiddenDimensionStrategyUnspecified - * Default value, do not use. (Value: - * "CHART_HIDDEN_DIMENSION_STRATEGY_UNSPECIFIED") - * @arg @c kGTLRSheets_ChartSpec_HiddenDimensionStrategy_ShowAll Charts will - * not skip any hidden rows or columns. (Value: "SHOW_ALL") - * @arg @c kGTLRSheets_ChartSpec_HiddenDimensionStrategy_SkipHiddenColumns - * Charts will skip hidden columns only. (Value: "SKIP_HIDDEN_COLUMNS") - * @arg @c kGTLRSheets_ChartSpec_HiddenDimensionStrategy_SkipHiddenRows - * Charts will skip hidden rows only. (Value: "SKIP_HIDDEN_ROWS") - * @arg @c kGTLRSheets_ChartSpec_HiddenDimensionStrategy_SkipHiddenRowsAndColumns - * Charts will skip hidden rows and columns. (Value: - * "SKIP_HIDDEN_ROWS_AND_COLUMNS") - */ -@property(nonatomic, copy, nullable) NSString *hiddenDimensionStrategy; - -/** A histogram chart specification. */ -@property(nonatomic, strong, nullable) GTLRSheets_HistogramChartSpec *histogramChart; - -/** - * True to make a chart fill the entire space in which it's rendered with - * minimum padding. False to use the default padding. - * (Not applicable to Geo and Org charts.) - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *maximized; - -/** An org chart specification. */ -@property(nonatomic, strong, nullable) GTLRSheets_OrgChartSpec *orgChart; - -/** A pie chart specification. */ -@property(nonatomic, strong, nullable) GTLRSheets_PieChartSpec *pieChart; - -/** The subtitle of the chart. */ -@property(nonatomic, copy, nullable) NSString *subtitle; - -/** - * The subtitle text format. - * Strikethrough and underline are not supported. - */ -@property(nonatomic, strong, nullable) GTLRSheets_TextFormat *subtitleTextFormat; - -/** - * The subtitle text position. - * This field is optional. - */ -@property(nonatomic, strong, nullable) GTLRSheets_TextPosition *subtitleTextPosition; - -/** The title of the chart. */ -@property(nonatomic, copy, nullable) NSString *title; - -/** - * The title text format. - * Strikethrough and underline are not supported. - */ -@property(nonatomic, strong, nullable) GTLRSheets_TextFormat *titleTextFormat; - -/** - * The title text position. - * This field is optional. - */ -@property(nonatomic, strong, nullable) GTLRSheets_TextPosition *titleTextPosition; - -/** A treemap chart specification. */ -@property(nonatomic, strong, nullable) GTLRSheets_TreemapChartSpec *treemapChart; - -/** A waterfall chart specification. */ -@property(nonatomic, strong, nullable) GTLRSheets_WaterfallChartSpec *waterfallChart; - -@end - - -/** - * Clears the basic filter, if any exists on the sheet. - */ -@interface GTLRSheets_ClearBasicFilterRequest : GTLRObject - -/** - * The sheet ID on which the basic filter should be cleared. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *sheetId; - -@end - - -/** - * The request for clearing a range of values in a spreadsheet. - */ -@interface GTLRSheets_ClearValuesRequest : GTLRObject -@end - - -/** - * The response when clearing a range of values in a spreadsheet. - */ -@interface GTLRSheets_ClearValuesResponse : GTLRObject - -/** - * The range (in A1 notation) that was cleared. - * (If the request was for an unbounded range or a ranger larger - * than the bounds of the sheet, this will be the actual range - * that was cleared, bounded to the sheet's limits.) - */ -@property(nonatomic, copy, nullable) NSString *clearedRange; - -/** The spreadsheet the updates were applied to. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -@end - - -/** - * Represents a color in the RGBA color space. This representation is designed - * for simplicity of conversion to/from color representations in various - * languages over compactness; for example, the fields of this representation - * can be trivially provided to the constructor of "java.awt.Color" in Java; it - * can also be trivially provided to UIColor's "+colorWithRed:green:blue:alpha" - * method in iOS; and, with just a little work, it can be easily formatted into - * a CSS "rgba()" string in JavaScript, as well. Here are some examples: - * Example (Java): - * import com.google.type.Color; - * // ... - * public static java.awt.Color fromProto(Color protocolor) { - * float alpha = protocolor.hasAlpha() - * ? protocolor.getAlpha().getValue() - * : 1.0; - * return new java.awt.Color( - * protocolor.getRed(), - * protocolor.getGreen(), - * protocolor.getBlue(), - * alpha); - * } - * public static Color toProto(java.awt.Color color) { - * float red = (float) color.getRed(); - * float green = (float) color.getGreen(); - * float blue = (float) color.getBlue(); - * float denominator = 255.0; - * Color.Builder resultBuilder = - * Color - * .newBuilder() - * .setRed(red / denominator) - * .setGreen(green / denominator) - * .setBlue(blue / denominator); - * int alpha = color.getAlpha(); - * if (alpha != 255) { - * result.setAlpha( - * FloatValue - * .newBuilder() - * .setValue(((float) alpha) / denominator) - * .build()); - * } - * return resultBuilder.build(); - * } - * // ... - * Example (iOS / Obj-C): - * // ... - * static UIColor* fromProto(Color* protocolor) { - * float red = [protocolor red]; - * float green = [protocolor green]; - * float blue = [protocolor blue]; - * FloatValue* alpha_wrapper = [protocolor alpha]; - * float alpha = 1.0; - * if (alpha_wrapper != nil) { - * alpha = [alpha_wrapper value]; - * } - * return [UIColor colorWithRed:red green:green blue:blue alpha:alpha]; - * } - * static Color* toProto(UIColor* color) { - * CGFloat red, green, blue, alpha; - * if (![color getRed:&red green:&green blue:&blue alpha:&alpha]) { - * return nil; - * } - * Color* result = [[Color alloc] init]; - * [result setRed:red]; - * [result setGreen:green]; - * [result setBlue:blue]; - * if (alpha <= 0.9999) { - * [result setAlpha:floatWrapperWithValue(alpha)]; - * } - * [result autorelease]; - * return result; - * } - * // ... - * Example (JavaScript): - * // ... - * var protoToCssColor = function(rgb_color) { - * var redFrac = rgb_color.red || 0.0; - * var greenFrac = rgb_color.green || 0.0; - * var blueFrac = rgb_color.blue || 0.0; - * var red = Math.floor(redFrac * 255); - * var green = Math.floor(greenFrac * 255); - * var blue = Math.floor(blueFrac * 255); - * if (!('alpha' in rgb_color)) { - * return rgbToCssColor_(red, green, blue); - * } - * var alphaFrac = rgb_color.alpha.value || 0.0; - * var rgbParams = [red, green, blue].join(','); - * return ['rgba(', rgbParams, ',', alphaFrac, ')'].join(''); - * }; - * var rgbToCssColor_ = function(red, green, blue) { - * var rgbNumber = new Number((red << 16) | (green << 8) | blue); - * var hexString = rgbNumber.toString(16); - * var missingZeros = 6 - hexString.length; - * var resultBuilder = ['#']; - * for (var i = 0; i < missingZeros; i++) { - * resultBuilder.push('0'); - * } - * resultBuilder.push(hexString); - * return resultBuilder.join(''); - * }; - * // ... - */ -@interface GTLRSheets_Color : GTLRObject - -/** - * The fraction of this color that should be applied to the pixel. That is, - * the final pixel color is defined by the equation: - * pixel color = alpha * (this color) + (1.0 - alpha) * (background color) - * This means that a value of 1.0 corresponds to a solid color, whereas - * a value of 0.0 corresponds to a completely transparent color. This - * uses a wrapper message rather than a simple float scalar so that it is - * possible to distinguish between a default value and the value being unset. - * If omitted, this color object is to be rendered as a solid color - * (as if the alpha value had been explicitly given with a value of 1.0). - * - * Uses NSNumber of floatValue. - */ -@property(nonatomic, strong, nullable) NSNumber *alpha; - -/** - * The amount of blue in the color as a value in the interval [0, 1]. - * - * Uses NSNumber of floatValue. - */ -@property(nonatomic, strong, nullable) NSNumber *blue; - -/** - * The amount of green in the color as a value in the interval [0, 1]. - * - * Uses NSNumber of floatValue. - */ -@property(nonatomic, strong, nullable) NSNumber *green; - -/** - * The amount of red in the color as a value in the interval [0, 1]. - * - * Uses NSNumber of floatValue. - */ -@property(nonatomic, strong, nullable) NSNumber *red; - -@end - - -/** - * A rule describing a conditional format. - */ -@interface GTLRSheets_ConditionalFormatRule : GTLRObject - -/** The formatting is either "on" or "off" according to the rule. */ -@property(nonatomic, strong, nullable) GTLRSheets_BooleanRule *booleanRule; - -/** The formatting will vary based on the gradients in the rule. */ -@property(nonatomic, strong, nullable) GTLRSheets_GradientRule *gradientRule; - -/** - * The ranges that are formatted if the condition is true. - * All the ranges must be on the same grid. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_GridRange *> *ranges; - -@end - - -/** - * The value of the condition. - */ -@interface GTLRSheets_ConditionValue : GTLRObject - -/** - * A relative date (based on the current date). - * Valid only if the type is - * DATE_BEFORE, - * DATE_AFTER, - * DATE_ON_OR_BEFORE or - * DATE_ON_OR_AFTER. - * Relative dates are not supported in data validation. - * They are supported only in conditional formatting and - * conditional filters. - * - * Likely values: - * @arg @c kGTLRSheets_ConditionValue_RelativeDate_PastMonth The value is one - * month before today. (Value: "PAST_MONTH") - * @arg @c kGTLRSheets_ConditionValue_RelativeDate_PastWeek The value is one - * week before today. (Value: "PAST_WEEK") - * @arg @c kGTLRSheets_ConditionValue_RelativeDate_PastYear The value is one - * year before today. (Value: "PAST_YEAR") - * @arg @c kGTLRSheets_ConditionValue_RelativeDate_RelativeDateUnspecified - * Default value, do not use. (Value: "RELATIVE_DATE_UNSPECIFIED") - * @arg @c kGTLRSheets_ConditionValue_RelativeDate_Today The value is today. - * (Value: "TODAY") - * @arg @c kGTLRSheets_ConditionValue_RelativeDate_Tomorrow The value is - * tomorrow. (Value: "TOMORROW") - * @arg @c kGTLRSheets_ConditionValue_RelativeDate_Yesterday The value is - * yesterday. (Value: "YESTERDAY") - */ -@property(nonatomic, copy, nullable) NSString *relativeDate; - -/** - * A value the condition is based on. - * The value is parsed as if the user typed into a cell. - * Formulas are supported (and must begin with an `=` or a '+'). - */ -@property(nonatomic, copy, nullable) NSString *userEnteredValue; - -@end - - -/** - * Copies data from the source to the destination. - */ -@interface GTLRSheets_CopyPasteRequest : GTLRObject - -/** - * The location to paste to. If the range covers a span that's - * a multiple of the source's height or width, then the - * data will be repeated to fill in the destination range. - * If the range is smaller than the source range, the entire - * source data will still be copied (beyond the end of the destination range). - */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *destination; - -/** - * How that data should be oriented when pasting. - * - * Likely values: - * @arg @c kGTLRSheets_CopyPasteRequest_PasteOrientation_Normal Paste - * normally. (Value: "NORMAL") - * @arg @c kGTLRSheets_CopyPasteRequest_PasteOrientation_Transpose Paste - * transposed, where all rows become columns and vice versa. (Value: - * "TRANSPOSE") - */ -@property(nonatomic, copy, nullable) NSString *pasteOrientation; - -/** - * What kind of data to paste. - * - * Likely values: - * @arg @c kGTLRSheets_CopyPasteRequest_PasteType_PasteConditionalFormatting - * Paste the conditional formatting rules only. (Value: - * "PASTE_CONDITIONAL_FORMATTING") - * @arg @c kGTLRSheets_CopyPasteRequest_PasteType_PasteDataValidation Paste - * the data validation only. (Value: "PASTE_DATA_VALIDATION") - * @arg @c kGTLRSheets_CopyPasteRequest_PasteType_PasteFormat Paste the - * format and data validation only. (Value: "PASTE_FORMAT") - * @arg @c kGTLRSheets_CopyPasteRequest_PasteType_PasteFormula Paste the - * formulas only. (Value: "PASTE_FORMULA") - * @arg @c kGTLRSheets_CopyPasteRequest_PasteType_PasteNoBorders Like - * PASTE_NORMAL but without borders. (Value: "PASTE_NO_BORDERS") - * @arg @c kGTLRSheets_CopyPasteRequest_PasteType_PasteNormal Paste values, - * formulas, formats, and merges. (Value: "PASTE_NORMAL") - * @arg @c kGTLRSheets_CopyPasteRequest_PasteType_PasteValues Paste the - * values ONLY without formats, formulas, or merges. (Value: - * "PASTE_VALUES") - */ -@property(nonatomic, copy, nullable) NSString *pasteType; - -/** The source range to copy. */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *source; - -@end - - -/** - * The request to copy a sheet across spreadsheets. - */ -@interface GTLRSheets_CopySheetToAnotherSpreadsheetRequest : GTLRObject - -/** The ID of the spreadsheet to copy the sheet to. */ -@property(nonatomic, copy, nullable) NSString *destinationSpreadsheetId; - -@end - - -/** - * A request to create developer metadata. - */ -@interface GTLRSheets_CreateDeveloperMetadataRequest : GTLRObject - -/** The developer metadata to create. */ -@property(nonatomic, strong, nullable) GTLRSheets_DeveloperMetadata *developerMetadata; - -@end - - -/** - * The response from creating developer metadata. - */ -@interface GTLRSheets_CreateDeveloperMetadataResponse : GTLRObject - -/** The developer metadata that was created. */ -@property(nonatomic, strong, nullable) GTLRSheets_DeveloperMetadata *developerMetadata; - -@end - - -/** - * Moves data from the source to the destination. - */ -@interface GTLRSheets_CutPasteRequest : GTLRObject - -/** The top-left coordinate where the data should be pasted. */ -@property(nonatomic, strong, nullable) GTLRSheets_GridCoordinate *destination; - -/** - * What kind of data to paste. All the source data will be cut, regardless - * of what is pasted. - * - * Likely values: - * @arg @c kGTLRSheets_CutPasteRequest_PasteType_PasteConditionalFormatting - * Paste the conditional formatting rules only. (Value: - * "PASTE_CONDITIONAL_FORMATTING") - * @arg @c kGTLRSheets_CutPasteRequest_PasteType_PasteDataValidation Paste - * the data validation only. (Value: "PASTE_DATA_VALIDATION") - * @arg @c kGTLRSheets_CutPasteRequest_PasteType_PasteFormat Paste the format - * and data validation only. (Value: "PASTE_FORMAT") - * @arg @c kGTLRSheets_CutPasteRequest_PasteType_PasteFormula Paste the - * formulas only. (Value: "PASTE_FORMULA") - * @arg @c kGTLRSheets_CutPasteRequest_PasteType_PasteNoBorders Like - * PASTE_NORMAL but without borders. (Value: "PASTE_NO_BORDERS") - * @arg @c kGTLRSheets_CutPasteRequest_PasteType_PasteNormal Paste values, - * formulas, formats, and merges. (Value: "PASTE_NORMAL") - * @arg @c kGTLRSheets_CutPasteRequest_PasteType_PasteValues Paste the values - * ONLY without formats, formulas, or merges. (Value: "PASTE_VALUES") - */ -@property(nonatomic, copy, nullable) NSString *pasteType; - -/** The source data to cut. */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *source; - -@end - - -/** - * Filter that describes what data should be selected or returned from a - * request. - */ -@interface GTLRSheets_DataFilter : GTLRObject - -/** Selects data that matches the specified A1 range. */ -@property(nonatomic, copy, nullable) NSString *a1Range; - -/** - * Selects data associated with the developer metadata matching the criteria - * described by this DeveloperMetadataLookup. - */ -@property(nonatomic, strong, nullable) GTLRSheets_DeveloperMetadataLookup *developerMetadataLookup; - -/** Selects data that matches the range described by the GridRange. */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *gridRange; - -@end - - -/** - * A range of values whose location is specified by a DataFilter. - */ -@interface GTLRSheets_DataFilterValueRange : GTLRObject - -/** - * The data filter describing the location of the values in the spreadsheet. - */ -@property(nonatomic, strong, nullable) GTLRSheets_DataFilter *dataFilter; - -/** - * The major dimension of the values. - * - * Likely values: - * @arg @c kGTLRSheets_DataFilterValueRange_MajorDimension_Columns Operates - * on the columns of a sheet. (Value: "COLUMNS") - * @arg @c kGTLRSheets_DataFilterValueRange_MajorDimension_DimensionUnspecified - * The default value, do not use. (Value: "DIMENSION_UNSPECIFIED") - * @arg @c kGTLRSheets_DataFilterValueRange_MajorDimension_Rows Operates on - * the rows of a sheet. (Value: "ROWS") - */ -@property(nonatomic, copy, nullable) NSString *majorDimension; - -/** - * The data to be written. If the provided values exceed any of the ranges - * matched by the data filter then the request will fail. If the provided - * values are less than the matched ranges only the specified values will be - * written, existing values in the matched ranges will remain unaffected. - * - * Can be any valid JSON type. - */ -@property(nonatomic, strong, nullable) NSArray<NSArray *> *values; - -@end - - -/** - * A data validation rule. - */ -@interface GTLRSheets_DataValidationRule : GTLRObject - -/** The condition that data in the cell must match. */ -@property(nonatomic, strong, nullable) GTLRSheets_BooleanCondition *condition; - -/** A message to show the user when adding data to the cell. */ -@property(nonatomic, copy, nullable) NSString *inputMessage; - -/** - * True if the UI should be customized based on the kind of condition. - * If true, "List" conditions will show a dropdown. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *showCustomUi; - -/** - * True if invalid data should be rejected. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *strict; - -@end - - -/** - * Allows you to organize the date-time values in a source data column into - * buckets based on selected parts of their date or time values. For example, - * consider a pivot table showing sales transactions by date: - * +----------+--------------+ - * | Date | SUM of Sales | - * +----------+--------------+ - * | 1/1/2017 | $621.14 | - * | 2/3/2017 | $708.84 | - * | 5/8/2017 | $326.84 | - * ... - * +----------+--------------+ - * Applying a date-time group rule with a DateTimeRuleType of YEAR_MONTH - * results in the following pivot table. - * +--------------+--------------+ - * | Grouped Date | SUM of Sales | - * +--------------+--------------+ - * | 2017-Jan | $53,731.78 | - * | 2017-Feb | $83,475.32 | - * | 2017-Mar | $94,385.05 | - * ... - * +--------------+--------------+ - */ -@interface GTLRSheets_DateTimeRule : GTLRObject - -/** - * The type of date-time grouping to apply. - * - * Likely values: - * @arg @c kGTLRSheets_DateTimeRule_Type_DateTimeRuleTypeUnspecified The - * default type, do not use. (Value: "DATE_TIME_RULE_TYPE_UNSPECIFIED") - * @arg @c kGTLRSheets_DateTimeRule_Type_DayMonth Group dates by day and - * month, for example 22-Nov. The month is - * translated based on the spreadsheet locale. (Value: "DAY_MONTH") - * @arg @c kGTLRSheets_DateTimeRule_Type_DayOfMonth Group dates by day of - * month, from 1 to 31. (Value: "DAY_OF_MONTH") - * @arg @c kGTLRSheets_DateTimeRule_Type_DayOfWeek Group dates by day of - * week, for example Sunday. The days of the week will - * be translated based on the spreadsheet locale. (Value: "DAY_OF_WEEK") - * @arg @c kGTLRSheets_DateTimeRule_Type_DayOfYear Group dates by day of - * year, from 1 to 366. Note that dates after Feb. 29 - * fall in different buckets in leap years than in non-leap years. - * (Value: "DAY_OF_YEAR") - * @arg @c kGTLRSheets_DateTimeRule_Type_Hour Group dates by hour using a - * 24-hour system, from 0 to 23. (Value: "HOUR") - * @arg @c kGTLRSheets_DateTimeRule_Type_HourMinute Group dates by hour and - * minute using a 24-hour system, for example 19:45. (Value: - * "HOUR_MINUTE") - * @arg @c kGTLRSheets_DateTimeRule_Type_HourMinuteAmpm Group dates by hour - * and minute using a 12-hour system, for example 7:45 - * PM. The AM/PM designation is translated based on the spreadsheet - * locale. (Value: "HOUR_MINUTE_AMPM") - * @arg @c kGTLRSheets_DateTimeRule_Type_Minute Group dates by minute, from 0 - * to 59. (Value: "MINUTE") - * @arg @c kGTLRSheets_DateTimeRule_Type_Month Group dates by month, for - * example Nov. The month is translated based - * on the spreadsheet locale. (Value: "MONTH") - * @arg @c kGTLRSheets_DateTimeRule_Type_Quarter Group dates by quarter, for - * example Q1 (which represents Jan-Mar). (Value: "QUARTER") - * @arg @c kGTLRSheets_DateTimeRule_Type_Second Group dates by second, from 0 - * to 59. (Value: "SECOND") - * @arg @c kGTLRSheets_DateTimeRule_Type_Year Group dates by year, for - * example 2008. (Value: "YEAR") - * @arg @c kGTLRSheets_DateTimeRule_Type_YearMonth Group dates by year and - * month, for example 2008-Nov. The month is - * translated based on the spreadsheet locale. (Value: "YEAR_MONTH") - * @arg @c kGTLRSheets_DateTimeRule_Type_YearMonthDay Group dates by year, - * month, and day, for example 2008-11-22. (Value: "YEAR_MONTH_DAY") - * @arg @c kGTLRSheets_DateTimeRule_Type_YearQuarter Group dates by year and - * quarter, for example 2008 Q4. (Value: "YEAR_QUARTER") - */ -@property(nonatomic, copy, nullable) NSString *type; - -@end - - -/** - * Removes the banded range with the given ID from the spreadsheet. - */ -@interface GTLRSheets_DeleteBandingRequest : GTLRObject - -/** - * The ID of the banded range to delete. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *bandedRangeId; - -@end - - -/** - * Deletes a conditional format rule at the given index. - * All subsequent rules' indexes are decremented. - */ -@interface GTLRSheets_DeleteConditionalFormatRuleRequest : GTLRObject - -/** - * The zero-based index of the rule to be deleted. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *index; - -/** - * The sheet the rule is being deleted from. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *sheetId; - -@end - - -/** - * The result of deleting a conditional format rule. - */ -@interface GTLRSheets_DeleteConditionalFormatRuleResponse : GTLRObject - -/** The rule that was deleted. */ -@property(nonatomic, strong, nullable) GTLRSheets_ConditionalFormatRule *rule; - -@end - - -/** - * A request to delete developer metadata. - */ -@interface GTLRSheets_DeleteDeveloperMetadataRequest : GTLRObject - -/** - * The data filter describing the criteria used to select which developer - * metadata entry to delete. - */ -@property(nonatomic, strong, nullable) GTLRSheets_DataFilter *dataFilter; - -@end - - -/** - * The response from deleting developer metadata. - */ -@interface GTLRSheets_DeleteDeveloperMetadataResponse : GTLRObject - -/** The metadata that was deleted. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_DeveloperMetadata *> *deletedDeveloperMetadata; - -@end - - -/** - * Deletes a group over the specified range by decrementing the depth of the - * dimensions in the range. - * For example, assume the sheet has a depth-1 group over B:E and a depth-2 - * group over C:D. Deleting a group over D:E leaves the sheet with a - * depth-1 group over B:D and a depth-2 group over C:C. - */ -@interface GTLRSheets_DeleteDimensionGroupRequest : GTLRObject - -/** The range of the group to be deleted. */ -@property(nonatomic, strong, nullable) GTLRSheets_DimensionRange *range; - -@end - - -/** - * The result of deleting a group. - */ -@interface GTLRSheets_DeleteDimensionGroupResponse : GTLRObject - -/** All groups of a dimension after deleting a group from that dimension. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_DimensionGroup *> *dimensionGroups; - -@end - - -/** - * Deletes the dimensions from the sheet. - */ -@interface GTLRSheets_DeleteDimensionRequest : GTLRObject - -/** The dimensions to delete from the sheet. */ -@property(nonatomic, strong, nullable) GTLRSheets_DimensionRange *range; - -@end - - -/** - * Deletes the embedded object with the given ID. - */ -@interface GTLRSheets_DeleteEmbeddedObjectRequest : GTLRObject - -/** - * The ID of the embedded object to delete. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *objectId; - -@end - - -/** - * Deletes a particular filter view. - */ -@interface GTLRSheets_DeleteFilterViewRequest : GTLRObject - -/** - * The ID of the filter to delete. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *filterId; - -@end - - -/** - * Removes the named range with the given ID from the spreadsheet. - */ -@interface GTLRSheets_DeleteNamedRangeRequest : GTLRObject - -/** The ID of the named range to delete. */ -@property(nonatomic, copy, nullable) NSString *namedRangeId; - -@end - - -/** - * Deletes the protected range with the given ID. - */ -@interface GTLRSheets_DeleteProtectedRangeRequest : GTLRObject - -/** - * The ID of the protected range to delete. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *protectedRangeId; - -@end - - -/** - * Deletes a range of cells, shifting other cells into the deleted area. - */ -@interface GTLRSheets_DeleteRangeRequest : GTLRObject - -/** The range of cells to delete. */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *range; - -/** - * The dimension from which deleted cells will be replaced with. - * If ROWS, existing cells will be shifted upward to - * replace the deleted cells. If COLUMNS, existing cells - * will be shifted left to replace the deleted cells. - * - * Likely values: - * @arg @c kGTLRSheets_DeleteRangeRequest_ShiftDimension_Columns Operates on - * the columns of a sheet. (Value: "COLUMNS") - * @arg @c kGTLRSheets_DeleteRangeRequest_ShiftDimension_DimensionUnspecified - * The default value, do not use. (Value: "DIMENSION_UNSPECIFIED") - * @arg @c kGTLRSheets_DeleteRangeRequest_ShiftDimension_Rows Operates on the - * rows of a sheet. (Value: "ROWS") - */ -@property(nonatomic, copy, nullable) NSString *shiftDimension; - -@end - - -/** - * Deletes the requested sheet. - */ -@interface GTLRSheets_DeleteSheetRequest : GTLRObject - -/** - * The ID of the sheet to delete. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *sheetId; - -@end - - -/** - * Developer metadata associated with a location or object in a spreadsheet. - * Developer metadata may be used to associate arbitrary data with various - * parts of a spreadsheet and will remain associated at those locations as they - * move around and the spreadsheet is edited. For example, if developer - * metadata is associated with row 5 and another row is then subsequently - * inserted above row 5, that original metadata will still be associated with - * the row it was first associated with (what is now row 6). If the associated - * object is deleted its metadata is deleted too. - */ -@interface GTLRSheets_DeveloperMetadata : GTLRObject - -/** The location where the metadata is associated. */ -@property(nonatomic, strong, nullable) GTLRSheets_DeveloperMetadataLocation *location; - -/** - * The spreadsheet-scoped unique ID that identifies the metadata. IDs may be - * specified when metadata is created, otherwise one will be randomly - * generated and assigned. Must be positive. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *metadataId; - -/** - * The metadata key. There may be multiple metadata in a spreadsheet with the - * same key. Developer metadata must always have a key specified. - */ -@property(nonatomic, copy, nullable) NSString *metadataKey; - -/** Data associated with the metadata's key. */ -@property(nonatomic, copy, nullable) NSString *metadataValue; - -/** - * The metadata visibility. Developer metadata must always have a visibility - * specified. - * - * Likely values: - * @arg @c kGTLRSheets_DeveloperMetadata_Visibility_DeveloperMetadataVisibilityUnspecified - * Default value. (Value: "DEVELOPER_METADATA_VISIBILITY_UNSPECIFIED") - * @arg @c kGTLRSheets_DeveloperMetadata_Visibility_Document Document-visible - * metadata is accessible from any developer project with - * access to the document. (Value: "DOCUMENT") - * @arg @c kGTLRSheets_DeveloperMetadata_Visibility_Project Project-visible - * metadata is only visible to and accessible by the developer - * project that created the metadata. (Value: "PROJECT") - */ -@property(nonatomic, copy, nullable) NSString *visibility; - -@end - - -/** - * A location where metadata may be associated in a spreadsheet. - */ -@interface GTLRSheets_DeveloperMetadataLocation : GTLRObject - -/** - * Represents the row or column when metadata is associated with - * a dimension. The specified DimensionRange must represent a single row - * or column; it cannot be unbounded or span multiple rows or columns. - */ -@property(nonatomic, strong, nullable) GTLRSheets_DimensionRange *dimensionRange; - -/** - * The type of location this object represents. This field is read-only. - * - * Likely values: - * @arg @c kGTLRSheets_DeveloperMetadataLocation_LocationType_Column - * Developer metadata associated on an entire column dimension. (Value: - * "COLUMN") - * @arg @c kGTLRSheets_DeveloperMetadataLocation_LocationType_DeveloperMetadataLocationTypeUnspecified - * Default value. (Value: "DEVELOPER_METADATA_LOCATION_TYPE_UNSPECIFIED") - * @arg @c kGTLRSheets_DeveloperMetadataLocation_LocationType_Row Developer - * metadata associated on an entire row dimension. (Value: "ROW") - * @arg @c kGTLRSheets_DeveloperMetadataLocation_LocationType_Sheet Developer - * metadata associated on an entire sheet. (Value: "SHEET") - * @arg @c kGTLRSheets_DeveloperMetadataLocation_LocationType_Spreadsheet - * Developer metadata associated on the entire spreadsheet. (Value: - * "SPREADSHEET") - */ -@property(nonatomic, copy, nullable) NSString *locationType; - -/** - * The ID of the sheet when metadata is associated with an entire sheet. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *sheetId; - -/** - * True when metadata is associated with an entire spreadsheet. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *spreadsheet; - -@end - - -/** - * Selects DeveloperMetadata that matches all of the specified fields. For - * example, if only a metadata ID is specified this considers the - * DeveloperMetadata with that particular unique ID. If a metadata key is - * specified, this considers all developer metadata with that key. If a - * key, visibility, and location type are all specified, this considers all - * developer metadata with that key and visibility that are associated with a - * location of that type. In general, this - * selects all DeveloperMetadata that matches the intersection of all the - * specified fields; any field or combination of fields may be specified. - */ -@interface GTLRSheets_DeveloperMetadataLookup : GTLRObject - -/** - * Determines how this lookup matches the location. If this field is - * specified as EXACT, only developer metadata associated on the exact - * location specified is matched. If this field is specified to INTERSECTING, - * developer metadata associated on intersecting locations is also - * matched. If left unspecified, this field assumes a default value of - * INTERSECTING. - * If this field is specified, a metadataLocation - * must also be specified. - * - * Likely values: - * @arg @c kGTLRSheets_DeveloperMetadataLookup_LocationMatchingStrategy_DeveloperMetadataLocationMatchingStrategyUnspecified - * Default value. This value must not be used. (Value: - * "DEVELOPER_METADATA_LOCATION_MATCHING_STRATEGY_UNSPECIFIED") - * @arg @c kGTLRSheets_DeveloperMetadataLookup_LocationMatchingStrategy_ExactLocation - * Indicates that a specified location should be matched exactly. For - * example, if row three were specified as a location this matching - * strategy - * would only match developer metadata also associated on row three. - * Metadata - * associated on other locations would not be considered. (Value: - * "EXACT_LOCATION") - * @arg @c kGTLRSheets_DeveloperMetadataLookup_LocationMatchingStrategy_IntersectingLocation - * Indicates that a specified location should match that exact location - * as - * well as any intersecting locations. For example, if row three were - * specified as a location this matching strategy would match developer - * metadata associated on row three as well as metadata associated on - * locations that intersect row three. If, for instance, there was - * developer - * metadata associated on column B, this matching strategy would also - * match - * that location because column B intersects row three. (Value: - * "INTERSECTING_LOCATION") - */ -@property(nonatomic, copy, nullable) NSString *locationMatchingStrategy; - -/** - * Limits the selected developer metadata to those entries which are - * associated with locations of the specified type. For example, when this - * field is specified as ROW this lookup - * only considers developer metadata associated on rows. If the field is left - * unspecified, all location types are considered. This field cannot be - * specified as SPREADSHEET when - * the locationMatchingStrategy - * is specified as INTERSECTING or when the - * metadataLocation is specified as a - * non-spreadsheet location: spreadsheet metadata cannot intersect any other - * developer metadata location. This field also must be left unspecified when - * the locationMatchingStrategy - * is specified as EXACT. - * - * Likely values: - * @arg @c kGTLRSheets_DeveloperMetadataLookup_LocationType_Column Developer - * metadata associated on an entire column dimension. (Value: "COLUMN") - * @arg @c kGTLRSheets_DeveloperMetadataLookup_LocationType_DeveloperMetadataLocationTypeUnspecified - * Default value. (Value: "DEVELOPER_METADATA_LOCATION_TYPE_UNSPECIFIED") - * @arg @c kGTLRSheets_DeveloperMetadataLookup_LocationType_Row Developer - * metadata associated on an entire row dimension. (Value: "ROW") - * @arg @c kGTLRSheets_DeveloperMetadataLookup_LocationType_Sheet Developer - * metadata associated on an entire sheet. (Value: "SHEET") - * @arg @c kGTLRSheets_DeveloperMetadataLookup_LocationType_Spreadsheet - * Developer metadata associated on the entire spreadsheet. (Value: - * "SPREADSHEET") - */ -@property(nonatomic, copy, nullable) NSString *locationType; - -/** - * Limits the selected developer metadata to that which has a matching - * DeveloperMetadata.metadata_id. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *metadataId; - -/** - * Limits the selected developer metadata to that which has a matching - * DeveloperMetadata.metadata_key. - */ -@property(nonatomic, copy, nullable) NSString *metadataKey; - -/** - * Limits the selected developer metadata to those entries associated with - * the specified location. This field either matches exact locations or all - * intersecting locations according the specified - * locationMatchingStrategy. - */ -@property(nonatomic, strong, nullable) GTLRSheets_DeveloperMetadataLocation *metadataLocation; - -/** - * Limits the selected developer metadata to that which has a matching - * DeveloperMetadata.metadata_value. - */ -@property(nonatomic, copy, nullable) NSString *metadataValue; - -/** - * Limits the selected developer metadata to that which has a matching - * DeveloperMetadata.visibility. If left unspecified, all developer - * metadata visibile to the requesting project is considered. - * - * Likely values: - * @arg @c kGTLRSheets_DeveloperMetadataLookup_Visibility_DeveloperMetadataVisibilityUnspecified - * Default value. (Value: "DEVELOPER_METADATA_VISIBILITY_UNSPECIFIED") - * @arg @c kGTLRSheets_DeveloperMetadataLookup_Visibility_Document - * Document-visible metadata is accessible from any developer project - * with - * access to the document. (Value: "DOCUMENT") - * @arg @c kGTLRSheets_DeveloperMetadataLookup_Visibility_Project - * Project-visible metadata is only visible to and accessible by the - * developer - * project that created the metadata. (Value: "PROJECT") - */ -@property(nonatomic, copy, nullable) NSString *visibility; - -@end - - -/** - * A group over an interval of rows or columns on a sheet, which can contain or - * be contained within other groups. A group can be collapsed or expanded as a - * unit on the sheet. - */ -@interface GTLRSheets_DimensionGroup : GTLRObject - -/** - * This field is true if this group is collapsed. A collapsed group remains - * collapsed if an overlapping group at a shallower depth is expanded. - * A true value does not imply that all dimensions within the group are - * hidden, since a dimension's visibility can change independently from this - * group property. However, when this property is updated, all dimensions - * within it are set to hidden if this field is true, or set to visible if - * this field is false. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *collapsed; - -/** - * The depth of the group, representing how many groups have a range that - * wholly contains the range of this group. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *depth; - -/** The range over which this group exists. */ -@property(nonatomic, strong, nullable) GTLRSheets_DimensionRange *range; - -@end - - -/** - * Properties about a dimension. - */ -@interface GTLRSheets_DimensionProperties : GTLRObject - -/** The developer metadata associated with a single row or column. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_DeveloperMetadata *> *developerMetadata; - -/** - * True if this dimension is being filtered. - * This field is read-only. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *hiddenByFilter; - -/** - * True if this dimension is explicitly hidden. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *hiddenByUser; - -/** - * The height (if a row) or width (if a column) of the dimension in pixels. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *pixelSize; - -@end - - -/** - * A range along a single dimension on a sheet. - * All indexes are zero-based. - * Indexes are half open: the start index is inclusive - * and the end index is exclusive. - * Missing indexes indicate the range is unbounded on that side. - */ -@interface GTLRSheets_DimensionRange : GTLRObject - -/** - * The dimension of the span. - * - * Likely values: - * @arg @c kGTLRSheets_DimensionRange_Dimension_Columns Operates on the - * columns of a sheet. (Value: "COLUMNS") - * @arg @c kGTLRSheets_DimensionRange_Dimension_DimensionUnspecified The - * default value, do not use. (Value: "DIMENSION_UNSPECIFIED") - * @arg @c kGTLRSheets_DimensionRange_Dimension_Rows Operates on the rows of - * a sheet. (Value: "ROWS") - */ -@property(nonatomic, copy, nullable) NSString *dimension; - -/** - * The end (exclusive) of the span, or not set if unbounded. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *endIndex; - -/** - * The sheet this span is on. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *sheetId; - -/** - * The start (inclusive) of the span, or not set if unbounded. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *startIndex; - -@end - - -/** - * Duplicates a particular filter view. - */ -@interface GTLRSheets_DuplicateFilterViewRequest : GTLRObject - -/** - * The ID of the filter being duplicated. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *filterId; - -@end - - -/** - * The result of a filter view being duplicated. - */ -@interface GTLRSheets_DuplicateFilterViewResponse : GTLRObject - -/** The newly created filter. */ -@property(nonatomic, strong, nullable) GTLRSheets_FilterView *filter; - -@end - - -/** - * Duplicates the contents of a sheet. - */ -@interface GTLRSheets_DuplicateSheetRequest : GTLRObject - -/** - * The zero-based index where the new sheet should be inserted. - * The index of all sheets after this are incremented. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *insertSheetIndex; - -/** - * If set, the ID of the new sheet. If not set, an ID is chosen. - * If set, the ID must not conflict with any existing sheet ID. - * If set, it must be non-negative. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *newSheetId NS_RETURNS_NOT_RETAINED; - -/** The name of the new sheet. If empty, a new name is chosen for you. */ -@property(nonatomic, copy, nullable) NSString *newSheetName NS_RETURNS_NOT_RETAINED; - -/** - * The sheet to duplicate. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *sourceSheetId; - -@end - - -/** - * The result of duplicating a sheet. - */ -@interface GTLRSheets_DuplicateSheetResponse : GTLRObject - -/** The properties of the duplicate sheet. */ -@property(nonatomic, strong, nullable) GTLRSheets_SheetProperties *properties; - -@end - - -/** - * The editors of a protected range. - */ -@interface GTLRSheets_Editors : GTLRObject - -/** - * True if anyone in the document's domain has edit access to the protected - * range. Domain protection is only supported on documents within a domain. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *domainUsersCanEdit; - -/** The email addresses of groups with edit access to the protected range. */ -@property(nonatomic, strong, nullable) NSArray<NSString *> *groups; - -/** The email addresses of users with edit access to the protected range. */ -@property(nonatomic, strong, nullable) NSArray<NSString *> *users; - -@end - - -/** - * A chart embedded in a sheet. - */ -@interface GTLRSheets_EmbeddedChart : GTLRObject - -/** - * The ID of the chart. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *chartId; - -/** The position of the chart. */ -@property(nonatomic, strong, nullable) GTLRSheets_EmbeddedObjectPosition *position; - -/** The specification of the chart. */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartSpec *spec; - -@end - - -/** - * The position of an embedded object such as a chart. - */ -@interface GTLRSheets_EmbeddedObjectPosition : GTLRObject - -/** - * If true, the embedded object is put on a new sheet whose ID - * is chosen for you. Used only when writing. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *newSheet NS_RETURNS_NOT_RETAINED; - -/** The position at which the object is overlaid on top of a grid. */ -@property(nonatomic, strong, nullable) GTLRSheets_OverlayPosition *overlayPosition; - -/** - * The sheet this is on. Set only if the embedded object - * is on its own sheet. Must be non-negative. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *sheetId; - -@end - - -/** - * An error in a cell. - */ -@interface GTLRSheets_ErrorValue : GTLRObject - -/** - * A message with more information about the error - * (in the spreadsheet's locale). - */ -@property(nonatomic, copy, nullable) NSString *message; - -/** - * The type of error. - * - * Likely values: - * @arg @c kGTLRSheets_ErrorValue_Type_DivideByZero Corresponds to the - * `#DIV/0` error. (Value: "DIVIDE_BY_ZERO") - * @arg @c kGTLRSheets_ErrorValue_Type_Error Corresponds to the `#ERROR!` - * error. (Value: "ERROR") - * @arg @c kGTLRSheets_ErrorValue_Type_ErrorTypeUnspecified The default error - * type, do not use this. (Value: "ERROR_TYPE_UNSPECIFIED") - * @arg @c kGTLRSheets_ErrorValue_Type_Loading Corresponds to the - * `Loading...` state. (Value: "LOADING") - * @arg @c kGTLRSheets_ErrorValue_Type_NA Corresponds to the `#N/A` error. - * (Value: "N_A") - * @arg @c kGTLRSheets_ErrorValue_Type_Name Corresponds to the `#NAME?` - * error. (Value: "NAME") - * @arg @c kGTLRSheets_ErrorValue_Type_NullValue Corresponds to the `#NULL!` - * error. (Value: "NULL_VALUE") - * @arg @c kGTLRSheets_ErrorValue_Type_Num Corresponds to the `#NUM`! error. - * (Value: "NUM") - * @arg @c kGTLRSheets_ErrorValue_Type_Ref Corresponds to the `#REF!` error. - * (Value: "REF") - * @arg @c kGTLRSheets_ErrorValue_Type_Value Corresponds to the `#VALUE!` - * error. (Value: "VALUE") - */ -@property(nonatomic, copy, nullable) NSString *type; - -@end - - -/** - * The kinds of value that a cell in a spreadsheet can have. - */ -@interface GTLRSheets_ExtendedValue : GTLRObject - -/** - * Represents a boolean value. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *boolValue; - -/** - * Represents an error. - * This field is read-only. - */ -@property(nonatomic, strong, nullable) GTLRSheets_ErrorValue *errorValue; - -/** Represents a formula. */ -@property(nonatomic, copy, nullable) NSString *formulaValue; - -/** - * Represents a double value. - * Note: Dates, Times and DateTimes are represented as doubles in - * "serial number" format. - * - * Uses NSNumber of doubleValue. - */ -@property(nonatomic, strong, nullable) NSNumber *numberValue; - -/** - * Represents a string value. - * Leading single quotes are not included. For example, if the user typed - * `'123` into the UI, this would be represented as a `stringValue` of - * `"123"`. - */ -@property(nonatomic, copy, nullable) NSString *stringValue; - -@end - - -/** - * Criteria for showing/hiding rows in a filter or filter view. - */ -@interface GTLRSheets_FilterCriteria : GTLRObject - -/** - * A condition that must be true for values to be shown. - * (This does not override hiddenValues -- if a value is listed there, - * it will still be hidden.) - */ -@property(nonatomic, strong, nullable) GTLRSheets_BooleanCondition *condition; - -/** Values that should be hidden. */ -@property(nonatomic, strong, nullable) NSArray<NSString *> *hiddenValues; - -@end - - -/** - * A filter view. - */ -@interface GTLRSheets_FilterView : GTLRObject - -/** - * The criteria for showing/hiding values per column. - * The map's key is the column index, and the value is the criteria for - * that column. - */ -@property(nonatomic, strong, nullable) GTLRSheets_FilterView_Criteria *criteria; - -/** - * The ID of the filter view. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *filterViewId; - -/** - * The named range this filter view is backed by, if any. - * When writing, only one of range or named_range_id - * may be set. - */ -@property(nonatomic, copy, nullable) NSString *namedRangeId; - -/** - * The range this filter view covers. - * When writing, only one of range or named_range_id - * may be set. - */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *range; - -/** - * The sort order per column. Later specifications are used when values - * are equal in the earlier specifications. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_SortSpec *> *sortSpecs; - -/** The name of the filter view. */ -@property(nonatomic, copy, nullable) NSString *title; - -@end - - -/** - * The criteria for showing/hiding values per column. - * The map's key is the column index, and the value is the criteria for - * that column. - * - * @note This class is documented as having more properties of - * GTLRSheets_FilterCriteria. Use @c -additionalJSONKeys and @c - * -additionalPropertyForName: to get the list of properties and then - * fetch them; or @c -additionalProperties to fetch them all at once. - */ -@interface GTLRSheets_FilterView_Criteria : GTLRObject -@end - - -/** - * Finds and replaces data in cells over a range, sheet, or all sheets. - */ -@interface GTLRSheets_FindReplaceRequest : GTLRObject - -/** - * True to find/replace over all sheets. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *allSheets; - -/** The value to search. */ -@property(nonatomic, copy, nullable) NSString *find; - -/** - * True if the search should include cells with formulas. - * False to skip cells with formulas. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *includeFormulas; - -/** - * True if the search is case sensitive. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *matchCase; - -/** - * True if the find value should match the entire cell. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *matchEntireCell; - -/** The range to find/replace over. */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *range; - -/** The value to use as the replacement. */ -@property(nonatomic, copy, nullable) NSString *replacement; - -/** - * True if the find value is a regex. - * The regular expression and replacement should follow Java regex rules - * at https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html. - * The replacement string is allowed to refer to capturing groups. - * For example, if one cell has the contents `"Google Sheets"` and another - * has `"Google Docs"`, then searching for `"o.* (.*)"` with a replacement of - * `"$1 Rocks"` would change the contents of the cells to - * `"GSheets Rocks"` and `"GDocs Rocks"` respectively. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *searchByRegex; - -/** - * The sheet to find/replace over. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *sheetId; - -@end - - -/** - * The result of the find/replace. - */ -@interface GTLRSheets_FindReplaceResponse : GTLRObject - -/** - * The number of formula cells changed. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *formulasChanged; - -/** - * The number of occurrences (possibly multiple within a cell) changed. - * For example, if replacing `"e"` with `"o"` in `"Google Sheets"`, this would - * be `"3"` because `"Google Sheets"` -> `"Googlo Shoots"`. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *occurrencesChanged; - -/** - * The number of rows changed. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *rowsChanged; - -/** - * The number of sheets changed. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *sheetsChanged; - -/** - * The number of non-formula cells changed. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *valuesChanged; - -@end - - -/** - * The request for retrieving a Spreadsheet. - */ -@interface GTLRSheets_GetSpreadsheetByDataFilterRequest : GTLRObject - -/** - * The DataFilters used to select which ranges to retrieve from - * the spreadsheet. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_DataFilter *> *dataFilters; - -/** - * True if grid data should be returned. - * This parameter is ignored if a field mask was set in the request. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *includeGridData; - -@end - - -/** - * A rule that applies a gradient color scale format, based on - * the interpolation points listed. The format of a cell will vary - * based on its contents as compared to the values of the interpolation - * points. - */ -@interface GTLRSheets_GradientRule : GTLRObject - -/** The final interpolation point. */ -@property(nonatomic, strong, nullable) GTLRSheets_InterpolationPoint *maxpoint; - -/** An optional midway interpolation point. */ -@property(nonatomic, strong, nullable) GTLRSheets_InterpolationPoint *midpoint; - -/** The starting interpolation point. */ -@property(nonatomic, strong, nullable) GTLRSheets_InterpolationPoint *minpoint; - -@end - - -/** - * A coordinate in a sheet. - * All indexes are zero-based. - */ -@interface GTLRSheets_GridCoordinate : GTLRObject - -/** - * The column index of the coordinate. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *columnIndex; - -/** - * The row index of the coordinate. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *rowIndex; - -/** - * The sheet this coordinate is on. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *sheetId; - -@end - - -/** - * Data in the grid, as well as metadata about the dimensions. - */ -@interface GTLRSheets_GridData : GTLRObject - -/** - * Metadata about the requested columns in the grid, starting with the column - * in start_column. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_DimensionProperties *> *columnMetadata; - -/** - * The data in the grid, one entry per row, - * starting with the row in startRow. - * The values in RowData will correspond to columns starting - * at start_column. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_RowData *> *rowData; - -/** - * Metadata about the requested rows in the grid, starting with the row - * in start_row. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_DimensionProperties *> *rowMetadata; - -/** - * The first column this GridData refers to, zero-based. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *startColumn; - -/** - * The first row this GridData refers to, zero-based. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *startRow; - -@end - - -/** - * Properties of a grid. - */ -@interface GTLRSheets_GridProperties : GTLRObject - -/** - * The number of columns in the grid. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *columnCount; - -/** - * True if the column grouping control toggle is shown after the group. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *columnGroupControlAfter; - -/** - * The number of columns that are frozen in the grid. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *frozenColumnCount; - -/** - * The number of rows that are frozen in the grid. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *frozenRowCount; - -/** - * True if the grid isn't showing gridlines in the UI. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *hideGridlines; - -/** - * The number of rows in the grid. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *rowCount; - -/** - * True if the row grouping control toggle is shown after the group. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *rowGroupControlAfter; - -@end - - -/** - * A range on a sheet. - * All indexes are zero-based. - * Indexes are half open, e.g the start index is inclusive - * and the end index is exclusive -- [start_index, end_index). - * Missing indexes indicate the range is unbounded on that side. - * For example, if `"Sheet1"` is sheet ID 0, then: - * `Sheet1!A1:A1 == sheet_id: 0, - * start_row_index: 0, end_row_index: 1, - * start_column_index: 0, end_column_index: 1` - * `Sheet1!A3:B4 == sheet_id: 0, - * start_row_index: 2, end_row_index: 4, - * start_column_index: 0, end_column_index: 2` - * `Sheet1!A:B == sheet_id: 0, - * start_column_index: 0, end_column_index: 2` - * `Sheet1!A5:B == sheet_id: 0, - * start_row_index: 4, - * start_column_index: 0, end_column_index: 2` - * `Sheet1 == sheet_id:0` - * The start index must always be less than or equal to the end index. - * If the start index equals the end index, then the range is empty. - * Empty ranges are typically not meaningful and are usually rendered in the - * UI as `#REF!`. - */ -@interface GTLRSheets_GridRange : GTLRObject - -/** - * The end column (exclusive) of the range, or not set if unbounded. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *endColumnIndex; - -/** - * The end row (exclusive) of the range, or not set if unbounded. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *endRowIndex; - -/** - * The sheet this range is on. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *sheetId; - -/** - * The start column (inclusive) of the range, or not set if unbounded. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *startColumnIndex; - -/** - * The start row (inclusive) of the range, or not set if unbounded. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *startRowIndex; - -@end - - -/** - * A <a href="/chart/interactive/docs/gallery/histogram">histogram chart</a>. - * A histogram chart groups data items into bins, displaying each bin as a - * column of stacked items. Histograms are used to display the distribution - * of a dataset. Each column of items represents a range into which those - * items fall. The number of bins can be chosen automatically or specified - * explicitly. - */ -@interface GTLRSheets_HistogramChartSpec : GTLRObject - -/** - * By default the bucket size (the range of values stacked in a single - * column) is chosen automatically, but it may be overridden here. - * E.g., A bucket size of 1.5 results in buckets from 0 - 1.5, 1.5 - 3.0, etc. - * Cannot be negative. - * This field is optional. - * - * Uses NSNumber of doubleValue. - */ -@property(nonatomic, strong, nullable) NSNumber *bucketSize; - -/** - * The position of the chart legend. - * - * Likely values: - * @arg @c kGTLRSheets_HistogramChartSpec_LegendPosition_BottomLegend The - * legend is rendered on the bottom of the chart. (Value: - * "BOTTOM_LEGEND") - * @arg @c kGTLRSheets_HistogramChartSpec_LegendPosition_HistogramChartLegendPositionUnspecified - * Default value, do not use. (Value: - * "HISTOGRAM_CHART_LEGEND_POSITION_UNSPECIFIED") - * @arg @c kGTLRSheets_HistogramChartSpec_LegendPosition_InsideLegend The - * legend is rendered inside the chart area. (Value: "INSIDE_LEGEND") - * @arg @c kGTLRSheets_HistogramChartSpec_LegendPosition_LeftLegend The - * legend is rendered on the left of the chart. (Value: "LEFT_LEGEND") - * @arg @c kGTLRSheets_HistogramChartSpec_LegendPosition_NoLegend No legend - * is rendered. (Value: "NO_LEGEND") - * @arg @c kGTLRSheets_HistogramChartSpec_LegendPosition_RightLegend The - * legend is rendered on the right of the chart. (Value: "RIGHT_LEGEND") - * @arg @c kGTLRSheets_HistogramChartSpec_LegendPosition_TopLegend The legend - * is rendered on the top of the chart. (Value: "TOP_LEGEND") - */ -@property(nonatomic, copy, nullable) NSString *legendPosition; - -/** - * The outlier percentile is used to ensure that outliers do not adversely - * affect the calculation of bucket sizes. For example, setting an outlier - * percentile of 0.05 indicates that the top and bottom 5% of values when - * calculating buckets. The values are still included in the chart, they will - * be added to the first or last buckets instead of their own buckets. - * Must be between 0.0 and 0.5. - * - * Uses NSNumber of doubleValue. - */ -@property(nonatomic, strong, nullable) NSNumber *outlierPercentile; - -/** - * The series for a histogram may be either a single series of values to be - * bucketed or multiple series, each of the same length, containing the name - * of the series followed by the values to be bucketed for that series. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_HistogramSeries *> *series; - -/** - * Whether horizontal divider lines should be displayed between items in each - * column. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *showItemDividers; - -@end - - -/** - * Allows you to organize the numeric values in a source data column into - * buckets of a constant size. All values from HistogramRule.start to - * HistogramRule.end are placed into groups of size - * HistogramRule.interval. In addition, all values below - * HistogramRule.start are placed in one group, and all values above - * HistogramRule.end are placed in another. Only - * HistogramRule.interval is required, though if HistogramRule.start - * and HistogramRule.end are both provided, HistogramRule.start must - * be less than HistogramRule.end. For example, a pivot table showing - * average purchase amount by age that has 50+ rows: - * +-----+-------------------+ - * | Age | AVERAGE of Amount | - * +-----+-------------------+ - * | 16 | $27.13 | - * | 17 | $5.24 | - * | 18 | $20.15 | - * ... - * +-----+-------------------+ - * could be turned into a pivot table that looks like the one below by - * applying a histogram group rule with a HistogramRule.start of 25, - * an HistogramRule.interval of 20, and an HistogramRule.end - * of 65. - * +-------------+-------------------+ - * | Grouped Age | AVERAGE of Amount | - * +-------------+-------------------+ - * | < 25 | $19.34 | - * | 25-45 | $31.43 | - * | 45-65 | $35.87 | - * | > 65 | $27.55 | - * +-------------+-------------------+ - * | Grand Total | $29.12 | - * +-------------+-------------------+ - */ -@interface GTLRSheets_HistogramRule : GTLRObject - -/** - * The maximum value at which items are placed into buckets - * of constant size. Values above end are lumped into a single bucket. - * This field is optional. - * - * Uses NSNumber of doubleValue. - */ -@property(nonatomic, strong, nullable) NSNumber *end; - -/** - * The size of the buckets that are created. Must be positive. - * - * Uses NSNumber of doubleValue. - */ -@property(nonatomic, strong, nullable) NSNumber *interval; - -/** - * The minimum value at which items are placed into buckets - * of constant size. Values below start are lumped into a single bucket. - * This field is optional. - * - * Uses NSNumber of doubleValue. - */ -@property(nonatomic, strong, nullable) NSNumber *start; - -@end - - -/** - * A histogram series containing the series color and data. - */ -@interface GTLRSheets_HistogramSeries : GTLRObject - -/** - * The color of the column representing this series in each bucket. - * This field is optional. - */ -@property(nonatomic, strong, nullable) GTLRSheets_Color *barColor; - -/** The data for this histogram series. */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartData *data; - -@end - - -/** - * Inserts rows or columns in a sheet at a particular index. - */ -@interface GTLRSheets_InsertDimensionRequest : GTLRObject - -/** - * Whether dimension properties should be extended from the dimensions - * before or after the newly inserted dimensions. - * True to inherit from the dimensions before (in which case the start - * index must be greater than 0), and false to inherit from the dimensions - * after. - * For example, if row index 0 has red background and row index 1 - * has a green background, then inserting 2 rows at index 1 can inherit - * either the green or red background. If `inheritFromBefore` is true, - * the two new rows will be red (because the row before the insertion point - * was red), whereas if `inheritFromBefore` is false, the two new rows will - * be green (because the row after the insertion point was green). - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *inheritFromBefore; - -/** - * The dimensions to insert. Both the start and end indexes must be bounded. - */ -@property(nonatomic, strong, nullable) GTLRSheets_DimensionRange *range; - -@end - - -/** - * Inserts cells into a range, shifting the existing cells over or down. - */ -@interface GTLRSheets_InsertRangeRequest : GTLRObject - -/** The range to insert new cells into. */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *range; - -/** - * The dimension which will be shifted when inserting cells. - * If ROWS, existing cells will be shifted down. - * If COLUMNS, existing cells will be shifted right. - * - * Likely values: - * @arg @c kGTLRSheets_InsertRangeRequest_ShiftDimension_Columns Operates on - * the columns of a sheet. (Value: "COLUMNS") - * @arg @c kGTLRSheets_InsertRangeRequest_ShiftDimension_DimensionUnspecified - * The default value, do not use. (Value: "DIMENSION_UNSPECIFIED") - * @arg @c kGTLRSheets_InsertRangeRequest_ShiftDimension_Rows Operates on the - * rows of a sheet. (Value: "ROWS") - */ -@property(nonatomic, copy, nullable) NSString *shiftDimension; - -@end - - -/** - * A single interpolation point on a gradient conditional format. - * These pin the gradient color scale according to the color, - * type and value chosen. - */ -@interface GTLRSheets_InterpolationPoint : GTLRObject - -/** The color this interpolation point should use. */ -@property(nonatomic, strong, nullable) GTLRSheets_Color *color; - -/** - * How the value should be interpreted. - * - * Likely values: - * @arg @c kGTLRSheets_InterpolationPoint_Type_InterpolationPointTypeUnspecified - * The default value, do not use. (Value: - * "INTERPOLATION_POINT_TYPE_UNSPECIFIED") - * @arg @c kGTLRSheets_InterpolationPoint_Type_Max The interpolation point - * uses the maximum value in the - * cells over the range of the conditional format. (Value: "MAX") - * @arg @c kGTLRSheets_InterpolationPoint_Type_Min The interpolation point - * uses the minimum value in the - * cells over the range of the conditional format. (Value: "MIN") - * @arg @c kGTLRSheets_InterpolationPoint_Type_Number The interpolation point - * uses exactly the value in - * InterpolationPoint.value. (Value: "NUMBER") - * @arg @c kGTLRSheets_InterpolationPoint_Type_Percent The interpolation - * point is the given percentage over - * all the cells in the range of the conditional format. - * This is equivalent to NUMBER if the value was: - * `=(MAX(FLATTEN(range)) * (value / 100)) - * + (MIN(FLATTEN(range)) * (1 - (value / 100)))` - * (where errors in the range are ignored when flattening). (Value: - * "PERCENT") - * @arg @c kGTLRSheets_InterpolationPoint_Type_Percentile The interpolation - * point is the given percentile - * over all the cells in the range of the conditional format. - * This is equivalent to NUMBER if the value was: - * `=PERCENTILE(FLATTEN(range), value / 100)` - * (where errors in the range are ignored when flattening). (Value: - * "PERCENTILE") - */ -@property(nonatomic, copy, nullable) NSString *type; - -/** - * The value this interpolation point uses. May be a formula. - * Unused if type is MIN or - * MAX. - */ -@property(nonatomic, copy, nullable) NSString *value; - -@end - - -/** - * Settings to control how circular dependencies are resolved with iterative - * calculation. - */ -@interface GTLRSheets_IterativeCalculationSettings : GTLRObject - -/** - * When iterative calculation is enabled and successive results differ by - * less than this threshold value, the calculation rounds stop. - * - * Uses NSNumber of doubleValue. - */ -@property(nonatomic, strong, nullable) NSNumber *convergenceThreshold; - -/** - * When iterative calculation is enabled, the maximum number of calculation - * rounds to perform. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *maxIterations; - -@end - - -/** - * Properties that describe the style of a line. - */ -@interface GTLRSheets_LineStyle : GTLRObject - -/** - * The dash type of the line. - * - * Likely values: - * @arg @c kGTLRSheets_LineStyle_Type_Custom A custom dash for a line. - * Modifying the exact custom dash style is - * currently unsupported. (Value: "CUSTOM") - * @arg @c kGTLRSheets_LineStyle_Type_Dotted A dotted line. (Value: "DOTTED") - * @arg @c kGTLRSheets_LineStyle_Type_Invisible No dash type, which is - * equivalent to a non-visible line. (Value: "INVISIBLE") - * @arg @c kGTLRSheets_LineStyle_Type_LineDashTypeUnspecified Default value, - * do not use. (Value: "LINE_DASH_TYPE_UNSPECIFIED") - * @arg @c kGTLRSheets_LineStyle_Type_LongDashed A dashed line where the - * dashes have "long" length. (Value: "LONG_DASHED") - * @arg @c kGTLRSheets_LineStyle_Type_LongDashedDotted A line that alternates - * between a "long" dash and a dot. (Value: "LONG_DASHED_DOTTED") - * @arg @c kGTLRSheets_LineStyle_Type_MediumDashed A dashed line where the - * dashes have "medium" length. (Value: "MEDIUM_DASHED") - * @arg @c kGTLRSheets_LineStyle_Type_MediumDashedDotted A line that - * alternates between a "medium" dash and a dot. (Value: - * "MEDIUM_DASHED_DOTTED") - * @arg @c kGTLRSheets_LineStyle_Type_Solid A solid line. (Value: "SOLID") - */ -@property(nonatomic, copy, nullable) NSString *type; - -/** - * The thickness of the line, in px. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *width; - -@end - - -/** - * Allows you to manually organize the values in a source data column into - * buckets with names of your choosing. For example, a pivot table that - * aggregates population by state: - * +-------+-------------------+ - * | State | SUM of Population | - * +-------+-------------------+ - * | AK | 0.7 | - * | AL | 4.8 | - * | AR | 2.9 | - * ... - * +-------+-------------------+ - * could be turned into a pivot table that aggregates population by time zone - * by providing a list of groups (for example, groupName = 'Central', - * items = ['AL', 'AR', 'IA', ...]) to a manual group rule. - * Note that a similar effect could be achieved by adding a time zone column - * to the source data and adjusting the pivot table. - * +-----------+-------------------+ - * | Time Zone | SUM of Population | - * +-----------+-------------------+ - * | Central | 106.3 | - * | Eastern | 151.9 | - * | Mountain | 17.4 | - * ... - * +-----------+-------------------+ - */ -@interface GTLRSheets_ManualRule : GTLRObject - -/** - * The list of group names and the corresponding items from the source data - * that map to each group name. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_ManualRuleGroup *> *groups; - -@end - - -/** - * A group name and a list of items from the source data that should be placed - * in the group with this name. - * - * @note This class supports NSFastEnumeration and indexed subscripting over - * its "items" property. - */ -@interface GTLRSheets_ManualRuleGroup : GTLRCollectionObject - -/** - * The group name, which must be a string. Each group in a given - * ManualRule must have a unique group name. - */ -@property(nonatomic, strong, nullable) GTLRSheets_ExtendedValue *groupName; - -/** - * The items in the source data that should be placed into this group. Each - * item may be a string, number, or boolean. Items may appear in at most one - * group within a given ManualRule. Items that do not appear in any - * group will appear on their own. - * - * @note This property is used to support NSFastEnumeration and indexed - * subscripting on this class. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_ExtendedValue *> *items; - -@end - - -/** - * A developer metadata entry and the data filters specified in the original - * request that matched it. - */ -@interface GTLRSheets_MatchedDeveloperMetadata : GTLRObject - -/** All filters matching the returned developer metadata. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_DataFilter *> *dataFilters; - -/** The developer metadata matching the specified filters. */ -@property(nonatomic, strong, nullable) GTLRSheets_DeveloperMetadata *developerMetadata; - -@end - - -/** - * A value range that was matched by one or more data filers. - */ -@interface GTLRSheets_MatchedValueRange : GTLRObject - -/** - * The DataFilters from the request that matched the range of - * values. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_DataFilter *> *dataFilters; - -/** The values matched by the DataFilter. */ -@property(nonatomic, strong, nullable) GTLRSheets_ValueRange *valueRange; - -@end - - -/** - * Merges all cells in the range. - */ -@interface GTLRSheets_MergeCellsRequest : GTLRObject - -/** - * How the cells should be merged. - * - * Likely values: - * @arg @c kGTLRSheets_MergeCellsRequest_MergeType_MergeAll Create a single - * merge from the range (Value: "MERGE_ALL") - * @arg @c kGTLRSheets_MergeCellsRequest_MergeType_MergeColumns Create a - * merge for each column in the range (Value: "MERGE_COLUMNS") - * @arg @c kGTLRSheets_MergeCellsRequest_MergeType_MergeRows Create a merge - * for each row in the range (Value: "MERGE_ROWS") - */ -@property(nonatomic, copy, nullable) NSString *mergeType; - -/** The range of cells to merge. */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *range; - -@end - - -/** - * Moves one or more rows or columns. - */ -@interface GTLRSheets_MoveDimensionRequest : GTLRObject - -/** - * The zero-based start index of where to move the source data to, - * based on the coordinates *before* the source data is removed - * from the grid. Existing data will be shifted down or right - * (depending on the dimension) to make room for the moved dimensions. - * The source dimensions are removed from the grid, so the - * the data may end up in a different index than specified. - * For example, given `A1..A5` of `0, 1, 2, 3, 4` and wanting to move - * `"1"` and `"2"` to between `"3"` and `"4"`, the source would be - * `ROWS [1..3)`,and the destination index would be `"4"` - * (the zero-based index of row 5). - * The end result would be `A1..A5` of `0, 3, 1, 2, 4`. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *destinationIndex; - -/** The source dimensions to move. */ -@property(nonatomic, strong, nullable) GTLRSheets_DimensionRange *source; - -@end - - -/** - * A named range. - */ -@interface GTLRSheets_NamedRange : GTLRObject - -/** The name of the named range. */ -@property(nonatomic, copy, nullable) NSString *name; - -/** The ID of the named range. */ -@property(nonatomic, copy, nullable) NSString *namedRangeId; - -/** The range this represents. */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *range; - -@end - - -/** - * The number format of a cell. - */ -@interface GTLRSheets_NumberFormat : GTLRObject - -/** - * Pattern string used for formatting. If not set, a default pattern based on - * the user's locale will be used if necessary for the given type. - * See the [Date and Number Formats guide](/sheets/api/guides/formats) for more - * information about the supported patterns. - */ -@property(nonatomic, copy, nullable) NSString *pattern; - -/** - * The type of the number format. - * When writing, this field must be set. - * - * Likely values: - * @arg @c kGTLRSheets_NumberFormat_Type_Currency Currency formatting, e.g - * `$1,000.12` (Value: "CURRENCY") - * @arg @c kGTLRSheets_NumberFormat_Type_Date Date formatting, e.g - * `9/26/2008` (Value: "DATE") - * @arg @c kGTLRSheets_NumberFormat_Type_DateTime Date+Time formatting, e.g - * `9/26/08 15:59:00` (Value: "DATE_TIME") - * @arg @c kGTLRSheets_NumberFormat_Type_Number Number formatting, e.g, - * `1,000.12` (Value: "NUMBER") - * @arg @c kGTLRSheets_NumberFormat_Type_NumberFormatTypeUnspecified The - * number format is not specified - * and is based on the contents of the cell. - * Do not explicitly use this. (Value: "NUMBER_FORMAT_TYPE_UNSPECIFIED") - * @arg @c kGTLRSheets_NumberFormat_Type_Percent Percent formatting, e.g - * `10.12%` (Value: "PERCENT") - * @arg @c kGTLRSheets_NumberFormat_Type_Scientific Scientific number - * formatting, e.g `1.01E+03` (Value: "SCIENTIFIC") - * @arg @c kGTLRSheets_NumberFormat_Type_Text Text formatting, e.g `1000.12` - * (Value: "TEXT") - * @arg @c kGTLRSheets_NumberFormat_Type_Time Time formatting, e.g `3:59:00 - * PM` (Value: "TIME") - */ -@property(nonatomic, copy, nullable) NSString *type; - -@end - - -/** - * An <a href="/chart/interactive/docs/gallery/orgchart">org chart</a>. - * Org charts require a unique set of labels in labels and may - * optionally include parent_labels and tooltips. - * parent_labels contain, for each node, the label identifying the parent - * node. tooltips contain, for each node, an optional tooltip. - * For example, to describe an OrgChart with Alice as the CEO, Bob as the - * President (reporting to Alice) and Cathy as VP of Sales (also reporting to - * Alice), have labels contain "Alice", "Bob", "Cathy", - * parent_labels contain "", "Alice", "Alice" and tooltips contain - * "CEO", "President", "VP Sales". - */ -@interface GTLRSheets_OrgChartSpec : GTLRObject - -/** - * The data containing the labels for all the nodes in the chart. Labels - * must be unique. - */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartData *labels; - -/** The color of the org chart nodes. */ -@property(nonatomic, strong, nullable) GTLRSheets_Color *nodeColor; - -/** - * The size of the org chart nodes. - * - * Likely values: - * @arg @c kGTLRSheets_OrgChartSpec_NodeSize_Large The large org chart node - * size. (Value: "LARGE") - * @arg @c kGTLRSheets_OrgChartSpec_NodeSize_Medium The medium org chart node - * size. (Value: "MEDIUM") - * @arg @c kGTLRSheets_OrgChartSpec_NodeSize_OrgChartLabelSizeUnspecified - * Default value, do not use. (Value: "ORG_CHART_LABEL_SIZE_UNSPECIFIED") - * @arg @c kGTLRSheets_OrgChartSpec_NodeSize_Small The small org chart node - * size. (Value: "SMALL") - */ -@property(nonatomic, copy, nullable) NSString *nodeSize; - -/** - * The data containing the label of the parent for the corresponding node. - * A blank value indicates that the node has no parent and is a top-level - * node. - * This field is optional. - */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartData *parentLabels; - -/** The color of the selected org chart nodes. */ -@property(nonatomic, strong, nullable) GTLRSheets_Color *selectedNodeColor; - -/** - * The data containing the tooltip for the corresponding node. A blank value - * results in no tooltip being displayed for the node. - * This field is optional. - */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartData *tooltips; - -@end - - -/** - * The location an object is overlaid on top of a grid. - */ -@interface GTLRSheets_OverlayPosition : GTLRObject - -/** The cell the object is anchored to. */ -@property(nonatomic, strong, nullable) GTLRSheets_GridCoordinate *anchorCell; - -/** - * The height of the object, in pixels. Defaults to 371. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *heightPixels; - -/** - * The horizontal offset, in pixels, that the object is offset - * from the anchor cell. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *offsetXPixels; - -/** - * The vertical offset, in pixels, that the object is offset - * from the anchor cell. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *offsetYPixels; - -/** - * The width of the object, in pixels. Defaults to 600. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *widthPixels; - -@end - - -/** - * The amount of padding around the cell, in pixels. - * When updating padding, every field must be specified. - */ -@interface GTLRSheets_Padding : GTLRObject - -/** - * The bottom padding of the cell. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *bottom; - -/** - * The left padding of the cell. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *left; - -/** - * The right padding of the cell. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *right; - -/** - * The top padding of the cell. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *top; - -@end - - -/** - * Inserts data into the spreadsheet starting at the specified coordinate. - */ -@interface GTLRSheets_PasteDataRequest : GTLRObject - -/** The coordinate at which the data should start being inserted. */ -@property(nonatomic, strong, nullable) GTLRSheets_GridCoordinate *coordinate; - -/** The data to insert. */ -@property(nonatomic, copy, nullable) NSString *data; - -/** The delimiter in the data. */ -@property(nonatomic, copy, nullable) NSString *delimiter; - -/** - * True if the data is HTML. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *html; - -/** - * How the data should be pasted. - * - * Likely values: - * @arg @c kGTLRSheets_PasteDataRequest_Type_PasteConditionalFormatting Paste - * the conditional formatting rules only. (Value: - * "PASTE_CONDITIONAL_FORMATTING") - * @arg @c kGTLRSheets_PasteDataRequest_Type_PasteDataValidation Paste the - * data validation only. (Value: "PASTE_DATA_VALIDATION") - * @arg @c kGTLRSheets_PasteDataRequest_Type_PasteFormat Paste the format and - * data validation only. (Value: "PASTE_FORMAT") - * @arg @c kGTLRSheets_PasteDataRequest_Type_PasteFormula Paste the formulas - * only. (Value: "PASTE_FORMULA") - * @arg @c kGTLRSheets_PasteDataRequest_Type_PasteNoBorders Like PASTE_NORMAL - * but without borders. (Value: "PASTE_NO_BORDERS") - * @arg @c kGTLRSheets_PasteDataRequest_Type_PasteNormal Paste values, - * formulas, formats, and merges. (Value: "PASTE_NORMAL") - * @arg @c kGTLRSheets_PasteDataRequest_Type_PasteValues Paste the values - * ONLY without formats, formulas, or merges. (Value: "PASTE_VALUES") - */ -@property(nonatomic, copy, nullable) NSString *type; - -@end - - -/** - * A <a href="/chart/interactive/docs/gallery/piechart">pie chart</a>. - */ -@interface GTLRSheets_PieChartSpec : GTLRObject - -/** The data that covers the domain of the pie chart. */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartData *domain; - -/** - * Where the legend of the pie chart should be drawn. - * - * Likely values: - * @arg @c kGTLRSheets_PieChartSpec_LegendPosition_BottomLegend The legend is - * rendered on the bottom of the chart. (Value: "BOTTOM_LEGEND") - * @arg @c kGTLRSheets_PieChartSpec_LegendPosition_LabeledLegend Each pie - * slice has a label attached to it. (Value: "LABELED_LEGEND") - * @arg @c kGTLRSheets_PieChartSpec_LegendPosition_LeftLegend The legend is - * rendered on the left of the chart. (Value: "LEFT_LEGEND") - * @arg @c kGTLRSheets_PieChartSpec_LegendPosition_NoLegend No legend is - * rendered. (Value: "NO_LEGEND") - * @arg @c kGTLRSheets_PieChartSpec_LegendPosition_PieChartLegendPositionUnspecified - * Default value, do not use. (Value: - * "PIE_CHART_LEGEND_POSITION_UNSPECIFIED") - * @arg @c kGTLRSheets_PieChartSpec_LegendPosition_RightLegend The legend is - * rendered on the right of the chart. (Value: "RIGHT_LEGEND") - * @arg @c kGTLRSheets_PieChartSpec_LegendPosition_TopLegend The legend is - * rendered on the top of the chart. (Value: "TOP_LEGEND") - */ -@property(nonatomic, copy, nullable) NSString *legendPosition; - -/** - * The size of the hole in the pie chart. - * - * Uses NSNumber of doubleValue. - */ -@property(nonatomic, strong, nullable) NSNumber *pieHole; - -/** The data that covers the one and only series of the pie chart. */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartData *series; - -/** - * True if the pie is three dimensional. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *threeDimensional; - -@end - - -/** - * Criteria for showing/hiding rows in a pivot table. - */ -@interface GTLRSheets_PivotFilterCriteria : GTLRObject - -/** Values that should be included. Values not listed here are excluded. */ -@property(nonatomic, strong, nullable) NSArray<NSString *> *visibleValues; - -@end - - -/** - * A single grouping (either row or column) in a pivot table. - */ -@interface GTLRSheets_PivotGroup : GTLRObject - -/** The group rule to apply to this row/column group. */ -@property(nonatomic, strong, nullable) GTLRSheets_PivotGroupRule *groupRule; - -/** - * The labels to use for the row/column groups which can be customized. For - * example, in the following pivot table, the row label is `Region` (which - * could be renamed to `State`) and the column label is `Product` (which - * could be renamed `Item`). Pivot tables created before December 2017 do - * not have header labels. If you'd like to add header labels to an existing - * pivot table, please delete the existing pivot table and then create a new - * pivot table with same parameters. - * +--------------+---------+-------+ - * | SUM of Units | Product | | - * | Region | Pen | Paper | - * +--------------+---------+-------+ - * | New York | 345 | 98 | - * | Oregon | 234 | 123 | - * | Tennessee | 531 | 415 | - * +--------------+---------+-------+ - * | Grand Total | 1110 | 636 | - * +--------------+---------+-------+ - */ -@property(nonatomic, copy, nullable) NSString *label; - -/** - * True if the headings in this pivot group should be repeated. - * This is only valid for row groupings and is ignored by columns. - * By default, we minimize repitition of headings by not showing higher - * level headings where they are the same. For example, even though the - * third row below corresponds to "Q1 Mar", "Q1" is not shown because - * it is redundant with previous rows. Setting repeat_headings to true - * would cause "Q1" to be repeated for "Feb" and "Mar". - * +--------------+ - * | Q1 | Jan | - * | | Feb | - * | | Mar | - * +--------+-----+ - * | Q1 Total | - * +--------------+ - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *repeatHeadings; - -/** - * True if the pivot table should include the totals for this grouping. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *showTotals; - -/** - * The order the values in this group should be sorted. - * - * Likely values: - * @arg @c kGTLRSheets_PivotGroup_SortOrder_Ascending Sort ascending. (Value: - * "ASCENDING") - * @arg @c kGTLRSheets_PivotGroup_SortOrder_Descending Sort descending. - * (Value: "DESCENDING") - * @arg @c kGTLRSheets_PivotGroup_SortOrder_SortOrderUnspecified Default - * value, do not use this. (Value: "SORT_ORDER_UNSPECIFIED") - */ -@property(nonatomic, copy, nullable) NSString *sortOrder; - -/** - * The column offset of the source range that this grouping is based on. - * For example, if the source was `C10:E15`, a `sourceColumnOffset` of `0` - * means this group refers to column `C`, whereas the offset `1` would refer - * to column `D`. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *sourceColumnOffset; - -/** - * The bucket of the opposite pivot group to sort by. - * If not specified, sorting is alphabetical by this group's values. - */ -@property(nonatomic, strong, nullable) GTLRSheets_PivotGroupSortValueBucket *valueBucket; - -/** Metadata about values in the grouping. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_PivotGroupValueMetadata *> *valueMetadata; - -@end - - -/** - * An optional setting on a PivotGroup that defines buckets for the values - * in the source data column rather than breaking out each individual value. - * Only one PivotGroup with a group rule may be added for each column in - * the source data, though on any given column you may add both a - * PivotGroup that has a rule and a PivotGroup that does not. - */ -@interface GTLRSheets_PivotGroupRule : GTLRObject - -/** A DateTimeRule. */ -@property(nonatomic, strong, nullable) GTLRSheets_DateTimeRule *dateTimeRule; - -/** A HistogramRule. */ -@property(nonatomic, strong, nullable) GTLRSheets_HistogramRule *histogramRule; - -/** A ManualRule. */ -@property(nonatomic, strong, nullable) GTLRSheets_ManualRule *manualRule; - -@end - - -/** - * Information about which values in a pivot group should be used for sorting. - */ -@interface GTLRSheets_PivotGroupSortValueBucket : GTLRObject - -/** - * Determines the bucket from which values are chosen to sort. - * For example, in a pivot table with one row group & two column groups, - * the row group can list up to two values. The first value corresponds - * to a value within the first column group, and the second value - * corresponds to a value in the second column group. If no values - * are listed, this would indicate that the row should be sorted according - * to the "Grand Total" over the column groups. If a single value is listed, - * this would correspond to using the "Total" of that bucket. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_ExtendedValue *> *buckets; - -/** - * The offset in the PivotTable.values list which the values in this - * grouping should be sorted by. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *valuesIndex; - -@end - - -/** - * Metadata about a value in a pivot grouping. - */ -@interface GTLRSheets_PivotGroupValueMetadata : GTLRObject - -/** - * True if the data corresponding to the value is collapsed. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *collapsed; - -/** - * The calculated value the metadata corresponds to. - * (Note that formulaValue is not valid, - * because the values will be calculated.) - */ -@property(nonatomic, strong, nullable) GTLRSheets_ExtendedValue *value; - -@end - - -/** - * A pivot table. - */ -@interface GTLRSheets_PivotTable : GTLRObject - -/** Each column grouping in the pivot table. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_PivotGroup *> *columns; - -/** - * An optional mapping of filters per source column offset. - * The filters are applied before aggregating data into the pivot table. - * The map's key is the column offset of the source range that you want to - * filter, and the value is the criteria for that column. - * For example, if the source was `C10:E15`, a key of `0` will have the filter - * for column `C`, whereas the key `1` is for column `D`. - */ -@property(nonatomic, strong, nullable) GTLRSheets_PivotTable_Criteria *criteria; - -/** Each row grouping in the pivot table. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_PivotGroup *> *rows; - -/** The range the pivot table is reading data from. */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *source; - -/** - * Whether values should be listed horizontally (as columns) - * or vertically (as rows). - * - * Likely values: - * @arg @c kGTLRSheets_PivotTable_ValueLayout_Horizontal Values are laid out - * horizontally (as columns). (Value: "HORIZONTAL") - * @arg @c kGTLRSheets_PivotTable_ValueLayout_Vertical Values are laid out - * vertically (as rows). (Value: "VERTICAL") - */ -@property(nonatomic, copy, nullable) NSString *valueLayout; - -/** A list of values to include in the pivot table. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_PivotValue *> *values; - -@end - - -/** - * An optional mapping of filters per source column offset. - * The filters are applied before aggregating data into the pivot table. - * The map's key is the column offset of the source range that you want to - * filter, and the value is the criteria for that column. - * For example, if the source was `C10:E15`, a key of `0` will have the filter - * for column `C`, whereas the key `1` is for column `D`. - * - * @note This class is documented as having more properties of - * GTLRSheets_PivotFilterCriteria. Use @c -additionalJSONKeys and @c - * -additionalPropertyForName: to get the list of properties and then - * fetch them; or @c -additionalProperties to fetch them all at once. - */ -@interface GTLRSheets_PivotTable_Criteria : GTLRObject -@end - - -/** - * The definition of how a value in a pivot table should be calculated. - */ -@interface GTLRSheets_PivotValue : GTLRObject - -/** - * If specified, indicates that pivot values should be displayed as - * the result of a calculation with another pivot value. For example, if - * calculated_display_type is specified as PERCENT_OF_GRAND_TOTAL, all the - * pivot values are displayed as the percentage of the grand total. In - * the Sheets UI, this is referred to as "Show As" in the value section of a - * pivot table. - * - * Likely values: - * @arg @c kGTLRSheets_PivotValue_CalculatedDisplayType_PercentOfColumnTotal - * Shows the pivot values as percentage of the column total values. - * (Value: "PERCENT_OF_COLUMN_TOTAL") - * @arg @c kGTLRSheets_PivotValue_CalculatedDisplayType_PercentOfGrandTotal - * Shows the pivot values as percentage of the grand total values. - * (Value: "PERCENT_OF_GRAND_TOTAL") - * @arg @c kGTLRSheets_PivotValue_CalculatedDisplayType_PercentOfRowTotal - * Shows the pivot values as percentage of the row total values. (Value: - * "PERCENT_OF_ROW_TOTAL") - * @arg @c kGTLRSheets_PivotValue_CalculatedDisplayType_PivotValueCalculatedDisplayTypeUnspecified - * Default value, do not use. (Value: - * "PIVOT_VALUE_CALCULATED_DISPLAY_TYPE_UNSPECIFIED") - */ -@property(nonatomic, copy, nullable) NSString *calculatedDisplayType; - -/** - * A custom formula to calculate the value. The formula must start - * with an `=` character. - */ -@property(nonatomic, copy, nullable) NSString *formula; - -/** A name to use for the value. */ -@property(nonatomic, copy, nullable) NSString *name; - -/** - * The column offset of the source range that this value reads from. - * For example, if the source was `C10:E15`, a `sourceColumnOffset` of `0` - * means this value refers to column `C`, whereas the offset `1` would - * refer to column `D`. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *sourceColumnOffset; - -/** - * A function to summarize the value. - * If formula is set, the only supported values are - * SUM and - * CUSTOM. - * If sourceColumnOffset is set, then `CUSTOM` - * is not supported. - * - * Likely values: - * @arg @c kGTLRSheets_PivotValue_SummarizeFunction_Average Corresponds to - * the `AVERAGE` function. (Value: "AVERAGE") - * @arg @c kGTLRSheets_PivotValue_SummarizeFunction_Count Corresponds to the - * `COUNT` function. (Value: "COUNT") - * @arg @c kGTLRSheets_PivotValue_SummarizeFunction_Counta Corresponds to the - * `COUNTA` function. (Value: "COUNTA") - * @arg @c kGTLRSheets_PivotValue_SummarizeFunction_Countunique Corresponds - * to the `COUNTUNIQUE` function. (Value: "COUNTUNIQUE") - * @arg @c kGTLRSheets_PivotValue_SummarizeFunction_Custom Indicates the - * formula should be used as-is. - * Only valid if PivotValue.formula was set. (Value: "CUSTOM") - * @arg @c kGTLRSheets_PivotValue_SummarizeFunction_Max Corresponds to the - * `MAX` function. (Value: "MAX") - * @arg @c kGTLRSheets_PivotValue_SummarizeFunction_Median Corresponds to the - * `MEDIAN` function. (Value: "MEDIAN") - * @arg @c kGTLRSheets_PivotValue_SummarizeFunction_Min Corresponds to the - * `MIN` function. (Value: "MIN") - * @arg @c kGTLRSheets_PivotValue_SummarizeFunction_PivotStandardValueFunctionUnspecified - * The default, do not use. (Value: - * "PIVOT_STANDARD_VALUE_FUNCTION_UNSPECIFIED") - * @arg @c kGTLRSheets_PivotValue_SummarizeFunction_Product Corresponds to - * the `PRODUCT` function. (Value: "PRODUCT") - * @arg @c kGTLRSheets_PivotValue_SummarizeFunction_Stdev Corresponds to the - * `STDEV` function. (Value: "STDEV") - * @arg @c kGTLRSheets_PivotValue_SummarizeFunction_Stdevp Corresponds to the - * `STDEVP` function. (Value: "STDEVP") - * @arg @c kGTLRSheets_PivotValue_SummarizeFunction_Sum Corresponds to the - * `SUM` function. (Value: "SUM") - * @arg @c kGTLRSheets_PivotValue_SummarizeFunction_Var Corresponds to the - * `VAR` function. (Value: "VAR") - * @arg @c kGTLRSheets_PivotValue_SummarizeFunction_Varp Corresponds to the - * `VARP` function. (Value: "VARP") - */ -@property(nonatomic, copy, nullable) NSString *summarizeFunction; - -@end - - -/** - * A protected range. - */ -@interface GTLRSheets_ProtectedRange : GTLRObject - -/** - * The description of this protected range. - * - * Remapped to 'descriptionProperty' to avoid NSObject's 'description'. - */ -@property(nonatomic, copy, nullable) NSString *descriptionProperty; - -/** - * The users and groups with edit access to the protected range. - * This field is only visible to users with edit access to the protected - * range and the document. - * Editors are not supported with warning_only protection. - */ -@property(nonatomic, strong, nullable) GTLRSheets_Editors *editors; - -/** - * The named range this protected range is backed by, if any. - * When writing, only one of range or named_range_id - * may be set. - */ -@property(nonatomic, copy, nullable) NSString *namedRangeId; - -/** - * The ID of the protected range. - * This field is read-only. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *protectedRangeId; - -/** - * The range that is being protected. - * The range may be fully unbounded, in which case this is considered - * a protected sheet. - * When writing, only one of range or named_range_id - * may be set. - */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *range; - -/** - * True if the user who requested this protected range can edit the - * protected area. - * This field is read-only. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *requestingUserCanEdit; - -/** - * The list of unprotected ranges within a protected sheet. - * Unprotected ranges are only supported on protected sheets. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_GridRange *> *unprotectedRanges; - -/** - * True if this protected range will show a warning when editing. - * Warning-based protection means that every user can edit data in the - * protected range, except editing will prompt a warning asking the user - * to confirm the edit. - * When writing: if this field is true, then editors is ignored. - * Additionally, if this field is changed from true to false and the - * `editors` field is not set (nor included in the field mask), then - * the editors will be set to all the editors in the document. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *warningOnly; - -@end - - -/** - * Randomizes the order of the rows in a range. - */ -@interface GTLRSheets_RandomizeRangeRequest : GTLRObject - -/** The range to randomize. */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *range; - -@end - - -/** - * Updates all cells in the range to the values in the given Cell object. - * Only the fields listed in the fields field are updated; others are - * unchanged. - * If writing a cell with a formula, the formula's ranges will automatically - * increment for each field in the range. - * For example, if writing a cell with formula `=A1` into range B2:C4, - * B2 would be `=A1`, B3 would be `=A2`, B4 would be `=A3`, - * C2 would be `=B1`, C3 would be `=B2`, C4 would be `=B3`. - * To keep the formula's ranges static, use the `$` indicator. - * For example, use the formula `=$A$1` to prevent both the row and the - * column from incrementing. - */ -@interface GTLRSheets_RepeatCellRequest : GTLRObject - -/** The data to write. */ -@property(nonatomic, strong, nullable) GTLRSheets_CellData *cell; - -/** - * The fields that should be updated. At least one field must be specified. - * The root `cell` is implied and should not be specified. - * A single `"*"` can be used as short-hand for listing every field. - * - * String format is a comma-separated list of fields. - */ -@property(nonatomic, copy, nullable) NSString *fields; - -/** The range to repeat the cell in. */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *range; - -@end - - -/** - * A single kind of update to apply to a spreadsheet. - */ -@interface GTLRSheets_Request : GTLRObject - -/** Adds a new banded range */ -@property(nonatomic, strong, nullable) GTLRSheets_AddBandingRequest *addBanding; - -/** Adds a chart. */ -@property(nonatomic, strong, nullable) GTLRSheets_AddChartRequest *addChart; - -/** Adds a new conditional format rule. */ -@property(nonatomic, strong, nullable) GTLRSheets_AddConditionalFormatRuleRequest *addConditionalFormatRule; - -/** Creates a group over the specified range. */ -@property(nonatomic, strong, nullable) GTLRSheets_AddDimensionGroupRequest *addDimensionGroup; - -/** Adds a filter view. */ -@property(nonatomic, strong, nullable) GTLRSheets_AddFilterViewRequest *addFilterView; - -/** Adds a named range. */ -@property(nonatomic, strong, nullable) GTLRSheets_AddNamedRangeRequest *addNamedRange; - -/** Adds a protected range. */ -@property(nonatomic, strong, nullable) GTLRSheets_AddProtectedRangeRequest *addProtectedRange; - -/** Adds a sheet. */ -@property(nonatomic, strong, nullable) GTLRSheets_AddSheetRequest *addSheet; - -/** Appends cells after the last row with data in a sheet. */ -@property(nonatomic, strong, nullable) GTLRSheets_AppendCellsRequest *appendCells; - -/** Appends dimensions to the end of a sheet. */ -@property(nonatomic, strong, nullable) GTLRSheets_AppendDimensionRequest *appendDimension; - -/** Automatically fills in more data based on existing data. */ -@property(nonatomic, strong, nullable) GTLRSheets_AutoFillRequest *autoFill; - -/** - * Automatically resizes one or more dimensions based on the contents - * of the cells in that dimension. - */ -@property(nonatomic, strong, nullable) GTLRSheets_AutoResizeDimensionsRequest *autoResizeDimensions; - -/** Clears the basic filter on a sheet. */ -@property(nonatomic, strong, nullable) GTLRSheets_ClearBasicFilterRequest *clearBasicFilter; - -/** Copies data from one area and pastes it to another. */ -@property(nonatomic, strong, nullable) GTLRSheets_CopyPasteRequest *copyPaste NS_RETURNS_NOT_RETAINED; - -/** Creates new developer metadata */ -@property(nonatomic, strong, nullable) GTLRSheets_CreateDeveloperMetadataRequest *createDeveloperMetadata; - -/** Cuts data from one area and pastes it to another. */ -@property(nonatomic, strong, nullable) GTLRSheets_CutPasteRequest *cutPaste; - -/** Removes a banded range */ -@property(nonatomic, strong, nullable) GTLRSheets_DeleteBandingRequest *deleteBanding; - -/** Deletes an existing conditional format rule. */ -@property(nonatomic, strong, nullable) GTLRSheets_DeleteConditionalFormatRuleRequest *deleteConditionalFormatRule; - -/** Deletes developer metadata */ -@property(nonatomic, strong, nullable) GTLRSheets_DeleteDeveloperMetadataRequest *deleteDeveloperMetadata; - -/** Deletes rows or columns in a sheet. */ -@property(nonatomic, strong, nullable) GTLRSheets_DeleteDimensionRequest *deleteDimension; - -/** Deletes a group over the specified range. */ -@property(nonatomic, strong, nullable) GTLRSheets_DeleteDimensionGroupRequest *deleteDimensionGroup; - -/** Deletes an embedded object (e.g, chart, image) in a sheet. */ -@property(nonatomic, strong, nullable) GTLRSheets_DeleteEmbeddedObjectRequest *deleteEmbeddedObject; - -/** Deletes a filter view from a sheet. */ -@property(nonatomic, strong, nullable) GTLRSheets_DeleteFilterViewRequest *deleteFilterView; - -/** Deletes a named range. */ -@property(nonatomic, strong, nullable) GTLRSheets_DeleteNamedRangeRequest *deleteNamedRange; - -/** Deletes a protected range. */ -@property(nonatomic, strong, nullable) GTLRSheets_DeleteProtectedRangeRequest *deleteProtectedRange; - -/** Deletes a range of cells from a sheet, shifting the remaining cells. */ -@property(nonatomic, strong, nullable) GTLRSheets_DeleteRangeRequest *deleteRange; - -/** Deletes a sheet. */ -@property(nonatomic, strong, nullable) GTLRSheets_DeleteSheetRequest *deleteSheet; - -/** Duplicates a filter view. */ -@property(nonatomic, strong, nullable) GTLRSheets_DuplicateFilterViewRequest *duplicateFilterView; - -/** Duplicates a sheet. */ -@property(nonatomic, strong, nullable) GTLRSheets_DuplicateSheetRequest *duplicateSheet; - -/** Finds and replaces occurrences of some text with other text. */ -@property(nonatomic, strong, nullable) GTLRSheets_FindReplaceRequest *findReplace; - -/** Inserts new rows or columns in a sheet. */ -@property(nonatomic, strong, nullable) GTLRSheets_InsertDimensionRequest *insertDimension; - -/** Inserts new cells in a sheet, shifting the existing cells. */ -@property(nonatomic, strong, nullable) GTLRSheets_InsertRangeRequest *insertRange; - -/** Merges cells together. */ -@property(nonatomic, strong, nullable) GTLRSheets_MergeCellsRequest *mergeCells; - -/** Moves rows or columns to another location in a sheet. */ -@property(nonatomic, strong, nullable) GTLRSheets_MoveDimensionRequest *moveDimension; - -/** Pastes data (HTML or delimited) into a sheet. */ -@property(nonatomic, strong, nullable) GTLRSheets_PasteDataRequest *pasteData; - -/** Randomizes the order of the rows in a range. */ -@property(nonatomic, strong, nullable) GTLRSheets_RandomizeRangeRequest *randomizeRange; - -/** Repeats a single cell across a range. */ -@property(nonatomic, strong, nullable) GTLRSheets_RepeatCellRequest *repeatCell; - -/** Sets the basic filter on a sheet. */ -@property(nonatomic, strong, nullable) GTLRSheets_SetBasicFilterRequest *setBasicFilter; - -/** Sets data validation for one or more cells. */ -@property(nonatomic, strong, nullable) GTLRSheets_SetDataValidationRequest *setDataValidation; - -/** Sorts data in a range. */ -@property(nonatomic, strong, nullable) GTLRSheets_SortRangeRequest *sortRange; - -/** Converts a column of text into many columns of text. */ -@property(nonatomic, strong, nullable) GTLRSheets_TextToColumnsRequest *textToColumns; - -/** Unmerges merged cells. */ -@property(nonatomic, strong, nullable) GTLRSheets_UnmergeCellsRequest *unmergeCells; - -/** Updates a banded range */ -@property(nonatomic, strong, nullable) GTLRSheets_UpdateBandingRequest *updateBanding; - -/** Updates the borders in a range of cells. */ -@property(nonatomic, strong, nullable) GTLRSheets_UpdateBordersRequest *updateBorders; - -/** Updates many cells at once. */ -@property(nonatomic, strong, nullable) GTLRSheets_UpdateCellsRequest *updateCells; - -/** Updates a chart's specifications. */ -@property(nonatomic, strong, nullable) GTLRSheets_UpdateChartSpecRequest *updateChartSpec; - -/** Updates an existing conditional format rule. */ -@property(nonatomic, strong, nullable) GTLRSheets_UpdateConditionalFormatRuleRequest *updateConditionalFormatRule; - -/** Updates an existing developer metadata entry */ -@property(nonatomic, strong, nullable) GTLRSheets_UpdateDeveloperMetadataRequest *updateDeveloperMetadata; - -/** Updates the state of the specified group. */ -@property(nonatomic, strong, nullable) GTLRSheets_UpdateDimensionGroupRequest *updateDimensionGroup; - -/** Updates dimensions' properties. */ -@property(nonatomic, strong, nullable) GTLRSheets_UpdateDimensionPropertiesRequest *updateDimensionProperties; - -/** Updates an embedded object's (e.g. chart, image) position. */ -@property(nonatomic, strong, nullable) GTLRSheets_UpdateEmbeddedObjectPositionRequest *updateEmbeddedObjectPosition; - -/** Updates the properties of a filter view. */ -@property(nonatomic, strong, nullable) GTLRSheets_UpdateFilterViewRequest *updateFilterView; - -/** Updates a named range. */ -@property(nonatomic, strong, nullable) GTLRSheets_UpdateNamedRangeRequest *updateNamedRange; - -/** Updates a protected range. */ -@property(nonatomic, strong, nullable) GTLRSheets_UpdateProtectedRangeRequest *updateProtectedRange; - -/** Updates a sheet's properties. */ -@property(nonatomic, strong, nullable) GTLRSheets_UpdateSheetPropertiesRequest *updateSheetProperties; - -/** Updates the spreadsheet's properties. */ -@property(nonatomic, strong, nullable) GTLRSheets_UpdateSpreadsheetPropertiesRequest *updateSpreadsheetProperties; - -@end - - -/** - * A single response from an update. - */ -@interface GTLRSheets_Response : GTLRObject - -/** A reply from adding a banded range. */ -@property(nonatomic, strong, nullable) GTLRSheets_AddBandingResponse *addBanding; - -/** A reply from adding a chart. */ -@property(nonatomic, strong, nullable) GTLRSheets_AddChartResponse *addChart; - -/** A reply from adding a dimension group. */ -@property(nonatomic, strong, nullable) GTLRSheets_AddDimensionGroupResponse *addDimensionGroup; - -/** A reply from adding a filter view. */ -@property(nonatomic, strong, nullable) GTLRSheets_AddFilterViewResponse *addFilterView; - -/** A reply from adding a named range. */ -@property(nonatomic, strong, nullable) GTLRSheets_AddNamedRangeResponse *addNamedRange; - -/** A reply from adding a protected range. */ -@property(nonatomic, strong, nullable) GTLRSheets_AddProtectedRangeResponse *addProtectedRange; - -/** A reply from adding a sheet. */ -@property(nonatomic, strong, nullable) GTLRSheets_AddSheetResponse *addSheet; - -/** A reply from creating a developer metadata entry. */ -@property(nonatomic, strong, nullable) GTLRSheets_CreateDeveloperMetadataResponse *createDeveloperMetadata; - -/** A reply from deleting a conditional format rule. */ -@property(nonatomic, strong, nullable) GTLRSheets_DeleteConditionalFormatRuleResponse *deleteConditionalFormatRule; - -/** A reply from deleting a developer metadata entry. */ -@property(nonatomic, strong, nullable) GTLRSheets_DeleteDeveloperMetadataResponse *deleteDeveloperMetadata; - -/** A reply from deleting a dimension group. */ -@property(nonatomic, strong, nullable) GTLRSheets_DeleteDimensionGroupResponse *deleteDimensionGroup; - -/** A reply from duplicating a filter view. */ -@property(nonatomic, strong, nullable) GTLRSheets_DuplicateFilterViewResponse *duplicateFilterView; - -/** A reply from duplicating a sheet. */ -@property(nonatomic, strong, nullable) GTLRSheets_DuplicateSheetResponse *duplicateSheet; - -/** A reply from doing a find/replace. */ -@property(nonatomic, strong, nullable) GTLRSheets_FindReplaceResponse *findReplace; - -/** A reply from updating a conditional format rule. */ -@property(nonatomic, strong, nullable) GTLRSheets_UpdateConditionalFormatRuleResponse *updateConditionalFormatRule; - -/** A reply from updating a developer metadata entry. */ -@property(nonatomic, strong, nullable) GTLRSheets_UpdateDeveloperMetadataResponse *updateDeveloperMetadata; - -/** A reply from updating an embedded object's position. */ -@property(nonatomic, strong, nullable) GTLRSheets_UpdateEmbeddedObjectPositionResponse *updateEmbeddedObjectPosition; - -@end - - -/** - * Data about each cell in a row. - */ -@interface GTLRSheets_RowData : GTLRObject - -/** The values in the row, one per column. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_CellData *> *values; - -@end - - -/** - * A request to retrieve all developer metadata matching the set of specified - * criteria. - */ -@interface GTLRSheets_SearchDeveloperMetadataRequest : GTLRObject - -/** - * The data filters describing the criteria used to determine which - * DeveloperMetadata entries to return. DeveloperMetadata matching any of the - * specified filters will be included in the response. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_DataFilter *> *dataFilters; - -@end - - -/** - * A reply to a developer metadata search request. - */ -@interface GTLRSheets_SearchDeveloperMetadataResponse : GTLRObject - -/** The metadata matching the criteria of the search request. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_MatchedDeveloperMetadata *> *matchedDeveloperMetadata; - -@end - - -/** - * Sets the basic filter associated with a sheet. - */ -@interface GTLRSheets_SetBasicFilterRequest : GTLRObject - -/** The filter to set. */ -@property(nonatomic, strong, nullable) GTLRSheets_BasicFilter *filter; - -@end - - -/** - * Sets a data validation rule to every cell in the range. - * To clear validation in a range, call this with no rule specified. - */ -@interface GTLRSheets_SetDataValidationRequest : GTLRObject - -/** The range the data validation rule should apply to. */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *range; - -/** - * The data validation rule to set on each cell in the range, - * or empty to clear the data validation in the range. - */ -@property(nonatomic, strong, nullable) GTLRSheets_DataValidationRule *rule; - -@end - - -/** - * A sheet in a spreadsheet. - */ -@interface GTLRSheets_Sheet : GTLRObject - -/** The banded (alternating colors) ranges on this sheet. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_BandedRange *> *bandedRanges; - -/** The filter on this sheet, if any. */ -@property(nonatomic, strong, nullable) GTLRSheets_BasicFilter *basicFilter; - -/** The specifications of every chart on this sheet. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_EmbeddedChart *> *charts; - -/** - * All column groups on this sheet, ordered by increasing range start index, - * then by group depth. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_DimensionGroup *> *columnGroups; - -/** The conditional format rules in this sheet. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_ConditionalFormatRule *> *conditionalFormats; - -/** - * Data in the grid, if this is a grid sheet. - * The number of GridData objects returned is dependent on the number of - * ranges requested on this sheet. For example, if this is representing - * `Sheet1`, and the spreadsheet was requested with ranges - * `Sheet1!A1:C10` and `Sheet1!D15:E20`, then the first GridData will have a - * startRow/startColumn of `0`, - * while the second one will have `startRow 14` (zero-based row 15), - * and `startColumn 3` (zero-based column D). - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_GridData *> *data; - -/** The developer metadata associated with a sheet. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_DeveloperMetadata *> *developerMetadata; - -/** The filter views in this sheet. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_FilterView *> *filterViews; - -/** The ranges that are merged together. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_GridRange *> *merges; - -/** The properties of the sheet. */ -@property(nonatomic, strong, nullable) GTLRSheets_SheetProperties *properties; - -/** The protected ranges in this sheet. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_ProtectedRange *> *protectedRanges; - -/** - * All row groups on this sheet, ordered by increasing range start index, then - * by group depth. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_DimensionGroup *> *rowGroups; - -@end - - -/** - * Properties of a sheet. - */ -@interface GTLRSheets_SheetProperties : GTLRObject - -/** - * Additional properties of the sheet if this sheet is a grid. - * (If the sheet is an object sheet, containing a chart or image, then - * this field will be absent.) - * When writing it is an error to set any grid properties on non-grid sheets. - */ -@property(nonatomic, strong, nullable) GTLRSheets_GridProperties *gridProperties; - -/** - * True if the sheet is hidden in the UI, false if it's visible. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *hidden; - -/** - * The index of the sheet within the spreadsheet. - * When adding or updating sheet properties, if this field - * is excluded then the sheet is added or moved to the end - * of the sheet list. When updating sheet indices or inserting - * sheets, movement is considered in "before the move" indexes. - * For example, if there were 3 sheets (S1, S2, S3) in order to - * move S1 ahead of S2 the index would have to be set to 2. A sheet - * index update request is ignored if the requested index is - * identical to the sheets current index or if the requested new - * index is equal to the current sheet index + 1. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *index; - -/** - * True if the sheet is an RTL sheet instead of an LTR sheet. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *rightToLeft; - -/** - * The ID of the sheet. Must be non-negative. - * This field cannot be changed once set. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *sheetId; - -/** - * The type of sheet. Defaults to GRID. - * This field cannot be changed once set. - * - * Likely values: - * @arg @c kGTLRSheets_SheetProperties_SheetType_Grid The sheet is a grid. - * (Value: "GRID") - * @arg @c kGTLRSheets_SheetProperties_SheetType_Object The sheet has no grid - * and instead has an object like a chart or image. (Value: "OBJECT") - * @arg @c kGTLRSheets_SheetProperties_SheetType_SheetTypeUnspecified Default - * value, do not use. (Value: "SHEET_TYPE_UNSPECIFIED") - */ -@property(nonatomic, copy, nullable) NSString *sheetType; - -/** The color of the tab in the UI. */ -@property(nonatomic, strong, nullable) GTLRSheets_Color *tabColor; - -/** The name of the sheet. */ -@property(nonatomic, copy, nullable) NSString *title; - -@end - - -/** - * Sorts data in rows based on a sort order per column. - */ -@interface GTLRSheets_SortRangeRequest : GTLRObject - -/** The range to sort. */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *range; - -/** - * The sort order per column. Later specifications are used when values - * are equal in the earlier specifications. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_SortSpec *> *sortSpecs; - -@end - - -/** - * A sort order associated with a specific column or row. - */ -@interface GTLRSheets_SortSpec : GTLRObject - -/** - * The dimension the sort should be applied to. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *dimensionIndex; - -/** - * The order data should be sorted. - * - * Likely values: - * @arg @c kGTLRSheets_SortSpec_SortOrder_Ascending Sort ascending. (Value: - * "ASCENDING") - * @arg @c kGTLRSheets_SortSpec_SortOrder_Descending Sort descending. (Value: - * "DESCENDING") - * @arg @c kGTLRSheets_SortSpec_SortOrder_SortOrderUnspecified Default value, - * do not use this. (Value: "SORT_ORDER_UNSPECIFIED") - */ -@property(nonatomic, copy, nullable) NSString *sortOrder; - -@end - - -/** - * A combination of a source range and how to extend that source. - */ -@interface GTLRSheets_SourceAndDestination : GTLRObject - -/** - * The dimension that data should be filled into. - * - * Likely values: - * @arg @c kGTLRSheets_SourceAndDestination_Dimension_Columns Operates on the - * columns of a sheet. (Value: "COLUMNS") - * @arg @c kGTLRSheets_SourceAndDestination_Dimension_DimensionUnspecified - * The default value, do not use. (Value: "DIMENSION_UNSPECIFIED") - * @arg @c kGTLRSheets_SourceAndDestination_Dimension_Rows Operates on the - * rows of a sheet. (Value: "ROWS") - */ -@property(nonatomic, copy, nullable) NSString *dimension; - -/** - * The number of rows or columns that data should be filled into. - * Positive numbers expand beyond the last row or last column - * of the source. Negative numbers expand before the first row - * or first column of the source. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *fillLength; - -/** The location of the data to use as the source of the autofill. */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *source; - -@end - - -/** - * Resource that represents a spreadsheet. - */ -@interface GTLRSheets_Spreadsheet : GTLRObject - -/** The developer metadata associated with a spreadsheet. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_DeveloperMetadata *> *developerMetadata; - -/** The named ranges defined in a spreadsheet. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_NamedRange *> *namedRanges; - -/** Overall properties of a spreadsheet. */ -@property(nonatomic, strong, nullable) GTLRSheets_SpreadsheetProperties *properties; - -/** The sheets that are part of a spreadsheet. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_Sheet *> *sheets; - -/** - * The ID of the spreadsheet. - * This field is read-only. - */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * The url of the spreadsheet. - * This field is read-only. - */ -@property(nonatomic, copy, nullable) NSString *spreadsheetUrl; - -@end - - -/** - * Properties of a spreadsheet. - */ -@interface GTLRSheets_SpreadsheetProperties : GTLRObject - -/** - * The amount of time to wait before volatile functions are recalculated. - * - * Likely values: - * @arg @c kGTLRSheets_SpreadsheetProperties_AutoRecalc_Hour Volatile - * functions are updated on every change and hourly. (Value: "HOUR") - * @arg @c kGTLRSheets_SpreadsheetProperties_AutoRecalc_Minute Volatile - * functions are updated on every change and every minute. (Value: - * "MINUTE") - * @arg @c kGTLRSheets_SpreadsheetProperties_AutoRecalc_OnChange Volatile - * functions are updated on every change. (Value: "ON_CHANGE") - * @arg @c kGTLRSheets_SpreadsheetProperties_AutoRecalc_RecalculationIntervalUnspecified - * Default value. This value must not be used. (Value: - * "RECALCULATION_INTERVAL_UNSPECIFIED") - */ -@property(nonatomic, copy, nullable) NSString *autoRecalc; - -/** - * The default format of all cells in the spreadsheet. - * CellData.effectiveFormat will not be set if - * the cell's format is equal to this default format. This field is read-only. - */ -@property(nonatomic, strong, nullable) GTLRSheets_CellFormat *defaultFormat; - -/** - * Determines whether and how circular references are resolved with iterative - * calculation. Absence of this field means that circular references will - * result in calculation errors. - */ -@property(nonatomic, strong, nullable) GTLRSheets_IterativeCalculationSettings *iterativeCalculationSettings; - -/** - * The locale of the spreadsheet in one of the following formats: - * * an ISO 639-1 language code such as `en` - * * an ISO 639-2 language code such as `fil`, if no 639-1 code exists - * * a combination of the ISO language code and country code, such as `en_US` - * Note: when updating this field, not all locales/languages are supported. - */ -@property(nonatomic, copy, nullable) NSString *locale; - -/** - * The time zone of the spreadsheet, in CLDR format such as - * `America/New_York`. If the time zone isn't recognized, this may - * be a custom time zone such as `GMT-07:00`. - */ -@property(nonatomic, copy, nullable) NSString *timeZone; - -/** The title of the spreadsheet. */ -@property(nonatomic, copy, nullable) NSString *title; - -@end - - -/** - * The format of a run of text in a cell. - * Absent values indicate that the field isn't specified. - */ -@interface GTLRSheets_TextFormat : GTLRObject - -/** - * True if the text is bold. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *bold; - -/** The font family. */ -@property(nonatomic, copy, nullable) NSString *fontFamily; - -/** - * The size of the font. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *fontSize; - -/** The foreground color of the text. */ -@property(nonatomic, strong, nullable) GTLRSheets_Color *foregroundColor; - -/** - * True if the text is italicized. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *italic; - -/** - * True if the text has a strikethrough. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *strikethrough; - -/** - * True if the text is underlined. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *underline; - -@end - - -/** - * A run of a text format. The format of this run continues until the start - * index of the next run. - * When updating, all fields must be set. - */ -@interface GTLRSheets_TextFormatRun : GTLRObject - -/** The format of this run. Absent values inherit the cell's format. */ -@property(nonatomic, strong, nullable) GTLRSheets_TextFormat *format; - -/** - * The character index where this run starts. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *startIndex; - -@end - - -/** - * Position settings for text. - */ -@interface GTLRSheets_TextPosition : GTLRObject - -/** - * Horizontal alignment setting for the piece of text. - * - * Likely values: - * @arg @c kGTLRSheets_TextPosition_HorizontalAlignment_Center The text is - * explicitly aligned to the center of the cell. (Value: "CENTER") - * @arg @c kGTLRSheets_TextPosition_HorizontalAlignment_HorizontalAlignUnspecified - * The horizontal alignment is not specified. Do not use this. (Value: - * "HORIZONTAL_ALIGN_UNSPECIFIED") - * @arg @c kGTLRSheets_TextPosition_HorizontalAlignment_Left The text is - * explicitly aligned to the left of the cell. (Value: "LEFT") - * @arg @c kGTLRSheets_TextPosition_HorizontalAlignment_Right The text is - * explicitly aligned to the right of the cell. (Value: "RIGHT") - */ -@property(nonatomic, copy, nullable) NSString *horizontalAlignment; - -@end - - -/** - * The rotation applied to text in a cell. - */ -@interface GTLRSheets_TextRotation : GTLRObject - -/** - * The angle between the standard orientation and the desired orientation. - * Measured in degrees. Valid values are between -90 and 90. Positive - * angles are angled upwards, negative are angled downwards. - * Note: For LTR text direction positive angles are in the counterclockwise - * direction, whereas for RTL they are in the clockwise direction - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *angle; - -/** - * If true, text reads top to bottom, but the orientation of individual - * characters is unchanged. - * For example: - * | V | - * | e | - * | r | - * | t | - * | i | - * | c | - * | a | - * | l | - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *vertical; - -@end - - -/** - * Splits a column of text into multiple columns, - * based on a delimiter in each cell. - */ -@interface GTLRSheets_TextToColumnsRequest : GTLRObject - -/** - * The delimiter to use. Used only if delimiterType is - * CUSTOM. - */ -@property(nonatomic, copy, nullable) NSString *delimiter; - -/** - * The delimiter type to use. - * - * Likely values: - * @arg @c kGTLRSheets_TextToColumnsRequest_DelimiterType_Autodetect - * Automatically detect columns. (Value: "AUTODETECT") - * @arg @c kGTLRSheets_TextToColumnsRequest_DelimiterType_Comma "," (Value: - * "COMMA") - * @arg @c kGTLRSheets_TextToColumnsRequest_DelimiterType_Custom A custom - * value as defined in delimiter. (Value: "CUSTOM") - * @arg @c kGTLRSheets_TextToColumnsRequest_DelimiterType_DelimiterTypeUnspecified - * Default value. This value must not be used. (Value: - * "DELIMITER_TYPE_UNSPECIFIED") - * @arg @c kGTLRSheets_TextToColumnsRequest_DelimiterType_Period "." (Value: - * "PERIOD") - * @arg @c kGTLRSheets_TextToColumnsRequest_DelimiterType_Semicolon ";" - * (Value: "SEMICOLON") - * @arg @c kGTLRSheets_TextToColumnsRequest_DelimiterType_Space " " (Value: - * "SPACE") - */ -@property(nonatomic, copy, nullable) NSString *delimiterType; - -/** The source data range. This must span exactly one column. */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *source; - -@end - - -/** - * A color scale for a treemap chart. - */ -@interface GTLRSheets_TreemapChartColorScale : GTLRObject - -/** - * The background color for cells with a color value greater than or equal - * to maxValue. Defaults to #109618 if not - * specified. - */ -@property(nonatomic, strong, nullable) GTLRSheets_Color *maxValueColor; - -/** - * The background color for cells with a color value at the midpoint between - * minValue and - * maxValue. Defaults to #efe6dc if not - * specified. - */ -@property(nonatomic, strong, nullable) GTLRSheets_Color *midValueColor; - -/** - * The background color for cells with a color value less than or equal to - * minValue. Defaults to #dc3912 if not - * specified. - */ -@property(nonatomic, strong, nullable) GTLRSheets_Color *minValueColor; - -/** - * The background color for cells that have no color data associated with - * them. Defaults to #000000 if not specified. - */ -@property(nonatomic, strong, nullable) GTLRSheets_Color *noDataColor; - -@end - - -/** - * A <a href="/chart/interactive/docs/gallery/treemap">Treemap chart</a>. - */ -@interface GTLRSheets_TreemapChartSpec : GTLRObject - -/** - * The data that determines the background color of each treemap data cell. - * This field is optional. If not specified, size_data is used to - * determine background colors. If specified, the data is expected to be - * numeric. color_scale will determine how the values in this data map to - * data cell background colors. - */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartData *colorData; - -/** - * The color scale for data cells in the treemap chart. Data cells are - * assigned colors based on their color values. These color values come from - * color_data, or from size_data if color_data is not specified. - * Cells with color values less than or equal to min_value will - * have minValueColor as their - * background color. Cells with color values greater than or equal to - * max_value will have - * maxValueColor as their background - * color. Cells with color values between min_value and max_value will - * have background colors on a gradient between - * minValueColor and - * maxValueColor, the midpoint of - * the gradient being midValueColor. - * Cells with missing or non-numeric color values will have - * noDataColor as their background - * color. - */ -@property(nonatomic, strong, nullable) GTLRSheets_TreemapChartColorScale *colorScale; - -/** The background color for header cells. */ -@property(nonatomic, strong, nullable) GTLRSheets_Color *headerColor; - -/** - * True to hide tooltips. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *hideTooltips; - -/** - * The number of additional data levels beyond the labeled levels to be shown - * on the treemap chart. These levels are not interactive and are shown - * without their labels. Defaults to 0 if not specified. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *hintedLevels; - -/** The data that contains the treemap cell labels. */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartData *labels; - -/** - * The number of data levels to show on the treemap chart. These levels are - * interactive and are shown with their labels. Defaults to 2 if not - * specified. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *levels; - -/** - * The maximum possible data value. Cells with values greater than this will - * have the same color as cells with this value. If not specified, defaults - * to the actual maximum value from color_data, or the maximum value from - * size_data if color_data is not specified. - * - * Uses NSNumber of doubleValue. - */ -@property(nonatomic, strong, nullable) NSNumber *maxValue; - -/** - * The minimum possible data value. Cells with values less than this will - * have the same color as cells with this value. If not specified, defaults - * to the actual minimum value from color_data, or the minimum value from - * size_data if color_data is not specified. - * - * Uses NSNumber of doubleValue. - */ -@property(nonatomic, strong, nullable) NSNumber *minValue; - -/** The data the contains the treemap cells' parent labels. */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartData *parentLabels; - -/** - * The data that determines the size of each treemap data cell. This data is - * expected to be numeric. The cells corresponding to non-numeric or missing - * data will not be rendered. If color_data is not specified, this data - * is used to determine data cell background colors as well. - */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartData *sizeData; - -/** The text format for all labels on the chart. */ -@property(nonatomic, strong, nullable) GTLRSheets_TextFormat *textFormat; - -@end - - -/** - * Unmerges cells in the given range. - */ -@interface GTLRSheets_UnmergeCellsRequest : GTLRObject - -/** - * The range within which all cells should be unmerged. - * If the range spans multiple merges, all will be unmerged. - * The range must not partially span any merge. - */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *range; - -@end - - -/** - * Updates properties of the supplied banded range. - */ -@interface GTLRSheets_UpdateBandingRequest : GTLRObject - -/** The banded range to update with the new properties. */ -@property(nonatomic, strong, nullable) GTLRSheets_BandedRange *bandedRange; - -/** - * The fields that should be updated. At least one field must be specified. - * The root `bandedRange` is implied and should not be specified. - * A single `"*"` can be used as short-hand for listing every field. - * - * String format is a comma-separated list of fields. - */ -@property(nonatomic, copy, nullable) NSString *fields; - -@end - - -/** - * Updates the borders of a range. - * If a field is not set in the request, that means the border remains as-is. - * For example, with two subsequent UpdateBordersRequest: - * 1. range: A1:A5 `{ top: RED, bottom: WHITE }` - * 2. range: A1:A5 `{ left: BLUE }` - * That would result in A1:A5 having a borders of - * `{ top: RED, bottom: WHITE, left: BLUE }`. - * If you want to clear a border, explicitly set the style to - * NONE. - */ -@interface GTLRSheets_UpdateBordersRequest : GTLRObject - -/** The border to put at the bottom of the range. */ -@property(nonatomic, strong, nullable) GTLRSheets_Border *bottom; - -/** The horizontal border to put within the range. */ -@property(nonatomic, strong, nullable) GTLRSheets_Border *innerHorizontal; - -/** The vertical border to put within the range. */ -@property(nonatomic, strong, nullable) GTLRSheets_Border *innerVertical; - -/** The border to put at the left of the range. */ -@property(nonatomic, strong, nullable) GTLRSheets_Border *left; - -/** The range whose borders should be updated. */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *range; - -/** The border to put at the right of the range. */ -@property(nonatomic, strong, nullable) GTLRSheets_Border *right; - -/** The border to put at the top of the range. */ -@property(nonatomic, strong, nullable) GTLRSheets_Border *top; - -@end - - -/** - * Updates all cells in a range with new data. - */ -@interface GTLRSheets_UpdateCellsRequest : GTLRObject - -/** - * The fields of CellData that should be updated. - * At least one field must be specified. - * The root is the CellData; 'row.values.' should not be specified. - * A single `"*"` can be used as short-hand for listing every field. - * - * String format is a comma-separated list of fields. - */ -@property(nonatomic, copy, nullable) NSString *fields; - -/** - * The range to write data to. - * If the data in rows does not cover the entire requested range, - * the fields matching those set in fields will be cleared. - */ -@property(nonatomic, strong, nullable) GTLRSheets_GridRange *range; - -/** The data to write. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_RowData *> *rows; - -/** - * The coordinate to start writing data at. - * Any number of rows and columns (including a different number of - * columns per row) may be written. - */ -@property(nonatomic, strong, nullable) GTLRSheets_GridCoordinate *start; - -@end - - -/** - * Updates a chart's specifications. - * (This does not move or resize a chart. To move or resize a chart, use - * UpdateEmbeddedObjectPositionRequest.) - */ -@interface GTLRSheets_UpdateChartSpecRequest : GTLRObject - -/** - * The ID of the chart to update. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *chartId; - -/** The specification to apply to the chart. */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartSpec *spec; - -@end - - -/** - * Updates a conditional format rule at the given index, - * or moves a conditional format rule to another index. - */ -@interface GTLRSheets_UpdateConditionalFormatRuleRequest : GTLRObject - -/** - * The zero-based index of the rule that should be replaced or moved. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *index; - -/** - * The zero-based new index the rule should end up at. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *newIndex NS_RETURNS_NOT_RETAINED; - -/** The rule that should replace the rule at the given index. */ -@property(nonatomic, strong, nullable) GTLRSheets_ConditionalFormatRule *rule; - -/** - * The sheet of the rule to move. Required if new_index is set, - * unused otherwise. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *sheetId; - -@end - - -/** - * The result of updating a conditional format rule. - */ -@interface GTLRSheets_UpdateConditionalFormatRuleResponse : GTLRObject - -/** - * The index of the new rule. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *newIndex NS_RETURNS_NOT_RETAINED; - -/** - * The new rule that replaced the old rule (if replacing), - * or the rule that was moved (if moved) - */ -@property(nonatomic, strong, nullable) GTLRSheets_ConditionalFormatRule *newRule NS_RETURNS_NOT_RETAINED; - -/** - * The old index of the rule. Not set if a rule was replaced - * (because it is the same as new_index). - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *oldIndex; - -/** - * The old (deleted) rule. Not set if a rule was moved - * (because it is the same as new_rule). - */ -@property(nonatomic, strong, nullable) GTLRSheets_ConditionalFormatRule *oldRule; - -@end - - -/** - * A request to update properties of developer metadata. - * Updates the properties of the developer metadata selected by the filters to - * the values provided in the DeveloperMetadata resource. Callers must - * specify the properties they wish to update in the fields parameter, as well - * as specify at least one DataFilter matching the metadata they wish to - * update. - */ -@interface GTLRSheets_UpdateDeveloperMetadataRequest : GTLRObject - -/** The filters matching the developer metadata entries to update. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_DataFilter *> *dataFilters; - -/** - * The value that all metadata matched by the data filters will be updated to. - */ -@property(nonatomic, strong, nullable) GTLRSheets_DeveloperMetadata *developerMetadata; - -/** - * The fields that should be updated. At least one field must be specified. - * The root `developerMetadata` is implied and should not be specified. - * A single `"*"` can be used as short-hand for listing every field. - * - * String format is a comma-separated list of fields. - */ -@property(nonatomic, copy, nullable) NSString *fields; - -@end - - -/** - * The response from updating developer metadata. - */ -@interface GTLRSheets_UpdateDeveloperMetadataResponse : GTLRObject - -/** The updated developer metadata. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_DeveloperMetadata *> *developerMetadata; - -@end - - -/** - * Updates the state of the specified group. - */ -@interface GTLRSheets_UpdateDimensionGroupRequest : GTLRObject - -/** - * The group whose state should be updated. The range and depth of the group - * should specify a valid group on the sheet, and all other fields updated. - */ -@property(nonatomic, strong, nullable) GTLRSheets_DimensionGroup *dimensionGroup; - -/** - * The fields that should be updated. At least one field must be specified. - * The root `dimensionGroup` is implied and should not be specified. - * A single `"*"` can be used as short-hand for listing every field. - * - * String format is a comma-separated list of fields. - */ -@property(nonatomic, copy, nullable) NSString *fields; - -@end - - -/** - * Updates properties of dimensions within the specified range. - */ -@interface GTLRSheets_UpdateDimensionPropertiesRequest : GTLRObject - -/** - * The fields that should be updated. At least one field must be specified. - * The root `properties` is implied and should not be specified. - * A single `"*"` can be used as short-hand for listing every field. - * - * String format is a comma-separated list of fields. - */ -@property(nonatomic, copy, nullable) NSString *fields; - -/** Properties to update. */ -@property(nonatomic, strong, nullable) GTLRSheets_DimensionProperties *properties; - -/** The rows or columns to update. */ -@property(nonatomic, strong, nullable) GTLRSheets_DimensionRange *range; - -@end - - -/** - * Update an embedded object's position (such as a moving or resizing a - * chart or image). - */ -@interface GTLRSheets_UpdateEmbeddedObjectPositionRequest : GTLRObject - -/** - * The fields of OverlayPosition - * that should be updated when setting a new position. Used only if - * newPosition.overlayPosition - * is set, in which case at least one field must - * be specified. The root `newPosition.overlayPosition` is implied and - * should not be specified. - * A single `"*"` can be used as short-hand for listing every field. - * - * String format is a comma-separated list of fields. - */ -@property(nonatomic, copy, nullable) NSString *fields; - -/** - * An explicit position to move the embedded object to. - * If newPosition.sheetId is set, - * a new sheet with that ID will be created. - * If newPosition.newSheet is set to true, - * a new sheet will be created with an ID that will be chosen for you. - */ -@property(nonatomic, strong, nullable) GTLRSheets_EmbeddedObjectPosition *newPosition NS_RETURNS_NOT_RETAINED; - -/** - * The ID of the object to moved. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *objectId; - -@end - - -/** - * The result of updating an embedded object's position. - */ -@interface GTLRSheets_UpdateEmbeddedObjectPositionResponse : GTLRObject - -/** The new position of the embedded object. */ -@property(nonatomic, strong, nullable) GTLRSheets_EmbeddedObjectPosition *position; - -@end - - -/** - * Updates properties of the filter view. - */ -@interface GTLRSheets_UpdateFilterViewRequest : GTLRObject - -/** - * The fields that should be updated. At least one field must be specified. - * The root `filter` is implied and should not be specified. - * A single `"*"` can be used as short-hand for listing every field. - * - * String format is a comma-separated list of fields. - */ -@property(nonatomic, copy, nullable) NSString *fields; - -/** The new properties of the filter view. */ -@property(nonatomic, strong, nullable) GTLRSheets_FilterView *filter; - -@end - - -/** - * Updates properties of the named range with the specified - * namedRangeId. - */ -@interface GTLRSheets_UpdateNamedRangeRequest : GTLRObject - -/** - * The fields that should be updated. At least one field must be specified. - * The root `namedRange` is implied and should not be specified. - * A single `"*"` can be used as short-hand for listing every field. - * - * String format is a comma-separated list of fields. - */ -@property(nonatomic, copy, nullable) NSString *fields; - -/** The named range to update with the new properties. */ -@property(nonatomic, strong, nullable) GTLRSheets_NamedRange *namedRange; - -@end - - -/** - * Updates an existing protected range with the specified - * protectedRangeId. - */ -@interface GTLRSheets_UpdateProtectedRangeRequest : GTLRObject - -/** - * The fields that should be updated. At least one field must be specified. - * The root `protectedRange` is implied and should not be specified. - * A single `"*"` can be used as short-hand for listing every field. - * - * String format is a comma-separated list of fields. - */ -@property(nonatomic, copy, nullable) NSString *fields; - -/** The protected range to update with the new properties. */ -@property(nonatomic, strong, nullable) GTLRSheets_ProtectedRange *protectedRange; - -@end - - -/** - * Updates properties of the sheet with the specified - * sheetId. - */ -@interface GTLRSheets_UpdateSheetPropertiesRequest : GTLRObject - -/** - * The fields that should be updated. At least one field must be specified. - * The root `properties` is implied and should not be specified. - * A single `"*"` can be used as short-hand for listing every field. - * - * String format is a comma-separated list of fields. - */ -@property(nonatomic, copy, nullable) NSString *fields; - -/** The properties to update. */ -@property(nonatomic, strong, nullable) GTLRSheets_SheetProperties *properties; - -@end - - -/** - * Updates properties of a spreadsheet. - */ -@interface GTLRSheets_UpdateSpreadsheetPropertiesRequest : GTLRObject - -/** - * The fields that should be updated. At least one field must be specified. - * The root 'properties' is implied and should not be specified. - * A single `"*"` can be used as short-hand for listing every field. - * - * String format is a comma-separated list of fields. - */ -@property(nonatomic, copy, nullable) NSString *fields; - -/** The properties to update. */ -@property(nonatomic, strong, nullable) GTLRSheets_SpreadsheetProperties *properties; - -@end - - -/** - * The response when updating a range of values by a data filter in a - * spreadsheet. - */ -@interface GTLRSheets_UpdateValuesByDataFilterResponse : GTLRObject - -/** The data filter that selected the range that was updated. */ -@property(nonatomic, strong, nullable) GTLRSheets_DataFilter *dataFilter; - -/** - * The number of cells updated. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *updatedCells; - -/** - * The number of columns where at least one cell in the column was updated. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *updatedColumns; - -/** - * The values of the cells in the range matched by the dataFilter after all - * updates were applied. This is only included if the request's - * `includeValuesInResponse` field was `true`. - */ -@property(nonatomic, strong, nullable) GTLRSheets_ValueRange *updatedData; - -/** The range (in A1 notation) that updates were applied to. */ -@property(nonatomic, copy, nullable) NSString *updatedRange; - -/** - * The number of rows where at least one cell in the row was updated. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *updatedRows; - -@end - - -/** - * The response when updating a range of values in a spreadsheet. - */ -@interface GTLRSheets_UpdateValuesResponse : GTLRObject - -/** The spreadsheet the updates were applied to. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * The number of cells updated. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *updatedCells; - -/** - * The number of columns where at least one cell in the column was updated. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *updatedColumns; - -/** - * The values of the cells after updates were applied. - * This is only included if the request's `includeValuesInResponse` field - * was `true`. - */ -@property(nonatomic, strong, nullable) GTLRSheets_ValueRange *updatedData; - -/** The range (in A1 notation) that updates were applied to. */ -@property(nonatomic, copy, nullable) NSString *updatedRange; - -/** - * The number of rows where at least one cell in the row was updated. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *updatedRows; - -@end - - -/** - * Data within a range of the spreadsheet. - */ -@interface GTLRSheets_ValueRange : GTLRObject - -/** - * The major dimension of the values. - * For output, if the spreadsheet data is: `A1=1,B1=2,A2=3,B2=4`, - * then requesting `range=A1:B2,majorDimension=ROWS` will return - * `[[1,2],[3,4]]`, - * whereas requesting `range=A1:B2,majorDimension=COLUMNS` will return - * `[[1,3],[2,4]]`. - * For input, with `range=A1:B2,majorDimension=ROWS` then `[[1,2],[3,4]]` - * will set `A1=1,B1=2,A2=3,B2=4`. With `range=A1:B2,majorDimension=COLUMNS` - * then `[[1,2],[3,4]]` will set `A1=1,B1=3,A2=2,B2=4`. - * When writing, if this field is not set, it defaults to ROWS. - * - * Likely values: - * @arg @c kGTLRSheets_ValueRange_MajorDimension_Columns Operates on the - * columns of a sheet. (Value: "COLUMNS") - * @arg @c kGTLRSheets_ValueRange_MajorDimension_DimensionUnspecified The - * default value, do not use. (Value: "DIMENSION_UNSPECIFIED") - * @arg @c kGTLRSheets_ValueRange_MajorDimension_Rows Operates on the rows of - * a sheet. (Value: "ROWS") - */ -@property(nonatomic, copy, nullable) NSString *majorDimension; - -/** - * The range the values cover, in A1 notation. - * For output, this range indicates the entire requested range, - * even though the values will exclude trailing rows and columns. - * When appending values, this field represents the range to search for a - * table, after which values will be appended. - */ -@property(nonatomic, copy, nullable) NSString *range; - -/** - * The data that was read or to be written. This is an array of arrays, - * the outer array representing all the data and each inner array - * representing a major dimension. Each item in the inner array - * corresponds with one cell. - * For output, empty trailing rows and columns will not be included. - * For input, supported value types are: bool, string, and double. - * Null values will be skipped. - * To set a cell to an empty value, set the string value to an empty string. - * - * Can be any valid JSON type. - */ -@property(nonatomic, strong, nullable) NSArray<NSArray *> *values; - -@end - - -/** - * Styles for a waterfall chart column. - */ -@interface GTLRSheets_WaterfallChartColumnStyle : GTLRObject - -/** The color of the column. */ -@property(nonatomic, strong, nullable) GTLRSheets_Color *color; - -/** The label of the column's legend. */ -@property(nonatomic, copy, nullable) NSString *label; - -@end - - -/** - * A custom subtotal column for a waterfall chart series. - */ -@interface GTLRSheets_WaterfallChartCustomSubtotal : GTLRObject - -/** - * True if the data point at subtotal_index is the subtotal. If false, - * the subtotal will be computed and appear after the data point. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *dataIsSubtotal; - -/** A label for the subtotal column. */ -@property(nonatomic, copy, nullable) NSString *label; - -/** - * The 0-based index of a data point within the series. If - * data_is_subtotal is true, the data point at this index is the - * subtotal. Otherwise, the subtotal appears after the data point with - * this index. A series can have multiple subtotals at arbitrary indices, - * but subtotals do not affect the indices of the data points. For - * example, if a series has three data points, their indices will always - * be 0, 1, and 2, regardless of how many subtotals exist on the series or - * what data points they are associated with. - * - * Uses NSNumber of intValue. - */ -@property(nonatomic, strong, nullable) NSNumber *subtotalIndex; - -@end - - -/** - * The domain of a waterfall chart. - */ -@interface GTLRSheets_WaterfallChartDomain : GTLRObject - -/** The data of the WaterfallChartDomain. */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartData *data; - -/** - * True to reverse the order of the domain values (horizontal axis). - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *reversed; - -@end - - -/** - * A single series of data for a waterfall chart. - */ -@interface GTLRSheets_WaterfallChartSeries : GTLRObject - -/** - * Custom subtotal columns appearing in this series. The order in which - * subtotals are defined is not significant. Only one subtotal may be - * defined for each data point. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_WaterfallChartCustomSubtotal *> *customSubtotals; - -/** The data being visualized in this series. */ -@property(nonatomic, strong, nullable) GTLRSheets_ChartData *data; - -/** - * True to hide the subtotal column from the end of the series. By default, - * a subtotal column will appear at the end of each series. Setting this - * field to true will hide that subtotal column for this series. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *hideTrailingSubtotal; - -/** Styles for all columns in this series with negative values. */ -@property(nonatomic, strong, nullable) GTLRSheets_WaterfallChartColumnStyle *negativeColumnsStyle; - -/** Styles for all columns in this series with positive values. */ -@property(nonatomic, strong, nullable) GTLRSheets_WaterfallChartColumnStyle *positiveColumnsStyle; - -/** Styles for all subtotal columns in this series. */ -@property(nonatomic, strong, nullable) GTLRSheets_WaterfallChartColumnStyle *subtotalColumnsStyle; - -@end - - -/** - * A waterfall chart. - */ -@interface GTLRSheets_WaterfallChartSpec : GTLRObject - -/** The line style for the connector lines. */ -@property(nonatomic, strong, nullable) GTLRSheets_LineStyle *connectorLineStyle; - -/** The domain data (horizontal axis) for the waterfall chart. */ -@property(nonatomic, strong, nullable) GTLRSheets_WaterfallChartDomain *domain; - -/** - * True to interpret the first value as a total. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *firstValueIsTotal; - -/** - * True to hide connector lines between columns. - * - * Uses NSNumber of boolValue. - */ -@property(nonatomic, strong, nullable) NSNumber *hideConnectorLines; - -/** The data this waterfall chart is visualizing. */ -@property(nonatomic, strong, nullable) NSArray<GTLRSheets_WaterfallChartSeries *> *series; - -/** - * The stacked type. - * - * Likely values: - * @arg @c kGTLRSheets_WaterfallChartSpec_StackedType_Sequential Series will - * spread out along the horizontal axis. (Value: "SEQUENTIAL") - * @arg @c kGTLRSheets_WaterfallChartSpec_StackedType_Stacked Values - * corresponding to the same domain (horizontal axis) value will be - * stacked vertically. (Value: "STACKED") - * @arg @c kGTLRSheets_WaterfallChartSpec_StackedType_WaterfallStackedTypeUnspecified - * Default value, do not use. (Value: - * "WATERFALL_STACKED_TYPE_UNSPECIFIED") - */ -@property(nonatomic, copy, nullable) NSString *stackedType; - -@end - -NS_ASSUME_NONNULL_END - -#pragma clang diagnostic pop diff --git a/Pods/GoogleAPIClientForREST/Source/GeneratedServices/Sheets/GTLRSheetsObjects.m b/Pods/GoogleAPIClientForREST/Source/GeneratedServices/Sheets/GTLRSheetsObjects.m @@ -1,2856 +0,0 @@ -// NOTE: This file was generated by the ServiceGenerator. - -// ---------------------------------------------------------------------------- -// API: -// Google Sheets API (sheets/v4) -// Description: -// Reads and writes Google Sheets. -// Documentation: -// https://developers.google.com/sheets/ - -#import "GTLRSheetsObjects.h" - -// ---------------------------------------------------------------------------- -// Constants - -// GTLRSheets_AppendDimensionRequest.dimension -NSString * const kGTLRSheets_AppendDimensionRequest_Dimension_Columns = @"COLUMNS"; -NSString * const kGTLRSheets_AppendDimensionRequest_Dimension_DimensionUnspecified = @"DIMENSION_UNSPECIFIED"; -NSString * const kGTLRSheets_AppendDimensionRequest_Dimension_Rows = @"ROWS"; - -// GTLRSheets_BasicChartAxis.position -NSString * const kGTLRSheets_BasicChartAxis_Position_BasicChartAxisPositionUnspecified = @"BASIC_CHART_AXIS_POSITION_UNSPECIFIED"; -NSString * const kGTLRSheets_BasicChartAxis_Position_BottomAxis = @"BOTTOM_AXIS"; -NSString * const kGTLRSheets_BasicChartAxis_Position_LeftAxis = @"LEFT_AXIS"; -NSString * const kGTLRSheets_BasicChartAxis_Position_RightAxis = @"RIGHT_AXIS"; - -// GTLRSheets_BasicChartSeries.targetAxis -NSString * const kGTLRSheets_BasicChartSeries_TargetAxis_BasicChartAxisPositionUnspecified = @"BASIC_CHART_AXIS_POSITION_UNSPECIFIED"; -NSString * const kGTLRSheets_BasicChartSeries_TargetAxis_BottomAxis = @"BOTTOM_AXIS"; -NSString * const kGTLRSheets_BasicChartSeries_TargetAxis_LeftAxis = @"LEFT_AXIS"; -NSString * const kGTLRSheets_BasicChartSeries_TargetAxis_RightAxis = @"RIGHT_AXIS"; - -// GTLRSheets_BasicChartSeries.type -NSString * const kGTLRSheets_BasicChartSeries_Type_Area = @"AREA"; -NSString * const kGTLRSheets_BasicChartSeries_Type_Bar = @"BAR"; -NSString * const kGTLRSheets_BasicChartSeries_Type_BasicChartTypeUnspecified = @"BASIC_CHART_TYPE_UNSPECIFIED"; -NSString * const kGTLRSheets_BasicChartSeries_Type_Column = @"COLUMN"; -NSString * const kGTLRSheets_BasicChartSeries_Type_Combo = @"COMBO"; -NSString * const kGTLRSheets_BasicChartSeries_Type_Line = @"LINE"; -NSString * const kGTLRSheets_BasicChartSeries_Type_Scatter = @"SCATTER"; -NSString * const kGTLRSheets_BasicChartSeries_Type_SteppedArea = @"STEPPED_AREA"; - -// GTLRSheets_BasicChartSpec.chartType -NSString * const kGTLRSheets_BasicChartSpec_ChartType_Area = @"AREA"; -NSString * const kGTLRSheets_BasicChartSpec_ChartType_Bar = @"BAR"; -NSString * const kGTLRSheets_BasicChartSpec_ChartType_BasicChartTypeUnspecified = @"BASIC_CHART_TYPE_UNSPECIFIED"; -NSString * const kGTLRSheets_BasicChartSpec_ChartType_Column = @"COLUMN"; -NSString * const kGTLRSheets_BasicChartSpec_ChartType_Combo = @"COMBO"; -NSString * const kGTLRSheets_BasicChartSpec_ChartType_Line = @"LINE"; -NSString * const kGTLRSheets_BasicChartSpec_ChartType_Scatter = @"SCATTER"; -NSString * const kGTLRSheets_BasicChartSpec_ChartType_SteppedArea = @"STEPPED_AREA"; - -// GTLRSheets_BasicChartSpec.compareMode -NSString * const kGTLRSheets_BasicChartSpec_CompareMode_BasicChartCompareModeUnspecified = @"BASIC_CHART_COMPARE_MODE_UNSPECIFIED"; -NSString * const kGTLRSheets_BasicChartSpec_CompareMode_Category = @"CATEGORY"; -NSString * const kGTLRSheets_BasicChartSpec_CompareMode_Datum = @"DATUM"; - -// GTLRSheets_BasicChartSpec.legendPosition -NSString * const kGTLRSheets_BasicChartSpec_LegendPosition_BasicChartLegendPositionUnspecified = @"BASIC_CHART_LEGEND_POSITION_UNSPECIFIED"; -NSString * const kGTLRSheets_BasicChartSpec_LegendPosition_BottomLegend = @"BOTTOM_LEGEND"; -NSString * const kGTLRSheets_BasicChartSpec_LegendPosition_LeftLegend = @"LEFT_LEGEND"; -NSString * const kGTLRSheets_BasicChartSpec_LegendPosition_NoLegend = @"NO_LEGEND"; -NSString * const kGTLRSheets_BasicChartSpec_LegendPosition_RightLegend = @"RIGHT_LEGEND"; -NSString * const kGTLRSheets_BasicChartSpec_LegendPosition_TopLegend = @"TOP_LEGEND"; - -// GTLRSheets_BasicChartSpec.stackedType -NSString * const kGTLRSheets_BasicChartSpec_StackedType_BasicChartStackedTypeUnspecified = @"BASIC_CHART_STACKED_TYPE_UNSPECIFIED"; -NSString * const kGTLRSheets_BasicChartSpec_StackedType_NotStacked = @"NOT_STACKED"; -NSString * const kGTLRSheets_BasicChartSpec_StackedType_PercentStacked = @"PERCENT_STACKED"; -NSString * const kGTLRSheets_BasicChartSpec_StackedType_Stacked = @"STACKED"; - -// GTLRSheets_BatchGetValuesByDataFilterRequest.dateTimeRenderOption -NSString * const kGTLRSheets_BatchGetValuesByDataFilterRequest_DateTimeRenderOption_FormattedString = @"FORMATTED_STRING"; -NSString * const kGTLRSheets_BatchGetValuesByDataFilterRequest_DateTimeRenderOption_SerialNumber = @"SERIAL_NUMBER"; - -// GTLRSheets_BatchGetValuesByDataFilterRequest.majorDimension -NSString * const kGTLRSheets_BatchGetValuesByDataFilterRequest_MajorDimension_Columns = @"COLUMNS"; -NSString * const kGTLRSheets_BatchGetValuesByDataFilterRequest_MajorDimension_DimensionUnspecified = @"DIMENSION_UNSPECIFIED"; -NSString * const kGTLRSheets_BatchGetValuesByDataFilterRequest_MajorDimension_Rows = @"ROWS"; - -// GTLRSheets_BatchGetValuesByDataFilterRequest.valueRenderOption -NSString * const kGTLRSheets_BatchGetValuesByDataFilterRequest_ValueRenderOption_FormattedValue = @"FORMATTED_VALUE"; -NSString * const kGTLRSheets_BatchGetValuesByDataFilterRequest_ValueRenderOption_Formula = @"FORMULA"; -NSString * const kGTLRSheets_BatchGetValuesByDataFilterRequest_ValueRenderOption_UnformattedValue = @"UNFORMATTED_VALUE"; - -// GTLRSheets_BatchUpdateValuesByDataFilterRequest.responseDateTimeRenderOption -NSString * const kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ResponseDateTimeRenderOption_FormattedString = @"FORMATTED_STRING"; -NSString * const kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ResponseDateTimeRenderOption_SerialNumber = @"SERIAL_NUMBER"; - -// GTLRSheets_BatchUpdateValuesByDataFilterRequest.responseValueRenderOption -NSString * const kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ResponseValueRenderOption_FormattedValue = @"FORMATTED_VALUE"; -NSString * const kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ResponseValueRenderOption_Formula = @"FORMULA"; -NSString * const kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ResponseValueRenderOption_UnformattedValue = @"UNFORMATTED_VALUE"; - -// GTLRSheets_BatchUpdateValuesByDataFilterRequest.valueInputOption -NSString * const kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ValueInputOption_InputValueOptionUnspecified = @"INPUT_VALUE_OPTION_UNSPECIFIED"; -NSString * const kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ValueInputOption_Raw = @"RAW"; -NSString * const kGTLRSheets_BatchUpdateValuesByDataFilterRequest_ValueInputOption_UserEntered = @"USER_ENTERED"; - -// GTLRSheets_BatchUpdateValuesRequest.responseDateTimeRenderOption -NSString * const kGTLRSheets_BatchUpdateValuesRequest_ResponseDateTimeRenderOption_FormattedString = @"FORMATTED_STRING"; -NSString * const kGTLRSheets_BatchUpdateValuesRequest_ResponseDateTimeRenderOption_SerialNumber = @"SERIAL_NUMBER"; - -// GTLRSheets_BatchUpdateValuesRequest.responseValueRenderOption -NSString * const kGTLRSheets_BatchUpdateValuesRequest_ResponseValueRenderOption_FormattedValue = @"FORMATTED_VALUE"; -NSString * const kGTLRSheets_BatchUpdateValuesRequest_ResponseValueRenderOption_Formula = @"FORMULA"; -NSString * const kGTLRSheets_BatchUpdateValuesRequest_ResponseValueRenderOption_UnformattedValue = @"UNFORMATTED_VALUE"; - -// GTLRSheets_BatchUpdateValuesRequest.valueInputOption -NSString * const kGTLRSheets_BatchUpdateValuesRequest_ValueInputOption_InputValueOptionUnspecified = @"INPUT_VALUE_OPTION_UNSPECIFIED"; -NSString * const kGTLRSheets_BatchUpdateValuesRequest_ValueInputOption_Raw = @"RAW"; -NSString * const kGTLRSheets_BatchUpdateValuesRequest_ValueInputOption_UserEntered = @"USER_ENTERED"; - -// GTLRSheets_BooleanCondition.type -NSString * const kGTLRSheets_BooleanCondition_Type_Blank = @"BLANK"; -NSString * const kGTLRSheets_BooleanCondition_Type_Boolean = @"BOOLEAN"; -NSString * const kGTLRSheets_BooleanCondition_Type_ConditionTypeUnspecified = @"CONDITION_TYPE_UNSPECIFIED"; -NSString * const kGTLRSheets_BooleanCondition_Type_CustomFormula = @"CUSTOM_FORMULA"; -NSString * const kGTLRSheets_BooleanCondition_Type_DateAfter = @"DATE_AFTER"; -NSString * const kGTLRSheets_BooleanCondition_Type_DateBefore = @"DATE_BEFORE"; -NSString * const kGTLRSheets_BooleanCondition_Type_DateBetween = @"DATE_BETWEEN"; -NSString * const kGTLRSheets_BooleanCondition_Type_DateEq = @"DATE_EQ"; -NSString * const kGTLRSheets_BooleanCondition_Type_DateIsValid = @"DATE_IS_VALID"; -NSString * const kGTLRSheets_BooleanCondition_Type_DateNotBetween = @"DATE_NOT_BETWEEN"; -NSString * const kGTLRSheets_BooleanCondition_Type_DateOnOrAfter = @"DATE_ON_OR_AFTER"; -NSString * const kGTLRSheets_BooleanCondition_Type_DateOnOrBefore = @"DATE_ON_OR_BEFORE"; -NSString * const kGTLRSheets_BooleanCondition_Type_NotBlank = @"NOT_BLANK"; -NSString * const kGTLRSheets_BooleanCondition_Type_NumberBetween = @"NUMBER_BETWEEN"; -NSString * const kGTLRSheets_BooleanCondition_Type_NumberEq = @"NUMBER_EQ"; -NSString * const kGTLRSheets_BooleanCondition_Type_NumberGreater = @"NUMBER_GREATER"; -NSString * const kGTLRSheets_BooleanCondition_Type_NumberGreaterThanEq = @"NUMBER_GREATER_THAN_EQ"; -NSString * const kGTLRSheets_BooleanCondition_Type_NumberLess = @"NUMBER_LESS"; -NSString * const kGTLRSheets_BooleanCondition_Type_NumberLessThanEq = @"NUMBER_LESS_THAN_EQ"; -NSString * const kGTLRSheets_BooleanCondition_Type_NumberNotBetween = @"NUMBER_NOT_BETWEEN"; -NSString * const kGTLRSheets_BooleanCondition_Type_NumberNotEq = @"NUMBER_NOT_EQ"; -NSString * const kGTLRSheets_BooleanCondition_Type_OneOfList = @"ONE_OF_LIST"; -NSString * const kGTLRSheets_BooleanCondition_Type_OneOfRange = @"ONE_OF_RANGE"; -NSString * const kGTLRSheets_BooleanCondition_Type_TextContains = @"TEXT_CONTAINS"; -NSString * const kGTLRSheets_BooleanCondition_Type_TextEndsWith = @"TEXT_ENDS_WITH"; -NSString * const kGTLRSheets_BooleanCondition_Type_TextEq = @"TEXT_EQ"; -NSString * const kGTLRSheets_BooleanCondition_Type_TextIsEmail = @"TEXT_IS_EMAIL"; -NSString * const kGTLRSheets_BooleanCondition_Type_TextIsUrl = @"TEXT_IS_URL"; -NSString * const kGTLRSheets_BooleanCondition_Type_TextNotContains = @"TEXT_NOT_CONTAINS"; -NSString * const kGTLRSheets_BooleanCondition_Type_TextStartsWith = @"TEXT_STARTS_WITH"; - -// GTLRSheets_Border.style -NSString * const kGTLRSheets_Border_Style_Dashed = @"DASHED"; -NSString * const kGTLRSheets_Border_Style_Dotted = @"DOTTED"; -NSString * const kGTLRSheets_Border_Style_Double = @"DOUBLE"; -NSString * const kGTLRSheets_Border_Style_None = @"NONE"; -NSString * const kGTLRSheets_Border_Style_Solid = @"SOLID"; -NSString * const kGTLRSheets_Border_Style_SolidMedium = @"SOLID_MEDIUM"; -NSString * const kGTLRSheets_Border_Style_SolidThick = @"SOLID_THICK"; -NSString * const kGTLRSheets_Border_Style_StyleUnspecified = @"STYLE_UNSPECIFIED"; - -// GTLRSheets_BubbleChartSpec.legendPosition -NSString * const kGTLRSheets_BubbleChartSpec_LegendPosition_BottomLegend = @"BOTTOM_LEGEND"; -NSString * const kGTLRSheets_BubbleChartSpec_LegendPosition_BubbleChartLegendPositionUnspecified = @"BUBBLE_CHART_LEGEND_POSITION_UNSPECIFIED"; -NSString * const kGTLRSheets_BubbleChartSpec_LegendPosition_InsideLegend = @"INSIDE_LEGEND"; -NSString * const kGTLRSheets_BubbleChartSpec_LegendPosition_LeftLegend = @"LEFT_LEGEND"; -NSString * const kGTLRSheets_BubbleChartSpec_LegendPosition_NoLegend = @"NO_LEGEND"; -NSString * const kGTLRSheets_BubbleChartSpec_LegendPosition_RightLegend = @"RIGHT_LEGEND"; -NSString * const kGTLRSheets_BubbleChartSpec_LegendPosition_TopLegend = @"TOP_LEGEND"; - -// GTLRSheets_CellFormat.horizontalAlignment -NSString * const kGTLRSheets_CellFormat_HorizontalAlignment_Center = @"CENTER"; -NSString * const kGTLRSheets_CellFormat_HorizontalAlignment_HorizontalAlignUnspecified = @"HORIZONTAL_ALIGN_UNSPECIFIED"; -NSString * const kGTLRSheets_CellFormat_HorizontalAlignment_Left = @"LEFT"; -NSString * const kGTLRSheets_CellFormat_HorizontalAlignment_Right = @"RIGHT"; - -// GTLRSheets_CellFormat.hyperlinkDisplayType -NSString * const kGTLRSheets_CellFormat_HyperlinkDisplayType_HyperlinkDisplayTypeUnspecified = @"HYPERLINK_DISPLAY_TYPE_UNSPECIFIED"; -NSString * const kGTLRSheets_CellFormat_HyperlinkDisplayType_Linked = @"LINKED"; -NSString * const kGTLRSheets_CellFormat_HyperlinkDisplayType_PlainText = @"PLAIN_TEXT"; - -// GTLRSheets_CellFormat.textDirection -NSString * const kGTLRSheets_CellFormat_TextDirection_LeftToRight = @"LEFT_TO_RIGHT"; -NSString * const kGTLRSheets_CellFormat_TextDirection_RightToLeft = @"RIGHT_TO_LEFT"; -NSString * const kGTLRSheets_CellFormat_TextDirection_TextDirectionUnspecified = @"TEXT_DIRECTION_UNSPECIFIED"; - -// GTLRSheets_CellFormat.verticalAlignment -NSString * const kGTLRSheets_CellFormat_VerticalAlignment_Bottom = @"BOTTOM"; -NSString * const kGTLRSheets_CellFormat_VerticalAlignment_Middle = @"MIDDLE"; -NSString * const kGTLRSheets_CellFormat_VerticalAlignment_Top = @"TOP"; -NSString * const kGTLRSheets_CellFormat_VerticalAlignment_VerticalAlignUnspecified = @"VERTICAL_ALIGN_UNSPECIFIED"; - -// GTLRSheets_CellFormat.wrapStrategy -NSString * const kGTLRSheets_CellFormat_WrapStrategy_Clip = @"CLIP"; -NSString * const kGTLRSheets_CellFormat_WrapStrategy_LegacyWrap = @"LEGACY_WRAP"; -NSString * const kGTLRSheets_CellFormat_WrapStrategy_OverflowCell = @"OVERFLOW_CELL"; -NSString * const kGTLRSheets_CellFormat_WrapStrategy_Wrap = @"WRAP"; -NSString * const kGTLRSheets_CellFormat_WrapStrategy_WrapStrategyUnspecified = @"WRAP_STRATEGY_UNSPECIFIED"; - -// GTLRSheets_ChartSpec.hiddenDimensionStrategy -NSString * const kGTLRSheets_ChartSpec_HiddenDimensionStrategy_ChartHiddenDimensionStrategyUnspecified = @"CHART_HIDDEN_DIMENSION_STRATEGY_UNSPECIFIED"; -NSString * const kGTLRSheets_ChartSpec_HiddenDimensionStrategy_ShowAll = @"SHOW_ALL"; -NSString * const kGTLRSheets_ChartSpec_HiddenDimensionStrategy_SkipHiddenColumns = @"SKIP_HIDDEN_COLUMNS"; -NSString * const kGTLRSheets_ChartSpec_HiddenDimensionStrategy_SkipHiddenRows = @"SKIP_HIDDEN_ROWS"; -NSString * const kGTLRSheets_ChartSpec_HiddenDimensionStrategy_SkipHiddenRowsAndColumns = @"SKIP_HIDDEN_ROWS_AND_COLUMNS"; - -// GTLRSheets_ConditionValue.relativeDate -NSString * const kGTLRSheets_ConditionValue_RelativeDate_PastMonth = @"PAST_MONTH"; -NSString * const kGTLRSheets_ConditionValue_RelativeDate_PastWeek = @"PAST_WEEK"; -NSString * const kGTLRSheets_ConditionValue_RelativeDate_PastYear = @"PAST_YEAR"; -NSString * const kGTLRSheets_ConditionValue_RelativeDate_RelativeDateUnspecified = @"RELATIVE_DATE_UNSPECIFIED"; -NSString * const kGTLRSheets_ConditionValue_RelativeDate_Today = @"TODAY"; -NSString * const kGTLRSheets_ConditionValue_RelativeDate_Tomorrow = @"TOMORROW"; -NSString * const kGTLRSheets_ConditionValue_RelativeDate_Yesterday = @"YESTERDAY"; - -// GTLRSheets_CopyPasteRequest.pasteOrientation -NSString * const kGTLRSheets_CopyPasteRequest_PasteOrientation_Normal = @"NORMAL"; -NSString * const kGTLRSheets_CopyPasteRequest_PasteOrientation_Transpose = @"TRANSPOSE"; - -// GTLRSheets_CopyPasteRequest.pasteType -NSString * const kGTLRSheets_CopyPasteRequest_PasteType_PasteConditionalFormatting = @"PASTE_CONDITIONAL_FORMATTING"; -NSString * const kGTLRSheets_CopyPasteRequest_PasteType_PasteDataValidation = @"PASTE_DATA_VALIDATION"; -NSString * const kGTLRSheets_CopyPasteRequest_PasteType_PasteFormat = @"PASTE_FORMAT"; -NSString * const kGTLRSheets_CopyPasteRequest_PasteType_PasteFormula = @"PASTE_FORMULA"; -NSString * const kGTLRSheets_CopyPasteRequest_PasteType_PasteNoBorders = @"PASTE_NO_BORDERS"; -NSString * const kGTLRSheets_CopyPasteRequest_PasteType_PasteNormal = @"PASTE_NORMAL"; -NSString * const kGTLRSheets_CopyPasteRequest_PasteType_PasteValues = @"PASTE_VALUES"; - -// GTLRSheets_CutPasteRequest.pasteType -NSString * const kGTLRSheets_CutPasteRequest_PasteType_PasteConditionalFormatting = @"PASTE_CONDITIONAL_FORMATTING"; -NSString * const kGTLRSheets_CutPasteRequest_PasteType_PasteDataValidation = @"PASTE_DATA_VALIDATION"; -NSString * const kGTLRSheets_CutPasteRequest_PasteType_PasteFormat = @"PASTE_FORMAT"; -NSString * const kGTLRSheets_CutPasteRequest_PasteType_PasteFormula = @"PASTE_FORMULA"; -NSString * const kGTLRSheets_CutPasteRequest_PasteType_PasteNoBorders = @"PASTE_NO_BORDERS"; -NSString * const kGTLRSheets_CutPasteRequest_PasteType_PasteNormal = @"PASTE_NORMAL"; -NSString * const kGTLRSheets_CutPasteRequest_PasteType_PasteValues = @"PASTE_VALUES"; - -// GTLRSheets_DataFilterValueRange.majorDimension -NSString * const kGTLRSheets_DataFilterValueRange_MajorDimension_Columns = @"COLUMNS"; -NSString * const kGTLRSheets_DataFilterValueRange_MajorDimension_DimensionUnspecified = @"DIMENSION_UNSPECIFIED"; -NSString * const kGTLRSheets_DataFilterValueRange_MajorDimension_Rows = @"ROWS"; - -// GTLRSheets_DateTimeRule.type -NSString * const kGTLRSheets_DateTimeRule_Type_DateTimeRuleTypeUnspecified = @"DATE_TIME_RULE_TYPE_UNSPECIFIED"; -NSString * const kGTLRSheets_DateTimeRule_Type_DayMonth = @"DAY_MONTH"; -NSString * const kGTLRSheets_DateTimeRule_Type_DayOfMonth = @"DAY_OF_MONTH"; -NSString * const kGTLRSheets_DateTimeRule_Type_DayOfWeek = @"DAY_OF_WEEK"; -NSString * const kGTLRSheets_DateTimeRule_Type_DayOfYear = @"DAY_OF_YEAR"; -NSString * const kGTLRSheets_DateTimeRule_Type_Hour = @"HOUR"; -NSString * const kGTLRSheets_DateTimeRule_Type_HourMinute = @"HOUR_MINUTE"; -NSString * const kGTLRSheets_DateTimeRule_Type_HourMinuteAmpm = @"HOUR_MINUTE_AMPM"; -NSString * const kGTLRSheets_DateTimeRule_Type_Minute = @"MINUTE"; -NSString * const kGTLRSheets_DateTimeRule_Type_Month = @"MONTH"; -NSString * const kGTLRSheets_DateTimeRule_Type_Quarter = @"QUARTER"; -NSString * const kGTLRSheets_DateTimeRule_Type_Second = @"SECOND"; -NSString * const kGTLRSheets_DateTimeRule_Type_Year = @"YEAR"; -NSString * const kGTLRSheets_DateTimeRule_Type_YearMonth = @"YEAR_MONTH"; -NSString * const kGTLRSheets_DateTimeRule_Type_YearMonthDay = @"YEAR_MONTH_DAY"; -NSString * const kGTLRSheets_DateTimeRule_Type_YearQuarter = @"YEAR_QUARTER"; - -// GTLRSheets_DeleteRangeRequest.shiftDimension -NSString * const kGTLRSheets_DeleteRangeRequest_ShiftDimension_Columns = @"COLUMNS"; -NSString * const kGTLRSheets_DeleteRangeRequest_ShiftDimension_DimensionUnspecified = @"DIMENSION_UNSPECIFIED"; -NSString * const kGTLRSheets_DeleteRangeRequest_ShiftDimension_Rows = @"ROWS"; - -// GTLRSheets_DeveloperMetadata.visibility -NSString * const kGTLRSheets_DeveloperMetadata_Visibility_DeveloperMetadataVisibilityUnspecified = @"DEVELOPER_METADATA_VISIBILITY_UNSPECIFIED"; -NSString * const kGTLRSheets_DeveloperMetadata_Visibility_Document = @"DOCUMENT"; -NSString * const kGTLRSheets_DeveloperMetadata_Visibility_Project = @"PROJECT"; - -// GTLRSheets_DeveloperMetadataLocation.locationType -NSString * const kGTLRSheets_DeveloperMetadataLocation_LocationType_Column = @"COLUMN"; -NSString * const kGTLRSheets_DeveloperMetadataLocation_LocationType_DeveloperMetadataLocationTypeUnspecified = @"DEVELOPER_METADATA_LOCATION_TYPE_UNSPECIFIED"; -NSString * const kGTLRSheets_DeveloperMetadataLocation_LocationType_Row = @"ROW"; -NSString * const kGTLRSheets_DeveloperMetadataLocation_LocationType_Sheet = @"SHEET"; -NSString * const kGTLRSheets_DeveloperMetadataLocation_LocationType_Spreadsheet = @"SPREADSHEET"; - -// GTLRSheets_DeveloperMetadataLookup.locationMatchingStrategy -NSString * const kGTLRSheets_DeveloperMetadataLookup_LocationMatchingStrategy_DeveloperMetadataLocationMatchingStrategyUnspecified = @"DEVELOPER_METADATA_LOCATION_MATCHING_STRATEGY_UNSPECIFIED"; -NSString * const kGTLRSheets_DeveloperMetadataLookup_LocationMatchingStrategy_ExactLocation = @"EXACT_LOCATION"; -NSString * const kGTLRSheets_DeveloperMetadataLookup_LocationMatchingStrategy_IntersectingLocation = @"INTERSECTING_LOCATION"; - -// GTLRSheets_DeveloperMetadataLookup.locationType -NSString * const kGTLRSheets_DeveloperMetadataLookup_LocationType_Column = @"COLUMN"; -NSString * const kGTLRSheets_DeveloperMetadataLookup_LocationType_DeveloperMetadataLocationTypeUnspecified = @"DEVELOPER_METADATA_LOCATION_TYPE_UNSPECIFIED"; -NSString * const kGTLRSheets_DeveloperMetadataLookup_LocationType_Row = @"ROW"; -NSString * const kGTLRSheets_DeveloperMetadataLookup_LocationType_Sheet = @"SHEET"; -NSString * const kGTLRSheets_DeveloperMetadataLookup_LocationType_Spreadsheet = @"SPREADSHEET"; - -// GTLRSheets_DeveloperMetadataLookup.visibility -NSString * const kGTLRSheets_DeveloperMetadataLookup_Visibility_DeveloperMetadataVisibilityUnspecified = @"DEVELOPER_METADATA_VISIBILITY_UNSPECIFIED"; -NSString * const kGTLRSheets_DeveloperMetadataLookup_Visibility_Document = @"DOCUMENT"; -NSString * const kGTLRSheets_DeveloperMetadataLookup_Visibility_Project = @"PROJECT"; - -// GTLRSheets_DimensionRange.dimension -NSString * const kGTLRSheets_DimensionRange_Dimension_Columns = @"COLUMNS"; -NSString * const kGTLRSheets_DimensionRange_Dimension_DimensionUnspecified = @"DIMENSION_UNSPECIFIED"; -NSString * const kGTLRSheets_DimensionRange_Dimension_Rows = @"ROWS"; - -// GTLRSheets_ErrorValue.type -NSString * const kGTLRSheets_ErrorValue_Type_DivideByZero = @"DIVIDE_BY_ZERO"; -NSString * const kGTLRSheets_ErrorValue_Type_Error = @"ERROR"; -NSString * const kGTLRSheets_ErrorValue_Type_ErrorTypeUnspecified = @"ERROR_TYPE_UNSPECIFIED"; -NSString * const kGTLRSheets_ErrorValue_Type_Loading = @"LOADING"; -NSString * const kGTLRSheets_ErrorValue_Type_NA = @"N_A"; -NSString * const kGTLRSheets_ErrorValue_Type_Name = @"NAME"; -NSString * const kGTLRSheets_ErrorValue_Type_NullValue = @"NULL_VALUE"; -NSString * const kGTLRSheets_ErrorValue_Type_Num = @"NUM"; -NSString * const kGTLRSheets_ErrorValue_Type_Ref = @"REF"; -NSString * const kGTLRSheets_ErrorValue_Type_Value = @"VALUE"; - -// GTLRSheets_HistogramChartSpec.legendPosition -NSString * const kGTLRSheets_HistogramChartSpec_LegendPosition_BottomLegend = @"BOTTOM_LEGEND"; -NSString * const kGTLRSheets_HistogramChartSpec_LegendPosition_HistogramChartLegendPositionUnspecified = @"HISTOGRAM_CHART_LEGEND_POSITION_UNSPECIFIED"; -NSString * const kGTLRSheets_HistogramChartSpec_LegendPosition_InsideLegend = @"INSIDE_LEGEND"; -NSString * const kGTLRSheets_HistogramChartSpec_LegendPosition_LeftLegend = @"LEFT_LEGEND"; -NSString * const kGTLRSheets_HistogramChartSpec_LegendPosition_NoLegend = @"NO_LEGEND"; -NSString * const kGTLRSheets_HistogramChartSpec_LegendPosition_RightLegend = @"RIGHT_LEGEND"; -NSString * const kGTLRSheets_HistogramChartSpec_LegendPosition_TopLegend = @"TOP_LEGEND"; - -// GTLRSheets_InsertRangeRequest.shiftDimension -NSString * const kGTLRSheets_InsertRangeRequest_ShiftDimension_Columns = @"COLUMNS"; -NSString * const kGTLRSheets_InsertRangeRequest_ShiftDimension_DimensionUnspecified = @"DIMENSION_UNSPECIFIED"; -NSString * const kGTLRSheets_InsertRangeRequest_ShiftDimension_Rows = @"ROWS"; - -// GTLRSheets_InterpolationPoint.type -NSString * const kGTLRSheets_InterpolationPoint_Type_InterpolationPointTypeUnspecified = @"INTERPOLATION_POINT_TYPE_UNSPECIFIED"; -NSString * const kGTLRSheets_InterpolationPoint_Type_Max = @"MAX"; -NSString * const kGTLRSheets_InterpolationPoint_Type_Min = @"MIN"; -NSString * const kGTLRSheets_InterpolationPoint_Type_Number = @"NUMBER"; -NSString * const kGTLRSheets_InterpolationPoint_Type_Percent = @"PERCENT"; -NSString * const kGTLRSheets_InterpolationPoint_Type_Percentile = @"PERCENTILE"; - -// GTLRSheets_LineStyle.type -NSString * const kGTLRSheets_LineStyle_Type_Custom = @"CUSTOM"; -NSString * const kGTLRSheets_LineStyle_Type_Dotted = @"DOTTED"; -NSString * const kGTLRSheets_LineStyle_Type_Invisible = @"INVISIBLE"; -NSString * const kGTLRSheets_LineStyle_Type_LineDashTypeUnspecified = @"LINE_DASH_TYPE_UNSPECIFIED"; -NSString * const kGTLRSheets_LineStyle_Type_LongDashed = @"LONG_DASHED"; -NSString * const kGTLRSheets_LineStyle_Type_LongDashedDotted = @"LONG_DASHED_DOTTED"; -NSString * const kGTLRSheets_LineStyle_Type_MediumDashed = @"MEDIUM_DASHED"; -NSString * const kGTLRSheets_LineStyle_Type_MediumDashedDotted = @"MEDIUM_DASHED_DOTTED"; -NSString * const kGTLRSheets_LineStyle_Type_Solid = @"SOLID"; - -// GTLRSheets_MergeCellsRequest.mergeType -NSString * const kGTLRSheets_MergeCellsRequest_MergeType_MergeAll = @"MERGE_ALL"; -NSString * const kGTLRSheets_MergeCellsRequest_MergeType_MergeColumns = @"MERGE_COLUMNS"; -NSString * const kGTLRSheets_MergeCellsRequest_MergeType_MergeRows = @"MERGE_ROWS"; - -// GTLRSheets_NumberFormat.type -NSString * const kGTLRSheets_NumberFormat_Type_Currency = @"CURRENCY"; -NSString * const kGTLRSheets_NumberFormat_Type_Date = @"DATE"; -NSString * const kGTLRSheets_NumberFormat_Type_DateTime = @"DATE_TIME"; -NSString * const kGTLRSheets_NumberFormat_Type_Number = @"NUMBER"; -NSString * const kGTLRSheets_NumberFormat_Type_NumberFormatTypeUnspecified = @"NUMBER_FORMAT_TYPE_UNSPECIFIED"; -NSString * const kGTLRSheets_NumberFormat_Type_Percent = @"PERCENT"; -NSString * const kGTLRSheets_NumberFormat_Type_Scientific = @"SCIENTIFIC"; -NSString * const kGTLRSheets_NumberFormat_Type_Text = @"TEXT"; -NSString * const kGTLRSheets_NumberFormat_Type_Time = @"TIME"; - -// GTLRSheets_OrgChartSpec.nodeSize -NSString * const kGTLRSheets_OrgChartSpec_NodeSize_Large = @"LARGE"; -NSString * const kGTLRSheets_OrgChartSpec_NodeSize_Medium = @"MEDIUM"; -NSString * const kGTLRSheets_OrgChartSpec_NodeSize_OrgChartLabelSizeUnspecified = @"ORG_CHART_LABEL_SIZE_UNSPECIFIED"; -NSString * const kGTLRSheets_OrgChartSpec_NodeSize_Small = @"SMALL"; - -// GTLRSheets_PasteDataRequest.type -NSString * const kGTLRSheets_PasteDataRequest_Type_PasteConditionalFormatting = @"PASTE_CONDITIONAL_FORMATTING"; -NSString * const kGTLRSheets_PasteDataRequest_Type_PasteDataValidation = @"PASTE_DATA_VALIDATION"; -NSString * const kGTLRSheets_PasteDataRequest_Type_PasteFormat = @"PASTE_FORMAT"; -NSString * const kGTLRSheets_PasteDataRequest_Type_PasteFormula = @"PASTE_FORMULA"; -NSString * const kGTLRSheets_PasteDataRequest_Type_PasteNoBorders = @"PASTE_NO_BORDERS"; -NSString * const kGTLRSheets_PasteDataRequest_Type_PasteNormal = @"PASTE_NORMAL"; -NSString * const kGTLRSheets_PasteDataRequest_Type_PasteValues = @"PASTE_VALUES"; - -// GTLRSheets_PieChartSpec.legendPosition -NSString * const kGTLRSheets_PieChartSpec_LegendPosition_BottomLegend = @"BOTTOM_LEGEND"; -NSString * const kGTLRSheets_PieChartSpec_LegendPosition_LabeledLegend = @"LABELED_LEGEND"; -NSString * const kGTLRSheets_PieChartSpec_LegendPosition_LeftLegend = @"LEFT_LEGEND"; -NSString * const kGTLRSheets_PieChartSpec_LegendPosition_NoLegend = @"NO_LEGEND"; -NSString * const kGTLRSheets_PieChartSpec_LegendPosition_PieChartLegendPositionUnspecified = @"PIE_CHART_LEGEND_POSITION_UNSPECIFIED"; -NSString * const kGTLRSheets_PieChartSpec_LegendPosition_RightLegend = @"RIGHT_LEGEND"; -NSString * const kGTLRSheets_PieChartSpec_LegendPosition_TopLegend = @"TOP_LEGEND"; - -// GTLRSheets_PivotGroup.sortOrder -NSString * const kGTLRSheets_PivotGroup_SortOrder_Ascending = @"ASCENDING"; -NSString * const kGTLRSheets_PivotGroup_SortOrder_Descending = @"DESCENDING"; -NSString * const kGTLRSheets_PivotGroup_SortOrder_SortOrderUnspecified = @"SORT_ORDER_UNSPECIFIED"; - -// GTLRSheets_PivotTable.valueLayout -NSString * const kGTLRSheets_PivotTable_ValueLayout_Horizontal = @"HORIZONTAL"; -NSString * const kGTLRSheets_PivotTable_ValueLayout_Vertical = @"VERTICAL"; - -// GTLRSheets_PivotValue.calculatedDisplayType -NSString * const kGTLRSheets_PivotValue_CalculatedDisplayType_PercentOfColumnTotal = @"PERCENT_OF_COLUMN_TOTAL"; -NSString * const kGTLRSheets_PivotValue_CalculatedDisplayType_PercentOfGrandTotal = @"PERCENT_OF_GRAND_TOTAL"; -NSString * const kGTLRSheets_PivotValue_CalculatedDisplayType_PercentOfRowTotal = @"PERCENT_OF_ROW_TOTAL"; -NSString * const kGTLRSheets_PivotValue_CalculatedDisplayType_PivotValueCalculatedDisplayTypeUnspecified = @"PIVOT_VALUE_CALCULATED_DISPLAY_TYPE_UNSPECIFIED"; - -// GTLRSheets_PivotValue.summarizeFunction -NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Average = @"AVERAGE"; -NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Count = @"COUNT"; -NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Counta = @"COUNTA"; -NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Countunique = @"COUNTUNIQUE"; -NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Custom = @"CUSTOM"; -NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Max = @"MAX"; -NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Median = @"MEDIAN"; -NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Min = @"MIN"; -NSString * const kGTLRSheets_PivotValue_SummarizeFunction_PivotStandardValueFunctionUnspecified = @"PIVOT_STANDARD_VALUE_FUNCTION_UNSPECIFIED"; -NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Product = @"PRODUCT"; -NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Stdev = @"STDEV"; -NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Stdevp = @"STDEVP"; -NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Sum = @"SUM"; -NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Var = @"VAR"; -NSString * const kGTLRSheets_PivotValue_SummarizeFunction_Varp = @"VARP"; - -// GTLRSheets_SheetProperties.sheetType -NSString * const kGTLRSheets_SheetProperties_SheetType_Grid = @"GRID"; -NSString * const kGTLRSheets_SheetProperties_SheetType_Object = @"OBJECT"; -NSString * const kGTLRSheets_SheetProperties_SheetType_SheetTypeUnspecified = @"SHEET_TYPE_UNSPECIFIED"; - -// GTLRSheets_SortSpec.sortOrder -NSString * const kGTLRSheets_SortSpec_SortOrder_Ascending = @"ASCENDING"; -NSString * const kGTLRSheets_SortSpec_SortOrder_Descending = @"DESCENDING"; -NSString * const kGTLRSheets_SortSpec_SortOrder_SortOrderUnspecified = @"SORT_ORDER_UNSPECIFIED"; - -// GTLRSheets_SourceAndDestination.dimension -NSString * const kGTLRSheets_SourceAndDestination_Dimension_Columns = @"COLUMNS"; -NSString * const kGTLRSheets_SourceAndDestination_Dimension_DimensionUnspecified = @"DIMENSION_UNSPECIFIED"; -NSString * const kGTLRSheets_SourceAndDestination_Dimension_Rows = @"ROWS"; - -// GTLRSheets_SpreadsheetProperties.autoRecalc -NSString * const kGTLRSheets_SpreadsheetProperties_AutoRecalc_Hour = @"HOUR"; -NSString * const kGTLRSheets_SpreadsheetProperties_AutoRecalc_Minute = @"MINUTE"; -NSString * const kGTLRSheets_SpreadsheetProperties_AutoRecalc_OnChange = @"ON_CHANGE"; -NSString * const kGTLRSheets_SpreadsheetProperties_AutoRecalc_RecalculationIntervalUnspecified = @"RECALCULATION_INTERVAL_UNSPECIFIED"; - -// GTLRSheets_TextPosition.horizontalAlignment -NSString * const kGTLRSheets_TextPosition_HorizontalAlignment_Center = @"CENTER"; -NSString * const kGTLRSheets_TextPosition_HorizontalAlignment_HorizontalAlignUnspecified = @"HORIZONTAL_ALIGN_UNSPECIFIED"; -NSString * const kGTLRSheets_TextPosition_HorizontalAlignment_Left = @"LEFT"; -NSString * const kGTLRSheets_TextPosition_HorizontalAlignment_Right = @"RIGHT"; - -// GTLRSheets_TextToColumnsRequest.delimiterType -NSString * const kGTLRSheets_TextToColumnsRequest_DelimiterType_Autodetect = @"AUTODETECT"; -NSString * const kGTLRSheets_TextToColumnsRequest_DelimiterType_Comma = @"COMMA"; -NSString * const kGTLRSheets_TextToColumnsRequest_DelimiterType_Custom = @"CUSTOM"; -NSString * const kGTLRSheets_TextToColumnsRequest_DelimiterType_DelimiterTypeUnspecified = @"DELIMITER_TYPE_UNSPECIFIED"; -NSString * const kGTLRSheets_TextToColumnsRequest_DelimiterType_Period = @"PERIOD"; -NSString * const kGTLRSheets_TextToColumnsRequest_DelimiterType_Semicolon = @"SEMICOLON"; -NSString * const kGTLRSheets_TextToColumnsRequest_DelimiterType_Space = @"SPACE"; - -// GTLRSheets_ValueRange.majorDimension -NSString * const kGTLRSheets_ValueRange_MajorDimension_Columns = @"COLUMNS"; -NSString * const kGTLRSheets_ValueRange_MajorDimension_DimensionUnspecified = @"DIMENSION_UNSPECIFIED"; -NSString * const kGTLRSheets_ValueRange_MajorDimension_Rows = @"ROWS"; - -// GTLRSheets_WaterfallChartSpec.stackedType -NSString * const kGTLRSheets_WaterfallChartSpec_StackedType_Sequential = @"SEQUENTIAL"; -NSString * const kGTLRSheets_WaterfallChartSpec_StackedType_Stacked = @"STACKED"; -NSString * const kGTLRSheets_WaterfallChartSpec_StackedType_WaterfallStackedTypeUnspecified = @"WATERFALL_STACKED_TYPE_UNSPECIFIED"; - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_AddBandingRequest -// - -@implementation GTLRSheets_AddBandingRequest -@dynamic bandedRange; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_AddBandingResponse -// - -@implementation GTLRSheets_AddBandingResponse -@dynamic bandedRange; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_AddChartRequest -// - -@implementation GTLRSheets_AddChartRequest -@dynamic chart; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_AddChartResponse -// - -@implementation GTLRSheets_AddChartResponse -@dynamic chart; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_AddConditionalFormatRuleRequest -// - -@implementation GTLRSheets_AddConditionalFormatRuleRequest -@dynamic index, rule; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_AddDimensionGroupRequest -// - -@implementation GTLRSheets_AddDimensionGroupRequest -@dynamic range; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_AddDimensionGroupResponse -// - -@implementation GTLRSheets_AddDimensionGroupResponse -@dynamic dimensionGroups; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"dimensionGroups" : [GTLRSheets_DimensionGroup class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_AddFilterViewRequest -// - -@implementation GTLRSheets_AddFilterViewRequest -@dynamic filter; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_AddFilterViewResponse -// - -@implementation GTLRSheets_AddFilterViewResponse -@dynamic filter; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_AddNamedRangeRequest -// - -@implementation GTLRSheets_AddNamedRangeRequest -@dynamic namedRange; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_AddNamedRangeResponse -// - -@implementation GTLRSheets_AddNamedRangeResponse -@dynamic namedRange; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_AddProtectedRangeRequest -// - -@implementation GTLRSheets_AddProtectedRangeRequest -@dynamic protectedRange; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_AddProtectedRangeResponse -// - -@implementation GTLRSheets_AddProtectedRangeResponse -@dynamic protectedRange; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_AddSheetRequest -// - -@implementation GTLRSheets_AddSheetRequest -@dynamic properties; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_AddSheetResponse -// - -@implementation GTLRSheets_AddSheetResponse -@dynamic properties; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_AppendCellsRequest -// - -@implementation GTLRSheets_AppendCellsRequest -@dynamic fields, rows, sheetId; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"rows" : [GTLRSheets_RowData class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_AppendDimensionRequest -// - -@implementation GTLRSheets_AppendDimensionRequest -@dynamic dimension, length, sheetId; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_AppendValuesResponse -// - -@implementation GTLRSheets_AppendValuesResponse -@dynamic spreadsheetId, tableRange, updates; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_AutoFillRequest -// - -@implementation GTLRSheets_AutoFillRequest -@dynamic range, sourceAndDestination, useAlternateSeries; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_AutoResizeDimensionsRequest -// - -@implementation GTLRSheets_AutoResizeDimensionsRequest -@dynamic dimensions; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BandedRange -// - -@implementation GTLRSheets_BandedRange -@dynamic bandedRangeId, columnProperties, range, rowProperties; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BandingProperties -// - -@implementation GTLRSheets_BandingProperties -@dynamic firstBandColor, footerColor, headerColor, secondBandColor; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BasicChartAxis -// - -@implementation GTLRSheets_BasicChartAxis -@dynamic format, position, title, titleTextPosition; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BasicChartDomain -// - -@implementation GTLRSheets_BasicChartDomain -@dynamic domain, reversed; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BasicChartSeries -// - -@implementation GTLRSheets_BasicChartSeries -@dynamic color, lineStyle, series, targetAxis, type; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BasicChartSpec -// - -@implementation GTLRSheets_BasicChartSpec -@dynamic axis, chartType, compareMode, domains, headerCount, interpolateNulls, - legendPosition, lineSmoothing, series, stackedType, threeDimensional; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"axis" : [GTLRSheets_BasicChartAxis class], - @"domains" : [GTLRSheets_BasicChartDomain class], - @"series" : [GTLRSheets_BasicChartSeries class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BasicFilter -// - -@implementation GTLRSheets_BasicFilter -@dynamic criteria, range, sortSpecs; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"sortSpecs" : [GTLRSheets_SortSpec class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BasicFilter_Criteria -// - -@implementation GTLRSheets_BasicFilter_Criteria - -+ (Class)classForAdditionalProperties { - return [GTLRSheets_FilterCriteria class]; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BatchClearValuesByDataFilterRequest -// - -@implementation GTLRSheets_BatchClearValuesByDataFilterRequest -@dynamic dataFilters; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"dataFilters" : [GTLRSheets_DataFilter class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BatchClearValuesByDataFilterResponse -// - -@implementation GTLRSheets_BatchClearValuesByDataFilterResponse -@dynamic clearedRanges, spreadsheetId; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"clearedRanges" : [NSString class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BatchClearValuesRequest -// - -@implementation GTLRSheets_BatchClearValuesRequest -@dynamic ranges; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"ranges" : [NSString class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BatchClearValuesResponse -// - -@implementation GTLRSheets_BatchClearValuesResponse -@dynamic clearedRanges, spreadsheetId; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"clearedRanges" : [NSString class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BatchGetValuesByDataFilterRequest -// - -@implementation GTLRSheets_BatchGetValuesByDataFilterRequest -@dynamic dataFilters, dateTimeRenderOption, majorDimension, valueRenderOption; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"dataFilters" : [GTLRSheets_DataFilter class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BatchGetValuesByDataFilterResponse -// - -@implementation GTLRSheets_BatchGetValuesByDataFilterResponse -@dynamic spreadsheetId, valueRanges; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"valueRanges" : [GTLRSheets_MatchedValueRange class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BatchGetValuesResponse -// - -@implementation GTLRSheets_BatchGetValuesResponse -@dynamic spreadsheetId, valueRanges; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"valueRanges" : [GTLRSheets_ValueRange class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BatchUpdateSpreadsheetRequest -// - -@implementation GTLRSheets_BatchUpdateSpreadsheetRequest -@dynamic includeSpreadsheetInResponse, requests, responseIncludeGridData, - responseRanges; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"requests" : [GTLRSheets_Request class], - @"responseRanges" : [NSString class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BatchUpdateSpreadsheetResponse -// - -@implementation GTLRSheets_BatchUpdateSpreadsheetResponse -@dynamic replies, spreadsheetId, updatedSpreadsheet; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"replies" : [GTLRSheets_Response class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BatchUpdateValuesByDataFilterRequest -// - -@implementation GTLRSheets_BatchUpdateValuesByDataFilterRequest -@dynamic data, includeValuesInResponse, responseDateTimeRenderOption, - responseValueRenderOption, valueInputOption; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"data" : [GTLRSheets_DataFilterValueRange class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BatchUpdateValuesByDataFilterResponse -// - -@implementation GTLRSheets_BatchUpdateValuesByDataFilterResponse -@dynamic responses, spreadsheetId, totalUpdatedCells, totalUpdatedColumns, - totalUpdatedRows, totalUpdatedSheets; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"responses" : [GTLRSheets_UpdateValuesByDataFilterResponse class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BatchUpdateValuesRequest -// - -@implementation GTLRSheets_BatchUpdateValuesRequest -@dynamic data, includeValuesInResponse, responseDateTimeRenderOption, - responseValueRenderOption, valueInputOption; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"data" : [GTLRSheets_ValueRange class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BatchUpdateValuesResponse -// - -@implementation GTLRSheets_BatchUpdateValuesResponse -@dynamic responses, spreadsheetId, totalUpdatedCells, totalUpdatedColumns, - totalUpdatedRows, totalUpdatedSheets; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"responses" : [GTLRSheets_UpdateValuesResponse class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BooleanCondition -// - -@implementation GTLRSheets_BooleanCondition -@dynamic type, values; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"values" : [GTLRSheets_ConditionValue class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BooleanRule -// - -@implementation GTLRSheets_BooleanRule -@dynamic condition, format; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_Border -// - -@implementation GTLRSheets_Border -@dynamic color, style, width; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_Borders -// - -@implementation GTLRSheets_Borders -@dynamic bottom, left, right, top; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_BubbleChartSpec -// - -@implementation GTLRSheets_BubbleChartSpec -@dynamic bubbleBorderColor, bubbleLabels, bubbleMaxRadiusSize, - bubbleMinRadiusSize, bubbleOpacity, bubbleSizes, bubbleTextStyle, - domain, groupIds, legendPosition, series; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_CandlestickChartSpec -// - -@implementation GTLRSheets_CandlestickChartSpec -@dynamic data, domain; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"data" : [GTLRSheets_CandlestickData class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_CandlestickData -// - -@implementation GTLRSheets_CandlestickData -@dynamic closeSeries, highSeries, lowSeries, openSeries; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_CandlestickDomain -// - -@implementation GTLRSheets_CandlestickDomain -@dynamic data, reversed; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_CandlestickSeries -// - -@implementation GTLRSheets_CandlestickSeries -@dynamic data; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_CellData -// - -@implementation GTLRSheets_CellData -@dynamic dataValidation, effectiveFormat, effectiveValue, formattedValue, - hyperlink, note, pivotTable, textFormatRuns, userEnteredFormat, - userEnteredValue; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"textFormatRuns" : [GTLRSheets_TextFormatRun class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_CellFormat -// - -@implementation GTLRSheets_CellFormat -@dynamic backgroundColor, borders, horizontalAlignment, hyperlinkDisplayType, - numberFormat, padding, textDirection, textFormat, textRotation, - verticalAlignment, wrapStrategy; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_ChartData -// - -@implementation GTLRSheets_ChartData -@dynamic sourceRange; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_ChartSourceRange -// - -@implementation GTLRSheets_ChartSourceRange -@dynamic sources; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"sources" : [GTLRSheets_GridRange class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_ChartSpec -// - -@implementation GTLRSheets_ChartSpec -@dynamic altText, backgroundColor, basicChart, bubbleChart, candlestickChart, - fontName, hiddenDimensionStrategy, histogramChart, maximized, orgChart, - pieChart, subtitle, subtitleTextFormat, subtitleTextPosition, title, - titleTextFormat, titleTextPosition, treemapChart, waterfallChart; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_ClearBasicFilterRequest -// - -@implementation GTLRSheets_ClearBasicFilterRequest -@dynamic sheetId; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_ClearValuesRequest -// - -@implementation GTLRSheets_ClearValuesRequest -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_ClearValuesResponse -// - -@implementation GTLRSheets_ClearValuesResponse -@dynamic clearedRange, spreadsheetId; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_Color -// - -@implementation GTLRSheets_Color -@dynamic alpha, blue, green, red; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_ConditionalFormatRule -// - -@implementation GTLRSheets_ConditionalFormatRule -@dynamic booleanRule, gradientRule, ranges; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"ranges" : [GTLRSheets_GridRange class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_ConditionValue -// - -@implementation GTLRSheets_ConditionValue -@dynamic relativeDate, userEnteredValue; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_CopyPasteRequest -// - -@implementation GTLRSheets_CopyPasteRequest -@dynamic destination, pasteOrientation, pasteType, source; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_CopySheetToAnotherSpreadsheetRequest -// - -@implementation GTLRSheets_CopySheetToAnotherSpreadsheetRequest -@dynamic destinationSpreadsheetId; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_CreateDeveloperMetadataRequest -// - -@implementation GTLRSheets_CreateDeveloperMetadataRequest -@dynamic developerMetadata; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_CreateDeveloperMetadataResponse -// - -@implementation GTLRSheets_CreateDeveloperMetadataResponse -@dynamic developerMetadata; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_CutPasteRequest -// - -@implementation GTLRSheets_CutPasteRequest -@dynamic destination, pasteType, source; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DataFilter -// - -@implementation GTLRSheets_DataFilter -@dynamic a1Range, developerMetadataLookup, gridRange; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DataFilterValueRange -// - -@implementation GTLRSheets_DataFilterValueRange -@dynamic dataFilter, majorDimension, values; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"values" : [NSObject class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DataValidationRule -// - -@implementation GTLRSheets_DataValidationRule -@dynamic condition, inputMessage, showCustomUi, strict; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DateTimeRule -// - -@implementation GTLRSheets_DateTimeRule -@dynamic type; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DeleteBandingRequest -// - -@implementation GTLRSheets_DeleteBandingRequest -@dynamic bandedRangeId; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DeleteConditionalFormatRuleRequest -// - -@implementation GTLRSheets_DeleteConditionalFormatRuleRequest -@dynamic index, sheetId; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DeleteConditionalFormatRuleResponse -// - -@implementation GTLRSheets_DeleteConditionalFormatRuleResponse -@dynamic rule; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DeleteDeveloperMetadataRequest -// - -@implementation GTLRSheets_DeleteDeveloperMetadataRequest -@dynamic dataFilter; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DeleteDeveloperMetadataResponse -// - -@implementation GTLRSheets_DeleteDeveloperMetadataResponse -@dynamic deletedDeveloperMetadata; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"deletedDeveloperMetadata" : [GTLRSheets_DeveloperMetadata class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DeleteDimensionGroupRequest -// - -@implementation GTLRSheets_DeleteDimensionGroupRequest -@dynamic range; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DeleteDimensionGroupResponse -// - -@implementation GTLRSheets_DeleteDimensionGroupResponse -@dynamic dimensionGroups; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"dimensionGroups" : [GTLRSheets_DimensionGroup class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DeleteDimensionRequest -// - -@implementation GTLRSheets_DeleteDimensionRequest -@dynamic range; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DeleteEmbeddedObjectRequest -// - -@implementation GTLRSheets_DeleteEmbeddedObjectRequest -@dynamic objectId; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DeleteFilterViewRequest -// - -@implementation GTLRSheets_DeleteFilterViewRequest -@dynamic filterId; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DeleteNamedRangeRequest -// - -@implementation GTLRSheets_DeleteNamedRangeRequest -@dynamic namedRangeId; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DeleteProtectedRangeRequest -// - -@implementation GTLRSheets_DeleteProtectedRangeRequest -@dynamic protectedRangeId; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DeleteRangeRequest -// - -@implementation GTLRSheets_DeleteRangeRequest -@dynamic range, shiftDimension; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DeleteSheetRequest -// - -@implementation GTLRSheets_DeleteSheetRequest -@dynamic sheetId; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DeveloperMetadata -// - -@implementation GTLRSheets_DeveloperMetadata -@dynamic location, metadataId, metadataKey, metadataValue, visibility; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DeveloperMetadataLocation -// - -@implementation GTLRSheets_DeveloperMetadataLocation -@dynamic dimensionRange, locationType, sheetId, spreadsheet; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DeveloperMetadataLookup -// - -@implementation GTLRSheets_DeveloperMetadataLookup -@dynamic locationMatchingStrategy, locationType, metadataId, metadataKey, - metadataLocation, metadataValue, visibility; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DimensionGroup -// - -@implementation GTLRSheets_DimensionGroup -@dynamic collapsed, depth, range; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DimensionProperties -// - -@implementation GTLRSheets_DimensionProperties -@dynamic developerMetadata, hiddenByFilter, hiddenByUser, pixelSize; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"developerMetadata" : [GTLRSheets_DeveloperMetadata class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DimensionRange -// - -@implementation GTLRSheets_DimensionRange -@dynamic dimension, endIndex, sheetId, startIndex; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DuplicateFilterViewRequest -// - -@implementation GTLRSheets_DuplicateFilterViewRequest -@dynamic filterId; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DuplicateFilterViewResponse -// - -@implementation GTLRSheets_DuplicateFilterViewResponse -@dynamic filter; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DuplicateSheetRequest -// - -@implementation GTLRSheets_DuplicateSheetRequest -@dynamic insertSheetIndex, newSheetId, newSheetName, sourceSheetId; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_DuplicateSheetResponse -// - -@implementation GTLRSheets_DuplicateSheetResponse -@dynamic properties; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_Editors -// - -@implementation GTLRSheets_Editors -@dynamic domainUsersCanEdit, groups, users; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"groups" : [NSString class], - @"users" : [NSString class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_EmbeddedChart -// - -@implementation GTLRSheets_EmbeddedChart -@dynamic chartId, position, spec; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_EmbeddedObjectPosition -// - -@implementation GTLRSheets_EmbeddedObjectPosition -@dynamic newSheet, overlayPosition, sheetId; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_ErrorValue -// - -@implementation GTLRSheets_ErrorValue -@dynamic message, type; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_ExtendedValue -// - -@implementation GTLRSheets_ExtendedValue -@dynamic boolValue, errorValue, formulaValue, numberValue, stringValue; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_FilterCriteria -// - -@implementation GTLRSheets_FilterCriteria -@dynamic condition, hiddenValues; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"hiddenValues" : [NSString class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_FilterView -// - -@implementation GTLRSheets_FilterView -@dynamic criteria, filterViewId, namedRangeId, range, sortSpecs, title; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"sortSpecs" : [GTLRSheets_SortSpec class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_FilterView_Criteria -// - -@implementation GTLRSheets_FilterView_Criteria - -+ (Class)classForAdditionalProperties { - return [GTLRSheets_FilterCriteria class]; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_FindReplaceRequest -// - -@implementation GTLRSheets_FindReplaceRequest -@dynamic allSheets, find, includeFormulas, matchCase, matchEntireCell, range, - replacement, searchByRegex, sheetId; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_FindReplaceResponse -// - -@implementation GTLRSheets_FindReplaceResponse -@dynamic formulasChanged, occurrencesChanged, rowsChanged, sheetsChanged, - valuesChanged; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_GetSpreadsheetByDataFilterRequest -// - -@implementation GTLRSheets_GetSpreadsheetByDataFilterRequest -@dynamic dataFilters, includeGridData; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"dataFilters" : [GTLRSheets_DataFilter class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_GradientRule -// - -@implementation GTLRSheets_GradientRule -@dynamic maxpoint, midpoint, minpoint; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_GridCoordinate -// - -@implementation GTLRSheets_GridCoordinate -@dynamic columnIndex, rowIndex, sheetId; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_GridData -// - -@implementation GTLRSheets_GridData -@dynamic columnMetadata, rowData, rowMetadata, startColumn, startRow; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"columnMetadata" : [GTLRSheets_DimensionProperties class], - @"rowData" : [GTLRSheets_RowData class], - @"rowMetadata" : [GTLRSheets_DimensionProperties class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_GridProperties -// - -@implementation GTLRSheets_GridProperties -@dynamic columnCount, columnGroupControlAfter, frozenColumnCount, - frozenRowCount, hideGridlines, rowCount, rowGroupControlAfter; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_GridRange -// - -@implementation GTLRSheets_GridRange -@dynamic endColumnIndex, endRowIndex, sheetId, startColumnIndex, startRowIndex; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_HistogramChartSpec -// - -@implementation GTLRSheets_HistogramChartSpec -@dynamic bucketSize, legendPosition, outlierPercentile, series, - showItemDividers; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"series" : [GTLRSheets_HistogramSeries class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_HistogramRule -// - -@implementation GTLRSheets_HistogramRule -@dynamic end, interval, start; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_HistogramSeries -// - -@implementation GTLRSheets_HistogramSeries -@dynamic barColor, data; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_InsertDimensionRequest -// - -@implementation GTLRSheets_InsertDimensionRequest -@dynamic inheritFromBefore, range; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_InsertRangeRequest -// - -@implementation GTLRSheets_InsertRangeRequest -@dynamic range, shiftDimension; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_InterpolationPoint -// - -@implementation GTLRSheets_InterpolationPoint -@dynamic color, type, value; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_IterativeCalculationSettings -// - -@implementation GTLRSheets_IterativeCalculationSettings -@dynamic convergenceThreshold, maxIterations; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_LineStyle -// - -@implementation GTLRSheets_LineStyle -@dynamic type, width; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_ManualRule -// - -@implementation GTLRSheets_ManualRule -@dynamic groups; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"groups" : [GTLRSheets_ManualRuleGroup class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_ManualRuleGroup -// - -@implementation GTLRSheets_ManualRuleGroup -@dynamic groupName, items; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"items" : [GTLRSheets_ExtendedValue class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_MatchedDeveloperMetadata -// - -@implementation GTLRSheets_MatchedDeveloperMetadata -@dynamic dataFilters, developerMetadata; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"dataFilters" : [GTLRSheets_DataFilter class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_MatchedValueRange -// - -@implementation GTLRSheets_MatchedValueRange -@dynamic dataFilters, valueRange; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"dataFilters" : [GTLRSheets_DataFilter class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_MergeCellsRequest -// - -@implementation GTLRSheets_MergeCellsRequest -@dynamic mergeType, range; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_MoveDimensionRequest -// - -@implementation GTLRSheets_MoveDimensionRequest -@dynamic destinationIndex, source; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_NamedRange -// - -@implementation GTLRSheets_NamedRange -@dynamic name, namedRangeId, range; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_NumberFormat -// - -@implementation GTLRSheets_NumberFormat -@dynamic pattern, type; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_OrgChartSpec -// - -@implementation GTLRSheets_OrgChartSpec -@dynamic labels, nodeColor, nodeSize, parentLabels, selectedNodeColor, tooltips; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_OverlayPosition -// - -@implementation GTLRSheets_OverlayPosition -@dynamic anchorCell, heightPixels, offsetXPixels, offsetYPixels, widthPixels; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_Padding -// - -@implementation GTLRSheets_Padding -@dynamic bottom, left, right, top; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_PasteDataRequest -// - -@implementation GTLRSheets_PasteDataRequest -@dynamic coordinate, data, delimiter, html, type; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_PieChartSpec -// - -@implementation GTLRSheets_PieChartSpec -@dynamic domain, legendPosition, pieHole, series, threeDimensional; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_PivotFilterCriteria -// - -@implementation GTLRSheets_PivotFilterCriteria -@dynamic visibleValues; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"visibleValues" : [NSString class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_PivotGroup -// - -@implementation GTLRSheets_PivotGroup -@dynamic groupRule, label, repeatHeadings, showTotals, sortOrder, - sourceColumnOffset, valueBucket, valueMetadata; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"valueMetadata" : [GTLRSheets_PivotGroupValueMetadata class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_PivotGroupRule -// - -@implementation GTLRSheets_PivotGroupRule -@dynamic dateTimeRule, histogramRule, manualRule; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_PivotGroupSortValueBucket -// - -@implementation GTLRSheets_PivotGroupSortValueBucket -@dynamic buckets, valuesIndex; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"buckets" : [GTLRSheets_ExtendedValue class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_PivotGroupValueMetadata -// - -@implementation GTLRSheets_PivotGroupValueMetadata -@dynamic collapsed, value; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_PivotTable -// - -@implementation GTLRSheets_PivotTable -@dynamic columns, criteria, rows, source, valueLayout, values; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"columns" : [GTLRSheets_PivotGroup class], - @"rows" : [GTLRSheets_PivotGroup class], - @"values" : [GTLRSheets_PivotValue class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_PivotTable_Criteria -// - -@implementation GTLRSheets_PivotTable_Criteria - -+ (Class)classForAdditionalProperties { - return [GTLRSheets_PivotFilterCriteria class]; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_PivotValue -// - -@implementation GTLRSheets_PivotValue -@dynamic calculatedDisplayType, formula, name, sourceColumnOffset, - summarizeFunction; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_ProtectedRange -// - -@implementation GTLRSheets_ProtectedRange -@dynamic descriptionProperty, editors, namedRangeId, protectedRangeId, range, - requestingUserCanEdit, unprotectedRanges, warningOnly; - -+ (NSDictionary<NSString *, NSString *> *)propertyToJSONKeyMap { - return @{ @"descriptionProperty" : @"description" }; -} - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"unprotectedRanges" : [GTLRSheets_GridRange class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_RandomizeRangeRequest -// - -@implementation GTLRSheets_RandomizeRangeRequest -@dynamic range; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_RepeatCellRequest -// - -@implementation GTLRSheets_RepeatCellRequest -@dynamic cell, fields, range; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_Request -// - -@implementation GTLRSheets_Request -@dynamic addBanding, addChart, addConditionalFormatRule, addDimensionGroup, - addFilterView, addNamedRange, addProtectedRange, addSheet, appendCells, - appendDimension, autoFill, autoResizeDimensions, clearBasicFilter, - copyPaste, createDeveloperMetadata, cutPaste, deleteBanding, - deleteConditionalFormatRule, deleteDeveloperMetadata, deleteDimension, - deleteDimensionGroup, deleteEmbeddedObject, deleteFilterView, - deleteNamedRange, deleteProtectedRange, deleteRange, deleteSheet, - duplicateFilterView, duplicateSheet, findReplace, insertDimension, - insertRange, mergeCells, moveDimension, pasteData, randomizeRange, - repeatCell, setBasicFilter, setDataValidation, sortRange, - textToColumns, unmergeCells, updateBanding, updateBorders, updateCells, - updateChartSpec, updateConditionalFormatRule, updateDeveloperMetadata, - updateDimensionGroup, updateDimensionProperties, - updateEmbeddedObjectPosition, updateFilterView, updateNamedRange, - updateProtectedRange, updateSheetProperties, - updateSpreadsheetProperties; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_Response -// - -@implementation GTLRSheets_Response -@dynamic addBanding, addChart, addDimensionGroup, addFilterView, addNamedRange, - addProtectedRange, addSheet, createDeveloperMetadata, - deleteConditionalFormatRule, deleteDeveloperMetadata, - deleteDimensionGroup, duplicateFilterView, duplicateSheet, findReplace, - updateConditionalFormatRule, updateDeveloperMetadata, - updateEmbeddedObjectPosition; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_RowData -// - -@implementation GTLRSheets_RowData -@dynamic values; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"values" : [GTLRSheets_CellData class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_SearchDeveloperMetadataRequest -// - -@implementation GTLRSheets_SearchDeveloperMetadataRequest -@dynamic dataFilters; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"dataFilters" : [GTLRSheets_DataFilter class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_SearchDeveloperMetadataResponse -// - -@implementation GTLRSheets_SearchDeveloperMetadataResponse -@dynamic matchedDeveloperMetadata; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"matchedDeveloperMetadata" : [GTLRSheets_MatchedDeveloperMetadata class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_SetBasicFilterRequest -// - -@implementation GTLRSheets_SetBasicFilterRequest -@dynamic filter; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_SetDataValidationRequest -// - -@implementation GTLRSheets_SetDataValidationRequest -@dynamic range, rule; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_Sheet -// - -@implementation GTLRSheets_Sheet -@dynamic bandedRanges, basicFilter, charts, columnGroups, conditionalFormats, - data, developerMetadata, filterViews, merges, properties, - protectedRanges, rowGroups; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"bandedRanges" : [GTLRSheets_BandedRange class], - @"charts" : [GTLRSheets_EmbeddedChart class], - @"columnGroups" : [GTLRSheets_DimensionGroup class], - @"conditionalFormats" : [GTLRSheets_ConditionalFormatRule class], - @"data" : [GTLRSheets_GridData class], - @"developerMetadata" : [GTLRSheets_DeveloperMetadata class], - @"filterViews" : [GTLRSheets_FilterView class], - @"merges" : [GTLRSheets_GridRange class], - @"protectedRanges" : [GTLRSheets_ProtectedRange class], - @"rowGroups" : [GTLRSheets_DimensionGroup class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_SheetProperties -// - -@implementation GTLRSheets_SheetProperties -@dynamic gridProperties, hidden, index, rightToLeft, sheetId, sheetType, - tabColor, title; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_SortRangeRequest -// - -@implementation GTLRSheets_SortRangeRequest -@dynamic range, sortSpecs; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"sortSpecs" : [GTLRSheets_SortSpec class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_SortSpec -// - -@implementation GTLRSheets_SortSpec -@dynamic dimensionIndex, sortOrder; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_SourceAndDestination -// - -@implementation GTLRSheets_SourceAndDestination -@dynamic dimension, fillLength, source; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_Spreadsheet -// - -@implementation GTLRSheets_Spreadsheet -@dynamic developerMetadata, namedRanges, properties, sheets, spreadsheetId, - spreadsheetUrl; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"developerMetadata" : [GTLRSheets_DeveloperMetadata class], - @"namedRanges" : [GTLRSheets_NamedRange class], - @"sheets" : [GTLRSheets_Sheet class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_SpreadsheetProperties -// - -@implementation GTLRSheets_SpreadsheetProperties -@dynamic autoRecalc, defaultFormat, iterativeCalculationSettings, locale, - timeZone, title; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_TextFormat -// - -@implementation GTLRSheets_TextFormat -@dynamic bold, fontFamily, fontSize, foregroundColor, italic, strikethrough, - underline; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_TextFormatRun -// - -@implementation GTLRSheets_TextFormatRun -@dynamic format, startIndex; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_TextPosition -// - -@implementation GTLRSheets_TextPosition -@dynamic horizontalAlignment; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_TextRotation -// - -@implementation GTLRSheets_TextRotation -@dynamic angle, vertical; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_TextToColumnsRequest -// - -@implementation GTLRSheets_TextToColumnsRequest -@dynamic delimiter, delimiterType, source; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_TreemapChartColorScale -// - -@implementation GTLRSheets_TreemapChartColorScale -@dynamic maxValueColor, midValueColor, minValueColor, noDataColor; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_TreemapChartSpec -// - -@implementation GTLRSheets_TreemapChartSpec -@dynamic colorData, colorScale, headerColor, hideTooltips, hintedLevels, labels, - levels, maxValue, minValue, parentLabels, sizeData, textFormat; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_UnmergeCellsRequest -// - -@implementation GTLRSheets_UnmergeCellsRequest -@dynamic range; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_UpdateBandingRequest -// - -@implementation GTLRSheets_UpdateBandingRequest -@dynamic bandedRange, fields; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_UpdateBordersRequest -// - -@implementation GTLRSheets_UpdateBordersRequest -@dynamic bottom, innerHorizontal, innerVertical, left, range, right, top; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_UpdateCellsRequest -// - -@implementation GTLRSheets_UpdateCellsRequest -@dynamic fields, range, rows, start; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"rows" : [GTLRSheets_RowData class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_UpdateChartSpecRequest -// - -@implementation GTLRSheets_UpdateChartSpecRequest -@dynamic chartId, spec; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_UpdateConditionalFormatRuleRequest -// - -@implementation GTLRSheets_UpdateConditionalFormatRuleRequest -@dynamic index, newIndex, rule, sheetId; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_UpdateConditionalFormatRuleResponse -// - -@implementation GTLRSheets_UpdateConditionalFormatRuleResponse -@dynamic newIndex, newRule, oldIndex, oldRule; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_UpdateDeveloperMetadataRequest -// - -@implementation GTLRSheets_UpdateDeveloperMetadataRequest -@dynamic dataFilters, developerMetadata, fields; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"dataFilters" : [GTLRSheets_DataFilter class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_UpdateDeveloperMetadataResponse -// - -@implementation GTLRSheets_UpdateDeveloperMetadataResponse -@dynamic developerMetadata; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"developerMetadata" : [GTLRSheets_DeveloperMetadata class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_UpdateDimensionGroupRequest -// - -@implementation GTLRSheets_UpdateDimensionGroupRequest -@dynamic dimensionGroup, fields; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_UpdateDimensionPropertiesRequest -// - -@implementation GTLRSheets_UpdateDimensionPropertiesRequest -@dynamic fields, properties, range; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_UpdateEmbeddedObjectPositionRequest -// - -@implementation GTLRSheets_UpdateEmbeddedObjectPositionRequest -@dynamic fields, newPosition, objectId; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_UpdateEmbeddedObjectPositionResponse -// - -@implementation GTLRSheets_UpdateEmbeddedObjectPositionResponse -@dynamic position; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_UpdateFilterViewRequest -// - -@implementation GTLRSheets_UpdateFilterViewRequest -@dynamic fields, filter; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_UpdateNamedRangeRequest -// - -@implementation GTLRSheets_UpdateNamedRangeRequest -@dynamic fields, namedRange; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_UpdateProtectedRangeRequest -// - -@implementation GTLRSheets_UpdateProtectedRangeRequest -@dynamic fields, protectedRange; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_UpdateSheetPropertiesRequest -// - -@implementation GTLRSheets_UpdateSheetPropertiesRequest -@dynamic fields, properties; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_UpdateSpreadsheetPropertiesRequest -// - -@implementation GTLRSheets_UpdateSpreadsheetPropertiesRequest -@dynamic fields, properties; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_UpdateValuesByDataFilterResponse -// - -@implementation GTLRSheets_UpdateValuesByDataFilterResponse -@dynamic dataFilter, updatedCells, updatedColumns, updatedData, updatedRange, - updatedRows; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_UpdateValuesResponse -// - -@implementation GTLRSheets_UpdateValuesResponse -@dynamic spreadsheetId, updatedCells, updatedColumns, updatedData, updatedRange, - updatedRows; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_ValueRange -// - -@implementation GTLRSheets_ValueRange -@dynamic majorDimension, range, values; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"values" : [NSObject class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_WaterfallChartColumnStyle -// - -@implementation GTLRSheets_WaterfallChartColumnStyle -@dynamic color, label; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_WaterfallChartCustomSubtotal -// - -@implementation GTLRSheets_WaterfallChartCustomSubtotal -@dynamic dataIsSubtotal, label, subtotalIndex; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_WaterfallChartDomain -// - -@implementation GTLRSheets_WaterfallChartDomain -@dynamic data, reversed; -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_WaterfallChartSeries -// - -@implementation GTLRSheets_WaterfallChartSeries -@dynamic customSubtotals, data, hideTrailingSubtotal, negativeColumnsStyle, - positiveColumnsStyle, subtotalColumnsStyle; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"customSubtotals" : [GTLRSheets_WaterfallChartCustomSubtotal class] - }; - return map; -} - -@end - - -// ---------------------------------------------------------------------------- -// -// GTLRSheets_WaterfallChartSpec -// - -@implementation GTLRSheets_WaterfallChartSpec -@dynamic connectorLineStyle, domain, firstValueIsTotal, hideConnectorLines, - series, stackedType; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"series" : [GTLRSheets_WaterfallChartSeries class] - }; - return map; -} - -@end diff --git a/Pods/GoogleAPIClientForREST/Source/GeneratedServices/Sheets/GTLRSheetsQuery.h b/Pods/GoogleAPIClientForREST/Source/GeneratedServices/Sheets/GTLRSheetsQuery.h @@ -1,1078 +0,0 @@ -// NOTE: This file was generated by the ServiceGenerator. - -// ---------------------------------------------------------------------------- -// API: -// Google Sheets API (sheets/v4) -// Description: -// Reads and writes Google Sheets. -// Documentation: -// https://developers.google.com/sheets/ - -#if GTLR_BUILT_AS_FRAMEWORK - #import "GTLR/GTLRQuery.h" -#else - #import "GTLRQuery.h" -#endif - -#if GTLR_RUNTIME_VERSION != 3000 -#error This file was generated by a different version of ServiceGenerator which is incompatible with this GTLR library source. -#endif - -@class GTLRSheets_BatchClearValuesByDataFilterRequest; -@class GTLRSheets_BatchClearValuesRequest; -@class GTLRSheets_BatchGetValuesByDataFilterRequest; -@class GTLRSheets_BatchUpdateSpreadsheetRequest; -@class GTLRSheets_BatchUpdateValuesByDataFilterRequest; -@class GTLRSheets_BatchUpdateValuesRequest; -@class GTLRSheets_ClearValuesRequest; -@class GTLRSheets_CopySheetToAnotherSpreadsheetRequest; -@class GTLRSheets_GetSpreadsheetByDataFilterRequest; -@class GTLRSheets_SearchDeveloperMetadataRequest; -@class GTLRSheets_Spreadsheet; -@class GTLRSheets_ValueRange; - -// Generated comments include content from the discovery document; avoid them -// causing warnings since clang's checks are some what arbitrary. -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdocumentation" - -NS_ASSUME_NONNULL_BEGIN - -// ---------------------------------------------------------------------------- -// Constants - For some of the query classes' properties below. - -// ---------------------------------------------------------------------------- -// dateTimeRenderOption - -/** Value: "FORMATTED_STRING" */ -GTLR_EXTERN NSString * const kGTLRSheetsDateTimeRenderOptionFormattedString; -/** Value: "SERIAL_NUMBER" */ -GTLR_EXTERN NSString * const kGTLRSheetsDateTimeRenderOptionSerialNumber; - -// ---------------------------------------------------------------------------- -// insertDataOption - -/** Value: "INSERT_ROWS" */ -GTLR_EXTERN NSString * const kGTLRSheetsInsertDataOptionInsertRows; -/** Value: "OVERWRITE" */ -GTLR_EXTERN NSString * const kGTLRSheetsInsertDataOptionOverwrite; - -// ---------------------------------------------------------------------------- -// majorDimension - -/** Value: "COLUMNS" */ -GTLR_EXTERN NSString * const kGTLRSheetsMajorDimensionColumns; -/** Value: "DIMENSION_UNSPECIFIED" */ -GTLR_EXTERN NSString * const kGTLRSheetsMajorDimensionDimensionUnspecified; -/** Value: "ROWS" */ -GTLR_EXTERN NSString * const kGTLRSheetsMajorDimensionRows; - -// ---------------------------------------------------------------------------- -// responseDateTimeRenderOption - -/** Value: "FORMATTED_STRING" */ -GTLR_EXTERN NSString * const kGTLRSheetsResponseDateTimeRenderOptionFormattedString; -/** Value: "SERIAL_NUMBER" */ -GTLR_EXTERN NSString * const kGTLRSheetsResponseDateTimeRenderOptionSerialNumber; - -// ---------------------------------------------------------------------------- -// responseValueRenderOption - -/** Value: "FORMATTED_VALUE" */ -GTLR_EXTERN NSString * const kGTLRSheetsResponseValueRenderOptionFormattedValue; -/** Value: "FORMULA" */ -GTLR_EXTERN NSString * const kGTLRSheetsResponseValueRenderOptionFormula; -/** Value: "UNFORMATTED_VALUE" */ -GTLR_EXTERN NSString * const kGTLRSheetsResponseValueRenderOptionUnformattedValue; - -// ---------------------------------------------------------------------------- -// valueInputOption - -/** Value: "INPUT_VALUE_OPTION_UNSPECIFIED" */ -GTLR_EXTERN NSString * const kGTLRSheetsValueInputOptionInputValueOptionUnspecified; -/** Value: "RAW" */ -GTLR_EXTERN NSString * const kGTLRSheetsValueInputOptionRaw; -/** Value: "USER_ENTERED" */ -GTLR_EXTERN NSString * const kGTLRSheetsValueInputOptionUserEntered; - -// ---------------------------------------------------------------------------- -// valueRenderOption - -/** Value: "FORMATTED_VALUE" */ -GTLR_EXTERN NSString * const kGTLRSheetsValueRenderOptionFormattedValue; -/** Value: "FORMULA" */ -GTLR_EXTERN NSString * const kGTLRSheetsValueRenderOptionFormula; -/** Value: "UNFORMATTED_VALUE" */ -GTLR_EXTERN NSString * const kGTLRSheetsValueRenderOptionUnformattedValue; - -// ---------------------------------------------------------------------------- -// Query Classes -// - -/** - * Parent class for other Sheets query classes. - */ -@interface GTLRSheetsQuery : GTLRQuery - -/** Selector specifying which fields to include in a partial response. */ -@property(nonatomic, copy, nullable) NSString *fields; - -@end - -/** - * Applies one or more updates to the spreadsheet. - * Each request is validated before - * being applied. If any request is not valid then the entire request will - * fail and nothing will be applied. - * Some requests have replies to - * give you some information about how - * they are applied. The replies will mirror the requests. For example, - * if you applied 4 updates and the 3rd one had a reply, then the - * response will have 2 empty replies, the actual reply, and another empty - * reply, in that order. - * Due to the collaborative nature of spreadsheets, it is not guaranteed that - * the spreadsheet will reflect exactly your changes after this completes, - * however it is guaranteed that the updates in the request will be - * applied together atomically. Your changes may be altered with respect to - * collaborator changes. If there are no collaborators, the spreadsheet - * should reflect your changes. - * - * Method: sheets.spreadsheets.batchUpdate - * - * Authorization scope(s): - * @c kGTLRAuthScopeSheetsDrive - * @c kGTLRAuthScopeSheetsDriveFile - * @c kGTLRAuthScopeSheetsSpreadsheets - */ -@interface GTLRSheetsQuery_SpreadsheetsBatchUpdate : GTLRSheetsQuery -// Previous library name was -// +[GTLQuerySheets queryForSpreadsheetsBatchUpdateWithObject:spreadsheetId:] - -/** The spreadsheet to apply the updates to. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * Fetches a @c GTLRSheets_BatchUpdateSpreadsheetResponse. - * - * Applies one or more updates to the spreadsheet. - * Each request is validated before - * being applied. If any request is not valid then the entire request will - * fail and nothing will be applied. - * Some requests have replies to - * give you some information about how - * they are applied. The replies will mirror the requests. For example, - * if you applied 4 updates and the 3rd one had a reply, then the - * response will have 2 empty replies, the actual reply, and another empty - * reply, in that order. - * Due to the collaborative nature of spreadsheets, it is not guaranteed that - * the spreadsheet will reflect exactly your changes after this completes, - * however it is guaranteed that the updates in the request will be - * applied together atomically. Your changes may be altered with respect to - * collaborator changes. If there are no collaborators, the spreadsheet - * should reflect your changes. - * - * @param object The @c GTLRSheets_BatchUpdateSpreadsheetRequest to include in - * the query. - * @param spreadsheetId The spreadsheet to apply the updates to. - * - * @return GTLRSheetsQuery_SpreadsheetsBatchUpdate - */ -+ (instancetype)queryWithObject:(GTLRSheets_BatchUpdateSpreadsheetRequest *)object - spreadsheetId:(NSString *)spreadsheetId; - -@end - -/** - * Creates a spreadsheet, returning the newly created spreadsheet. - * - * Method: sheets.spreadsheets.create - * - * Authorization scope(s): - * @c kGTLRAuthScopeSheetsDrive - * @c kGTLRAuthScopeSheetsDriveFile - * @c kGTLRAuthScopeSheetsSpreadsheets - */ -@interface GTLRSheetsQuery_SpreadsheetsCreate : GTLRSheetsQuery -// Previous library name was -// +[GTLQuerySheets queryForSpreadsheetsCreateWithObject:] - -/** - * Fetches a @c GTLRSheets_Spreadsheet. - * - * Creates a spreadsheet, returning the newly created spreadsheet. - * - * @param object The @c GTLRSheets_Spreadsheet to include in the query. - * - * @return GTLRSheetsQuery_SpreadsheetsCreate - */ -+ (instancetype)queryWithObject:(GTLRSheets_Spreadsheet *)object; - -@end - -/** - * Returns the developer metadata with the specified ID. - * The caller must specify the spreadsheet ID and the developer metadata's - * unique metadataId. - * - * Method: sheets.spreadsheets.developerMetadata.get - * - * Authorization scope(s): - * @c kGTLRAuthScopeSheetsDrive - * @c kGTLRAuthScopeSheetsDriveFile - * @c kGTLRAuthScopeSheetsSpreadsheets - */ -@interface GTLRSheetsQuery_SpreadsheetsDeveloperMetadataGet : GTLRSheetsQuery -// Previous library name was -// +[GTLQuerySheets queryForSpreadsheetsDeveloperMetadataGetWithspreadsheetId:metadataId:] - -/** The ID of the developer metadata to retrieve. */ -@property(nonatomic, assign) NSInteger metadataId; - -/** The ID of the spreadsheet to retrieve metadata from. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * Fetches a @c GTLRSheets_DeveloperMetadata. - * - * Returns the developer metadata with the specified ID. - * The caller must specify the spreadsheet ID and the developer metadata's - * unique metadataId. - * - * @param spreadsheetId The ID of the spreadsheet to retrieve metadata from. - * @param metadataId The ID of the developer metadata to retrieve. - * - * @return GTLRSheetsQuery_SpreadsheetsDeveloperMetadataGet - */ -+ (instancetype)queryWithSpreadsheetId:(NSString *)spreadsheetId - metadataId:(NSInteger)metadataId; - -@end - -/** - * Returns all developer metadata matching the specified DataFilter. - * If the provided DataFilter represents a DeveloperMetadataLookup object, - * this will return all DeveloperMetadata entries selected by it. If the - * DataFilter represents a location in a spreadsheet, this will return all - * developer metadata associated with locations intersecting that region. - * - * Method: sheets.spreadsheets.developerMetadata.search - * - * Authorization scope(s): - * @c kGTLRAuthScopeSheetsDrive - * @c kGTLRAuthScopeSheetsDriveFile - * @c kGTLRAuthScopeSheetsSpreadsheets - */ -@interface GTLRSheetsQuery_SpreadsheetsDeveloperMetadataSearch : GTLRSheetsQuery -// Previous library name was -// +[GTLQuerySheets queryForSpreadsheetsDeveloperMetadataSearchWithObject:spreadsheetId:] - -/** The ID of the spreadsheet to retrieve metadata from. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * Fetches a @c GTLRSheets_SearchDeveloperMetadataResponse. - * - * Returns all developer metadata matching the specified DataFilter. - * If the provided DataFilter represents a DeveloperMetadataLookup object, - * this will return all DeveloperMetadata entries selected by it. If the - * DataFilter represents a location in a spreadsheet, this will return all - * developer metadata associated with locations intersecting that region. - * - * @param object The @c GTLRSheets_SearchDeveloperMetadataRequest to include in - * the query. - * @param spreadsheetId The ID of the spreadsheet to retrieve metadata from. - * - * @return GTLRSheetsQuery_SpreadsheetsDeveloperMetadataSearch - */ -+ (instancetype)queryWithObject:(GTLRSheets_SearchDeveloperMetadataRequest *)object - spreadsheetId:(NSString *)spreadsheetId; - -@end - -/** - * Returns the spreadsheet at the given ID. - * The caller must specify the spreadsheet ID. - * By default, data within grids will not be returned. - * You can include grid data one of two ways: - * * Specify a field mask listing your desired fields using the `fields` URL - * parameter in HTTP - * * Set the includeGridData - * URL parameter to true. If a field mask is set, the `includeGridData` - * parameter is ignored - * For large spreadsheets, it is recommended to retrieve only the specific - * fields of the spreadsheet that you want. - * To retrieve only subsets of the spreadsheet, use the - * ranges URL parameter. - * Multiple ranges can be specified. Limiting the range will - * return only the portions of the spreadsheet that intersect the requested - * ranges. Ranges are specified using A1 notation. - * - * Method: sheets.spreadsheets.get - * - * Authorization scope(s): - * @c kGTLRAuthScopeSheetsDrive - * @c kGTLRAuthScopeSheetsDriveFile - * @c kGTLRAuthScopeSheetsDriveReadonly - * @c kGTLRAuthScopeSheetsSpreadsheets - * @c kGTLRAuthScopeSheetsSpreadsheetsReadonly - */ -@interface GTLRSheetsQuery_SpreadsheetsGet : GTLRSheetsQuery -// Previous library name was -// +[GTLQuerySheets queryForSpreadsheetsGetWithspreadsheetId:] - -/** - * True if grid data should be returned. - * This parameter is ignored if a field mask was set in the request. - */ -@property(nonatomic, assign) BOOL includeGridData; - -/** The ranges to retrieve from the spreadsheet. */ -@property(nonatomic, strong, nullable) NSArray<NSString *> *ranges; - -/** The spreadsheet to request. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * Fetches a @c GTLRSheets_Spreadsheet. - * - * Returns the spreadsheet at the given ID. - * The caller must specify the spreadsheet ID. - * By default, data within grids will not be returned. - * You can include grid data one of two ways: - * * Specify a field mask listing your desired fields using the `fields` URL - * parameter in HTTP - * * Set the includeGridData - * URL parameter to true. If a field mask is set, the `includeGridData` - * parameter is ignored - * For large spreadsheets, it is recommended to retrieve only the specific - * fields of the spreadsheet that you want. - * To retrieve only subsets of the spreadsheet, use the - * ranges URL parameter. - * Multiple ranges can be specified. Limiting the range will - * return only the portions of the spreadsheet that intersect the requested - * ranges. Ranges are specified using A1 notation. - * - * @param spreadsheetId The spreadsheet to request. - * - * @return GTLRSheetsQuery_SpreadsheetsGet - */ -+ (instancetype)queryWithSpreadsheetId:(NSString *)spreadsheetId; - -@end - -/** - * Returns the spreadsheet at the given ID. - * The caller must specify the spreadsheet ID. - * This method differs from GetSpreadsheet in that it allows selecting - * which subsets of spreadsheet data to return by specifying a - * dataFilters parameter. - * Multiple DataFilters can be specified. Specifying one or - * more data filters will return the portions of the spreadsheet that - * intersect ranges matched by any of the filters. - * By default, data within grids will not be returned. - * You can include grid data one of two ways: - * * Specify a field mask listing your desired fields using the `fields` URL - * parameter in HTTP - * * Set the includeGridData - * parameter to true. If a field mask is set, the `includeGridData` - * parameter is ignored - * For large spreadsheets, it is recommended to retrieve only the specific - * fields of the spreadsheet that you want. - * - * Method: sheets.spreadsheets.getByDataFilter - * - * Authorization scope(s): - * @c kGTLRAuthScopeSheetsDrive - * @c kGTLRAuthScopeSheetsDriveFile - * @c kGTLRAuthScopeSheetsSpreadsheets - */ -@interface GTLRSheetsQuery_SpreadsheetsGetByDataFilter : GTLRSheetsQuery -// Previous library name was -// +[GTLQuerySheets queryForSpreadsheetsGetByDataFilterWithObject:spreadsheetId:] - -/** The spreadsheet to request. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * Fetches a @c GTLRSheets_Spreadsheet. - * - * Returns the spreadsheet at the given ID. - * The caller must specify the spreadsheet ID. - * This method differs from GetSpreadsheet in that it allows selecting - * which subsets of spreadsheet data to return by specifying a - * dataFilters parameter. - * Multiple DataFilters can be specified. Specifying one or - * more data filters will return the portions of the spreadsheet that - * intersect ranges matched by any of the filters. - * By default, data within grids will not be returned. - * You can include grid data one of two ways: - * * Specify a field mask listing your desired fields using the `fields` URL - * parameter in HTTP - * * Set the includeGridData - * parameter to true. If a field mask is set, the `includeGridData` - * parameter is ignored - * For large spreadsheets, it is recommended to retrieve only the specific - * fields of the spreadsheet that you want. - * - * @param object The @c GTLRSheets_GetSpreadsheetByDataFilterRequest to include - * in the query. - * @param spreadsheetId The spreadsheet to request. - * - * @return GTLRSheetsQuery_SpreadsheetsGetByDataFilter - */ -+ (instancetype)queryWithObject:(GTLRSheets_GetSpreadsheetByDataFilterRequest *)object - spreadsheetId:(NSString *)spreadsheetId; - -@end - -/** - * Copies a single sheet from a spreadsheet to another spreadsheet. - * Returns the properties of the newly created sheet. - * - * Method: sheets.spreadsheets.sheets.copyTo - * - * Authorization scope(s): - * @c kGTLRAuthScopeSheetsDrive - * @c kGTLRAuthScopeSheetsDriveFile - * @c kGTLRAuthScopeSheetsSpreadsheets - */ -@interface GTLRSheetsQuery_SpreadsheetsSheetsCopyTo : GTLRSheetsQuery -// Previous library name was -// +[GTLQuerySheets queryForSpreadsheetsSheetsCopyToWithObject:spreadsheetId:sheetId:] - -/** The ID of the sheet to copy. */ -@property(nonatomic, assign) NSInteger sheetId; - -/** The ID of the spreadsheet containing the sheet to copy. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * Fetches a @c GTLRSheets_SheetProperties. - * - * Copies a single sheet from a spreadsheet to another spreadsheet. - * Returns the properties of the newly created sheet. - * - * @param object The @c GTLRSheets_CopySheetToAnotherSpreadsheetRequest to - * include in the query. - * @param spreadsheetId The ID of the spreadsheet containing the sheet to copy. - * @param sheetId The ID of the sheet to copy. - * - * @return GTLRSheetsQuery_SpreadsheetsSheetsCopyTo - */ -+ (instancetype)queryWithObject:(GTLRSheets_CopySheetToAnotherSpreadsheetRequest *)object - spreadsheetId:(NSString *)spreadsheetId - sheetId:(NSInteger)sheetId; - -@end - -/** - * Appends values to a spreadsheet. The input range is used to search for - * existing data and find a "table" within that range. Values will be - * appended to the next row of the table, starting with the first column of - * the table. See the - * [guide](/sheets/api/guides/values#appending_values) - * and - * [sample code](/sheets/api/samples/writing#append_values) - * for specific details of how tables are detected and data is appended. - * The caller must specify the spreadsheet ID, range, and - * a valueInputOption. The `valueInputOption` only - * controls how the input data will be added to the sheet (column-wise or - * row-wise), it does not influence what cell the data starts being written - * to. - * - * Method: sheets.spreadsheets.values.append - * - * Authorization scope(s): - * @c kGTLRAuthScopeSheetsDrive - * @c kGTLRAuthScopeSheetsDriveFile - * @c kGTLRAuthScopeSheetsSpreadsheets - */ -@interface GTLRSheetsQuery_SpreadsheetsValuesAppend : GTLRSheetsQuery -// Previous library name was -// +[GTLQuerySheets queryForSpreadsheetsValuesAppendWithObject:spreadsheetId:range:] - -/** - * Determines if the update response should include the values - * of the cells that were appended. By default, responses - * do not include the updated values. - */ -@property(nonatomic, assign) BOOL includeValuesInResponse; - -/** - * How the input data should be inserted. - * - * Likely values: - * @arg @c kGTLRSheetsInsertDataOptionOverwrite Value "OVERWRITE" - * @arg @c kGTLRSheetsInsertDataOptionInsertRows Value "INSERT_ROWS" - */ -@property(nonatomic, copy, nullable) NSString *insertDataOption; - -/** - * The A1 notation of a range to search for a logical table of data. - * Values will be appended after the last row of the table. - */ -@property(nonatomic, copy, nullable) NSString *range; - -/** - * Determines how dates, times, and durations in the response should be - * rendered. This is ignored if response_value_render_option is - * FORMATTED_VALUE. - * The default dateTime render option is [DateTimeRenderOption.SERIAL_NUMBER]. - * - * Likely values: - * @arg @c kGTLRSheetsResponseDateTimeRenderOptionSerialNumber Value - * "SERIAL_NUMBER" - * @arg @c kGTLRSheetsResponseDateTimeRenderOptionFormattedString Value - * "FORMATTED_STRING" - */ -@property(nonatomic, copy, nullable) NSString *responseDateTimeRenderOption; - -/** - * Determines how values in the response should be rendered. - * The default render option is ValueRenderOption.FORMATTED_VALUE. - * - * Likely values: - * @arg @c kGTLRSheetsResponseValueRenderOptionFormattedValue Value - * "FORMATTED_VALUE" - * @arg @c kGTLRSheetsResponseValueRenderOptionUnformattedValue Value - * "UNFORMATTED_VALUE" - * @arg @c kGTLRSheetsResponseValueRenderOptionFormula Value "FORMULA" - */ -@property(nonatomic, copy, nullable) NSString *responseValueRenderOption; - -/** The ID of the spreadsheet to update. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * How the input data should be interpreted. - * - * Likely values: - * @arg @c kGTLRSheetsValueInputOptionInputValueOptionUnspecified Value - * "INPUT_VALUE_OPTION_UNSPECIFIED" - * @arg @c kGTLRSheetsValueInputOptionRaw Value "RAW" - * @arg @c kGTLRSheetsValueInputOptionUserEntered Value "USER_ENTERED" - */ -@property(nonatomic, copy, nullable) NSString *valueInputOption; - -/** - * Fetches a @c GTLRSheets_AppendValuesResponse. - * - * Appends values to a spreadsheet. The input range is used to search for - * existing data and find a "table" within that range. Values will be - * appended to the next row of the table, starting with the first column of - * the table. See the - * [guide](/sheets/api/guides/values#appending_values) - * and - * [sample code](/sheets/api/samples/writing#append_values) - * for specific details of how tables are detected and data is appended. - * The caller must specify the spreadsheet ID, range, and - * a valueInputOption. The `valueInputOption` only - * controls how the input data will be added to the sheet (column-wise or - * row-wise), it does not influence what cell the data starts being written - * to. - * - * @param object The @c GTLRSheets_ValueRange to include in the query. - * @param spreadsheetId The ID of the spreadsheet to update. - * @param range The A1 notation of a range to search for a logical table of - * data. - * Values will be appended after the last row of the table. - * - * @return GTLRSheetsQuery_SpreadsheetsValuesAppend - */ -+ (instancetype)queryWithObject:(GTLRSheets_ValueRange *)object - spreadsheetId:(NSString *)spreadsheetId - range:(NSString *)range; - -@end - -/** - * Clears one or more ranges of values from a spreadsheet. - * The caller must specify the spreadsheet ID and one or more ranges. - * Only values are cleared -- all other properties of the cell (such as - * formatting, data validation, etc..) are kept. - * - * Method: sheets.spreadsheets.values.batchClear - * - * Authorization scope(s): - * @c kGTLRAuthScopeSheetsDrive - * @c kGTLRAuthScopeSheetsDriveFile - * @c kGTLRAuthScopeSheetsSpreadsheets - */ -@interface GTLRSheetsQuery_SpreadsheetsValuesBatchClear : GTLRSheetsQuery -// Previous library name was -// +[GTLQuerySheets queryForSpreadsheetsValuesBatchClearWithObject:spreadsheetId:] - -/** The ID of the spreadsheet to update. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * Fetches a @c GTLRSheets_BatchClearValuesResponse. - * - * Clears one or more ranges of values from a spreadsheet. - * The caller must specify the spreadsheet ID and one or more ranges. - * Only values are cleared -- all other properties of the cell (such as - * formatting, data validation, etc..) are kept. - * - * @param object The @c GTLRSheets_BatchClearValuesRequest to include in the - * query. - * @param spreadsheetId The ID of the spreadsheet to update. - * - * @return GTLRSheetsQuery_SpreadsheetsValuesBatchClear - */ -+ (instancetype)queryWithObject:(GTLRSheets_BatchClearValuesRequest *)object - spreadsheetId:(NSString *)spreadsheetId; - -@end - -/** - * Clears one or more ranges of values from a spreadsheet. - * The caller must specify the spreadsheet ID and one or more - * DataFilters. Ranges matching any of the specified data - * filters will be cleared. Only values are cleared -- all other properties - * of the cell (such as formatting, data validation, etc..) are kept. - * - * Method: sheets.spreadsheets.values.batchClearByDataFilter - * - * Authorization scope(s): - * @c kGTLRAuthScopeSheetsDrive - * @c kGTLRAuthScopeSheetsDriveFile - * @c kGTLRAuthScopeSheetsSpreadsheets - */ -@interface GTLRSheetsQuery_SpreadsheetsValuesBatchClearByDataFilter : GTLRSheetsQuery -// Previous library name was -// +[GTLQuerySheets queryForSpreadsheetsValuesBatchClearByDataFilterWithObject:spreadsheetId:] - -/** The ID of the spreadsheet to update. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * Fetches a @c GTLRSheets_BatchClearValuesByDataFilterResponse. - * - * Clears one or more ranges of values from a spreadsheet. - * The caller must specify the spreadsheet ID and one or more - * DataFilters. Ranges matching any of the specified data - * filters will be cleared. Only values are cleared -- all other properties - * of the cell (such as formatting, data validation, etc..) are kept. - * - * @param object The @c GTLRSheets_BatchClearValuesByDataFilterRequest to - * include in the query. - * @param spreadsheetId The ID of the spreadsheet to update. - * - * @return GTLRSheetsQuery_SpreadsheetsValuesBatchClearByDataFilter - */ -+ (instancetype)queryWithObject:(GTLRSheets_BatchClearValuesByDataFilterRequest *)object - spreadsheetId:(NSString *)spreadsheetId; - -@end - -/** - * Returns one or more ranges of values from a spreadsheet. - * The caller must specify the spreadsheet ID and one or more ranges. - * - * Method: sheets.spreadsheets.values.batchGet - * - * Authorization scope(s): - * @c kGTLRAuthScopeSheetsDrive - * @c kGTLRAuthScopeSheetsDriveFile - * @c kGTLRAuthScopeSheetsDriveReadonly - * @c kGTLRAuthScopeSheetsSpreadsheets - * @c kGTLRAuthScopeSheetsSpreadsheetsReadonly - */ -@interface GTLRSheetsQuery_SpreadsheetsValuesBatchGet : GTLRSheetsQuery -// Previous library name was -// +[GTLQuerySheets queryForSpreadsheetsValuesBatchGetWithspreadsheetId:] - -/** - * How dates, times, and durations should be represented in the output. - * This is ignored if value_render_option is - * FORMATTED_VALUE. - * The default dateTime render option is [DateTimeRenderOption.SERIAL_NUMBER]. - * - * Likely values: - * @arg @c kGTLRSheetsDateTimeRenderOptionSerialNumber Value "SERIAL_NUMBER" - * @arg @c kGTLRSheetsDateTimeRenderOptionFormattedString Value - * "FORMATTED_STRING" - */ -@property(nonatomic, copy, nullable) NSString *dateTimeRenderOption; - -/** - * The major dimension that results should use. - * For example, if the spreadsheet data is: `A1=1,B1=2,A2=3,B2=4`, - * then requesting `range=A1:B2,majorDimension=ROWS` will return - * `[[1,2],[3,4]]`, - * whereas requesting `range=A1:B2,majorDimension=COLUMNS` will return - * `[[1,3],[2,4]]`. - * - * Likely values: - * @arg @c kGTLRSheetsMajorDimensionDimensionUnspecified Value - * "DIMENSION_UNSPECIFIED" - * @arg @c kGTLRSheetsMajorDimensionRows Value "ROWS" - * @arg @c kGTLRSheetsMajorDimensionColumns Value "COLUMNS" - */ -@property(nonatomic, copy, nullable) NSString *majorDimension; - -/** The A1 notation of the values to retrieve. */ -@property(nonatomic, strong, nullable) NSArray<NSString *> *ranges; - -/** The ID of the spreadsheet to retrieve data from. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * How values should be represented in the output. - * The default render option is ValueRenderOption.FORMATTED_VALUE. - * - * Likely values: - * @arg @c kGTLRSheetsValueRenderOptionFormattedValue Value "FORMATTED_VALUE" - * @arg @c kGTLRSheetsValueRenderOptionUnformattedValue Value - * "UNFORMATTED_VALUE" - * @arg @c kGTLRSheetsValueRenderOptionFormula Value "FORMULA" - */ -@property(nonatomic, copy, nullable) NSString *valueRenderOption; - -/** - * Fetches a @c GTLRSheets_BatchGetValuesResponse. - * - * Returns one or more ranges of values from a spreadsheet. - * The caller must specify the spreadsheet ID and one or more ranges. - * - * @param spreadsheetId The ID of the spreadsheet to retrieve data from. - * - * @return GTLRSheetsQuery_SpreadsheetsValuesBatchGet - */ -+ (instancetype)queryWithSpreadsheetId:(NSString *)spreadsheetId; - -@end - -/** - * Returns one or more ranges of values that match the specified data filters. - * The caller must specify the spreadsheet ID and one or more - * DataFilters. Ranges that match any of the data filters in - * the request will be returned. - * - * Method: sheets.spreadsheets.values.batchGetByDataFilter - * - * Authorization scope(s): - * @c kGTLRAuthScopeSheetsDrive - * @c kGTLRAuthScopeSheetsDriveFile - * @c kGTLRAuthScopeSheetsSpreadsheets - */ -@interface GTLRSheetsQuery_SpreadsheetsValuesBatchGetByDataFilter : GTLRSheetsQuery -// Previous library name was -// +[GTLQuerySheets queryForSpreadsheetsValuesBatchGetByDataFilterWithObject:spreadsheetId:] - -/** The ID of the spreadsheet to retrieve data from. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * Fetches a @c GTLRSheets_BatchGetValuesByDataFilterResponse. - * - * Returns one or more ranges of values that match the specified data filters. - * The caller must specify the spreadsheet ID and one or more - * DataFilters. Ranges that match any of the data filters in - * the request will be returned. - * - * @param object The @c GTLRSheets_BatchGetValuesByDataFilterRequest to include - * in the query. - * @param spreadsheetId The ID of the spreadsheet to retrieve data from. - * - * @return GTLRSheetsQuery_SpreadsheetsValuesBatchGetByDataFilter - */ -+ (instancetype)queryWithObject:(GTLRSheets_BatchGetValuesByDataFilterRequest *)object - spreadsheetId:(NSString *)spreadsheetId; - -@end - -/** - * Sets values in one or more ranges of a spreadsheet. - * The caller must specify the spreadsheet ID, - * a valueInputOption, and one or more - * ValueRanges. - * - * Method: sheets.spreadsheets.values.batchUpdate - * - * Authorization scope(s): - * @c kGTLRAuthScopeSheetsDrive - * @c kGTLRAuthScopeSheetsDriveFile - * @c kGTLRAuthScopeSheetsSpreadsheets - */ -@interface GTLRSheetsQuery_SpreadsheetsValuesBatchUpdate : GTLRSheetsQuery -// Previous library name was -// +[GTLQuerySheets queryForSpreadsheetsValuesBatchUpdateWithObject:spreadsheetId:] - -/** The ID of the spreadsheet to update. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * Fetches a @c GTLRSheets_BatchUpdateValuesResponse. - * - * Sets values in one or more ranges of a spreadsheet. - * The caller must specify the spreadsheet ID, - * a valueInputOption, and one or more - * ValueRanges. - * - * @param object The @c GTLRSheets_BatchUpdateValuesRequest to include in the - * query. - * @param spreadsheetId The ID of the spreadsheet to update. - * - * @return GTLRSheetsQuery_SpreadsheetsValuesBatchUpdate - */ -+ (instancetype)queryWithObject:(GTLRSheets_BatchUpdateValuesRequest *)object - spreadsheetId:(NSString *)spreadsheetId; - -@end - -/** - * Sets values in one or more ranges of a spreadsheet. - * The caller must specify the spreadsheet ID, - * a valueInputOption, and one or more - * DataFilterValueRanges. - * - * Method: sheets.spreadsheets.values.batchUpdateByDataFilter - * - * Authorization scope(s): - * @c kGTLRAuthScopeSheetsDrive - * @c kGTLRAuthScopeSheetsDriveFile - * @c kGTLRAuthScopeSheetsSpreadsheets - */ -@interface GTLRSheetsQuery_SpreadsheetsValuesBatchUpdateByDataFilter : GTLRSheetsQuery -// Previous library name was -// +[GTLQuerySheets queryForSpreadsheetsValuesBatchUpdateByDataFilterWithObject:spreadsheetId:] - -/** The ID of the spreadsheet to update. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * Fetches a @c GTLRSheets_BatchUpdateValuesByDataFilterResponse. - * - * Sets values in one or more ranges of a spreadsheet. - * The caller must specify the spreadsheet ID, - * a valueInputOption, and one or more - * DataFilterValueRanges. - * - * @param object The @c GTLRSheets_BatchUpdateValuesByDataFilterRequest to - * include in the query. - * @param spreadsheetId The ID of the spreadsheet to update. - * - * @return GTLRSheetsQuery_SpreadsheetsValuesBatchUpdateByDataFilter - */ -+ (instancetype)queryWithObject:(GTLRSheets_BatchUpdateValuesByDataFilterRequest *)object - spreadsheetId:(NSString *)spreadsheetId; - -@end - -/** - * Clears values from a spreadsheet. - * The caller must specify the spreadsheet ID and range. - * Only values are cleared -- all other properties of the cell (such as - * formatting, data validation, etc..) are kept. - * - * Method: sheets.spreadsheets.values.clear - * - * Authorization scope(s): - * @c kGTLRAuthScopeSheetsDrive - * @c kGTLRAuthScopeSheetsDriveFile - * @c kGTLRAuthScopeSheetsSpreadsheets - */ -@interface GTLRSheetsQuery_SpreadsheetsValuesClear : GTLRSheetsQuery -// Previous library name was -// +[GTLQuerySheets queryForSpreadsheetsValuesClearWithObject:spreadsheetId:range:] - -/** The A1 notation of the values to clear. */ -@property(nonatomic, copy, nullable) NSString *range; - -/** The ID of the spreadsheet to update. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * Fetches a @c GTLRSheets_ClearValuesResponse. - * - * Clears values from a spreadsheet. - * The caller must specify the spreadsheet ID and range. - * Only values are cleared -- all other properties of the cell (such as - * formatting, data validation, etc..) are kept. - * - * @param object The @c GTLRSheets_ClearValuesRequest to include in the query. - * @param spreadsheetId The ID of the spreadsheet to update. - * @param range The A1 notation of the values to clear. - * - * @return GTLRSheetsQuery_SpreadsheetsValuesClear - */ -+ (instancetype)queryWithObject:(GTLRSheets_ClearValuesRequest *)object - spreadsheetId:(NSString *)spreadsheetId - range:(NSString *)range; - -@end - -/** - * Returns a range of values from a spreadsheet. - * The caller must specify the spreadsheet ID and a range. - * - * Method: sheets.spreadsheets.values.get - * - * Authorization scope(s): - * @c kGTLRAuthScopeSheetsDrive - * @c kGTLRAuthScopeSheetsDriveFile - * @c kGTLRAuthScopeSheetsDriveReadonly - * @c kGTLRAuthScopeSheetsSpreadsheets - * @c kGTLRAuthScopeSheetsSpreadsheetsReadonly - */ -@interface GTLRSheetsQuery_SpreadsheetsValuesGet : GTLRSheetsQuery -// Previous library name was -// +[GTLQuerySheets queryForSpreadsheetsValuesGetWithspreadsheetId:range:] - -/** - * How dates, times, and durations should be represented in the output. - * This is ignored if value_render_option is - * FORMATTED_VALUE. - * The default dateTime render option is [DateTimeRenderOption.SERIAL_NUMBER]. - * - * Likely values: - * @arg @c kGTLRSheetsDateTimeRenderOptionSerialNumber Value "SERIAL_NUMBER" - * @arg @c kGTLRSheetsDateTimeRenderOptionFormattedString Value - * "FORMATTED_STRING" - */ -@property(nonatomic, copy, nullable) NSString *dateTimeRenderOption; - -/** - * The major dimension that results should use. - * For example, if the spreadsheet data is: `A1=1,B1=2,A2=3,B2=4`, - * then requesting `range=A1:B2,majorDimension=ROWS` will return - * `[[1,2],[3,4]]`, - * whereas requesting `range=A1:B2,majorDimension=COLUMNS` will return - * `[[1,3],[2,4]]`. - * - * Likely values: - * @arg @c kGTLRSheetsMajorDimensionDimensionUnspecified Value - * "DIMENSION_UNSPECIFIED" - * @arg @c kGTLRSheetsMajorDimensionRows Value "ROWS" - * @arg @c kGTLRSheetsMajorDimensionColumns Value "COLUMNS" - */ -@property(nonatomic, copy, nullable) NSString *majorDimension; - -/** The A1 notation of the values to retrieve. */ -@property(nonatomic, copy, nullable) NSString *range; - -/** The ID of the spreadsheet to retrieve data from. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * How values should be represented in the output. - * The default render option is ValueRenderOption.FORMATTED_VALUE. - * - * Likely values: - * @arg @c kGTLRSheetsValueRenderOptionFormattedValue Value "FORMATTED_VALUE" - * @arg @c kGTLRSheetsValueRenderOptionUnformattedValue Value - * "UNFORMATTED_VALUE" - * @arg @c kGTLRSheetsValueRenderOptionFormula Value "FORMULA" - */ -@property(nonatomic, copy, nullable) NSString *valueRenderOption; - -/** - * Fetches a @c GTLRSheets_ValueRange. - * - * Returns a range of values from a spreadsheet. - * The caller must specify the spreadsheet ID and a range. - * - * @param spreadsheetId The ID of the spreadsheet to retrieve data from. - * @param range The A1 notation of the values to retrieve. - * - * @return GTLRSheetsQuery_SpreadsheetsValuesGet - */ -+ (instancetype)queryWithSpreadsheetId:(NSString *)spreadsheetId - range:(NSString *)range; - -@end - -/** - * Sets values in a range of a spreadsheet. - * The caller must specify the spreadsheet ID, range, and - * a valueInputOption. - * - * Method: sheets.spreadsheets.values.update - * - * Authorization scope(s): - * @c kGTLRAuthScopeSheetsDrive - * @c kGTLRAuthScopeSheetsDriveFile - * @c kGTLRAuthScopeSheetsSpreadsheets - */ -@interface GTLRSheetsQuery_SpreadsheetsValuesUpdate : GTLRSheetsQuery -// Previous library name was -// +[GTLQuerySheets queryForSpreadsheetsValuesUpdateWithObject:spreadsheetId:range:] - -/** - * Determines if the update response should include the values - * of the cells that were updated. By default, responses - * do not include the updated values. - * If the range to write was larger than than the range actually written, - * the response will include all values in the requested range (excluding - * trailing empty rows and columns). - */ -@property(nonatomic, assign) BOOL includeValuesInResponse; - -/** The A1 notation of the values to update. */ -@property(nonatomic, copy, nullable) NSString *range; - -/** - * Determines how dates, times, and durations in the response should be - * rendered. This is ignored if response_value_render_option is - * FORMATTED_VALUE. - * The default dateTime render option is - * DateTimeRenderOption.SERIAL_NUMBER. - * - * Likely values: - * @arg @c kGTLRSheetsResponseDateTimeRenderOptionSerialNumber Value - * "SERIAL_NUMBER" - * @arg @c kGTLRSheetsResponseDateTimeRenderOptionFormattedString Value - * "FORMATTED_STRING" - */ -@property(nonatomic, copy, nullable) NSString *responseDateTimeRenderOption; - -/** - * Determines how values in the response should be rendered. - * The default render option is ValueRenderOption.FORMATTED_VALUE. - * - * Likely values: - * @arg @c kGTLRSheetsResponseValueRenderOptionFormattedValue Value - * "FORMATTED_VALUE" - * @arg @c kGTLRSheetsResponseValueRenderOptionUnformattedValue Value - * "UNFORMATTED_VALUE" - * @arg @c kGTLRSheetsResponseValueRenderOptionFormula Value "FORMULA" - */ -@property(nonatomic, copy, nullable) NSString *responseValueRenderOption; - -/** The ID of the spreadsheet to update. */ -@property(nonatomic, copy, nullable) NSString *spreadsheetId; - -/** - * How the input data should be interpreted. - * - * Likely values: - * @arg @c kGTLRSheetsValueInputOptionInputValueOptionUnspecified Value - * "INPUT_VALUE_OPTION_UNSPECIFIED" - * @arg @c kGTLRSheetsValueInputOptionRaw Value "RAW" - * @arg @c kGTLRSheetsValueInputOptionUserEntered Value "USER_ENTERED" - */ -@property(nonatomic, copy, nullable) NSString *valueInputOption; - -/** - * Fetches a @c GTLRSheets_UpdateValuesResponse. - * - * Sets values in a range of a spreadsheet. - * The caller must specify the spreadsheet ID, range, and - * a valueInputOption. - * - * @param object The @c GTLRSheets_ValueRange to include in the query. - * @param spreadsheetId The ID of the spreadsheet to update. - * @param range The A1 notation of the values to update. - * - * @return GTLRSheetsQuery_SpreadsheetsValuesUpdate - */ -+ (instancetype)queryWithObject:(GTLRSheets_ValueRange *)object - spreadsheetId:(NSString *)spreadsheetId - range:(NSString *)range; - -@end - -NS_ASSUME_NONNULL_END - -#pragma clang diagnostic pop diff --git a/Pods/GoogleAPIClientForREST/Source/GeneratedServices/Sheets/GTLRSheetsQuery.m b/Pods/GoogleAPIClientForREST/Source/GeneratedServices/Sheets/GTLRSheetsQuery.m @@ -1,497 +0,0 @@ -// NOTE: This file was generated by the ServiceGenerator. - -// ---------------------------------------------------------------------------- -// API: -// Google Sheets API (sheets/v4) -// Description: -// Reads and writes Google Sheets. -// Documentation: -// https://developers.google.com/sheets/ - -#import "GTLRSheetsQuery.h" - -#import "GTLRSheetsObjects.h" - -// ---------------------------------------------------------------------------- -// Constants - -// dateTimeRenderOption -NSString * const kGTLRSheetsDateTimeRenderOptionFormattedString = @"FORMATTED_STRING"; -NSString * const kGTLRSheetsDateTimeRenderOptionSerialNumber = @"SERIAL_NUMBER"; - -// insertDataOption -NSString * const kGTLRSheetsInsertDataOptionInsertRows = @"INSERT_ROWS"; -NSString * const kGTLRSheetsInsertDataOptionOverwrite = @"OVERWRITE"; - -// majorDimension -NSString * const kGTLRSheetsMajorDimensionColumns = @"COLUMNS"; -NSString * const kGTLRSheetsMajorDimensionDimensionUnspecified = @"DIMENSION_UNSPECIFIED"; -NSString * const kGTLRSheetsMajorDimensionRows = @"ROWS"; - -// responseDateTimeRenderOption -NSString * const kGTLRSheetsResponseDateTimeRenderOptionFormattedString = @"FORMATTED_STRING"; -NSString * const kGTLRSheetsResponseDateTimeRenderOptionSerialNumber = @"SERIAL_NUMBER"; - -// responseValueRenderOption -NSString * const kGTLRSheetsResponseValueRenderOptionFormattedValue = @"FORMATTED_VALUE"; -NSString * const kGTLRSheetsResponseValueRenderOptionFormula = @"FORMULA"; -NSString * const kGTLRSheetsResponseValueRenderOptionUnformattedValue = @"UNFORMATTED_VALUE"; - -// valueInputOption -NSString * const kGTLRSheetsValueInputOptionInputValueOptionUnspecified = @"INPUT_VALUE_OPTION_UNSPECIFIED"; -NSString * const kGTLRSheetsValueInputOptionRaw = @"RAW"; -NSString * const kGTLRSheetsValueInputOptionUserEntered = @"USER_ENTERED"; - -// valueRenderOption -NSString * const kGTLRSheetsValueRenderOptionFormattedValue = @"FORMATTED_VALUE"; -NSString * const kGTLRSheetsValueRenderOptionFormula = @"FORMULA"; -NSString * const kGTLRSheetsValueRenderOptionUnformattedValue = @"UNFORMATTED_VALUE"; - -// ---------------------------------------------------------------------------- -// Query Classes -// - -@implementation GTLRSheetsQuery - -@dynamic fields; - -@end - -@implementation GTLRSheetsQuery_SpreadsheetsBatchUpdate - -@dynamic spreadsheetId; - -+ (instancetype)queryWithObject:(GTLRSheets_BatchUpdateSpreadsheetRequest *)object - spreadsheetId:(NSString *)spreadsheetId { - if (object == nil) { - GTLR_DEBUG_ASSERT(object != nil, @"Got a nil object"); - return nil; - } - NSArray *pathParams = @[ @"spreadsheetId" ]; - NSString *pathURITemplate = @"v4/spreadsheets/{spreadsheetId}:batchUpdate"; - GTLRSheetsQuery_SpreadsheetsBatchUpdate *query = - [[self alloc] initWithPathURITemplate:pathURITemplate - HTTPMethod:@"POST" - pathParameterNames:pathParams]; - query.bodyObject = object; - query.spreadsheetId = spreadsheetId; - query.expectedObjectClass = [GTLRSheets_BatchUpdateSpreadsheetResponse class]; - query.loggingName = @"sheets.spreadsheets.batchUpdate"; - return query; -} - -@end - -@implementation GTLRSheetsQuery_SpreadsheetsCreate - -+ (instancetype)queryWithObject:(GTLRSheets_Spreadsheet *)object { - if (object == nil) { - GTLR_DEBUG_ASSERT(object != nil, @"Got a nil object"); - return nil; - } - NSString *pathURITemplate = @"v4/spreadsheets"; - GTLRSheetsQuery_SpreadsheetsCreate *query = - [[self alloc] initWithPathURITemplate:pathURITemplate - HTTPMethod:@"POST" - pathParameterNames:nil]; - query.bodyObject = object; - query.expectedObjectClass = [GTLRSheets_Spreadsheet class]; - query.loggingName = @"sheets.spreadsheets.create"; - return query; -} - -@end - -@implementation GTLRSheetsQuery_SpreadsheetsDeveloperMetadataGet - -@dynamic metadataId, spreadsheetId; - -+ (instancetype)queryWithSpreadsheetId:(NSString *)spreadsheetId - metadataId:(NSInteger)metadataId { - NSArray *pathParams = @[ - @"metadataId", @"spreadsheetId" - ]; - NSString *pathURITemplate = @"v4/spreadsheets/{spreadsheetId}/developerMetadata/{metadataId}"; - GTLRSheetsQuery_SpreadsheetsDeveloperMetadataGet *query = - [[self alloc] initWithPathURITemplate:pathURITemplate - HTTPMethod:nil - pathParameterNames:pathParams]; - query.spreadsheetId = spreadsheetId; - query.metadataId = metadataId; - query.expectedObjectClass = [GTLRSheets_DeveloperMetadata class]; - query.loggingName = @"sheets.spreadsheets.developerMetadata.get"; - return query; -} - -@end - -@implementation GTLRSheetsQuery_SpreadsheetsDeveloperMetadataSearch - -@dynamic spreadsheetId; - -+ (instancetype)queryWithObject:(GTLRSheets_SearchDeveloperMetadataRequest *)object - spreadsheetId:(NSString *)spreadsheetId { - if (object == nil) { - GTLR_DEBUG_ASSERT(object != nil, @"Got a nil object"); - return nil; - } - NSArray *pathParams = @[ @"spreadsheetId" ]; - NSString *pathURITemplate = @"v4/spreadsheets/{spreadsheetId}/developerMetadata:search"; - GTLRSheetsQuery_SpreadsheetsDeveloperMetadataSearch *query = - [[self alloc] initWithPathURITemplate:pathURITemplate - HTTPMethod:@"POST" - pathParameterNames:pathParams]; - query.bodyObject = object; - query.spreadsheetId = spreadsheetId; - query.expectedObjectClass = [GTLRSheets_SearchDeveloperMetadataResponse class]; - query.loggingName = @"sheets.spreadsheets.developerMetadata.search"; - return query; -} - -@end - -@implementation GTLRSheetsQuery_SpreadsheetsGet - -@dynamic includeGridData, ranges, spreadsheetId; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"ranges" : [NSString class] - }; - return map; -} - -+ (instancetype)queryWithSpreadsheetId:(NSString *)spreadsheetId { - NSArray *pathParams = @[ @"spreadsheetId" ]; - NSString *pathURITemplate = @"v4/spreadsheets/{spreadsheetId}"; - GTLRSheetsQuery_SpreadsheetsGet *query = - [[self alloc] initWithPathURITemplate:pathURITemplate - HTTPMethod:nil - pathParameterNames:pathParams]; - query.spreadsheetId = spreadsheetId; - query.expectedObjectClass = [GTLRSheets_Spreadsheet class]; - query.loggingName = @"sheets.spreadsheets.get"; - return query; -} - -@end - -@implementation GTLRSheetsQuery_SpreadsheetsGetByDataFilter - -@dynamic spreadsheetId; - -+ (instancetype)queryWithObject:(GTLRSheets_GetSpreadsheetByDataFilterRequest *)object - spreadsheetId:(NSString *)spreadsheetId { - if (object == nil) { - GTLR_DEBUG_ASSERT(object != nil, @"Got a nil object"); - return nil; - } - NSArray *pathParams = @[ @"spreadsheetId" ]; - NSString *pathURITemplate = @"v4/spreadsheets/{spreadsheetId}:getByDataFilter"; - GTLRSheetsQuery_SpreadsheetsGetByDataFilter *query = - [[self alloc] initWithPathURITemplate:pathURITemplate - HTTPMethod:@"POST" - pathParameterNames:pathParams]; - query.bodyObject = object; - query.spreadsheetId = spreadsheetId; - query.expectedObjectClass = [GTLRSheets_Spreadsheet class]; - query.loggingName = @"sheets.spreadsheets.getByDataFilter"; - return query; -} - -@end - -@implementation GTLRSheetsQuery_SpreadsheetsSheetsCopyTo - -@dynamic sheetId, spreadsheetId; - -+ (instancetype)queryWithObject:(GTLRSheets_CopySheetToAnotherSpreadsheetRequest *)object - spreadsheetId:(NSString *)spreadsheetId - sheetId:(NSInteger)sheetId { - if (object == nil) { - GTLR_DEBUG_ASSERT(object != nil, @"Got a nil object"); - return nil; - } - NSArray *pathParams = @[ - @"sheetId", @"spreadsheetId" - ]; - NSString *pathURITemplate = @"v4/spreadsheets/{spreadsheetId}/sheets/{sheetId}:copyTo"; - GTLRSheetsQuery_SpreadsheetsSheetsCopyTo *query = - [[self alloc] initWithPathURITemplate:pathURITemplate - HTTPMethod:@"POST" - pathParameterNames:pathParams]; - query.bodyObject = object; - query.spreadsheetId = spreadsheetId; - query.sheetId = sheetId; - query.expectedObjectClass = [GTLRSheets_SheetProperties class]; - query.loggingName = @"sheets.spreadsheets.sheets.copyTo"; - return query; -} - -@end - -@implementation GTLRSheetsQuery_SpreadsheetsValuesAppend - -@dynamic includeValuesInResponse, insertDataOption, range, - responseDateTimeRenderOption, responseValueRenderOption, spreadsheetId, - valueInputOption; - -+ (instancetype)queryWithObject:(GTLRSheets_ValueRange *)object - spreadsheetId:(NSString *)spreadsheetId - range:(NSString *)range { - if (object == nil) { - GTLR_DEBUG_ASSERT(object != nil, @"Got a nil object"); - return nil; - } - NSArray *pathParams = @[ - @"range", @"spreadsheetId" - ]; - NSString *pathURITemplate = @"v4/spreadsheets/{spreadsheetId}/values/{range}:append"; - GTLRSheetsQuery_SpreadsheetsValuesAppend *query = - [[self alloc] initWithPathURITemplate:pathURITemplate - HTTPMethod:@"POST" - pathParameterNames:pathParams]; - query.bodyObject = object; - query.spreadsheetId = spreadsheetId; - query.range = range; - query.expectedObjectClass = [GTLRSheets_AppendValuesResponse class]; - query.loggingName = @"sheets.spreadsheets.values.append"; - return query; -} - -@end - -@implementation GTLRSheetsQuery_SpreadsheetsValuesBatchClear - -@dynamic spreadsheetId; - -+ (instancetype)queryWithObject:(GTLRSheets_BatchClearValuesRequest *)object - spreadsheetId:(NSString *)spreadsheetId { - if (object == nil) { - GTLR_DEBUG_ASSERT(object != nil, @"Got a nil object"); - return nil; - } - NSArray *pathParams = @[ @"spreadsheetId" ]; - NSString *pathURITemplate = @"v4/spreadsheets/{spreadsheetId}/values:batchClear"; - GTLRSheetsQuery_SpreadsheetsValuesBatchClear *query = - [[self alloc] initWithPathURITemplate:pathURITemplate - HTTPMethod:@"POST" - pathParameterNames:pathParams]; - query.bodyObject = object; - query.spreadsheetId = spreadsheetId; - query.expectedObjectClass = [GTLRSheets_BatchClearValuesResponse class]; - query.loggingName = @"sheets.spreadsheets.values.batchClear"; - return query; -} - -@end - -@implementation GTLRSheetsQuery_SpreadsheetsValuesBatchClearByDataFilter - -@dynamic spreadsheetId; - -+ (instancetype)queryWithObject:(GTLRSheets_BatchClearValuesByDataFilterRequest *)object - spreadsheetId:(NSString *)spreadsheetId { - if (object == nil) { - GTLR_DEBUG_ASSERT(object != nil, @"Got a nil object"); - return nil; - } - NSArray *pathParams = @[ @"spreadsheetId" ]; - NSString *pathURITemplate = @"v4/spreadsheets/{spreadsheetId}/values:batchClearByDataFilter"; - GTLRSheetsQuery_SpreadsheetsValuesBatchClearByDataFilter *query = - [[self alloc] initWithPathURITemplate:pathURITemplate - HTTPMethod:@"POST" - pathParameterNames:pathParams]; - query.bodyObject = object; - query.spreadsheetId = spreadsheetId; - query.expectedObjectClass = [GTLRSheets_BatchClearValuesByDataFilterResponse class]; - query.loggingName = @"sheets.spreadsheets.values.batchClearByDataFilter"; - return query; -} - -@end - -@implementation GTLRSheetsQuery_SpreadsheetsValuesBatchGet - -@dynamic dateTimeRenderOption, majorDimension, ranges, spreadsheetId, - valueRenderOption; - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - NSDictionary<NSString *, Class> *map = @{ - @"ranges" : [NSString class] - }; - return map; -} - -+ (instancetype)queryWithSpreadsheetId:(NSString *)spreadsheetId { - NSArray *pathParams = @[ @"spreadsheetId" ]; - NSString *pathURITemplate = @"v4/spreadsheets/{spreadsheetId}/values:batchGet"; - GTLRSheetsQuery_SpreadsheetsValuesBatchGet *query = - [[self alloc] initWithPathURITemplate:pathURITemplate - HTTPMethod:nil - pathParameterNames:pathParams]; - query.spreadsheetId = spreadsheetId; - query.expectedObjectClass = [GTLRSheets_BatchGetValuesResponse class]; - query.loggingName = @"sheets.spreadsheets.values.batchGet"; - return query; -} - -@end - -@implementation GTLRSheetsQuery_SpreadsheetsValuesBatchGetByDataFilter - -@dynamic spreadsheetId; - -+ (instancetype)queryWithObject:(GTLRSheets_BatchGetValuesByDataFilterRequest *)object - spreadsheetId:(NSString *)spreadsheetId { - if (object == nil) { - GTLR_DEBUG_ASSERT(object != nil, @"Got a nil object"); - return nil; - } - NSArray *pathParams = @[ @"spreadsheetId" ]; - NSString *pathURITemplate = @"v4/spreadsheets/{spreadsheetId}/values:batchGetByDataFilter"; - GTLRSheetsQuery_SpreadsheetsValuesBatchGetByDataFilter *query = - [[self alloc] initWithPathURITemplate:pathURITemplate - HTTPMethod:@"POST" - pathParameterNames:pathParams]; - query.bodyObject = object; - query.spreadsheetId = spreadsheetId; - query.expectedObjectClass = [GTLRSheets_BatchGetValuesByDataFilterResponse class]; - query.loggingName = @"sheets.spreadsheets.values.batchGetByDataFilter"; - return query; -} - -@end - -@implementation GTLRSheetsQuery_SpreadsheetsValuesBatchUpdate - -@dynamic spreadsheetId; - -+ (instancetype)queryWithObject:(GTLRSheets_BatchUpdateValuesRequest *)object - spreadsheetId:(NSString *)spreadsheetId { - if (object == nil) { - GTLR_DEBUG_ASSERT(object != nil, @"Got a nil object"); - return nil; - } - NSArray *pathParams = @[ @"spreadsheetId" ]; - NSString *pathURITemplate = @"v4/spreadsheets/{spreadsheetId}/values:batchUpdate"; - GTLRSheetsQuery_SpreadsheetsValuesBatchUpdate *query = - [[self alloc] initWithPathURITemplate:pathURITemplate - HTTPMethod:@"POST" - pathParameterNames:pathParams]; - query.bodyObject = object; - query.spreadsheetId = spreadsheetId; - query.expectedObjectClass = [GTLRSheets_BatchUpdateValuesResponse class]; - query.loggingName = @"sheets.spreadsheets.values.batchUpdate"; - return query; -} - -@end - -@implementation GTLRSheetsQuery_SpreadsheetsValuesBatchUpdateByDataFilter - -@dynamic spreadsheetId; - -+ (instancetype)queryWithObject:(GTLRSheets_BatchUpdateValuesByDataFilterRequest *)object - spreadsheetId:(NSString *)spreadsheetId { - if (object == nil) { - GTLR_DEBUG_ASSERT(object != nil, @"Got a nil object"); - return nil; - } - NSArray *pathParams = @[ @"spreadsheetId" ]; - NSString *pathURITemplate = @"v4/spreadsheets/{spreadsheetId}/values:batchUpdateByDataFilter"; - GTLRSheetsQuery_SpreadsheetsValuesBatchUpdateByDataFilter *query = - [[self alloc] initWithPathURITemplate:pathURITemplate - HTTPMethod:@"POST" - pathParameterNames:pathParams]; - query.bodyObject = object; - query.spreadsheetId = spreadsheetId; - query.expectedObjectClass = [GTLRSheets_BatchUpdateValuesByDataFilterResponse class]; - query.loggingName = @"sheets.spreadsheets.values.batchUpdateByDataFilter"; - return query; -} - -@end - -@implementation GTLRSheetsQuery_SpreadsheetsValuesClear - -@dynamic range, spreadsheetId; - -+ (instancetype)queryWithObject:(GTLRSheets_ClearValuesRequest *)object - spreadsheetId:(NSString *)spreadsheetId - range:(NSString *)range { - if (object == nil) { - GTLR_DEBUG_ASSERT(object != nil, @"Got a nil object"); - return nil; - } - NSArray *pathParams = @[ - @"range", @"spreadsheetId" - ]; - NSString *pathURITemplate = @"v4/spreadsheets/{spreadsheetId}/values/{range}:clear"; - GTLRSheetsQuery_SpreadsheetsValuesClear *query = - [[self alloc] initWithPathURITemplate:pathURITemplate - HTTPMethod:@"POST" - pathParameterNames:pathParams]; - query.bodyObject = object; - query.spreadsheetId = spreadsheetId; - query.range = range; - query.expectedObjectClass = [GTLRSheets_ClearValuesResponse class]; - query.loggingName = @"sheets.spreadsheets.values.clear"; - return query; -} - -@end - -@implementation GTLRSheetsQuery_SpreadsheetsValuesGet - -@dynamic dateTimeRenderOption, majorDimension, range, spreadsheetId, - valueRenderOption; - -+ (instancetype)queryWithSpreadsheetId:(NSString *)spreadsheetId - range:(NSString *)range { - NSArray *pathParams = @[ - @"range", @"spreadsheetId" - ]; - NSString *pathURITemplate = @"v4/spreadsheets/{spreadsheetId}/values/{range}"; - GTLRSheetsQuery_SpreadsheetsValuesGet *query = - [[self alloc] initWithPathURITemplate:pathURITemplate - HTTPMethod:nil - pathParameterNames:pathParams]; - query.spreadsheetId = spreadsheetId; - query.range = range; - query.expectedObjectClass = [GTLRSheets_ValueRange class]; - query.loggingName = @"sheets.spreadsheets.values.get"; - return query; -} - -@end - -@implementation GTLRSheetsQuery_SpreadsheetsValuesUpdate - -@dynamic includeValuesInResponse, range, responseDateTimeRenderOption, - responseValueRenderOption, spreadsheetId, valueInputOption; - -+ (instancetype)queryWithObject:(GTLRSheets_ValueRange *)object - spreadsheetId:(NSString *)spreadsheetId - range:(NSString *)range { - if (object == nil) { - GTLR_DEBUG_ASSERT(object != nil, @"Got a nil object"); - return nil; - } - NSArray *pathParams = @[ - @"range", @"spreadsheetId" - ]; - NSString *pathURITemplate = @"v4/spreadsheets/{spreadsheetId}/values/{range}"; - GTLRSheetsQuery_SpreadsheetsValuesUpdate *query = - [[self alloc] initWithPathURITemplate:pathURITemplate - HTTPMethod:@"PUT" - pathParameterNames:pathParams]; - query.bodyObject = object; - query.spreadsheetId = spreadsheetId; - query.range = range; - query.expectedObjectClass = [GTLRSheets_UpdateValuesResponse class]; - query.loggingName = @"sheets.spreadsheets.values.update"; - return query; -} - -@end diff --git a/Pods/GoogleAPIClientForREST/Source/GeneratedServices/Sheets/GTLRSheetsService.h b/Pods/GoogleAPIClientForREST/Source/GeneratedServices/Sheets/GTLRSheetsService.h @@ -1,103 +0,0 @@ -// NOTE: This file was generated by the ServiceGenerator. - -// ---------------------------------------------------------------------------- -// API: -// Google Sheets API (sheets/v4) -// Description: -// Reads and writes Google Sheets. -// Documentation: -// https://developers.google.com/sheets/ - -#if GTLR_BUILT_AS_FRAMEWORK - #import "GTLR/GTLRService.h" -#else - #import "GTLRService.h" -#endif - -#if GTLR_RUNTIME_VERSION != 3000 -#error This file was generated by a different version of ServiceGenerator which is incompatible with this GTLR library source. -#endif - -// Generated comments include content from the discovery document; avoid them -// causing warnings since clang's checks are some what arbitrary. -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdocumentation" - -NS_ASSUME_NONNULL_BEGIN - -// ---------------------------------------------------------------------------- -// Authorization scopes - -/** - * Authorization scope: See, edit, create, and delete all of your Google Drive - * files - * - * Value "https://www.googleapis.com/auth/drive" - */ -GTLR_EXTERN NSString * const kGTLRAuthScopeSheetsDrive; -/** - * Authorization scope: View and manage Google Drive files and folders that you - * have opened or created with this app - * - * Value "https://www.googleapis.com/auth/drive.file" - */ -GTLR_EXTERN NSString * const kGTLRAuthScopeSheetsDriveFile; -/** - * Authorization scope: See and download all your Google Drive files - * - * Value "https://www.googleapis.com/auth/drive.readonly" - */ -GTLR_EXTERN NSString * const kGTLRAuthScopeSheetsDriveReadonly; -/** - * Authorization scope: See, edit, create, and delete your spreadsheets in - * Google Drive - * - * Value "https://www.googleapis.com/auth/spreadsheets" - */ -GTLR_EXTERN NSString * const kGTLRAuthScopeSheetsSpreadsheets; -/** - * Authorization scope: View your Google Spreadsheets - * - * Value "https://www.googleapis.com/auth/spreadsheets.readonly" - */ -GTLR_EXTERN NSString * const kGTLRAuthScopeSheetsSpreadsheetsReadonly; - -// ---------------------------------------------------------------------------- -// GTLRSheetsService -// - -/** - * Service for executing Google Sheets API queries. - * - * Reads and writes Google Sheets. - */ -@interface GTLRSheetsService : GTLRService - -// No new methods - -// Clients should create a standard query with any of the class methods in -// GTLRSheetsQuery.h. The query can the be sent with GTLRService's execute -// methods, -// -// - (GTLRServiceTicket *)executeQuery:(GTLRQuery *)query -// completionHandler:(void (^)(GTLRServiceTicket *ticket, -// id object, NSError *error))handler; -// or -// - (GTLRServiceTicket *)executeQuery:(GTLRQuery *)query -// delegate:(id)delegate -// didFinishSelector:(SEL)finishedSelector; -// -// where finishedSelector has a signature of: -// -// - (void)serviceTicket:(GTLRServiceTicket *)ticket -// finishedWithObject:(id)object -// error:(NSError *)error; -// -// The object passed to the completion handler or delegate method -// is a subclass of GTLRObject, determined by the query method executed. - -@end - -NS_ASSUME_NONNULL_END - -#pragma clang diagnostic pop diff --git a/Pods/GoogleAPIClientForREST/Source/GeneratedServices/Sheets/GTLRSheetsService.m b/Pods/GoogleAPIClientForREST/Source/GeneratedServices/Sheets/GTLRSheetsService.m @@ -1,39 +0,0 @@ -// NOTE: This file was generated by the ServiceGenerator. - -// ---------------------------------------------------------------------------- -// API: -// Google Sheets API (sheets/v4) -// Description: -// Reads and writes Google Sheets. -// Documentation: -// https://developers.google.com/sheets/ - -#import "GTLRSheets.h" - -// ---------------------------------------------------------------------------- -// Authorization scopes - -NSString * const kGTLRAuthScopeSheetsDrive = @"https://www.googleapis.com/auth/drive"; -NSString * const kGTLRAuthScopeSheetsDriveFile = @"https://www.googleapis.com/auth/drive.file"; -NSString * const kGTLRAuthScopeSheetsDriveReadonly = @"https://www.googleapis.com/auth/drive.readonly"; -NSString * const kGTLRAuthScopeSheetsSpreadsheets = @"https://www.googleapis.com/auth/spreadsheets"; -NSString * const kGTLRAuthScopeSheetsSpreadsheetsReadonly = @"https://www.googleapis.com/auth/spreadsheets.readonly"; - -// ---------------------------------------------------------------------------- -// GTLRSheetsService -// - -@implementation GTLRSheetsService - -- (instancetype)init { - self = [super init]; - if (self) { - // From discovery. - self.rootURLString = @"https://sheets.googleapis.com/"; - self.batchPath = @"batch"; - self.prettyPrintQueryParameterNames = @[ @"prettyPrint" ]; - } - return self; -} - -@end diff --git a/Pods/GoogleAPIClientForREST/Source/Objects/GTLRBatchQuery.h b/Pods/GoogleAPIClientForREST/Source/Objects/GTLRBatchQuery.h @@ -1,85 +0,0 @@ -/* Copyright (c) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// Batch query documentation: -// https://github.com/google/google-api-objectivec-client-for-rest/wiki#batch-operations - -#import "GTLRQuery.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface GTLRBatchQuery : NSObject <GTLRQueryProtocol> - -/** - * Queries included in this batch. Each query should have a unique @c requestID. - */ -@property(atomic, copy, nullable) NSArray<GTLRQuery *> *queries; - -/** - * Flag indicating if query execution should skip authorization. Defaults to NO. - */ -@property(atomic, assign) BOOL shouldSkipAuthorization; - -/** - * Any additional HTTP headers for this batch. - * - * These headers override the same keys from the service object's - * @c additionalHTTPHeaders. - */ -@property(atomic, copy, nullable) NSDictionary<NSString *, NSString *> *additionalHTTPHeaders; - -/** - * Any additional URL query parameters to add to the batch query. - * - * These query parameters override the same keys from the service object's - * @c additionalURLQueryParameters - */ -@property(atomic, copy, nullable) NSDictionary<NSString *, NSString *> *additionalURLQueryParameters; - -/** - * The batch request multipart boundary, once determined. - */ -@property(atomic, copy, nullable) NSString *boundary; - -/** - * The brief string to identify this query in @c GTMSessionFetcher http logs. - * - * The default logging name for batch requests includes the API method names. - */ -@property(atomic, copy, nullable) NSString *loggingName; - -/** - * Constructor for a batch query, for use with @c addQuery: - */ -+ (instancetype)batchQuery; - -/** - * Constructor for a batch query, from an array of @c GTLRQuery objects. - */ -+ (instancetype)batchQueryWithQueries:(NSArray<GTLRQuery *> *)array; - -/** - * Add a single @c GTLRQuery to the batch. - */ -- (void)addQuery:(GTLRQuery *)query; - -/** - * Search the batch for a query with the specified ID. - */ -- (nullable GTLRQuery *)queryForRequestID:(NSString *)requestID; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleAPIClientForREST/Source/Objects/GTLRBatchQuery.m b/Pods/GoogleAPIClientForREST/Source/Objects/GTLRBatchQuery.m @@ -1,179 +0,0 @@ -/* Copyright (c) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if !__has_feature(objc_arc) -#error "This file needs to be compiled with ARC enabled." -#endif - -#import "GTLRBatchQuery.h" - -#import "GTLRService.h" - -#if DEBUG -static void DebugAssertValidBatchQueryItem(GTLRQuery *query) { - GTLR_DEBUG_ASSERT([query isKindOfClass:[GTLRQuery class]], - @"unexpected query class: %@", [query class]); - GTLR_DEBUG_ASSERT(query.uploadParameters == nil, - @"batch may not contain upload: %@", query); - GTLR_DEBUG_ASSERT(!query.hasExecutionParameters, - @"queries added to a batch may not contain executionParameters: %@", query); - GTLR_DEBUG_ASSERT(!query.queryInvalid, - @"batch may not contain query already executed: %@", query); -} -#else -static void DebugAssertValidBatchQueryItem(GTLRQuery *query) { } -#endif - -@implementation GTLRBatchQuery { - NSMutableArray<GTLRQuery *> *_queries; - NSMutableDictionary *_requestIDMap; - GTLRServiceExecutionParameters *_executionParameters; -} - -@synthesize shouldSkipAuthorization = _shouldSkipAuthorization, - additionalHTTPHeaders = _additionalHTTPHeaders, - additionalURLQueryParameters = _additionalURLQueryParameters, - boundary = _boundary, - loggingName = _loggingName; - -+ (instancetype)batchQuery { - GTLRBatchQuery *obj = [[self alloc] init]; - return obj; -} - -+ (instancetype)batchQueryWithQueries:(NSArray<GTLRQuery *> *)queries { - GTLRBatchQuery *obj = [self batchQuery]; - obj.queries = queries; - -#if DEBUG - for (GTLRQuery *query in queries) { - DebugAssertValidBatchQueryItem(query); - } -#endif - return obj; -} - -- (id)copyWithZone:(NSZone *)zone { - // Deep copy the list of queries - GTLRBatchQuery *newBatch = [[[self class] allocWithZone:zone] init]; - if (_queries) { - newBatch.queries = [[NSArray alloc] initWithArray:_queries - copyItems:YES]; - } - - // Using the executionParameters ivar avoids creating the object. - newBatch.executionParameters = _executionParameters; - - // Copied in the same order as synthesized above. - newBatch.shouldSkipAuthorization = _shouldSkipAuthorization; - newBatch.additionalHTTPHeaders = _additionalHTTPHeaders; - newBatch.additionalURLQueryParameters = _additionalURLQueryParameters; - newBatch.boundary = _boundary; - newBatch.loggingName = _loggingName; - - // No need to copy _requestIDMap as it's created on demand. - return newBatch; -} - -- (NSString *)description { - NSArray *queries = self.queries; - NSArray *loggingNames = [queries valueForKey:@"loggingName"]; - NSMutableSet *dedupedNames = [NSMutableSet setWithArray:loggingNames]; // de-dupe - [dedupedNames removeObject:[NSNull null]]; // In case any didn't have a loggingName. - NSString *namesStr = [[dedupedNames allObjects] componentsJoinedByString:@","]; - - return [NSString stringWithFormat:@"%@ %p (queries:%tu - %@)", - [self class], self, queries.count, namesStr]; -} - -#pragma mark - - -- (BOOL)isBatchQuery { - return YES; -} - -- (GTLRUploadParameters *)uploadParameters { - // File upload is not supported for batches - return nil; -} - -- (void)invalidateQuery { - NSArray *queries = self.queries; - [queries makeObjectsPerformSelector:@selector(invalidateQuery)]; - - _executionParameters = nil; -} - -- (GTLRQuery *)queryForRequestID:(NSString *)requestID { - GTLRQuery *result = [_requestIDMap objectForKey:requestID]; - if (result) return result; - - // We've not before tried to look up a query, or the map is stale - _requestIDMap = [[NSMutableDictionary alloc] init]; - - for (GTLRQuery *query in _queries) { - [_requestIDMap setObject:query forKey:query.requestID]; - } - - result = [_requestIDMap objectForKey:requestID]; - return result; -} - -#pragma mark - - -- (void)setQueries:(NSArray<GTLRQuery *> *)array { -#if DEBUG - for (GTLRQuery *query in array) { - DebugAssertValidBatchQueryItem(query); - } -#endif - - _queries = [array mutableCopy]; -} - -- (NSArray<GTLRQuery *> *)queries { - return _queries; -} - -- (void)addQuery:(GTLRQuery *)query { - DebugAssertValidBatchQueryItem(query); - - if (_queries == nil) { - _queries = [[NSMutableArray alloc] init]; - } - - [_queries addObject:query]; -} - -- (GTLRServiceExecutionParameters *)executionParameters { - @synchronized(self) { - if (!_executionParameters) { - _executionParameters = [[GTLRServiceExecutionParameters alloc] init]; - } - } - return _executionParameters; -} - -- (void)setExecutionParameters:(GTLRServiceExecutionParameters *)executionParameters { - @synchronized(self) { - _executionParameters = executionParameters; - } -} - -- (BOOL)hasExecutionParameters { - return _executionParameters.hasParameters; -} - -@end diff --git a/Pods/GoogleAPIClientForREST/Source/Objects/GTLRBatchResult.h b/Pods/GoogleAPIClientForREST/Source/Objects/GTLRBatchResult.h @@ -1,78 +0,0 @@ -/* Copyright (c) 2011 Google Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#import "GTLRObject.h" - -NS_ASSUME_NONNULL_BEGIN - -@class GTLRErrorObject; - -/** - * A batch result includes a dictionary of successes, a dictionary of failures, and a dictionary of - * HTTP response headers. - * - * Dictionary keys are request ID strings; dictionary values are @c GTLRObject for - * successes, @c GTLRErrorObject for failures, @c NSDictionary for responseHeaders. - * - * For successes with no returned object (such as from delete operations), - * the object for the dictionary entry is @c NSNull. - * - * The original query for each result is available from the service ticket, as shown in - * the code snippet here. - * - * When the queries in the batch are unrelated, adding a @c completionBlock to each of - * the queries may be a simpler way to handle the batch results. - * - * @code - * NSDictionary *successes = batchResults.successes; - * for (NSString *requestID in successes) { - * GTLRObject *obj = successes[requestID]; - * GTLRQuery *query = [ticket queryForRequestID:requestID]; - * NSLog(@"Query %@ returned object %@", query, obj); - * } - * - * NSDictionary *failures = batchResults.failures; - * for (NSString *requestID in failures) { - * GTLRErrorObject *errorObj = failures[requestID]; - * GTLRQuery *query = [ticket queryForRequestID:requestID]; - * NSLog(@"Query %@ failed with error %@", query, errorObj); - * } - * @endcode - */ -@interface GTLRBatchResult : GTLRObject - -/** - * Object results of successful queries in the batch, keyed by request ID. - * - * Queries which do not return an object when successful have a @c NSNull value. - */ -@property(atomic, strong, nullable) NSDictionary<NSString *, __kindof GTLRObject *> *successes; - -/** - * Object results of unsuccessful queries in the batch, keyed by request ID. - */ -@property(atomic, strong, nullable) NSDictionary<NSString *, GTLRErrorObject *> *failures; - -/** - * Any HTTP response headers that were returned for a query request. Headers are optional therefore - * not all queries will have them. Query request with response headers are stored in a - * dictionary and keyed by request ID. - */ -@property(atomic, strong, nullable) - NSDictionary<NSString *, NSDictionary *> *responseHeaders; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleAPIClientForREST/Source/Objects/GTLRBatchResult.m b/Pods/GoogleAPIClientForREST/Source/Objects/GTLRBatchResult.m @@ -1,168 +0,0 @@ -/* Copyright (c) 2011 Google Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#if !__has_feature(objc_arc) -#error "This file needs to be compiled with ARC enabled." -#endif - -#import "GTLRBatchResult.h" - -#import "GTLRErrorObject.h" -#import "GTLRUtilities.h" - -static NSString *const kGTLRBatchResultSuccessesKeys = @"successesKeys"; -static NSString *const kGTLRBatchResultSuccessKeyPrefix = @"Success-"; -static NSString *const kGTLRBatchResultFailuresKeys = @"failuresKeys"; -static NSString *const kGTLRBatchResultFailurKeyPrefix = @"Failure-"; -static NSString *const kGTLRBatchResultResponseHeaders = @"responseHeaders"; - -@implementation GTLRBatchResult - -@synthesize successes = _successes, - failures = _failures, - responseHeaders = _responseHeaders; - -// Since this class doesn't use the json property, provide the basic NSObject -// methods needed to ensure proper behaviors. - -- (id)copyWithZone:(NSZone *)zone { - GTLRBatchResult* newObject = [super copyWithZone:zone]; - newObject.successes = [self.successes copyWithZone:zone]; - newObject.failures = [self.failures copyWithZone:zone]; - newObject.responseHeaders = [self.responseHeaders copyWithZone:zone]; - return newObject; -} - -- (NSUInteger)hash { - NSUInteger result = [super hash]; - result += result * 13 + [self.successes hash]; - result += result * 13 + [self.failures hash]; - result += result * 13 + [self.responseHeaders hash]; - return result; -} - -- (BOOL)isEqual:(id)object { - if (self == object) return YES; - - if (![super isEqual:object]) { - return NO; - } - - if (![object isKindOfClass:[GTLRBatchResult class]]) { - return NO; - } - - GTLRBatchResult *other = (GTLRBatchResult *)object; - if (!GTLR_AreEqualOrBothNil(self.successes, other.successes)) { - return NO; - } - if (!GTLR_AreEqualOrBothNil(self.failures, other.failures)) { - return NO; - } - return GTLR_AreEqualOrBothNil(self.responseHeaders, other.responseHeaders); -} - -- (NSString *)description { - return [NSString stringWithFormat:@"%@ %p (successes:%tu failures:%tu responseHeaders:%tu)", - [self class], self, - self.successes.count, self.failures.count, self.responseHeaders.count]; -} - -// This class is a subclass of GTLRObject, which declares NSSecureCoding -// conformance. Since this class does't really use the json property, provide -// a custom implementation to maintain the contract. -// -// For success/failures, one could do: -// [encoder encodeObject:self.successes forKey:kGTLRBatchResultSuccesses]; -// [encoder encodeObject:self.failures forKey:kGTLRBatchResultFailuresKeys]; -// and then use -decodeObjectOfClasses:forKey:, but nothing actually checks the -// structure of the dictionary, so instead the dicts are blown out to provide -// better validation by the encoder/decoder. - -+ (BOOL)supportsSecureCoding { - return YES; -} - -- (instancetype)initWithCoder:(NSCoder *)decoder { - self = [super initWithCoder:decoder]; - if (self) { - NSArray<NSString *> *keys = - [decoder decodeObjectOfClass:[NSArray class] - forKey:kGTLRBatchResultSuccessesKeys]; - if (keys.count) { - NSMutableDictionary *dict = - [NSMutableDictionary dictionaryWithCapacity:keys.count]; - for (NSString *key in keys) { - NSString *storageKey = - [kGTLRBatchResultSuccessKeyPrefix stringByAppendingString:key]; - GTLRObject *obj = [decoder decodeObjectOfClass:[GTLRObject class] - forKey:storageKey]; - if (obj) { - [dict setObject:obj forKey:key]; - } - } - self.successes = dict; - } - - keys = [decoder decodeObjectOfClass:[NSArray class] - forKey:kGTLRBatchResultFailuresKeys]; - if (keys.count) { - NSMutableDictionary *dict = - [NSMutableDictionary dictionaryWithCapacity:keys.count]; - for (NSString *key in keys) { - NSString *storageKey = - [kGTLRBatchResultFailurKeyPrefix stringByAppendingString:key]; - GTLRObject *obj = [decoder decodeObjectOfClass:[GTLRObject class] - forKey:storageKey]; - if (obj) { - [dict setObject:obj forKey:key]; - } - } - self.failures = dict; - } - - self.responseHeaders = - [decoder decodeObjectOfClass:[NSDictionary class] - forKey:kGTLRBatchResultResponseHeaders]; - } - return self; -} - -- (void)encodeWithCoder:(NSCoder *)encoder { - [super encodeWithCoder:encoder]; - [encoder encodeObject:self.successes.allKeys - forKey:kGTLRBatchResultSuccessesKeys]; - [self.successes enumerateKeysAndObjectsUsingBlock:^(NSString *key, - GTLRObject * obj, - BOOL * stop) { - NSString *storageKey = - [kGTLRBatchResultSuccessKeyPrefix stringByAppendingString:key]; - [encoder encodeObject:obj forKey:storageKey]; - }]; - - [encoder encodeObject:self.failures.allKeys forKey:kGTLRBatchResultFailuresKeys]; - [self.failures enumerateKeysAndObjectsUsingBlock:^(NSString *key, - GTLRObject * obj, - BOOL * stop) { - NSString *storageKey = - [kGTLRBatchResultFailurKeyPrefix stringByAppendingString:key]; - [encoder encodeObject:obj forKey:storageKey]; - }]; - - [encoder encodeObject:self.responseHeaders - forKey:kGTLRBatchResultResponseHeaders]; -} - -@end diff --git a/Pods/GoogleAPIClientForREST/Source/Objects/GTLRDateTime.h b/Pods/GoogleAPIClientForREST/Source/Objects/GTLRDateTime.h @@ -1,115 +0,0 @@ -/* Copyright (c) 2011 Google Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#import <Foundation/Foundation.h> -#import "GTLRDefines.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - * An immutable class representing a date and optionally a time in UTC. - */ -@interface GTLRDateTime : NSObject <NSCopying> - -/** - * Constructor from a string representation. - */ -+ (nullable instancetype)dateTimeWithRFC3339String:(nullable NSString *)str; - -/** - * Constructor from a date and time representation. - */ -+ (instancetype)dateTimeWithDate:(NSDate *)date; - -/** - * Constructor from a date and time representation, along with an offset - * minutes value used when creating a RFC3339 string representation. - * - * The date value is independent of time zone; the offset affects how the - * date will be rendered as a string. - * - * The offsetMinutes may be initialized from a NSTimeZone as - * (timeZone.secondsFromGMT / 60) - */ -+ (instancetype)dateTimeWithDate:(NSDate *)date - offsetMinutes:(NSInteger)offsetMinutes; - -/** - * Constructor from a date for an all-day event. - * - * Use this constructor to create a @c GTLRDateTime that is "date only". - * - * @note @c hasTime will be set to NO. - */ -+ (instancetype)dateTimeForAllDayWithDate:(NSDate *)date; - -/** - * Constructor from date components. - */ -+ (instancetype)dateTimeWithDateComponents:(NSDateComponents *)date; - -/** - * The represented date and time. - * - * If @c hasTime is NO, the time is set to noon GMT so the date is valid for all time zones. - */ -@property(nonatomic, readonly) NSDate *date; - -/** - * The date and time as a RFC3339 string representation. - */ -@property(nonatomic, readonly) NSString *RFC3339String; - -/** - * The date and time as a RFC3339 string representation. - * - * This returns the same string as @c RFC3339String. - */ -@property(nonatomic, readonly) NSString *stringValue; - -/** - * The represented date and time as date components. - */ -@property(nonatomic, readonly, copy) NSDateComponents *dateComponents; - -/** - * The fraction of seconds represented, 0-999. - */ -@property(nonatomic, readonly) NSInteger milliseconds; - -/** - * The time offset displayed in the string representation, if any. - * - * If the offset is not nil, the date and time will be rendered as a string - * for the time zone indicated by the offset. - * - * An app may create a NSTimeZone for this with - * [NSTimeZone timeZoneForSecondsFromGMT:(offsetMinutes.integerValue * 60)] - */ -@property(nonatomic, readonly, nullable) NSNumber *offsetMinutes; - -/** - * Flag indicating if the object represents date only, or date with time. - */ -@property(nonatomic, readonly) BOOL hasTime; - -/** - * The calendar used by this class, Gregorian and UTC. - */ -+ (NSCalendar *)calendar; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleAPIClientForREST/Source/Objects/GTLRDateTime.m b/Pods/GoogleAPIClientForREST/Source/Objects/GTLRDateTime.m @@ -1,373 +0,0 @@ -/* Copyright (c) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if !__has_feature(objc_arc) -#error "This file needs to be compiled with ARC enabled." -#endif - -#import "GTLRDateTime.h" - -static NSUInteger const kGTLRDateComponentBits = (NSCalendarUnitYear | NSCalendarUnitMonth - | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute - | NSCalendarUnitSecond); - -@interface GTLRDateTime () - -- (void)setFromDate:(NSDate *)date; -- (void)setFromRFC3339String:(NSString *)str; - -@property(nonatomic, copy, readwrite) NSDateComponents *dateComponents; -@property(nonatomic, assign, readwrite) NSInteger milliseconds; -@property(nonatomic, strong, readwrite, nullable) NSNumber *offsetMinutes; - -@property(nonatomic, assign, readwrite) BOOL hasTime; - -@end - - -@implementation GTLRDateTime { - NSDate *_cachedDate; - NSString *_cachedRFC3339String; -} - -// A note about _milliseconds: -// RFC 3339 has support for fractions of a second. NSDateComponents is all -// NSInteger based, so it can't handle a fraction of a second. NSDate is -// built on NSTimeInterval so it has sub-millisecond precision. GTLR takes -// the compromise of supporting the RFC's optional fractional second support -// by maintaining a number of milliseconds past what fits in the -// NSDateComponents. The parsing and string conversions will include -// 3 decimal digits (hence milliseconds). When going to a string, the decimal -// digits are only included if the milliseconds are non zero. - -@dynamic date; -@dynamic RFC3339String; -@dynamic stringValue; -@dynamic hasTime; - -@synthesize dateComponents = _dateComponents, - milliseconds = _milliseconds, - offsetMinutes = _offsetMinutes; - -+ (instancetype)dateTimeWithRFC3339String:(NSString *)str { - if (str == nil) return nil; - - GTLRDateTime *result = [[self alloc] init]; - [result setFromRFC3339String:str]; - return result; -} - -+ (instancetype)dateTimeWithDate:(NSDate *)date { - if (date == nil) return nil; - - GTLRDateTime *result = [[self alloc] init]; - [result setFromDate:date]; - return result; -} - -+ (instancetype)dateTimeWithDate:(NSDate *)date - offsetMinutes:(NSInteger)offsetMinutes { - GTLRDateTime *result = [self dateTimeWithDate:date]; - result.offsetMinutes = @(offsetMinutes); - return result; -} - -+ (instancetype)dateTimeForAllDayWithDate:(NSDate *)date { - if (date == nil) return nil; - - GTLRDateTime *result = [[self alloc] init]; - [result setFromDate:date]; - result.hasTime = NO; - return result; -} - -+ (instancetype)dateTimeWithDateComponents:(NSDateComponents *)components { - NSCalendar *cal = components.calendar ?: [self calendar]; - NSDate *date = [cal dateFromComponents:components]; - - return [self dateTimeWithDate:date]; -} - -- (id)copyWithZone:(NSZone *)zone { - // Object is immutable - return self; -} - -- (BOOL)isEqual:(GTLRDateTime *)other { - if (self == other) return YES; - if (![other isKindOfClass:[GTLRDateTime class]]) return NO; - - BOOL areDateComponentsEqual = [self.dateComponents isEqual:other.dateComponents]; - if (!areDateComponentsEqual) return NO; - - NSNumber *offsetMinutes = self.offsetMinutes; - NSNumber *otherOffsetMinutes = other.offsetMinutes; - if ((offsetMinutes == nil) != (otherOffsetMinutes == nil) - || (offsetMinutes.integerValue != otherOffsetMinutes.integerValue)) return NO; - - return (self.milliseconds == other.milliseconds); -} - -- (NSUInteger)hash { - return [[self date] hash]; -} - -- (NSString *)description { - return [NSString stringWithFormat:@"%@ %p: {%@}", - [self class], self, self.RFC3339String]; -} - -- (NSDate *)date { - @synchronized(self) { - if (_cachedDate) return _cachedDate; - } - - NSDateComponents *dateComponents = self.dateComponents; - NSTimeInterval extraMillisecondsAsSeconds = 0.0; - NSCalendar *cal = [[self class] calendar]; - - if (!self.hasTime) { - // We're not keeping track of a time, but NSDate always is based on - // an absolute time. We want to avoid returning an NSDate where the - // calendar date appears different from what was used to create our - // date-time object. - // - // We'll make a copy of the date components, setting the time on our - // copy to noon GMT, since that ensures the date renders correctly for - // any time zone. - NSDateComponents *noonDateComponents = [dateComponents copy]; - [noonDateComponents setHour:12]; - [noonDateComponents setMinute:0]; - [noonDateComponents setSecond:0]; - dateComponents = noonDateComponents; - } else { - // Add in the fractional seconds that don't fit into NSDateComponents. - extraMillisecondsAsSeconds = ((NSTimeInterval)self.milliseconds) / 1000.0; - } - - NSDate *date = [cal dateFromComponents:dateComponents]; - - // Add in any milliseconds that didn't fit into the dateComponents. - if (extraMillisecondsAsSeconds > 0.0) { - date = [date dateByAddingTimeInterval:extraMillisecondsAsSeconds]; - } - - @synchronized(self) { - _cachedDate = date; - } - return date; -} - -- (NSString *)stringValue { - return self.RFC3339String; -} - -- (NSString *)RFC3339String { - @synchronized(self) { - if (_cachedRFC3339String) return _cachedRFC3339String; - } - - NSDateComponents *dateComponents = self.dateComponents; - - NSString *timeString = @""; // timeString like "T15:10:46-08:00" - - if (self.hasTime) { - NSString *fractionalSecondsString = @""; - if (self.milliseconds > 0.0) { - fractionalSecondsString = [NSString stringWithFormat:@".%03ld", (long)self.milliseconds]; - } - - // If the dateTime was created from a string with a time offset, render that back in - // and adjust the time. - NSString *offsetStr = @"Z"; - NSNumber *offsetMinutes = self.offsetMinutes; - if (offsetMinutes != nil) { - BOOL isNegative = NO; - NSInteger offsetVal = offsetMinutes.integerValue; - if (offsetVal < 0) { - isNegative = YES; - offsetVal = -offsetVal; - } - NSInteger mins = offsetVal % 60; - NSInteger hours = (offsetVal - mins) / 60; - offsetStr = [NSString stringWithFormat:@"%c%02ld:%02ld", - isNegative ? '-' : '+', (long)hours, (long)mins]; - - // Adjust date components back to account for the offset. - // - // This is the inverse of the adjustment done in setFromRFC3339String:. - if (offsetVal != 0) { - NSDate *adjustedDate = - [self.date dateByAddingTimeInterval:(offsetMinutes.integerValue * 60)]; - NSCalendar *calendar = [[self class] calendar]; - dateComponents = [calendar components:kGTLRDateComponentBits - fromDate:adjustedDate]; - } - } - - timeString = [NSString stringWithFormat:@"T%02ld:%02ld:%02ld%@%@", - (long)dateComponents.hour, (long)dateComponents.minute, - (long)dateComponents.second, fractionalSecondsString, - offsetStr]; - } - - // full dateString like "2006-11-17T15:10:46-08:00" - NSString *dateString = [NSString stringWithFormat:@"%04ld-%02ld-%02ld%@", - (long)dateComponents.year, (long)dateComponents.month, - (long)dateComponents.day, timeString]; - - @synchronized(self) { - _cachedRFC3339String = dateString; - } - return dateString; -} - -- (void)setFromDate:(NSDate *)date { - NSCalendar *cal = [[self class] calendar]; - - NSDateComponents *components = [cal components:kGTLRDateComponentBits - fromDate:date]; - self.dateComponents = components; - - // Extract the fractional seconds. - NSTimeInterval asTimeInterval = [date timeIntervalSince1970]; - NSTimeInterval worker = asTimeInterval - trunc(asTimeInterval); - self.milliseconds = (NSInteger)round(worker * 1000.0); -} - -- (void)setFromRFC3339String:(NSString *)str { - static NSCharacterSet *gDashSet; - static NSCharacterSet *gTSet; - static NSCharacterSet *gColonSet; - static NSCharacterSet *gPlusMinusZSet; - - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - gDashSet = [NSCharacterSet characterSetWithCharactersInString:@"-"]; - gTSet = [NSCharacterSet characterSetWithCharactersInString:@"Tt "]; - gColonSet = [NSCharacterSet characterSetWithCharactersInString:@":"]; - gPlusMinusZSet = [NSCharacterSet characterSetWithCharactersInString:@"+-zZ"]; - }); - - NSInteger year = NSDateComponentUndefined; - NSInteger month = NSDateComponentUndefined; - NSInteger day = NSDateComponentUndefined; - NSInteger hour = NSDateComponentUndefined; - NSInteger minute = NSDateComponentUndefined; - NSInteger sec = NSDateComponentUndefined; - NSInteger milliseconds = 0; - double secDouble = -1.0; - NSString* sign = nil; - NSInteger offsetHour = 0; - NSInteger offsetMinute = 0; - - if (str.length > 0) { - NSScanner* scanner = [NSScanner scannerWithString:str]; - // There should be no whitespace, so no skip characters. - [scanner setCharactersToBeSkipped:nil]; - - // for example, scan 2006-11-17T15:10:46-08:00 - // or 2006-11-17T15:10:46Z - if (// yyyy-mm-dd - [scanner scanInteger:&year] && - [scanner scanCharactersFromSet:gDashSet intoString:NULL] && - [scanner scanInteger:&month] && - [scanner scanCharactersFromSet:gDashSet intoString:NULL] && - [scanner scanInteger:&day] && - // Thh:mm:ss - [scanner scanCharactersFromSet:gTSet intoString:NULL] && - [scanner scanInteger:&hour] && - [scanner scanCharactersFromSet:gColonSet intoString:NULL] && - [scanner scanInteger:&minute] && - [scanner scanCharactersFromSet:gColonSet intoString:NULL] && - [scanner scanDouble:&secDouble]) { - - // At this point we got secDouble, pull it apart. - sec = (NSInteger)secDouble; - double worker = secDouble - ((double)sec); - milliseconds = (NSInteger)round(worker * 1000.0); - - // Finish parsing, now the offset info. - if (// Z or +hh:mm - [scanner scanCharactersFromSet:gPlusMinusZSet intoString:&sign] && - [scanner scanInteger:&offsetHour] && - [scanner scanCharactersFromSet:gColonSet intoString:NULL] && - [scanner scanInteger:&offsetMinute]) { - } - } - } - - NSDateComponents *dateComponents = [[NSDateComponents alloc] init]; - [dateComponents setYear:year]; - [dateComponents setMonth:month]; - [dateComponents setDay:day]; - [dateComponents setHour:hour]; - [dateComponents setMinute:minute]; - [dateComponents setSecond:sec]; - - BOOL isMinusOffset = [sign isEqual:@"-"]; - if (isMinusOffset || [sign isEqual:@"+"]) { - NSInteger totalOffsetMinutes = ((offsetHour * 60) + offsetMinute) * (isMinusOffset ? -1 : 1); - self.offsetMinutes = @(totalOffsetMinutes); - - // Minus offset means Universal time is that many hours and minutes ahead. - // - // This is the inverse of the adjustment done above in RFC3339String. - NSTimeInterval deltaOffsetSeconds = -totalOffsetMinutes * 60; - NSCalendar *calendar = [[self class] calendar]; - NSDate *scannedDate = [calendar dateFromComponents:dateComponents]; - NSDate *offsetDate = [scannedDate dateByAddingTimeInterval:deltaOffsetSeconds]; - - dateComponents = [calendar components:kGTLRDateComponentBits - fromDate:offsetDate]; - } - - self.dateComponents = dateComponents; - self.milliseconds = milliseconds; -} - -- (BOOL)hasTime { - NSDateComponents *dateComponents = self.dateComponents; - - BOOL hasTime = ([dateComponents hour] != NSDateComponentUndefined - && [dateComponents minute] != NSDateComponentUndefined); - - return hasTime; -} - -- (void)setHasTime:(BOOL)shouldHaveTime { - // We'll set time values to zero or kUndefinedDateComponent as appropriate. - BOOL hadTime = self.hasTime; - - if (shouldHaveTime && !hadTime) { - [_dateComponents setHour:0]; - [_dateComponents setMinute:0]; - [_dateComponents setSecond:0]; - _milliseconds = 0; - } else if (hadTime && !shouldHaveTime) { - [_dateComponents setHour:NSDateComponentUndefined]; - [_dateComponents setMinute:NSDateComponentUndefined]; - [_dateComponents setSecond:NSDateComponentUndefined]; - _milliseconds = 0; - } -} - -+ (NSCalendar *)calendar { - NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; - cal.timeZone = (NSTimeZone * _Nonnull)[NSTimeZone timeZoneWithName:@"Universal"]; - return cal; -} - -@end diff --git a/Pods/GoogleAPIClientForREST/Source/Objects/GTLRDuration.h b/Pods/GoogleAPIClientForREST/Source/Objects/GTLRDuration.h @@ -1,83 +0,0 @@ -/* Copyright (c) 2016 Google Inc. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#import <Foundation/Foundation.h> -#import "GTLRDefines.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - * An immutable class representing a string data type 'google-duration'. - * It is based off the protocol buffers definition: - * https://github.com/google/protobuf/blob/master/src/google/protobuf/duration.proto - */ -@interface GTLRDuration : NSObject <NSCopying> - -/** - * Signed seconds of the span of time. Must be from -315,576,000,000 - * to +315,576,000,000 inclusive. - **/ -@property(nonatomic, readonly) int64_t seconds; - -/** - * Signed fractions of a second at nanosecond resolution of the span - * of time. Durations less than one second are represented with a 0 - * `seconds` field and a positive or negative `nanos` field. For durations - * of one second or more, a non-zero value for the `nanos` field must be - * of the same sign as the `seconds` field. Must be from -999,999,999 - * to +999,999,999 inclusive. - **/ -@property(nonatomic, readonly) int32_t nanos; - -/** - * This duration expressed as a NSTimeInterval. - * - * @note: Not all second/nanos combinations can be represented in a - * NSTimeInterval, so this could be a lossy transform. - **/ -@property(nonatomic, readonly) NSTimeInterval timeInterval; - -/** - * Returns the string form used to send this data type in a JSON payload. - */ -@property(nonatomic, readonly) NSString *jsonString; - -/** - * Constructor for a new duration with the given seconds and nanoseconds. - * - * Will fail if seconds/nanos differ in sign or if nanos is more than one - * second. - **/ -+ (nullable instancetype)durationWithSeconds:(int64_t)seconds - nanos:(int32_t)nanos; - -/** - * Constructor for a new duration from the given string form. - * - * Will return nil if jsonString is invalid. - **/ -+ (nullable instancetype)durationWithJSONString:(nullable NSString *)jsonString; - -/** - * Constructor for a new duration from the NSTimeInterval. - * - * @note NSTimeInterval doesn't always express things as exactly as one might - * expect, so coverting from to integer seconds & nanos can reveal this. - **/ -+ (instancetype)durationWithTimeInterval:(NSTimeInterval)timeInterval; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleAPIClientForREST/Source/Objects/GTLRDuration.m b/Pods/GoogleAPIClientForREST/Source/Objects/GTLRDuration.m @@ -1,222 +0,0 @@ -/* Copyright (c) 2016 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if !__has_feature(objc_arc) -#error "This file needs to be compiled with ARC enabled." -#endif - -#import "GTLRDuration.h" - -static const int32_t kNanosPerMillisecond = 1000000; -static const int32_t kNanosPerMicrosecond = 1000; -static const int32_t kNanosPerSecond = 1000000000; - -static int32_t IntPow10(int x) { - int32_t result = 1; - for (int i = 0; i < x; ++i) { - result *= 10; - } - return result; -} - -@implementation GTLRDuration - -@dynamic timeInterval; - -@synthesize seconds = _seconds, - nanos = _nanos, - jsonString = _jsonString; - -+ (instancetype)durationWithSeconds:(int64_t)seconds nanos:(int32_t)nanos { - if (seconds < 0) { - if (nanos > 0) { - // secs was -, nanos was + - return nil; - } - } else if (seconds > 0) { - if (nanos < 0) { - // secs was +, nanos was - - return nil; - } - } - if ((nanos <= -kNanosPerSecond) || (nanos >= kNanosPerSecond)) { - // more than a seconds worth - return nil; - } - return [[self alloc] initWithSeconds:seconds nanos:nanos jsonString:NULL]; -} - -+ (instancetype)durationWithJSONString:(NSString *)jsonString { - // It has to end in "s", so it needs >1 character. - if (jsonString.length <= 1) { - return nil; - } - - static NSCharacterSet *gNumberSet; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - gNumberSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"]; - }); - - NSScanner* scanner = [NSScanner scannerWithString:jsonString]; - // There should be no whitespace, so no skip characters. - [scanner setCharactersToBeSkipped:nil]; - - // Can start with a '-'. - BOOL isNeg = [scanner scanString:@"-" intoString:NULL]; - - int64_t seconds; - if (![scanner scanLongLong:&seconds]) { - return nil; - } - - // Since the sign was manually scanned, seconds should be positive - // (i.e. no "--#" in the put). - if (seconds < 0) { - return nil; - } - - // See if it has a ".[nanos]". Spec seems to say it is required, but play - // it safe and make it optional. - int32_t nanos = 0; - if ([scanner scanString:@"." intoString:NULL]) { - NSString *nanosStr; - if (![scanner scanCharactersFromSet:gNumberSet intoString:&nanosStr]) { - return nil; - } - // Ensure not too many digits (also ensure it is within range). - if (nanosStr.length > 9) { - return nil; - } - // Can use NSString's intValue since the character set was controlled. - nanos = [nanosStr intValue]; - // Scale based on length. - nanos *= IntPow10(9 - (int)nanosStr.length); - } - - // And must have the final 's'. - if (![scanner scanString:@"s" intoString:NULL]) { - return nil; - } - - // Better be the end... - if (![scanner isAtEnd]) { - return nil; - } - - if (isNeg) { - seconds = -seconds; - nanos = -nanos; - } - - // Pass on the json string so it will be reflected back out as it came in - // (incase it had a different number of digits, etc). - return [[self alloc] initWithSeconds:seconds - nanos:nanos - jsonString:jsonString]; -} - -+ (instancetype)durationWithTimeInterval:(NSTimeInterval)timeInterval { - NSTimeInterval seconds; - NSTimeInterval nanos = modf(timeInterval, &seconds); - nanos *= (NSTimeInterval)kNanosPerSecond; - - return [[self alloc] initWithSeconds:(int64_t)seconds - nanos:(int32_t)nanos - jsonString:NULL]; -} - -- (instancetype)init { - return [self initWithSeconds:0 nanos:0 jsonString:NULL]; -} - -- (instancetype)initWithSeconds:(int64_t)seconds - nanos:(int32_t)nanos - jsonString:(NSString *)jsonString { - self = [super init]; - if (self) { - // Sanity asserts, the class methods should make sure this doesn't happen. - GTLR_DEBUG_ASSERT((((seconds <= 0) && (nanos <= 0)) || - ((seconds >= 0) && (nanos >= 0))), - @"Seconds and nanos must have the same sign (%lld & %d)", - seconds, nanos); - GTLR_DEBUG_ASSERT(((nanos < kNanosPerSecond) && - (nanos > -kNanosPerSecond)), - @"Nanos is a second or more (%d)", nanos); - - _seconds = seconds; - _nanos = nanos; - - if (jsonString.length) { - _jsonString = [jsonString copy]; - } else { - // Based off the JSON serialization code in protocol buffers - // ( https://github.com/google/protobuf/ ). - NSString *sign = @""; - if ((seconds < 0) || (nanos < 0)) { - sign = @"-"; - seconds = -seconds; - nanos = -nanos; - } - int nanoDigts; - int32_t nanoDivider; - if (nanos % kNanosPerMillisecond == 0) { - nanoDigts = 3; - nanoDivider = kNanosPerMillisecond; - } else if (nanos % kNanosPerMicrosecond == 0) { - nanoDigts = 6; - nanoDivider = kNanosPerMicrosecond; - } else { - nanoDigts = 9; - nanoDivider = 1; - } - _jsonString = [NSString stringWithFormat:@"%@%lld.%0*ds", - sign, seconds, nanoDigts, (nanos / nanoDivider)]; - } - } - return self; -} - -- (NSTimeInterval)timeInterval { - NSTimeInterval result = self.seconds; - result += (NSTimeInterval)self.nanos / (NSTimeInterval)kNanosPerSecond; - return result; -} - -- (id)copyWithZone:(NSZone *)zone { - // Object is immutable - return self; -} - -- (BOOL)isEqual:(GTLRDuration *)other { - if (self == other) return YES; - if (![other isKindOfClass:[GTLRDuration class]]) return NO; - - BOOL result = ((self.seconds == other.seconds) && - (self.nanos == other.nanos)); - return result; -} - -- (NSUInteger)hash { - NSUInteger result = (NSUInteger)((self.seconds * 13) + self.nanos); - return result; -} - -- (NSString *)description { - return [NSString stringWithFormat:@"%@ %p: {%@}", - [self class], self, self.jsonString]; -} - -@end diff --git a/Pods/GoogleAPIClientForREST/Source/Objects/GTLRErrorObject.h b/Pods/GoogleAPIClientForREST/Source/Objects/GTLRErrorObject.h @@ -1,116 +0,0 @@ -/* Copyright (c) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "GTLRObject.h" - -NS_ASSUME_NONNULL_BEGIN - -@class GTLRErrorObjectErrorItem; -@class GTLRErrorObjectDetail; - -/** - * This class wraps JSON responses (both V1 and V2 of Google JSON errors) and NSErrors. - * - * A GTLRErrorObject can be created using +objectWithJSON: or +objectWithFoundationError: - */ -@interface GTLRErrorObject : GTLRObject - -/** - * Convenience method for creating an error object from an NSError. - * - * @param error The @c NSError to be encapsulated by the @c GTLRErrorObject - * - * @return A @c GTLRErrorObject wrapping the NSError. - */ -+ (instancetype)objectWithFoundationError:(NSError *)error; - -/** - * Convenience utility for extracting the GTLRErrorObject that was used to create an NSError. - * - * @param foundationError The NSError that may have been obtained from a GTLRErrorObject. - * - * @return The GTLRErrorObject, nil if the error was not originally from a GTLRErrorObject. - */ -+ (nullable GTLRErrorObject *)underlyingObjectForError:(NSError *)foundationError; - -// -// V1 & V2 properties. -// - -/** - * The numeric error code. - */ -@property(nonatomic, strong, nullable) NSNumber *code; - -/** - * An error message string, typically provided by the API server. This is not localized, - * and its reliability depends on the API server. - */ -@property(nonatomic, strong, nullable) NSString *message; - -// -// V1 properties. -// - -/** - * Underlying errors that occurred on the server. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRErrorObjectErrorItem *> *errors; - -// -// V2 properties -// - -/** - * A status error string, defined by the API server, such as "NOT_FOUND". - */ -@property(nonatomic, strong, nullable) NSString *status; - -/** - * Additional diagnostic error details provided by the API server. - */ -@property(nonatomic, strong, nullable) NSArray<GTLRErrorObjectDetail *> *details; - -/** - * An NSError, either underlying the error object or manufactured from the error object's - * properties. - */ -@property(nonatomic, readonly) NSError *foundationError; - -@end - -/** - * Class representing the items of the "errors" array inside the Google V1 error JSON. - * - * Client applications should not rely on the property values of these items. - */ -@interface GTLRErrorObjectErrorItem : GTLRObject -@property(nonatomic, strong, nullable) NSString *domain; -@property(nonatomic, strong, nullable) NSString *reason; -@property(nonatomic, strong, nullable) NSString *message; -@property(nonatomic, strong, nullable) NSString *location; -@end - -/** - * Class representing the items of the "details" array inside the Google V2 error JSON. - * - * Client applications should not rely on the property values of these items. - */ -@interface GTLRErrorObjectDetail : GTLRObject -@property(nonatomic, strong, nullable) NSString *type; -@property(nonatomic, strong, nullable) NSString *detail; -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleAPIClientForREST/Source/Objects/GTLRErrorObject.m b/Pods/GoogleAPIClientForREST/Source/Objects/GTLRErrorObject.m @@ -1,140 +0,0 @@ -/* Copyright (c) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if !__has_feature(objc_arc) -#error "This file needs to be compiled with ARC enabled." -#endif - -#import "GTLRErrorObject.h" - -#import "GTLRUtilities.h" -#import "GTLRService.h" - -static NSString *const kGTLRErrorObjectFoundationErrorKey = @"foundationError"; - -@implementation GTLRErrorObject { - NSError *_originalFoundationError; -} - -// V1 & V2 properties. -@dynamic code; -@dynamic message; - -// V1 properties. -@dynamic errors; - -// V2 properties. -@dynamic status; -@dynamic details; - -// Implemented below. -@dynamic foundationError; - -+ (instancetype)objectWithFoundationError:(NSError *)error { - GTLRErrorObject *object = [self object]; - object->_originalFoundationError = error; - object.code = @(error.code); - object.message = error.localizedDescription; - return object; -} - -+ (NSDictionary *)arrayPropertyToClassMap { - return @{ - @"errors" : [GTLRErrorObjectErrorItem class], - @"details" : [GTLRErrorObjectDetail class] - }; -} - -- (NSError *)foundationError { - // If there was an original foundation error, copy its userInfo as the basis for ours. - NSMutableDictionary *userInfo = - [NSMutableDictionary dictionaryWithDictionary:_originalFoundationError.userInfo]; - - // This structured GTLRErrorObject will be available in the error's userInfo - // dictionary. - userInfo[kGTLRStructuredErrorKey] = self; - - NSError *error; - if (_originalFoundationError) { - error = [NSError errorWithDomain:_originalFoundationError.domain - code:_originalFoundationError.code - userInfo:userInfo]; - } else { - NSString *reasonStr = self.message; - if (reasonStr) { - userInfo[NSLocalizedDescriptionKey] = reasonStr; - } - - error = [NSError errorWithDomain:kGTLRErrorObjectDomain - code:self.code.integerValue - userInfo:userInfo]; - } - return error; -} - -+ (GTLRErrorObject *)underlyingObjectForError:(NSError *)foundationError { - NSDictionary *userInfo = [foundationError userInfo]; - GTLRErrorObject *errorObj = [userInfo objectForKey:kGTLRStructuredErrorKey]; - return errorObj; -} - -- (BOOL)isEqual:(id)object { - // Include the underlying foundation error in equality checks. - if (self == object) return YES; - if (![super isEqual:object]) return NO; - if (![object isKindOfClass:[GTLRErrorObject class]]) return NO; - GTLRErrorObject *other = (GTLRErrorObject *)object; - return GTLR_AreEqualOrBothNil(_originalFoundationError, - other->_originalFoundationError); -} - -+ (BOOL)supportsSecureCoding { - return YES; -} - -- (instancetype)initWithCoder:(NSCoder *)decoder { - self = [super initWithCoder:decoder]; - if (self) { - _originalFoundationError = - [decoder decodeObjectOfClass:[NSError class] - forKey:kGTLRErrorObjectFoundationErrorKey]; - } - return self; -} - -- (void)encodeWithCoder:(NSCoder *)encoder { - [super encodeWithCoder:encoder]; - [encoder encodeObject:_originalFoundationError - forKey:kGTLRErrorObjectFoundationErrorKey]; -} - -@end - -@implementation GTLRErrorObjectErrorItem -@dynamic domain; -@dynamic reason; -@dynamic message; -@dynamic location; -@end - -@implementation GTLRErrorObjectDetail -@dynamic type; -@dynamic detail; - -+ (NSDictionary *)propertyToJSONKeyMap { - return @{ @"type" : @"@type" }; -} - -@end diff --git a/Pods/GoogleAPIClientForREST/Source/Objects/GTLRObject.h b/Pods/GoogleAPIClientForREST/Source/Objects/GTLRObject.h @@ -1,317 +0,0 @@ -/* Copyright (c) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// GTLRObject documentation: -// https://github.com/google/google-api-objectivec-client-for-rest/wiki#objects-and-queries - -#import <Foundation/Foundation.h> - -#import "GTLRDefines.h" -#import "GTLRDateTime.h" -#import "GTLRDuration.h" - -NS_ASSUME_NONNULL_BEGIN - -@class GTLRObject; - -/** - * Protocol that can be implemented to provide custom logic for what class - * should be created out of the given JSON. - */ -@protocol GTLRObjectClassResolver <NSObject> -- (Class)classForJSON:(NSDictionary *)json - defaultClass:(Class)defaultClass; -@end - -/** - * Standard GTLRObjectClassResolver used by the core library. - */ -@interface GTLRObjectClassResolver : NSObject<GTLRObjectClassResolver> - -/** - * Returns a resolver that will look up the 'kind' properties to find classes - * based on the JSON. - * - * The generated service classes provide a +kindStringToClassMap method for any - * mappings that were found from discovery when generating the service. - */ -+ (instancetype)resolverWithKindMap:(NSDictionary<NSString *, Class> *)kindStringToClassMap; - -/** - * Returns a resolver that will look up the 'kind' properties to find classes - * based on the JSON and then applies mapping of surrogate classes to swap out - * specific classes. - * - * Surrogates are subclasses to be instantiated instead of standard classes - * when creating objects from the JSON. For example, this code will, for one query's - * execution, swap a service's default resolver for one that will then use - * MyCalendarEventSubclass instead of GTLRCalendarEvent and - * MyCalendarReminderSubclass instead of GTLRCalendarReminder. - * - * @code - * NSDictionary *surrogates = @{ - * [GTLRCalendarEvent class] : [MyCalendarEventSubclass class] - * [GTLRCalendarReminder class] : [MyCalendarReminderSubclass class], - * }; - * NSDictionary *serviceKindMap = [[calendarService class] kindStringToClassMap]; - * GTLRObjectClassResolver *updatedResolver = - * [GTLRObjectClassResolver resolverWithKindMap:serviceKindMap - * surrogates:surrogates]; - * query.executionParameters.objectClassResolver = updatedResolver; - * @endcode - * - * @note To install surrogates for all queries executed by the service, use - * the service's @c -setSurrogates method. - */ -+ (instancetype)resolverWithKindMap:(NSDictionary<NSString *, Class> *)kindStringToClassMap - surrogates:(NSDictionary<Class, Class> *)surrogates; - -@end - -/** - * @c GTLRObject serves as the common superclass for classes wrapping JSON, errors, and other data - * passed in server requests and responses. - * - * @note This class is @em not safe for simultaneous use from multiple threads. Applications should - * serialize or protect access to a @c GTLRObject instance as they would for any standard - * Cocoa mutable container. - */ -@interface GTLRObject : NSObject <NSCopying, NSSecureCoding> - -/** - * The JSON underlying the property values for this object. - * - * The JSON should be accessed or set using the generated properties of a - * class derived from GTLRObject or with the methods @c setJSONValue:forKey: - * and @c JSONValueForKey: - * - * @note: Applications should use @c additionalPropertyForKey: when accessing - * API object properties that do not have generated @c \@property accessors. - */ -@property(nonatomic, strong, nullable) NSMutableDictionary *JSON; - -/** - * A dictionary retained by the object for the convenience of the client application. - * - * A client application may use this to retain any dictionary. - * - * The values of the user properties dictionary will not be sent to the server during - * query execution, and will not be copied by NSCopying or encoded by NSSecureCoding. - */ -@property(nonatomic, strong) NSDictionary *userProperties; - -///////////////////////////////////////////////////////////////////////////////////////////// -// -// Public methods -// -// These methods are intended for users of the library -// -///////////////////////////////////////////////////////////////////////////////////////////// - -/** - * Constructor for an empty object. - */ -+ (instancetype)object; - -/** - * Constructor for an object including JSON. - */ -+ (instancetype)objectWithJSON:(nullable NSDictionary *)dict; - -/** - * Constructor for an object including JSON and providing a resolver to help - * select the correct classes for sub objects within the json. - * - * The generated services provide a default resolver (-objectClassResolver) - * that covers the kinds for that service. They also expose the kind mappings - * via the +kindStringToClassMap method. - */ -+ (instancetype)objectWithJSON:(nullable NSDictionary *)dict - objectClassResolver:(id<GTLRObjectClassResolver>)objectClassResolver; - -/** - * The JSON for the object, or an empty string if there is no JSON or if the JSON - * dictionary cannot be represented as JSON. - */ -- (NSString *)JSONString; - -/** - * Generic access for setting entries in the JSON dictionary. This creates the JSON dictionary - * if necessary. - * - * @note: Applications should use @c setAdditionalProperty:forKey: when setting - * API object properties that do not have generated @c \@property accessors. - */ -- (void)setJSONValue:(nullable id)obj forKey:(nonnull NSString *)key; - -/** - * Generic access to the JSON dictionary. - * - * @note: Applications should use @c additionalPropertyForKey: when accessing - * API object properties that do not have generated @c \@property accessors. - */ -- (nullable id)JSONValueForKey:(NSString *)key; - -/** - * The list of keys in this object's JSON that are not listed as properties on the object. - */ -- (nullable NSArray<NSString *> *)additionalJSONKeys; - -/** - * Setter for any key in the JSON that is not listed as a @c \@property in the class declaration. - */ -- (void)setAdditionalProperty:(id)obj forName:(NSString *)name; - -/** - * Accessor for any key in the JSON that is not listed as a @c \@property in the class - * declaration. - */ -- (nullable id)additionalPropertyForName:(NSString *)name; - -/** - * A dictionary of all keys in the JSON that is not listed as a @c \@property in the class - * declaration. - */ -- (NSDictionary<NSString *, id> *)additionalProperties; - -/** - * A string for a partial query describing the fields present. - * - * @note Only the first element of any array is examined. - * - * @see https://developers.google.com/google-apps/tasks/performance?csw=1#partial - * - * @return A @c fields string describing the fields present in the object. - */ -- (NSString *)fieldsDescription; - -/** - * An object containing only the changes needed to do a partial update (patch), - * where the patch would be to change an object from the original to the receiver, - * such as - * @c GTLRSomeObject *patchObject = [newVersion patchObjectFromOriginal:oldVersion]; - * - * @note This method returns nil if there are no changes between the original and the receiver. - * - * @see https://developers.google.com/google-apps/tasks/performance?csw=1#patch - * - * @param original The original object from which to create the patch object. - * - * @return The object used for the patch body. - */ -- (nullable id)patchObjectFromOriginal:(GTLRObject *)original; - -/** - * A null value to set object properties for patch queries that delete fields. - * - * Do not use this except when setting an object property for a patch query. - * - * @return The null value object. - */ -+ (id)nullValue; - -#pragma mark Internal - -/////////////////////////////////////////////////////////////////////////////// -// -// Protected methods -// -// These methods are intended for subclasses of GTLRObject -// - -// Creation of objects from a JSON dictionary. The class created depends on -// the content of the JSON, not the class messaged. -+ (nullable GTLRObject *)objectForJSON:(NSMutableDictionary *)json - defaultClass:(nullable Class)defaultClass - objectClassResolver:(id<GTLRObjectClassResolver>)objectClassResolver; - -// Property-to-key mapping (for JSON keys which are not used as method names) -+ (nullable NSDictionary<NSString *, NSString *> *)propertyToJSONKeyMap; - -// property-to-Class mapping for array properties (to say what is in the array) -+ (nullable NSDictionary<NSString *, Class> *)arrayPropertyToClassMap; - -// The default class for additional JSON keys -+ (nullable Class)classForAdditionalProperties; - -// Indicates if a "kind" property on this class can be used for the class -// registry or if it appears to be non standard. -+ (BOOL)isKindValidForClassRegistry; - -@end - -/** - * Collection results have a property containing an array of @c GTLRObject - * - * This provides support for @c NSFastEnumeration and for indexed subscripting to - * access the objects in the array. - */ -@interface GTLRCollectionObject : GTLRObject<NSFastEnumeration> - -/** - * The property name that holds the collection. - * - * @return The key for the property holding the array of @c GTLRObject items. - */ -+ (NSString *)collectionItemsKey; - -// objectAtIndexedSubscript: will throw if the index is out of bounds (like -// NSArray does). -- (nullable id)objectAtIndexedSubscript:(NSUInteger)idx; - -@end - -/** - * A GTLRDataObject holds media data and the MIME type of the data returned by a media - * download query. - * - * The JSON for the object may be nil. - */ -@interface GTLRDataObject : GTLRObject - -/** - * The downloaded media data. - */ -@property(atomic, strong) NSData *data; - -/** - * The MIME type of the downloaded media data. - */ -@property(atomic, copy) NSString *contentType; - -@end - -/** - * Base class used when a service method directly returns an array instead - * of a JSON object. This exists for the methods not up to spec. - */ -@interface GTLRResultArray : GTLRCollectionObject - -/** - * This method should only be called by subclasses. - */ -- (nullable NSArray *)itemsWithItemClass:(Class)itemClass; -@end - -/** - * Helper to call the resolver and find the class to use for the given JSON. - * Intended for internal library use only. - */ -Class GTLRObjectResolveClass( - id<GTLRObjectClassResolver> objectClassResolver, - NSDictionary *json, - Class defaultClass); - -NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleAPIClientForREST/Source/Objects/GTLRObject.m b/Pods/GoogleAPIClientForREST/Source/Objects/GTLRObject.m @@ -1,760 +0,0 @@ -/* Copyright (c) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if !__has_feature(objc_arc) -#error "This file needs to be compiled with ARC enabled." -#endif - -#include <objc/runtime.h> - -#import "GTLRObject.h" -#import "GTLRRuntimeCommon.h" -#import "GTLRUtilities.h" - -static NSString *const kUserDataPropertyKey = @"_userData"; - -static NSString *const kGTLRObjectJSONCoderKey = @"json"; - -static NSMutableDictionary *DeepMutableCopyOfJSONDictionary(NSDictionary *initialJSON); - -@interface GTLRObject () <GTLRRuntimeCommon> - -@property(nonatomic, strong) id<GTLRObjectClassResolver>objectClassResolver; - -@end - -@implementation GTLRObject { - // Any complex object hung off this object goes into the cache so the - // next fetch will get the same object back instead of having to recreate - // it. - NSMutableDictionary *_childCache; -} - -@synthesize JSON = _json, - objectClassResolver = _objectClassResolver, - userProperties = _userProperties; - -+ (instancetype)object { - return [[self alloc] init]; -} - -+ (instancetype)objectWithJSON:(NSDictionary *)dict { - GTLRObject *obj = [self object]; - obj->_json = DeepMutableCopyOfJSONDictionary(dict); - return obj; -} - -+ (instancetype)objectWithJSON:(nullable NSDictionary *)dict - objectClassResolver:(id<GTLRObjectClassResolver>)objectClassResolver { - GTLRObject *obj = [self objectWithJSON:dict]; - obj->_objectClassResolver = objectClassResolver; - return obj; -} - -+ (NSDictionary<NSString *, NSString *> *)propertyToJSONKeyMap { - return nil; -} - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - return nil; -} - -+ (Class)classForAdditionalProperties { - return Nil; -} - -+ (BOOL)isKindValidForClassRegistry { - return YES; -} - -- (BOOL)isEqual:(GTLRObject *)other { - if (self == other) return YES; - if (other == nil) return NO; - - // The objects should be the same class, or one should be a subclass of the - // other's class - if (![other isKindOfClass:[self class]] - && ![self isKindOfClass:[other class]]) return NO; - - // What we're not comparing here: - // properties - return GTLR_AreEqualOrBothNil(_json, [other JSON]); -} - -// By definition, for two objects to potentially be considered equal, -// they must have the same hash value. The hash is mostly ignored, -// but removeObjectsInArray: in Leopard does seem to check the hash, -// and NSObject's default hash method just returns the instance pointer. -// We'll define hash here for all of our GTLRObjects. -- (NSUInteger)hash { - return (NSUInteger) (__bridge void *) [GTLRObject class]; -} - -- (id)copyWithZone:(NSZone *)zone { - GTLRObject *newObject = [[[self class] allocWithZone:zone] init]; - newObject.JSON = DeepMutableCopyOfJSONDictionary(self.JSON); - newObject.objectClassResolver = self.objectClassResolver; - - // What we're not copying: - // userProperties - return newObject; -} - -- (NSString *)descriptionWithLocale:(id)locale { - return self.description; -} - -+ (BOOL)supportsSecureCoding { - return YES; -} - -- (instancetype)initWithCoder:(NSCoder *)decoder { - self = [super init]; - if (self) { - _json = [decoder decodeObjectOfClass:[NSMutableDictionary class] - forKey:kGTLRObjectJSONCoderKey]; - } - return self; -} - -- (void)encodeWithCoder:(NSCoder *)encoder { - [encoder encodeObject:_json forKey:kGTLRObjectJSONCoderKey]; -} - -#pragma mark JSON values - -- (void)setJSONValue:(id)obj forKey:(NSString *)key { - NSMutableDictionary *dict = self.JSON; - if (dict == nil && obj != nil) { - dict = [NSMutableDictionary dictionaryWithCapacity:1]; - self.JSON = dict; - } - [dict setValue:obj forKey:key]; -} - -- (id)JSONValueForKey:(NSString *)key { - id obj = [self.JSON objectForKey:key]; - return obj; -} - -- (NSString *)JSONString { - NSError *error; - NSDictionary *json = self.JSON; - if (json) { - NSData *data = [NSJSONSerialization dataWithJSONObject:json - options:NSJSONWritingPrettyPrinted - error:&error]; - GTLR_DEBUG_ASSERT(data != nil, @"JSONString generate failed: %@\n JSON: %@", error, json); - if (data) { - NSString *jsonStr = [[NSString alloc] initWithData:data - encoding:NSUTF8StringEncoding]; - if (jsonStr) return jsonStr; - } - } - return @""; -} - -- (NSArray<NSString *> *)additionalJSONKeys { - NSArray *knownKeys = [[self class] allKnownKeys]; - NSMutableArray *result; - NSArray *allKeys = _json.allKeys; - if (allKeys) { - result = [NSMutableArray arrayWithArray:allKeys]; - [result removeObjectsInArray:knownKeys]; - // Return nil instead of an empty array. - if (result.count == 0) { - result = nil; - } - } - return result; -} - -#pragma mark Partial - Fields - -- (NSString *)fieldsDescription { - NSString *str = [GTLRObject fieldsDescriptionForJSON:self.JSON]; - return str; -} - -+ (NSString *)fieldsDescriptionForJSON:(NSDictionary *)targetJSON { - // Internal routine: recursively generate a string field description - // by joining elements - NSArray *array = [self fieldsElementsForJSON:targetJSON]; - NSString *str = [array componentsJoinedByString:@","]; - return str; -} - -+ (NSArray *)fieldsElementsForJSON:(NSDictionary *)targetJSON { - // Internal routine: recursively generate an array of field description - // element strings - NSMutableArray *resultFields = [NSMutableArray array]; - - // Sorting the dictionary keys gives us deterministic results when iterating - NSArray *sortedKeys = [targetJSON.allKeys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; - for (NSString *key in sortedKeys) { - // We'll build a comma-separated list of fields - id value = [targetJSON objectForKey:key]; - if ([value isKindOfClass:[NSString class]] - || [value isKindOfClass:[NSNumber class]]) { - // Basic type (string, number), so the key is what we want - [resultFields addObject:key]; - } else if ([value isKindOfClass:[NSDictionary class]]) { - // Object (dictionary): "parent/child1,parent/child2,parent/child3" - NSArray *subElements = [self fieldsElementsForJSON:value]; - for (NSString *subElem in subElements) { - NSString *prepended = [NSString stringWithFormat:@"%@/%@", - key, subElem]; - [resultFields addObject:prepended]; - } - } else if ([value isKindOfClass:[NSArray class]]) { - // Array; we'll generate from the first array entry: - // "parent(child1,child2,child3)" - // - // Open question: should this instead create the union of elements for - // all items in the array, rather than just get fields from the first - // array object? - if (((NSArray *)value).count > 0) { - id firstObj = [value objectAtIndex:0]; - if ([firstObj isKindOfClass:[NSDictionary class]]) { - // An array of objects - NSString *contentsStr = [self fieldsDescriptionForJSON:firstObj]; - NSString *encapsulated = [NSString stringWithFormat:@"%@(%@)", - key, contentsStr]; - [resultFields addObject:encapsulated]; - } else { - // An array of some basic type, or of arrays - [resultFields addObject:key]; - } - } - } else { - GTLR_ASSERT(0, @"GTLRObject unknown field element for %@ (%@)", - key, NSStringFromClass([value class])); - } - } - return resultFields; -} - -#pragma mark Partial - Patch - -- (id)patchObjectFromOriginal:(GTLRObject *)original { - GTLRObject *resultObj; - NSMutableDictionary *resultJSON = [GTLRObject patchDictionaryForJSON:self.JSON - fromOriginalJSON:original.JSON]; - if (resultJSON.count > 0) { - // Avoid an extra copy by assigning the JSON directly rather than using +objectWithJSON: - resultObj = [[self class] object]; - resultObj.JSON = resultJSON; - } else { - // Client apps should not attempt to patch with an object containing - // empty JSON - resultObj = nil; - } - return resultObj; -} - -+ (NSMutableDictionary *)patchDictionaryForJSON:(NSDictionary *)newJSON - fromOriginalJSON:(NSDictionary *)originalJSON { - // Internal recursive routine to create an object suitable for - // our patch semantics - NSMutableDictionary *resultJSON = [NSMutableDictionary dictionary]; - - // Iterate through keys present in the old object - NSArray *originalKeys = originalJSON.allKeys; - for (NSString *key in originalKeys) { - id originalValue = [originalJSON objectForKey:key]; - id newValue = [newJSON valueForKey:key]; - if (newValue == nil) { - // There is no new value for this key, so set the value to NSNull - [resultJSON setValue:[NSNull null] forKey:key]; - } else if (!GTLR_AreEqualOrBothNil(originalValue, newValue)) { - // The values for this key differ - if ([originalValue isKindOfClass:[NSDictionary class]] - && [newValue isKindOfClass:[NSDictionary class]]) { - // Both are objects; recurse - NSMutableDictionary *subDict = [self patchDictionaryForJSON:newValue - fromOriginalJSON:originalValue]; - [resultJSON setValue:subDict forKey:key]; - } else { - // They are non-object values; the new replaces the old. Per the - // documentation for patch, this replaces entire arrays. - [resultJSON setValue:newValue forKey:key]; - } - } else { - // The values are the same; omit this key-value pair - } - } - - // Iterate through keys present only in the new object, and add them to the - // result - NSMutableArray *newKeys = [NSMutableArray arrayWithArray:newJSON.allKeys]; - [newKeys removeObjectsInArray:originalKeys]; - - for (NSString *key in newKeys) { - id value = [newJSON objectForKey:key]; - [resultJSON setValue:value forKey:key]; - } - return resultJSON; -} - -+ (id)nullValue { - return [NSNull null]; -} - -#pragma mark Additional Properties - -- (id)additionalPropertyForName:(NSString *)name { - // Return the cached object, if any, before creating one. - id result = [self cacheChildForKey:name]; - if (result != nil) { - return result; - } - - Class defaultClass = [[self class] classForAdditionalProperties]; - id jsonObj = [self JSONValueForKey:name]; - BOOL shouldCache = NO; - if (jsonObj != nil) { - id<GTLRObjectClassResolver>objectClassResolver = self.objectClassResolver; - result = [GTLRRuntimeCommon objectFromJSON:jsonObj - defaultClass:defaultClass - objectClassResolver:objectClassResolver - isCacheable:&shouldCache]; - } - - [self setCacheChild:(shouldCache ? result : nil) - forKey:name]; - return result; -} - -- (void)setAdditionalProperty:(id)obj forName:(NSString *)name { - BOOL shouldCache = NO; - Class defaultClass = [[self class] classForAdditionalProperties]; - id json = [GTLRRuntimeCommon jsonFromAPIObject:obj - expectedClass:defaultClass - isCacheable:&shouldCache]; - [self setJSONValue:json forKey:name]; - [self setCacheChild:(shouldCache ? obj : nil) - forKey:name]; -} - -- (NSDictionary<NSString *, id> *)additionalProperties { - NSMutableDictionary *result = [NSMutableDictionary dictionary]; - - NSArray *propertyNames = [self additionalJSONKeys]; - for (NSString *name in propertyNames) { - id obj = [self additionalPropertyForName:name]; - [result setObject:obj forKey:name]; - } - - return result; -} - -#pragma mark Child Cache methods - -// There is no property for _childCache as there shouldn't be KVC/KVO -// support for it, it's an implementation detail. - -- (void)setCacheChild:(id)obj forKey:(NSString *)key { - if (_childCache == nil && obj != nil) { - _childCache = [[NSMutableDictionary alloc] initWithObjectsAndKeys: - obj, key, nil]; - } else { - [_childCache setValue:obj forKey:key]; - } -} - -- (id)cacheChildForKey:(NSString *)key { - id obj = [_childCache objectForKey:key]; - return obj; -} - -#pragma mark Support methods - -+ (NSMutableArray *)allDeclaredProperties { - NSMutableArray *array = [NSMutableArray array]; - - // walk from this class up the hierarchy to GTLRObject - Class topClass = class_getSuperclass([GTLRObject class]); - for (Class currClass = self; - currClass != topClass; - currClass = class_getSuperclass(currClass)) { - // step through this class's properties, and add the property names to the - // array - objc_property_t *properties = class_copyPropertyList(currClass, NULL); - if (properties) { - for (objc_property_t *prop = properties; - *prop != NULL; - ++prop) { - const char *propName = property_getName(*prop); - // We only want dynamic properties; their attributes contain ",D". - const char *attr = property_getAttributes(*prop); - const char *dynamicMarker = strstr(attr, ",D"); - if (dynamicMarker && - (dynamicMarker[2] == 0 || dynamicMarker[2] == ',' )) { - [array addObject:(id _Nonnull)@(propName)]; - } - } - free(properties); - } - } - return array; -} - -+ (NSArray *)allKnownKeys { - NSArray *allProps = [self allDeclaredProperties]; - NSMutableArray *knownKeys = [NSMutableArray arrayWithArray:allProps]; - - NSDictionary *propMap = [GTLRObject propertyToJSONKeyMapForClass:[self class]]; - - NSUInteger idx = 0; - for (NSString *propName in allProps) { - NSString *jsonKey = [propMap objectForKey:propName]; - if (jsonKey) { - [knownKeys replaceObjectAtIndex:idx - withObject:jsonKey]; - } - ++idx; - } - return knownKeys; -} - -- (NSString *)description { - NSString *jsonDesc = [self JSONDescription]; - - NSString *str = [NSString stringWithFormat:@"%@ %p: %@", - [self class], self, jsonDesc]; - return str; -} - -// Internal utility for creating an appropriate description summary for the object's JSON. -- (NSString *)JSONDescription { - // Find the list of declared and otherwise known JSON keys for this class. - NSArray *knownKeys = [[self class] allKnownKeys]; - - NSMutableString *descStr = [NSMutableString stringWithString:@"{"]; - - NSString *spacer = @""; - for (NSString *key in [[_json allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]) { - NSString *value = nil; - // show question mark for JSON keys not supported by a declared property: - // foo?:"Hi mom." - NSString *qmark = [knownKeys containsObject:key] ? @"" : @"?"; - - // determine property value to dislay - id rawValue = [_json valueForKey:key]; - if ([rawValue isKindOfClass:[NSDictionary class]]) { - // for dictionaries, show the list of keys: - // {key1,key2,key3} - NSArray *subKeys = [((NSDictionary *)rawValue).allKeys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; - NSString *subkeyList = [subKeys componentsJoinedByString:@","]; - value = [NSString stringWithFormat:@"{%@}", subkeyList]; - } else if ([rawValue isKindOfClass:[NSArray class]]) { - // for arrays, show the number of items in the array: - // [3] - value = [NSString stringWithFormat:@"[%tu]", ((NSArray *)rawValue).count]; - } else if ([rawValue isKindOfClass:[NSString class]]) { - // for strings, show the string in quotes: - // "Hi mom." - value = [NSString stringWithFormat:@"\"%@\"", rawValue]; - } else { - // for numbers, show just the number - value = [rawValue description]; - } - [descStr appendFormat:@"%@%@%@:%@", spacer, key, qmark, value]; - spacer = @" "; - } - [descStr appendString:@"}"]; - return descStr; -} - -#pragma mark Object Instantiation - -+ (GTLRObject *)objectForJSON:(NSMutableDictionary *)json - defaultClass:(Class)defaultClass - objectClassResolver:(id<GTLRObjectClassResolver>)objectClassResolver { - if (((id)json == [NSNull null]) || json.count == 0) { - if (json != nil && defaultClass != Nil) { - // The JSON included an empty dictionary, just create the object. - Class classToCreate = - GTLRObjectResolveClass(objectClassResolver, - [NSDictionary dictionary], - defaultClass); - return [classToCreate object]; - } - // No actual result, such as the response from a delete. - return nil; - } - - if (defaultClass == Nil) { - defaultClass = self; - } - - Class classToCreate = - GTLRObjectResolveClass(objectClassResolver, json, defaultClass); - - // now instantiate the GTLRObject - GTLRObject *parsedObject = [classToCreate object]; - parsedObject.objectClassResolver = objectClassResolver; - parsedObject.JSON = json; - return parsedObject; -} - -#pragma mark Runtime Utilities - -static NSMutableDictionary *gJSONKeyMapCache = nil; -static NSMutableDictionary *gArrayPropertyToClassMapCache = nil; - -+ (void)initialize { - // Note that initialize is guaranteed by the runtime to be called in a - // thread-safe manner - if (gJSONKeyMapCache == nil) { - gJSONKeyMapCache = [[NSMutableDictionary alloc] init]; - } - if (gArrayPropertyToClassMapCache == nil) { - gArrayPropertyToClassMapCache = [[NSMutableDictionary alloc] init]; - } -} - -+ (NSDictionary *)propertyToJSONKeyMapForClass:(Class<GTLRRuntimeCommon>)aClass { - NSDictionary *resultMap = - [GTLRRuntimeCommon mergedClassDictionaryForSelector:@selector(propertyToJSONKeyMap) - startClass:aClass - ancestorClass:[GTLRObject class] - cache:gJSONKeyMapCache]; - return resultMap; -} - -+ (NSDictionary *)arrayPropertyToClassMapForClass:(Class<GTLRRuntimeCommon>)aClass { - NSDictionary *resultMap = - [GTLRRuntimeCommon mergedClassDictionaryForSelector:@selector(arrayPropertyToClassMap) - startClass:aClass - ancestorClass:[GTLRObject class] - cache:gArrayPropertyToClassMapCache]; - return resultMap; -} - -#pragma mark Runtime Support - -+ (Class<GTLRRuntimeCommon>)ancestorClass { - return [GTLRObject class]; -} - -+ (BOOL)resolveInstanceMethod:(SEL)sel { - BOOL resolved = [GTLRRuntimeCommon resolveInstanceMethod:sel onClass:self]; - if (resolved) - return YES; - - return [super resolveInstanceMethod:sel]; -} - -@end - -@implementation GTLRCollectionObject - -+ (NSString *)collectionItemsKey { - // GTLRCollectionObject fast enumeration, indexed access, and automatic pagination - // (when shouldFetchNextPages is enabled) applies to the object array property "items". - // The array property's key may be different if subclasses override this method. - return @"items"; -} - -- (id)objectAtIndexedSubscript:(NSUInteger)idx { - NSString *key = [[self class] collectionItemsKey]; - NSArray *items = [self valueForKey:key]; - if (items == nil) { - [NSException raise:NSRangeException - format:@"index %tu beyond bounds (%@ property \"%@\" is nil)", - idx, [self class], key]; - } - id result = [items objectAtIndexedSubscript:idx]; - return result; -} - -// NSFastEnumeration protocol -- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state - objects:(__unsafe_unretained id _Nonnull *)stackbuf - count:(NSUInteger)len { - NSString *key = [[self class] collectionItemsKey]; - NSArray *items = [self valueForKey:key]; - NSUInteger result = [items countByEnumeratingWithState:state - objects:stackbuf - count:len]; - return result; -} - -@end - -@implementation GTLRDataObject - -@synthesize data = _data, - contentType = _contentType; - -- (NSString *)description { - NSString *jsonDesc = @""; - if (self.JSON.count > 0) { - jsonDesc = [self JSONDescription]; - } - return [NSString stringWithFormat:@"%@ %p: %tu bytes, contentType:%@ %@", - [self class], self, self.data.length, self.contentType, jsonDesc]; -} - -- (id)copyWithZone:(NSZone *)zone { - GTLRDataObject *newObj = [super copyWithZone:zone]; - newObj.data = [self.data copy]; - newObj.contentType = self.contentType; - return newObj; -} - -@end - -@implementation GTLRResultArray - -- (NSArray *)itemsWithItemClass:(Class)itemClass { - // Return the cached array before creating on demand. - NSString *cacheKey = @"result_array_items"; - NSMutableArray *cachedArray = [self cacheChildForKey:cacheKey]; - if (cachedArray != nil) { - return cachedArray; - } - NSArray *result = nil; - NSArray *array = (NSArray *)self.JSON; - if (array != nil) { - if ([array isKindOfClass:[NSArray class]]) { - id<GTLRObjectClassResolver>objectClassResolver = self.objectClassResolver; - result = [GTLRRuntimeCommon objectFromJSON:array - defaultClass:itemClass - objectClassResolver:objectClassResolver - isCacheable:NULL]; - } else { -#if DEBUG - if (![array isKindOfClass:[NSNull class]]) { - GTLR_DEBUG_LOG(@"GTLRObject: unexpected JSON: %@ should be an array, actually is a %@:\n%@", - NSStringFromClass([self class]), - NSStringFromClass([array class]), - array); - } -#endif - result = array; - } - } - - [self setCacheChild:result forKey:cacheKey]; - return result; -} - -- (NSString *)JSONDescription { - // Just like GTLRObject's handing of arrays, just return the count. - return [NSString stringWithFormat:@"[%tu]", self.JSON.count]; -} - -@end - -Class GTLRObjectResolveClass( - id<GTLRObjectClassResolver>objectClassResolver, - NSDictionary *json, - Class defaultClass) { - Class result = [objectClassResolver classForJSON:json - defaultClass:defaultClass]; - if (result == Nil) { - result = defaultClass; - } - return result; -} - -@implementation GTLRObjectClassResolver { - NSDictionary<NSString *, Class> *_kindToClassMap; - NSDictionary<Class, Class> *_surrogates; -} - -+ (instancetype)resolverWithKindMap:(NSDictionary<NSString *, Class> *)kindStringToClassMap { - GTLRObjectClassResolver *result = [[self alloc] initWithKindMap:kindStringToClassMap - surrogates:nil]; - return result; -} - -+ (instancetype)resolverWithKindMap:(NSDictionary<NSString *, Class> *)kindStringToClassMap - surrogates:(NSDictionary<Class, Class> *)surrogates { - GTLRObjectClassResolver *result = [[self alloc] initWithKindMap:kindStringToClassMap - surrogates:surrogates]; - return result; -} - -- (instancetype)initWithKindMap:(NSDictionary<NSString *, Class> *)kindStringToClassMap - surrogates:(NSDictionary<Class, Class> *)surrogates { - self = [super init]; - if (self) { - _kindToClassMap = [kindStringToClassMap copy]; - _surrogates = [surrogates copy]; - } - return self; -} - -- (Class)classForJSON:(NSDictionary *)json - defaultClass:(Class)defaultClass { - Class result = defaultClass; - - // Apply kind map. - BOOL shouldUseKind = (result == Nil) || [result isKindValidForClassRegistry]; - if (shouldUseKind && [json isKindOfClass:[NSDictionary class]]) { - NSString *kind = [json valueForKey:@"kind"]; - if ([kind isKindOfClass:[NSString class]] && kind.length > 0) { - Class dynamicClass = [_kindToClassMap objectForKey:kind]; - if (dynamicClass) { - result = dynamicClass; - } - } - } - - // Apply surrogate map. - Class surrogate = [_surrogates objectForKey:result]; - if (surrogate) { - result = surrogate; - } - - return result; -} - -@end - -static NSMutableDictionary *DeepMutableCopyOfJSONDictionary(NSDictionary *initialJSON) { - if (!initialJSON) return nil; - - NSMutableDictionary *result; - CFPropertyListRef ref = CFPropertyListCreateDeepCopy(kCFAllocatorDefault, - (__bridge CFPropertyListRef)(initialJSON), - kCFPropertyListMutableContainers); - if (ref) { - result = CFBridgingRelease(ref); - } else { - // Failed to copy, probably due to a non-plist type such as NSNull. - // - // As a fallback, round-trip through NSJSONSerialization. - NSError *serializationError; - NSData *data = [NSJSONSerialization dataWithJSONObject:initialJSON - options:0 - error:&serializationError]; - if (!data) { - GTLR_DEBUG_ASSERT(0, @"Copy failed due to serialization: %@\nJSON: %@", - serializationError, initialJSON); - } else { - result = [NSJSONSerialization JSONObjectWithData:data - options:NSJSONReadingMutableContainers - error:&serializationError]; - GTLR_DEBUG_ASSERT(result != nil, @"Copy failed due to deserialization: %@\nJSON: %@", - serializationError, - [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); - } - } - return result; -} diff --git a/Pods/GoogleAPIClientForREST/Source/Objects/GTLRQuery.h b/Pods/GoogleAPIClientForREST/Source/Objects/GTLRQuery.h @@ -1,253 +0,0 @@ -/* Copyright (c) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// Query documentation: -// https://github.com/google/google-api-objectivec-client-for-rest/wiki#query-operations - -#import "GTLRObject.h" -#import "GTLRUploadParameters.h" - -NS_ASSUME_NONNULL_BEGIN - -@class GTLRServiceTicket; -@class GTLRServiceExecutionParameters; -@class GTLRQuery; - -/** - * This protocol is just to support passing of either a batch or a single query - * to a GTLRService instance. The library does not expect or support client app - * implementations of this protocol. - */ -@protocol GTLRQueryProtocol <NSObject, NSCopying> - -/** - * Service ticket values may be set in the execution parameters for an individual query - * prior to executing the query. - */ -@property(atomic, strong, null_resettable) GTLRServiceExecutionParameters *executionParameters; - -- (BOOL)isBatchQuery; -- (BOOL)hasExecutionParameters; -- (BOOL)shouldSkipAuthorization; -- (void)invalidateQuery; -- (nullable NSDictionary<NSString *, NSString *> *)additionalHTTPHeaders; -- (nullable NSDictionary<NSString *, NSString *> *)additionalURLQueryParameters; -- (nullable NSString *)loggingName; -- (nullable GTLRUploadParameters *)uploadParameters; - -@end - -@protocol GTLRQueryCollectionProtocol -@optional -@property(nonatomic, strong) NSString *pageToken; -@end - -/** - * A block called when a query completes executing. - * - * Errors passed to the completionBlock will have an "underlying" GTLRErrorObject - * when the server returned an error for this specific query: - * - * GTLRErrorObject *errorObj = [GTLRErrorObject underlyingObjectForError:callbackError]; - * if (errorObj) { - * // The server returned this error for this specific query. - * } else { - * // The query execution fetch failed. - * } - * - * @param callbackTicket The ticket that tracked query execution. - * @param object The result of query execution. This will be derived from - * GTLRObject. - * @param callbackError If non-nil, the query execution failed. - */ -typedef void (^GTLRQueryCompletionBlock)(GTLRServiceTicket *callbackTicket, - id _Nullable object, - NSError * _Nullable callbackError); - -/** - * Class for a single query. - */ -@interface GTLRQuery : NSObject <GTLRQueryProtocol, NSCopying> - -/** - * The object to be uploaded with the query. The JSON of this object becomes - * the body for PUT and POST requests. - */ -@property(atomic, strong, nullable) GTLRObject *bodyObject; - -/** - * Each query must have a request ID string. The client app may replace the - * default assigned request ID with a custom string, provided that if - * used in a batch query, all request IDs in the batch must be unique. - */ -@property(atomic, copy) NSString *requestID; - -/** - * For queries which support file upload, the MIME type and file URL - * or data must be provided. - */ -@property(atomic, copy, nullable) GTLRUploadParameters *uploadParameters; - -/** - * Any additional URL query parameters for this query. - * - * These query parameters override the same keys from the service object's - * additionalURLQueryParameters - */ -@property(atomic, copy, nullable) NSDictionary<NSString *, NSString *> *additionalURLQueryParameters; - -/** - * Any additional HTTP headers for this query. - * - * These headers override the same keys from the service object's additionalHTTPHeaders - */ -@property(atomic, copy, nullable) NSDictionary<NSString *, NSString *> *additionalHTTPHeaders; - -/** - * If set, when the query is executed, an @c "alt" query parameter is added - * with this value and the raw result of the query is returned in a - * GTLRDataObject. This is useful when the server documents result datatypes - * other than JSON ("csv", for example). - */ -@property(atomic, copy) NSString *downloadAsDataObjectType; - -/** - * If set, and the query also has a non-empty @c downloadAsDataObjectType, the - * URL to download from will be modified to include "download/". This extra path - * component avoids the need for a server redirect to the download URL. - */ -@property(atomic, assign) BOOL useMediaDownloadService; - -/** - * Clients may set this to YES to disallow authorization. Defaults to NO. - */ -@property(atomic, assign) BOOL shouldSkipAuthorization; - -/** - * An optional callback block to be called immediately before the executeQuery: completion handler. - * - * The completionBlock property is particularly useful for queries executed in a batch. - */ -@property(atomic, copy, nullable) GTLRQueryCompletionBlock completionBlock; - -/** - * The brief string to identify this query in GTMSessionFetcher http logs. - * - * A default logging name is set by the code generator, but may be overridden by the client app. - */ -@property(atomic, copy, nullable) NSString *loggingName; - -#pragma mark Internal -///////////////////////////////////////////////////////////////////////////////////////////// -// -// Properties below are used by the library and aren't typically needed by client apps. -// -///////////////////////////////////////////////////////////////////////////////////////////// - -/** - * The URITemplate path segment. This is initialized in by the service generator. - */ -@property(atomic, readonly) NSString *pathURITemplate; - -/** - * The HTTP method to use for this query. This is initialized in by the service generator. - */ -@property(atomic, readonly, nullable) NSString *httpMethod; - -/** - * The parameters names that are in the URI Template. - * This is initialized in by the service generator. - * - * The service generator collects these via the discovery info instead of having to parse the - * template to figure out what is part of the path. - */ -@property(atomic, readonly, nullable) NSArray<NSString *> *pathParameterNames; - -/** - * The JSON dictionary of all the parameters set on this query. - * - * The JSON values are set by setting the query's properties. - */ -@property(nonatomic, strong, nullable) NSMutableDictionary<NSString *, id> *JSON; - -/** - * A custom URI template for resumable uploads. This is initialized by the service generator - * if needed. - */ -@property(atomic, copy, nullable) NSString *resumableUploadPathURITemplateOverride; - -/** - * A custom URI template for simple and multipart media uploads. This is initialized - * by the service generator. - */ -@property(atomic, copy, nullable) NSString *simpleUploadPathURITemplateOverride; - -/** - * The GTLRObject subclass expected for results. This is initialized by the service generator. - * - * This is needed if the object returned by the server lacks a known "kind" string. - */ -@property(atomic, assign, nullable) Class expectedObjectClass; - -/** - * Set when the query has been invalidated, meaning it was slated for execution so it's been copied - * and its callbacks were released, or it's a copy that has finished executing. - * - * Once a query has been invalidated, it cannot be executed, added to a batch, or copied. - */ -@property(atomic, assign, getter=isQueryInvalid) BOOL queryInvalid; - -/** - * Internal query init method. - * - * @param pathURITemplate URI template to be filled in with parameters. - * @param httpMethod The requests's http method. A nil method will execute as GET. - * @param pathParameterNames Names of parameters to be replaced in the template. - */ -- (instancetype)initWithPathURITemplate:(NSString *)pathURITemplate - HTTPMethod:(nullable NSString *)httpMethod - pathParameterNames:(nullable NSArray<NSString *> *)pathParameterNames NS_DESIGNATED_INITIALIZER; - -/** - * @return Auto-generated request ID string. - */ -+ (NSString *)nextRequestID; - -/** - * Overridden by subclasses. - * - * @return Substitute parameter names where needed for Objective-C or library compatibility. - */ -+ (nullable NSDictionary<NSString *, NSString *> *)parameterNameMap; - -/** - * Overridden by subclasses. - * - * @return Map of property keys to specifying the class of objects to be instantiated in arrays. - */ -+ (nullable NSDictionary<NSString *, Class> *)arrayPropertyToClassMap; - -- (instancetype)init NS_UNAVAILABLE; - -@end - -/** - * The library doesn't use GTLRQueryCollectionImpl, but it provides a concrete implementation - * of the protocol so the methods do not cause private method errors in Xcode/AppStore review. - */ -@interface GTLRQueryCollectionImpl : GTLRQuery <GTLRQueryCollectionProtocol> -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleAPIClientForREST/Source/Objects/GTLRQuery.m b/Pods/GoogleAPIClientForREST/Source/Objects/GTLRQuery.m @@ -1,313 +0,0 @@ -/* Copyright (c) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if !__has_feature(objc_arc) -#error "This file needs to be compiled with ARC enabled." -#endif - -#include <objc/runtime.h> - -#import "GTLRQuery.h" -#import "GTLRRuntimeCommon.h" -#import "GTLRService.h" -#import "GTLRUtilities.h" - -@interface GTLRQuery () <GTLRRuntimeCommon> -@end - -@implementation GTLRQuery { - NSMutableDictionary *_childCache; - GTLRServiceExecutionParameters *_executionParameters; -} - -@synthesize additionalURLQueryParameters = _additionalURLQueryParameters, - additionalHTTPHeaders = _additionalHTTPHeaders, - bodyObject = _bodyObject, - completionBlock = _completionBlock, - downloadAsDataObjectType = _downloadAsDataObjectType, - expectedObjectClass = _expectedObjectClass, - httpMethod = _httpMethod, - JSON = _json, - loggingName = _loggingName, - pathParameterNames = _pathParameterNames, - pathURITemplate = _pathURITemplate, - queryInvalid = _queryInvalid, - requestID = _requestID, - resumableUploadPathURITemplateOverride = _resumableUploadPathURITemplateOverride, - shouldSkipAuthorization = _shouldSkipAuthorization, - simpleUploadPathURITemplateOverride = _simpleUploadPathURITemplateOverride, - uploadParameters = _uploadParameters, - useMediaDownloadService = _useMediaDownloadService; - -#if DEBUG -- (instancetype)init { - [self doesNotRecognizeSelector:_cmd]; - self = nil; - return self; -} -#endif - -- (instancetype)initWithPathURITemplate:(NSString *)pathURITemplate - HTTPMethod:(nullable NSString *)httpMethod - pathParameterNames:(nullable NSArray<NSString *> *)pathParameterNames { - self = [super init]; - if (self) { - _requestID = [[self class] nextRequestID]; - - _pathURITemplate = [pathURITemplate copy]; - _httpMethod = [httpMethod copy]; - _pathParameterNames = [pathParameterNames copy]; - - if (_pathURITemplate.length == 0) { - self = nil; - } - } - return self; -} - -- (id)copyWithZone:(NSZone *)zone { - GTLR_DEBUG_ASSERT(!self.queryInvalid, @"Cannot copy an executed query: %@", self); - - GTLRQuery *query = - [[[self class] allocWithZone:zone] initWithPathURITemplate:self.pathURITemplate - HTTPMethod:self.httpMethod - pathParameterNames:self.pathParameterNames]; - - if (_json.count > 0) { - // Deep copy the parameters - CFPropertyListRef ref = CFPropertyListCreateDeepCopy(kCFAllocatorDefault, - (__bridge CFPropertyListRef)(_json), - kCFPropertyListMutableContainers); - query.JSON = CFBridgingRelease(ref); - } - - // Using the executionParameters ivar avoids creating the object. - query.executionParameters = self.executionParameters; - - // Copied in the same order as synthesized above. - query.additionalHTTPHeaders = self.additionalHTTPHeaders; - query.additionalURLQueryParameters = self.additionalURLQueryParameters; - query.bodyObject = self.bodyObject; - query.completionBlock = self.completionBlock; - query.downloadAsDataObjectType = self.downloadAsDataObjectType; - query.expectedObjectClass = self.expectedObjectClass; - // http method passed to init above. - // JSON copied above. - query.loggingName = self.loggingName; - // pathParameterNames passed to init above. - // pathURITemplate passed to init above. - query.queryInvalid = self.queryInvalid; - query.requestID = self.requestID; - query.resumableUploadPathURITemplateOverride = self.resumableUploadPathURITemplateOverride; - query.shouldSkipAuthorization = self.shouldSkipAuthorization; - query.simpleUploadPathURITemplateOverride = self.simpleUploadPathURITemplateOverride; - query.uploadParameters = self.uploadParameters; - query.useMediaDownloadService = self.useMediaDownloadService; - - return query; -} - -#if DEBUG -- (NSString *)description { - NSArray *keys = self.JSON.allKeys; - NSArray *params = [keys sortedArrayUsingSelector:@selector(compare:)]; - NSString *paramsSummary = @""; - if (params.count > 0) { - paramsSummary = [NSString stringWithFormat:@" params:(%@)", - [params componentsJoinedByString:@","]]; - } - - NSString *invalidStr = @""; - if (self.queryInvalid) { - invalidStr = @" [callbacks released]"; - } - - keys = self.additionalURLQueryParameters.allKeys; - NSArray *urlQParams = [keys sortedArrayUsingSelector:@selector(compare:)]; - NSString *urlQParamsSummary = @""; - if (urlQParams.count > 0) { - urlQParamsSummary = [NSString stringWithFormat:@" urlQParams:(%@)", - [urlQParams componentsJoinedByString:@","]]; - } - - GTLRObject *bodyObj = self.bodyObject; - NSString *bodyObjSummary = @""; - if (bodyObj != nil) { - bodyObjSummary = [NSString stringWithFormat:@" bodyObject:%@", [bodyObj class]]; - } - - NSString *uploadStr = @""; - GTLRUploadParameters *uploadParams = self.uploadParameters; - if (uploadParams) { - uploadStr = [NSString stringWithFormat:@" %@", uploadParams]; - } - - NSString *httpMethod = self.httpMethod; - if (httpMethod == nil) { - httpMethod = @"GET"; - } - - NSString *dataObjectType = self.downloadAsDataObjectType; - NSString *downloadStr = @""; - if (dataObjectType.length > 0) { - downloadStr = - [NSString stringWithFormat:@" downloadDataAs:%@", dataObjectType]; - } - - return [NSString stringWithFormat:@"%@ %p:%@%@ {%@ pathTemplate:%@%@%@%@%@}", - [self class], self, invalidStr, downloadStr, - httpMethod, self.pathURITemplate, - paramsSummary, urlQParamsSummary, bodyObjSummary, uploadStr]; -} -#endif // DEBUG - -- (BOOL)isBatchQuery { - return NO; -} - -- (void)invalidateQuery { - self.queryInvalid = YES; - self.completionBlock = nil; - self.executionParameters = nil; -} - -- (GTLRServiceExecutionParameters *)executionParameters { - @synchronized(self) { - if (!_executionParameters) { - _executionParameters = [[GTLRServiceExecutionParameters alloc] init]; - } - return _executionParameters; - } -} - -- (void)setExecutionParameters:(nullable GTLRServiceExecutionParameters *)executionParameters { - @synchronized(self) { - _executionParameters = executionParameters; - } -} - -- (BOOL)hasExecutionParameters { - return self.executionParameters.hasParameters; -} - -+ (NSString *)nextRequestID { - static NSUInteger lastRequestID = 0; - NSString *result; - - @synchronized([GTLRQuery class]) { - ++lastRequestID; - result = [NSString stringWithFormat:@"gtlr_%tu", lastRequestID]; - } - return result; -} - -#pragma mark GTLRRuntimeCommon Support - -- (void)setJSONValue:(id)obj forKey:(NSString *)key { - NSMutableDictionary *dict = self.JSON; - if (dict == nil && obj != nil) { - dict = [NSMutableDictionary dictionaryWithCapacity:1]; - self.JSON = dict; - } - [dict setValue:obj forKey:key]; -} - -- (id)JSONValueForKey:(NSString *)key { - id obj = [self.JSON objectForKey:key]; - return obj; -} - -// There is no property for _childCache as there shouldn't be KVC/KVO -// support for it, since it's an implementation detail. - -- (void)setCacheChild:(id)obj forKey:(NSString *)key { - if (_childCache == nil && obj != nil) { - _childCache = [[NSMutableDictionary alloc] initWithObjectsAndKeys:obj, key, nil]; - } else { - [_childCache setValue:obj forKey:key]; - } -} - -- (id)cacheChildForKey:(NSString *)key { - id obj = [_childCache objectForKey:key]; - return obj; -} - -#pragma mark Methods for Subclasses to Override - -+ (NSDictionary<NSString *, NSString *> *)parameterNameMap { - return nil; -} - -+ (NSDictionary<NSString *, Class> *)arrayPropertyToClassMap { - return nil; -} - -#pragma mark Runtime Utilities - -static NSMutableDictionary *gQueryParameterNameMapCache = nil; -static NSMutableDictionary *gQueryArrayPropertyToClassMapCache = nil; - -+ (void)initialize { - // Note that +initialize is guaranteed by the runtime to be called in a thread-safe manner. - if (gQueryParameterNameMapCache == nil) { - gQueryParameterNameMapCache = [[NSMutableDictionary alloc] init]; - } - if (gQueryArrayPropertyToClassMapCache == nil) { - gQueryArrayPropertyToClassMapCache = [[NSMutableDictionary alloc] init]; - } -} - -+ (NSDictionary *)propertyToJSONKeyMapForClass:(Class<GTLRRuntimeCommon>)aClass { - NSDictionary *resultMap = - [GTLRRuntimeCommon mergedClassDictionaryForSelector:@selector(parameterNameMap) - startClass:aClass - ancestorClass:[GTLRQuery class] - cache:gQueryParameterNameMapCache]; - return resultMap; -} - -+ (NSDictionary *)arrayPropertyToClassMapForClass:(Class<GTLRRuntimeCommon>)aClass { - NSDictionary *resultMap = - [GTLRRuntimeCommon mergedClassDictionaryForSelector:@selector(arrayPropertyToClassMap) - startClass:aClass - ancestorClass:[GTLRQuery class] - cache:gQueryArrayPropertyToClassMapCache]; - return resultMap; -} - -#pragma mark Runtime Support - -- (id<GTLRObjectClassResolver>)objectClassResolver { - // Stub method just needed for RuntimeCommon. - return nil; -} - -+ (Class<GTLRRuntimeCommon>)ancestorClass { - return [GTLRQuery class]; -} - -+ (BOOL)resolveInstanceMethod:(SEL)sel { - BOOL resolved = [GTLRRuntimeCommon resolveInstanceMethod:sel onClass:self]; - if (resolved) return YES; - - return [super resolveInstanceMethod:sel]; -} - -@end - -@implementation GTLRQueryCollectionImpl -@dynamic pageToken; -@end diff --git a/Pods/GoogleAPIClientForREST/Source/Objects/GTLRRuntimeCommon.h b/Pods/GoogleAPIClientForREST/Source/Objects/GTLRRuntimeCommon.h @@ -1,73 +0,0 @@ -/* Copyright (c) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -#import "GTLRDefines.h" - -@protocol GTLRObjectClassResolver; - -NS_ASSUME_NONNULL_BEGIN - -// This protocol and support class are an internal implementation detail so -// GTLRObject and GTLRQuery can share some code. - -/** - * An internal protocol for the GTLR library. - * - * None of these methods should be used by client apps. - */ -@protocol GTLRRuntimeCommon <NSObject> -@required -// Get/Set properties -- (void)setJSONValue:(nullable id)obj forKey:(NSString *)key; -- (id)JSONValueForKey:(NSString *)key; -// Child cache -- (void)setCacheChild:(nullable id)obj forKey:(NSString *)key; -- (nullable id)cacheChildForKey:(NSString *)key; -// Object mapper. -- (nullable id<GTLRObjectClassResolver>)objectClassResolver; -// Key map -+ (nullable NSDictionary<NSString *, NSString *> *)propertyToJSONKeyMapForClass:(Class<GTLRRuntimeCommon>)aClass; -// Array item types -+ (nullable NSDictionary<NSString *, Class> *)arrayPropertyToClassMapForClass:(Class<GTLRRuntimeCommon>)aClass; -// The parent class for dynamic support -+ (nullable Class<GTLRRuntimeCommon>)ancestorClass; -@end - -/** - * An internal class for the GTLR library. - * - * None of these methods should be used by client apps. - */ -@interface GTLRRuntimeCommon : NSObject -// Wire things up. -+ (BOOL)resolveInstanceMethod:(SEL)sel onClass:(Class)onClass; -// Helpers -+ (nullable id)objectFromJSON:(id)json - defaultClass:(nullable Class)defaultClass - objectClassResolver:(id<GTLRObjectClassResolver>)objectClassResolver - isCacheable:(nullable BOOL *)isCacheable; -+ (nullable id)jsonFromAPIObject:(id)obj - expectedClass:(nullable Class)expectedClass - isCacheable:(nullable BOOL *)isCacheable; -// Walk up the class tree merging dictionaries and return the result. -+ (NSDictionary *)mergedClassDictionaryForSelector:(SEL)selector - startClass:(Class)startClass - ancestorClass:(Class)ancestorClass - cache:(NSMutableDictionary *)cache; -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleAPIClientForREST/Source/Objects/GTLRRuntimeCommon.m b/Pods/GoogleAPIClientForREST/Source/Objects/GTLRRuntimeCommon.m @@ -1,1060 +0,0 @@ -/* Copyright (c) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if !__has_feature(objc_arc) -#error "This file needs to be compiled with ARC enabled." -#endif - -#include <objc/runtime.h> -#include <TargetConditionals.h> - -#import "GTLRRuntimeCommon.h" - -#import "GTLRDateTime.h" -#import "GTLRDuration.h" -#import "GTLRObject.h" -#import "GTLRUtilities.h" - -// Note: NSObject's class is used as a marker for the expected/default class -// when Discovery says it can be any type of object. - -@implementation GTLRRuntimeCommon - -// Helper to generically convert JSON to an api object type. -+ (id)objectFromJSON:(id)json - defaultClass:(Class)defaultClass - objectClassResolver:(id<GTLRObjectClassResolver>)objectClassResolver - isCacheable:(BOOL*)isCacheable { - id result = nil; - BOOL canBeCached = YES; - - // TODO(TVL): use defaultClass to validate things like expectedClass is - // done in jsonFromAPIObject:expectedClass:isCacheable:? - - if ([json isKindOfClass:[NSDictionary class]]) { - // If no default, or the default was any object, then default to base - // object here (and hope there is a kind to get the right thing). - if ((defaultClass == Nil) || [defaultClass isEqual:[NSObject class]]) { - defaultClass = [GTLRObject class]; - } - result = [GTLRObject objectForJSON:json - defaultClass:defaultClass - objectClassResolver:objectClassResolver]; - } else if ([json isKindOfClass:[NSArray class]]) { - NSArray *jsonArray = json; - // make an object for each JSON dictionary in the array - NSMutableArray *resultArray = [NSMutableArray arrayWithCapacity:jsonArray.count]; - for (id jsonItem in jsonArray) { - id item = [self objectFromJSON:jsonItem - defaultClass:defaultClass - objectClassResolver:objectClassResolver - isCacheable:NULL]; - [resultArray addObject:item]; - } - result = resultArray; - } else if ([json isKindOfClass:[NSString class]]) { - // DateTimes and Durations live in JSON as strings, so convert. - if ([defaultClass isEqual:[GTLRDateTime class]]) { - result = [GTLRDateTime dateTimeWithRFC3339String:json]; - } else if ([defaultClass isEqual:[GTLRDuration class]]) { - result = [GTLRDuration durationWithJSONString:json]; - } else if ([defaultClass isEqual:[NSNumber class]]) { - result = GTLR_EnsureNSNumber(json); - canBeCached = NO; - } else { - result = json; - canBeCached = NO; - } - } else if ([json isKindOfClass:[NSNumber class]] || - [json isKindOfClass:[NSNull class]]) { - result = json; - canBeCached = NO; - } else { - GTLR_DEBUG_LOG(@"GTLRRuntimeCommon: unsupported class '%s' in objectFromJSON", - class_getName([json class])); - } - - if (isCacheable) { - *isCacheable = canBeCached; - } - return result; -} - -// Helper to generically convert an api object type to JSON. -// |expectedClass| is the type that was expected for |obj|. -+ (id)jsonFromAPIObject:(id)obj - expectedClass:(Class)expectedClass - isCacheable:(BOOL *)isCacheable { - id result = nil; - BOOL canBeCached = YES; - BOOL checkExpected = (expectedClass != Nil); - - if ([obj isKindOfClass:[NSString class]]) { - result = [obj copy]; - canBeCached = NO; - } else if ([obj isKindOfClass:[NSNumber class]] || - [obj isKindOfClass:[NSNull class]]) { - result = obj; - canBeCached = NO; - } else if ([obj isKindOfClass:[GTLRObject class]]) { - result = [(GTLRObject *)obj JSON]; - if (result == nil) { - // adding an empty object; it should have a JSON dictionary so it can - // hold future assignments - [(GTLRObject *)obj setJSON:[NSMutableDictionary dictionary]]; - result = [(GTLRObject *)obj JSON]; - } - } else if ([obj isKindOfClass:[NSArray class]]) { - checkExpected = NO; - NSArray *array = obj; - // get the JSON for each thing in the array - NSMutableArray *resultArray = [NSMutableArray arrayWithCapacity:array.count]; - for (id item in array) { - id itemJSON = [self jsonFromAPIObject:item - expectedClass:expectedClass - isCacheable:NULL]; - [resultArray addObject:itemJSON]; - } - result = resultArray; - } else if ([obj isKindOfClass:[GTLRDateTime class]]) { - // DateTimes live in JSON as strings, so convert. - GTLRDateTime *dateTime = obj; - result = dateTime.RFC3339String; - } else if ([obj isKindOfClass:[GTLRDuration class]]) { - // Durations live in JSON as strings, so convert. - GTLRDuration *duration = obj; - result = duration.jsonString; - } else { - checkExpected = NO; - if (obj) { - GTLR_DEBUG_LOG(@"GTLRRuntimeCommon: unsupported class '%s' in jsonFromAPIObject", - class_getName([obj class])); - } - } - - if (checkExpected) { - // If the default was any object, then clear it to skip validation checks. - if ([expectedClass isEqual:[NSObject class]] || - [obj isKindOfClass:[NSNull class]]) { - expectedClass = nil; - } - if (expectedClass && ![obj isKindOfClass:expectedClass]) { - GTLR_DEBUG_LOG(@"GTLRRuntimeCommon: jsonFromAPIObject expected class '%s' instead got '%s'", - class_getName(expectedClass), class_getName([obj class])); - } - } - - if (isCacheable) { - *isCacheable = canBeCached; - } - return result; -} - -+ (NSDictionary *)mergedClassDictionaryForSelector:(SEL)selector - startClass:(Class)startClass - ancestorClass:(Class)ancestorClass - cache:(NSMutableDictionary *)cache { - NSDictionary *result; - @synchronized(cache) { - result = [cache objectForKey:startClass]; - if (result == nil) { - // Collect the class's dictionary. -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warc-performSelector-leaks" - NSDictionary *classDict = [startClass performSelector:selector]; -#pragma clang diagnostic pop - - // Collect the parent class's merged dictionary. - NSDictionary *parentClassMergedDict; - if ([startClass isEqual:ancestorClass]) { - parentClassMergedDict = nil; - } else { - Class parentClass = class_getSuperclass(startClass); - parentClassMergedDict = - [self mergedClassDictionaryForSelector:selector - startClass:parentClass - ancestorClass:ancestorClass - cache:cache]; - } - - // Merge this class's into the parent's so things properly override. - NSMutableDictionary *mergeDict; - if (parentClassMergedDict != nil) { - mergeDict = - [NSMutableDictionary dictionaryWithDictionary:parentClassMergedDict]; - } else { - mergeDict = [NSMutableDictionary dictionary]; - } - if (classDict != nil) { - [mergeDict addEntriesFromDictionary:classDict]; - } - - // Make an immutable version. - result = [NSDictionary dictionaryWithDictionary:mergeDict]; - - // Save it. - [cache setObject:result forKey:(id<NSCopying>)startClass]; - } - } - return result; -} - -#pragma mark Runtime lookup support - -static objc_property_t PropertyForSel(Class<GTLRRuntimeCommon> startClass, - SEL sel, BOOL isSetter, - Class<GTLRRuntimeCommon> *outFoundClass) { - const char *selName = sel_getName(sel); - const char *baseName = selName; - size_t baseNameLen = strlen(baseName); - if (isSetter) { - baseName += 3; // skip "set" - baseNameLen -= 4; // subtract "set" and the final colon - } - - // walk from this class up the hierarchy to the ancestor class - Class<GTLRRuntimeCommon> topClass = class_getSuperclass([startClass ancestorClass]); - for (Class currClass = startClass; - currClass != topClass; - currClass = class_getSuperclass(currClass)) { - // step through this class's properties - objc_property_t foundProp = NULL; - objc_property_t *properties = class_copyPropertyList(currClass, NULL); - if (properties) { - for (objc_property_t *prop = properties; *prop != NULL; ++prop) { - const char *propAttrs = property_getAttributes(*prop); - const char *dynamicMarker = strstr(propAttrs, ",D"); - if (!dynamicMarker || - (dynamicMarker[2] != 0 && dynamicMarker[2] != ',' )) { - // It isn't dynamic, skip it. - continue; - } - - if (!isSetter) { - // See if this property has an explicit getter=. (the attributes always start with a T, - // so we can check for the leading ','. - const char *getterMarker = strstr(propAttrs, ",G"); - if (getterMarker) { - const char *getterStart = getterMarker + 2; - const char *getterEnd = getterStart; - while ((*getterEnd != 0) && (*getterEnd != ',')) { - ++getterEnd; - } - size_t getterLen = (size_t)(getterEnd - getterStart); - if ((strncmp(selName, getterStart, getterLen) == 0) - && (selName[getterLen] == 0)) { - // return the actual property - foundProp = *prop; - // if requested, return the class containing the property - if (outFoundClass) *outFoundClass = currClass; - break; - } - } // if (getterMarker) - } // if (!isSetter) - - // Search for an exact-name match (a getter), but case-insensitive on the - // first character (in case baseName comes from a setter) - const char *propName = property_getName(*prop); - size_t propNameLen = strlen(propName); - if (baseNameLen == propNameLen - && strncasecmp(baseName, propName, 1) == 0 - && (baseNameLen <= 1 - || strncmp(baseName + 1, propName + 1, baseNameLen - 1) == 0)) { - // return the actual property - foundProp = *prop; - - // if requested, return the class containing the property - if (outFoundClass) *outFoundClass = currClass; - break; - } - } // for (prop in properties) - free(properties); - } - if (foundProp) return foundProp; - } - - // not found; this occasionally happens when the system looks for a method - // like "getFoo" or "descriptionWithLocale:indent:" - return NULL; -} - -typedef NS_ENUM(NSUInteger, GTLRPropertyType) { -#if !defined(__LP64__) || !__LP64__ - // These two only needed in 32bit builds since NSInteger in 64bit ends up in the LongLong paths. - GTLRPropertyTypeInt32 = 1, - GTLRPropertyTypeUInt32, -#endif - GTLRPropertyTypeLongLong = 3, - GTLRPropertyTypeULongLong, - GTLRPropertyTypeFloat, - GTLRPropertyTypeDouble, - GTLRPropertyTypeBool, - GTLRPropertyTypeNSString, - GTLRPropertyTypeNSNumber, - GTLRPropertyTypeGTLRDateTime, - GTLRPropertyTypeGTLRDuration, - GTLRPropertyTypeNSArray, - GTLRPropertyTypeNSObject, - GTLRPropertyTypeGTLRObject, -}; - -typedef struct { - const char *attributePrefix; - - GTLRPropertyType propertyType; - const char *setterEncoding; - const char *getterEncoding; - - // These are the "fixed" return classes, but some properties will require - // looking up the return class instead (because it is a subclass of - // GTLRObject). - const char *returnClassName; - Class returnClass; - BOOL extractReturnClass; - -} GTLRDynamicImpInfo; - -static const GTLRDynamicImpInfo *DynamicImpInfoForProperty(objc_property_t prop, - Class *outReturnClass) { - - if (outReturnClass) *outReturnClass = nil; - - // dynamic method resolution: - // http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtDynamicResolution.html - // - // property runtimes: - // http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html - - // Get and parse the property attributes, which look something like - // T@"NSString",&,D,P - // Ti,D -- NSInteger on 32bit - // Tq,D -- NSInteger on 64bit, long long on 32bit & 64bit - // TB,D -- BOOL comes as bool on 64bit iOS - // Tc,D -- BOOL comes as char otherwise - // T@"NSString",D - // T@"GTLRLink",D - // T@"NSArray",D - - - static GTLRDynamicImpInfo kImplInfo[] = { -#if !defined(__LP64__) || !__LP64__ - { // NSInteger on 32bit - "Ti", - GTLRPropertyTypeInt32, - "v@:i", - "i@:", - nil, nil, - NO - }, - { // NSUInteger on 32bit - "TI", - GTLRPropertyTypeUInt32, - "v@:I", - "I@:", - nil, nil, - NO - }, -#endif - { // NSInteger on 64bit, long long on 32bit and 64bit. - "Tq", - GTLRPropertyTypeLongLong, - "v@:q", - "q@:", - nil, nil, - NO - }, - { // NSUInteger on 64bit, long long on 32bit and 64bit. - "TQ", - GTLRPropertyTypeULongLong, - "v@:Q", - "Q@:", - nil, nil, - NO - }, - { // float - "Tf", - GTLRPropertyTypeFloat, - "v@:f", - "f@:", - nil, nil, - NO - }, - { // double - "Td", - GTLRPropertyTypeDouble, - "v@:d", - "d@:", - nil, nil, - NO - }, -#if defined(OBJC_BOOL_IS_BOOL) && OBJC_BOOL_IS_BOOL - { // BOOL as bool - "TB", - GTLRPropertyTypeBool, - "v@:B", - "B@:", - nil, nil, - NO - }, -#elif defined(OBJC_BOOL_IS_CHAR) && OBJC_BOOL_IS_CHAR - { // BOOL as char - "Tc", - GTLRPropertyTypeBool, - "v@:c", - "c@:", - nil, nil, - NO - }, -#else - #error unknown definition for ObjC BOOL type -#endif - { // NSString - "T@\"NSString\"", - GTLRPropertyTypeNSString, - "v@:@", - "@@:", - "NSString", nil, - NO - }, - { // NSNumber - "T@\"NSNumber\"", - GTLRPropertyTypeNSNumber, - "v@:@", - "@@:", - "NSNumber", nil, - NO - }, - { // GTLRDateTime - "T@\"" GTLR_CLASSNAME_CSTR(GTLRDateTime) "\"", - GTLRPropertyTypeGTLRDateTime, - "v@:@", - "@@:", - GTLR_CLASSNAME_CSTR(GTLRDateTime), nil, - NO - }, - { // GTLRDuration - "T@\"" GTLR_CLASSNAME_CSTR(GTLRDuration) "\"", - GTLRPropertyTypeGTLRDuration, - "v@:@", - "@@:", - GTLR_CLASSNAME_CSTR(GTLRDuration), nil, - NO - }, - { // NSArray with type - "T@\"NSArray\"", - GTLRPropertyTypeNSArray, - "v@:@", - "@@:", - "NSArray", nil, - NO - }, - { // id (any of the objects above) - "T@,", - GTLRPropertyTypeNSObject, - "v@:@", - "@@:", - "NSObject", nil, - NO - }, - { // GTLRObject - Last, cause it's a special case and prefix is general - "T@\"", - GTLRPropertyTypeGTLRObject, - "v@:@", - "@@:", - nil, nil, - YES - }, - }; - - static BOOL hasLookedUpClasses = NO; - if (!hasLookedUpClasses) { - // Unfortunately, you can't put [NSString class] into the static structure, - // so this lookup has to be done at runtime. - hasLookedUpClasses = YES; - for (uint32_t idx = 0; idx < sizeof(kImplInfo)/sizeof(kImplInfo[0]); ++idx) { - if (kImplInfo[idx].returnClassName) { - kImplInfo[idx].returnClass = objc_getClass(kImplInfo[idx].returnClassName); - NSCAssert1(kImplInfo[idx].returnClass != nil, - @"GTLRRuntimeCommon: class lookup failed: %s", kImplInfo[idx].returnClassName); - } - } - } - - const char *attr = property_getAttributes(prop); - - const char *dynamicMarker = strstr(attr, ",D"); - if (!dynamicMarker || - (dynamicMarker[2] != 0 && dynamicMarker[2] != ',' )) { - GTLR_DEBUG_LOG(@"GTLRRuntimeCommon: property %s isn't dynamic, attributes %s", - property_getName(prop), attr ? attr : "(nil)"); - return NULL; - } - - const GTLRDynamicImpInfo *result = NULL; - - // Cycle over the list - - for (uint32_t idx = 0; idx < sizeof(kImplInfo)/sizeof(kImplInfo[0]); ++idx) { - const char *attributePrefix = kImplInfo[idx].attributePrefix; - if (strncmp(attr, attributePrefix, strlen(attributePrefix)) == 0) { - result = &kImplInfo[idx]; - if (outReturnClass) *outReturnClass = result->returnClass; - break; - } - } - - if (result == NULL) { - GTLR_DEBUG_LOG(@"GTLRRuntimeCommon: unexpected attributes %s for property %s", - attr ? attr : "(nil)", property_getName(prop)); - return NULL; - } - - if (result->extractReturnClass && outReturnClass) { - - // add a null at the next quotation mark - char *attrCopy = strdup(attr); - char *classNameStart = attrCopy + 3; - char *classNameEnd = strstr(classNameStart, "\""); - if (classNameEnd) { - *classNameEnd = '\0'; - - // Lookup the return class - *outReturnClass = objc_getClass(classNameStart); - if (*outReturnClass == nil) { - GTLR_DEBUG_LOG(@"GTLRRuntimeCommon: did not find class with name \"%s\" " - @"for property \"%s\" with attributes \"%s\"", - classNameStart, property_getName(prop), attr); - } - } else { - GTLR_DEBUG_LOG(@"GTLRRuntimeCommon: Failed to find end of class name for " - @"property \"%s\" with attributes \"%s\"", - property_getName(prop), attr); - } - free(attrCopy); - } - - return result; -} - -// Helper to get the IMP for wiring up the getters. -// NOTE: Every argument passed in should be safe to capture in a block. Avoid -// passing something like selName instead of sel, because nothing says that -// pointer will be valid when it is finally used when the method IMP is invoked -// some time later. -static IMP GTLRRuntimeGetterIMP(SEL sel, - GTLRPropertyType propertyType, - NSString *jsonKey, - Class containedClass, - Class returnClass) { - // Only used in DEBUG logging. -#pragma unused(sel) - - IMP resultIMP; - switch (propertyType) { - -#if !defined(__LP64__) || !__LP64__ - case GTLRPropertyTypeInt32: { - resultIMP = imp_implementationWithBlock(^(id obj) { - NSNumber *num = [obj JSONValueForKey:jsonKey]; - num = GTLR_EnsureNSNumber(num); - NSInteger result = num.integerValue; - return result; - }); - break; - } - - case GTLRPropertyTypeUInt32: { - resultIMP = imp_implementationWithBlock(^(id obj) { - NSNumber *num = [obj JSONValueForKey:jsonKey]; - num = GTLR_EnsureNSNumber(num); - NSUInteger result = num.unsignedIntegerValue; - return result; - }); - break; - } -#endif // __LP64__ - - case GTLRPropertyTypeLongLong: { - resultIMP = imp_implementationWithBlock(^(id obj) { - NSNumber *num = [obj JSONValueForKey:jsonKey]; - num = GTLR_EnsureNSNumber(num); - long long result = num.longLongValue; - return result; - }); - break; - } - - case GTLRPropertyTypeULongLong: { - resultIMP = imp_implementationWithBlock(^(id obj) { - NSNumber *num = [obj JSONValueForKey:jsonKey]; - num = GTLR_EnsureNSNumber(num); - unsigned long long result = num.unsignedLongLongValue; - return result; - }); - break; - } - - case GTLRPropertyTypeFloat: { - resultIMP = imp_implementationWithBlock(^(id obj) { - NSNumber *num = [obj JSONValueForKey:jsonKey]; - num = GTLR_EnsureNSNumber(num); - float result = num.floatValue; - return result; - }); - break; - } - - case GTLRPropertyTypeDouble: { - resultIMP = imp_implementationWithBlock(^(id obj) { - NSNumber *num = [obj JSONValueForKey:jsonKey]; - num = GTLR_EnsureNSNumber(num); - double result = num.doubleValue; - return result; - }); - break; - } - - case GTLRPropertyTypeBool: { - resultIMP = imp_implementationWithBlock(^(id obj) { - NSNumber *num = [obj JSONValueForKey:jsonKey]; - BOOL flag = num.boolValue; - return flag; - }); - break; - } - - case GTLRPropertyTypeNSString: { - resultIMP = imp_implementationWithBlock(^(id obj) { - NSString *str = [obj JSONValueForKey:jsonKey]; - return str; - }); - break; - } - - case GTLRPropertyTypeGTLRDateTime: { - resultIMP = imp_implementationWithBlock(^GTLRDateTime *(GTLRObject<GTLRRuntimeCommon> *obj) { - // Return the cached object before creating on demand. - GTLRDateTime *cachedDateTime = [obj cacheChildForKey:jsonKey]; - if (cachedDateTime != nil) { - return cachedDateTime; - } - NSString *str = [obj JSONValueForKey:jsonKey]; - id cacheValue, resultValue; - if (![str isKindOfClass:[NSNull class]]) { - GTLRDateTime *dateTime = [GTLRDateTime dateTimeWithRFC3339String:str]; - - cacheValue = dateTime; - resultValue = dateTime; - } else { - cacheValue = nil; - resultValue = [NSNull null]; - } - [obj setCacheChild:cacheValue forKey:jsonKey]; - return resultValue; - }); - break; - } - - case GTLRPropertyTypeGTLRDuration: { - resultIMP = imp_implementationWithBlock(^GTLRDuration *(GTLRObject<GTLRRuntimeCommon> *obj) { - // Return the cached object before creating on demand. - GTLRDuration *cachedDuration = [obj cacheChildForKey:jsonKey]; - if (cachedDuration != nil) { - return cachedDuration; - } - NSString *str = [obj JSONValueForKey:jsonKey]; - id cacheValue, resultValue; - if (![str isKindOfClass:[NSNull class]]) { - GTLRDuration *duration = [GTLRDuration durationWithJSONString:str]; - - cacheValue = duration; - resultValue = duration; - } else { - cacheValue = nil; - resultValue = [NSNull null]; - } - [obj setCacheChild:cacheValue forKey:jsonKey]; - return resultValue; - }); - break; - } - - case GTLRPropertyTypeNSNumber: { - resultIMP = imp_implementationWithBlock(^(id obj) { - NSNumber *num = [obj JSONValueForKey:jsonKey]; - num = GTLR_EnsureNSNumber(num); - return num; - }); - break; - } - - case GTLRPropertyTypeGTLRObject: { - // Default return class to GTLRObject if it wasn't found. - if (returnClass == Nil) { - returnClass = [GTLRObject class]; - } - resultIMP = imp_implementationWithBlock(^GTLRObject *(GTLRObject<GTLRRuntimeCommon> *obj) { - // Return the cached object before creating on demand. - GTLRObject *cachedObj = [obj cacheChildForKey:jsonKey]; - if (cachedObj != nil) { - return cachedObj; - } - NSMutableDictionary *dict = [obj JSONValueForKey:jsonKey]; - if ([dict isKindOfClass:[NSMutableDictionary class]]) { - id<GTLRObjectClassResolver>objectClassResolver = [obj objectClassResolver]; - GTLRObject *subObj = [GTLRObject objectForJSON:dict - defaultClass:returnClass - objectClassResolver:objectClassResolver]; - [obj setCacheChild:subObj forKey:jsonKey]; - return subObj; - } else if ([dict isKindOfClass:[NSNull class]]) { - [obj setCacheChild:nil forKey:jsonKey]; - return (GTLRObject*)[NSNull null]; - } else if (dict != nil) { - // unexpected; probably got a string -- let the caller figure it out - GTLR_DEBUG_LOG(@"GTLRObject: unexpected JSON: %@.%@ should be a dictionary, actually is a %@:\n%@", - NSStringFromClass([obj class]), - NSStringFromSelector(sel), - NSStringFromClass([dict class]), dict); - return (GTLRObject *)dict; - } - return nil; - }); - break; - } - - case GTLRPropertyTypeNSArray: { - resultIMP = imp_implementationWithBlock(^(GTLRObject<GTLRRuntimeCommon> *obj) { - // Return the cached array before creating on demand. - NSMutableArray *cachedArray = [obj cacheChildForKey:jsonKey]; - if (cachedArray != nil) { - return cachedArray; - } - NSMutableArray *result = nil; - NSArray *array = [obj JSONValueForKey:jsonKey]; - if (array != nil) { - if ([array isKindOfClass:[NSArray class]]) { - id<GTLRObjectClassResolver>objectClassResolver = [obj objectClassResolver]; - result = [GTLRRuntimeCommon objectFromJSON:array - defaultClass:containedClass - objectClassResolver:objectClassResolver - isCacheable:NULL]; - } else { -#if DEBUG - if (![array isKindOfClass:[NSNull class]]) { - GTLR_DEBUG_LOG(@"GTLRObject: unexpected JSON: %@.%@ should be an array, actually is a %@:\n%@", - NSStringFromClass([obj class]), - NSStringFromSelector(sel), - NSStringFromClass([array class]), array); - } -#endif - result = (NSMutableArray *)array; - } - } - [obj setCacheChild:result forKey:jsonKey]; - return result; - }); - break; - } - - case GTLRPropertyTypeNSObject: { - resultIMP = imp_implementationWithBlock(^id(GTLRObject<GTLRRuntimeCommon> *obj) { - // Return the cached object before creating on demand. - id cachedObj = [obj cacheChildForKey:jsonKey]; - if (cachedObj != nil) { - return cachedObj; - } - id jsonObj = [obj JSONValueForKey:jsonKey]; - if (jsonObj != nil) { - BOOL shouldCache = NO; - id<GTLRObjectClassResolver>objectClassResolver = [obj objectClassResolver]; - id result = [GTLRRuntimeCommon objectFromJSON:jsonObj - defaultClass:nil - objectClassResolver:objectClassResolver - isCacheable:&shouldCache]; - - [obj setCacheChild:(shouldCache ? result : nil) - forKey:jsonKey]; - return result; - } - return nil; - }); - break; - } - } // switch(propertyType) - - return resultIMP; -} - -// Helper to get the IMP for wiring up the setters. -// NOTE: Every argument passed in should be safe to capture in a block. Avoid -// passing something like selName instead of sel, because nothing says that -// pointer will be valid when it is finally used when the method IMP is invoked -// some time later. -static IMP GTLRRuntimeSetterIMP(SEL sel, - GTLRPropertyType propertyType, - NSString *jsonKey, - Class containedClass, - Class returnClass) { -#pragma unused(sel, returnClass) - IMP resultIMP; - switch (propertyType) { - -#if !defined(__LP64__) || !__LP64__ - case GTLRPropertyTypeInt32: { - resultIMP = imp_implementationWithBlock(^(id obj, NSInteger val) { - [obj setJSONValue:@(val) forKey:jsonKey]; - }); - break; - } - - case GTLRPropertyTypeUInt32: { - resultIMP = imp_implementationWithBlock(^(id obj, NSUInteger val) { - [obj setJSONValue:@(val) forKey:jsonKey]; - }); - break; - } -#endif // __LP64__ - - case GTLRPropertyTypeLongLong: { - resultIMP = imp_implementationWithBlock(^(id obj, long long val) { - [obj setJSONValue:@(val) forKey:jsonKey]; - }); - break; - } - - case GTLRPropertyTypeULongLong: { - resultIMP = imp_implementationWithBlock(^(id obj, - unsigned long long val) { - [obj setJSONValue:@(val) forKey:jsonKey]; - }); - break; - } - - case GTLRPropertyTypeFloat: { - resultIMP = imp_implementationWithBlock(^(id obj, float val) { - [obj setJSONValue:@(val) forKey:jsonKey]; - }); - break; - } - - case GTLRPropertyTypeDouble: { - resultIMP = imp_implementationWithBlock(^(id obj, double val) { - [obj setJSONValue:@(val) forKey:jsonKey]; - }); - break; - } - - case GTLRPropertyTypeBool: { - resultIMP = imp_implementationWithBlock(^(id obj, BOOL val) { - NSNumber *numValue = (NSNumber *)(val ? kCFBooleanTrue : kCFBooleanFalse); - [obj setJSONValue:numValue forKey:jsonKey]; - }); - break; - } - - case GTLRPropertyTypeNSString: { - resultIMP = imp_implementationWithBlock(^(id obj, NSString *val) { - NSString *copiedStr = [val copy]; - [obj setJSONValue:copiedStr forKey:jsonKey]; - }); - break; - } - - case GTLRPropertyTypeGTLRDateTime: { - resultIMP = imp_implementationWithBlock(^(GTLRObject<GTLRRuntimeCommon> *obj, - GTLRDateTime *val) { - id cacheValue, jsonValue; - if (![val isKindOfClass:[NSNull class]]) { - jsonValue = val.RFC3339String; - cacheValue = val; - } else { - jsonValue = [NSNull null]; - cacheValue = nil; - } - - [obj setJSONValue:jsonValue forKey:jsonKey]; - [obj setCacheChild:cacheValue forKey:jsonKey]; - }); - break; - } - - case GTLRPropertyTypeGTLRDuration: { - resultIMP = imp_implementationWithBlock(^(GTLRObject<GTLRRuntimeCommon> *obj, - GTLRDuration *val) { - id cacheValue, jsonValue; - if (![val isKindOfClass:[NSNull class]]) { - jsonValue = val.jsonString; - cacheValue = val; - } else { - jsonValue = [NSNull null]; - cacheValue = nil; - } - - [obj setJSONValue:jsonValue forKey:jsonKey]; - [obj setCacheChild:cacheValue forKey:jsonKey]; - }); - break; - } - - case GTLRPropertyTypeNSNumber: { - resultIMP = imp_implementationWithBlock(^(id obj, NSNumber *val) { - [obj setJSONValue:val forKey:jsonKey]; - }); - break; - } - - case GTLRPropertyTypeGTLRObject: { - resultIMP = imp_implementationWithBlock(^(GTLRObject<GTLRRuntimeCommon> *obj, - GTLRObject *val) { - id cacheValue, jsonValue; - if (![val isKindOfClass:[NSNull class]]) { - NSMutableDictionary *dict = [val JSON]; - if (dict == nil && val != nil) { - // adding an empty object; it should have a JSON dictionary so it - // can hold future assignments - val.JSON = [NSMutableDictionary dictionary]; - jsonValue = val.JSON; - } else { - jsonValue = dict; - } - cacheValue = val; - } else { - jsonValue = [NSNull null]; - cacheValue = nil; - } - [obj setJSONValue:jsonValue forKey:jsonKey]; - [obj setCacheChild:cacheValue forKey:jsonKey]; - }); - break; - } - - case GTLRPropertyTypeNSArray: { - resultIMP = imp_implementationWithBlock(^(GTLRObject<GTLRRuntimeCommon> *obj, - NSMutableArray *val) { - id json = [GTLRRuntimeCommon jsonFromAPIObject:val - expectedClass:containedClass - isCacheable:NULL]; - [obj setJSONValue:json forKey:jsonKey]; - [obj setCacheChild:val forKey:jsonKey]; - }); - break; - } - - case GTLRPropertyTypeNSObject: { - resultIMP = imp_implementationWithBlock(^(GTLRObject<GTLRRuntimeCommon> *obj, - id val) { - BOOL shouldCache = NO; - id json = [GTLRRuntimeCommon jsonFromAPIObject:val - expectedClass:Nil - isCacheable:&shouldCache]; - [obj setJSONValue:json forKey:jsonKey]; - [obj setCacheChild:(shouldCache ? val : nil) - forKey:jsonKey]; - }); - break; - } - } // switch(propertyType) - - return resultIMP; -} - -#pragma mark Runtime - wiring point - -+ (BOOL)resolveInstanceMethod:(SEL)sel onClass:(Class<GTLRRuntimeCommon>)onClass { - // dynamic method resolution: - // http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtDynamicResolution.html - // - // property runtimes: - // http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html - - const char *selName = sel_getName(sel); - size_t selNameLen = strlen(selName); - char lastChar = selName[selNameLen - 1]; - BOOL isSetter = (lastChar == ':'); - - // look for a declared property matching this selector name exactly - Class<GTLRRuntimeCommon> foundClass = nil; - - objc_property_t prop = PropertyForSel(onClass, sel, isSetter, &foundClass); - if (prop == NULL || foundClass == nil) { - return NO; // No luck, out of here. - } - - Class returnClass = nil; - const GTLRDynamicImpInfo *implInfo = DynamicImpInfoForProperty(prop, - &returnClass); - if (implInfo == NULL) { - GTLR_DEBUG_LOG(@"GTLRRuntimeCommon: unexpected return type class %s for " - @"property \"%s\" of class \"%s\"", - returnClass ? class_getName(returnClass) : "<nil>", - property_getName(prop), - class_getName(onClass)); - return NO; // Failed to find our impl info, out of here. - } - - const char *propName = property_getName(prop); - NSString *propStr = @(propName); - - // replace the property name with the proper JSON key if it's - // special-cased with a map in the found class; otherwise, the property - // name is the JSON key - // NOTE: These caches that are built up could likely be dropped and do this - // lookup on demand from the class tree. Most are checked once when a method - // is first resolved, so eventually become wasted memory. - NSDictionary *keyMap = - [[foundClass ancestorClass] propertyToJSONKeyMapForClass:foundClass]; - NSString *jsonKey = [keyMap objectForKey:propStr]; - if (jsonKey == nil) { - jsonKey = propStr; - } - - // For arrays we need to look up what the contained class is. - Class containedClass = nil; - if (implInfo->propertyType == GTLRPropertyTypeNSArray) { - NSDictionary *classMap = - [[foundClass ancestorClass] arrayPropertyToClassMapForClass:foundClass]; - containedClass = [classMap objectForKey:jsonKey]; - if (containedClass == Nil) { - GTLR_DEBUG_LOG(@"GTLRRuntimeCommon: expected array item class for " - @"property \"%s\" of class \"%s\"", - property_getName(prop), class_getName(foundClass)); - } - } - - // Wire in the method. - IMP imp; - const char *encoding; - if (isSetter) { - imp = GTLRRuntimeSetterIMP(sel, implInfo->propertyType, - jsonKey, containedClass, returnClass); - encoding = implInfo->setterEncoding; - } else { - imp = GTLRRuntimeGetterIMP(sel, implInfo->propertyType, - jsonKey, containedClass, returnClass); - encoding = implInfo->getterEncoding; - } - if (class_addMethod(foundClass, sel, imp, encoding)) { - return YES; - } - // Not much we can do if this fails, but leave a breadcumb in the log. - GTLR_DEBUG_LOG(@"GTLRRuntimeCommon: Failed to wire %@ on %@ (encoding: %s).", - NSStringFromSelector(sel), - NSStringFromClass(foundClass), - encoding); - return NO; -} - -@end diff --git a/Pods/GoogleAPIClientForREST/Source/Objects/GTLRService.h b/Pods/GoogleAPIClientForREST/Source/Objects/GTLRService.h @@ -1,879 +0,0 @@ -/* Copyright (c) 2016 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// Service object documentation: -// https://github.com/google/google-api-objectivec-client-for-rest/wiki#services-and-tickets - -#import <Foundation/Foundation.h> - -#import "GTLRDefines.h" -#import "GTLRBatchQuery.h" -#import "GTLRBatchResult.h" -#import "GTLRDateTime.h" -#import "GTLRDuration.h" -#import "GTLRErrorObject.h" -#import "GTLRObject.h" -#import "GTLRQuery.h" - -@class GTMSessionFetcher; -@class GTMSessionFetcherService; -@protocol GTMFetcherAuthorizationProtocol; - -NS_ASSUME_NONNULL_BEGIN - -/** - * The domain used used for NSErrors created by GTLRService query execution. - */ -extern NSString *const kGTLRServiceErrorDomain; - -typedef NS_ENUM(NSInteger, GTLRServiceError) { - GTLRServiceErrorQueryResultMissing = -3000, - GTLRServiceErrorBatchResponseUnexpected = -3001, - GTLRServiceErrorBatchResponseStatusCode = -3002 -}; - -/** - * The kGTLRServiceErrorDomain userInfo key for the server response body. - */ -extern NSString *const kGTLRServiceErrorBodyDataKey; - -/** - * The kGTLRServiceErrorDomain userInfo key for the response content ID, if appropriate. - */ -extern NSString *const kGTLRServiceErrorContentIDKey; - -/** - * The domain used for foundation errors created from GTLRErrorObjects that - * were not originally foundation errors. - */ -extern NSString *const kGTLRErrorObjectDomain; - -/** - * The userInfo key for a GTLRErrorObject for errors with domain kGTLRErrorObjectDomain - * when the error was created from a structured JSON error response body. - */ -extern NSString *const kGTLRStructuredErrorKey; - -/** - * A constant ETag for when updating or deleting a single entry, telling - * the server to replace the current value unconditionally. - * - * Do not use this in entries in a batch feed. - */ -extern NSString *const kGTLRETagWildcard; - -/** - * Notification of a ticket starting. The notification object is the ticket. - * This is posted on the main thread. - * - * Use the stopped notification to log all requests made by the library. - */ -extern NSString *const kGTLRServiceTicketStartedNotification; - -/** - * Notification of a ticket stopping. The notification object is the ticket. - * This is posted on the main thread. - */ -extern NSString *const kGTLRServiceTicketStoppedNotification; - -/** - * Notifications when parsing of a server response or entry begins. - * This is posted on the main thread. - */ -extern NSString *const kGTLRServiceTicketParsingStartedNotification; - -/** - * Notifications when parsing of a server response or entry ends. - * This is posted on the main thread. - */ -extern NSString *const kGTLRServiceTicketParsingStoppedNotification; - -/** - * The header name used to send an Application's Bundle Identifier. - * For more information on adding API restrictions see the docs: - * https://cloud.google.com/docs/authentication/api-keys#api_key_restrictions - */ -extern NSString *const kXIosBundleIdHeader; - -@class GTLRServiceTicket; - -/** - * Callback block for query execution. - * - * @param callbackTicket The ticket that tracked query execution. - * @param object The result of query execution. This will be derived from - * GTLRObject. The object may be nil for operations such as DELETE which - * do not return an object. The object will be a GTLRBatchResult for - * batch operations, and GTLRDataObject for media downloads. - * @param callbackError If non-nil, the query execution failed. For batch requests, - * this may be nil even if individual queries in the batch have failed. - */ -typedef void (^GTLRServiceCompletionHandler)(GTLRServiceTicket *callbackTicket, - id _Nullable object, - NSError * _Nullable callbackError); - -/** - * Callback block for upload of query data. - * - * @param progressTicket The ticket that tracks query execution. - * @param totalBytesUploaded Number of bytes uploaded so far. - * @param totalBytesExpectedToUpload Number of bytes expected to be uploaded. - */ -typedef void (^GTLRServiceUploadProgressBlock)(GTLRServiceTicket *progressTicket, - unsigned long long totalBytesUploaded, - unsigned long long totalBytesExpectedToUpload); - -/** - * Callback block invoked when an eror occurs during query execution. - * - * @param retryTicket The ticket that tracks query execution. - * @param suggestedWillRetry Flag indicating if the library would retry this without a retry block. - * @param fetchError The error that occurred. If the domain is - * kGTMSessionFetcherStatusDomain then the error's code is the server - * response status. Details on the error from the server are available - * in the userInfo via the keys kGTLRStructuredErrorKey and - * NSLocalizedDescriptionKey. - * - * @return YES if the request should be retried. - */ -typedef BOOL (^GTLRServiceRetryBlock)(GTLRServiceTicket *retryTicket, - BOOL suggestedWillRetry, - NSError * _Nullable fetchError); - -/** - * Block to be invoked by a test block. - * - * @param object The faked object, if any, to be passed to the test code's completion handler. - * @param error The faked error if any, to be passed to the test code's completion handler. - */ -typedef void (^GTLRServiceTestResponse)(id _Nullable object, NSError *_Nullable error); - -/** - * A test block enables testing of query execution without any network activity. - * - * The test block must finish by calling the response block, passing either an object - * (GTLRObject or GTLRBatchResult) or an NSError. - * - * The query is available to the test block code as testTicket.originalQuery. - * - * Because query execution is asynchronous, the test code must wait for a callback, - * either with GTLRService's waitForTicket:timeout:fetchedObject:error: or with - * XCTestCase's waitForExpectationsWithTimeout: - * - * Example usage is available in GTLRServiceTest. - * - * @param testTicket The ticket that tracks query execution. - * @param testResponse A block that must be invoked by the test block. This may be invoked - * synchronously or asynchornously. - */ -typedef void (^GTLRServiceTestBlock)(GTLRServiceTicket *testTicket, - GTLRServiceTestResponse testResponse); - -#pragma mark - - -/** - * Base class for the service that executes queries and manages tickets. - * - * Client apps will typically use a generated subclass of GTLRService. - */ -@interface GTLRService : NSObject - -#pragma mark Query Execution - -/** - * Executes the supplied query - * - * Success is indicated in the completion handler by a nil error parameter, not by a non-nil - * object parameter. - * - * The callback block is invoked exactly once unless the ticket is cancelled. - * The callback will be called on the service's callback queue. - * - * Various execution parameters will be taken from the service's properties, unless overridden - * in the query's @c executionParameters property. - * - * A query may only be executed a single time. To reuse a query, make a copy before executing - * it. - * - * To get a NSURLRequest that represents the query, use @c -[GTLRService requestForQuery:] - * - * @param query The API query, either a subclass of GTLRQuery, or a GTLRBatchQuery. - * @param handler The execution callback block. - * - * @return A ticket for tracking or canceling query execution. - */ -- (GTLRServiceTicket *)executeQuery:(id<GTLRQueryProtocol>)query - completionHandler:(nullable GTLRServiceCompletionHandler)handler; - -/** - * Executes the supplied query - * - * The callback is invoked exactly once unless the ticket is cancelled. - * The callback will be called on the service's callbackQueue. - * Various execution parameters will be taken from the service's properties, unless overridden - * in the query's @c executionParameters property. - * - * The selector should have a signature matching: - * @code - * - (void)serviceTicket:(GTLRServiceTicket *)callbackTicket - * finishedWithObject:(GTLRObject *)object - * error:(NSError *)callbackError - * @endcode - * - * @param query The API query, either a subclass of GTLRQuery, or a GTLRBatchQuery. - * @param delegate The object to be with the selector to be invoked upon completion. - * @param finishedSelector The selector to be invoked upon completion. - * - * @return A ticket for tracking or canceling query execution. - */ -- (GTLRServiceTicket *)executeQuery:(id<GTLRQueryProtocol>)query - delegate:(nullable id)delegate - didFinishSelector:(nullable SEL)finishedSelector; - - -/** - * Enable automatic pagination. - * - * A ticket can optionally do a sequence of fetches for queries where repeated requests - * with a @c nextPageToken query parameter is required to retrieve all pages of - * the response collection. The client's callback is invoked only when all items have - * been retrieved, or an error has occurred. - * - * The final object may be a combination of multiple page responses - * so it may not be the same as if all results had been returned in a single - * page. Some fields of the response may reflect only the final page's values. - * - * Automatic page fetches will return an error if more than 25 page fetches are - * required. For debug builds, this will log a warning to the console when more - * than 2 page fetches occur, as a reminder that the query's @c maxResults parameter - * should probably be increased to specify more items returned per page. - * - * Automatic page accumulation is available for query result objects that are derived - * from GTLRCollectionObject. - * - * This may also be specified for a single query in the query's @c executionParameters property. - * - * Default value is NO. - */ -@property(nonatomic, assign) BOOL shouldFetchNextPages; - -/** - * Some services require a developer key for quotas and limits. - * - * If you have enabled the iOS API Key Restriction, you will want - * to manually set the @c APIKeyRestrictionBundleID property, or - * use -setMainBundleIDRestrictionWithAPIKey: to set your API key - * and set the restriction to the main bundle's bundle id. - */ -@property(nonatomic, copy, nullable) NSString *APIKey; - -/** - * The Bundle Identifier to use for the API key restriction. This will be - * sent in an X-Ios-Bundle-Identifier header; for more information see - * the API key documentation - * https://cloud.google.com/docs/authentication/api-keys#api_key_restrictions - */ -@property(nonatomic, copy, nullable) NSString *APIKeyRestrictionBundleID; - -/** - * Helper method to set the @c APIKey to the given value and set the - * @c APIKeyRestrictionBundleID to the main bundle's bundle identifier. - */ -- (void)setMainBundleIDRestrictionWithAPIKey:(NSString *)apiKey; - -/** - * An authorizer adds user authentication headers to the request as needed. - * - * This may be overridden on individual queries with the @c shouldSkipAuthorization property. - */ -@property(nonatomic, retain, nullable) id <GTMFetcherAuthorizationProtocol> authorizer; - -/** - * Enable fetcher retry support. See the explanation of retry support in @c GTMSessionFetcher.h - * - * Default value is NO, but retry is also enabled if the retryBlock is not nil. - * - * This may also be specified for a single query in the query's @c executionParameters property. - */ -@property(nonatomic, assign, getter=isRetryEnabled) BOOL retryEnabled; - -/** - * A retry block may be provided to inspect and change retry criteria. - * - * This may also be specified for a single query in the query's @c executionParameters property. - */ -@property(atomic, copy, nullable) GTLRServiceRetryBlock retryBlock; - -/** - * The maximum retry interval. Retries occur at increasing intervals, up to the specified maximum. - * - * This may also be specified for a single query in the query's @c executionParameters property. - */ -@property(nonatomic, assign) NSTimeInterval maxRetryInterval; - -#pragma mark Fetch Object by Resource URL - -/** - * Fetch an object given the resource URL. This is appropriate when the object's - * full link is known, such as from a selfLink response property. - * - * @param resourceURL The URL of the object to be fetched. - * @param objectClass The GTLRObject subclass to be instantiated. If nil, the library - * will try to infer the class from the object's "kind" string property. - * @param executionParameters Values to override the service's properties when executing the - * ticket. - * @param handler The execution callback block. - * - * @return A ticket for tracking or canceling query execution. - */ -- (GTLRServiceTicket *)fetchObjectWithURL:(NSURL *)resourceURL - objectClass:(nullable Class)objectClass - executionParameters:(nullable GTLRServiceExecutionParameters *)executionParameters - completionHandler:(nullable GTLRServiceCompletionHandler)handler; - -#pragma mark Support for Client Tests - -/** - * A test block can be provided to test service calls without any network activity. - * - * See the description of @c GTLRServiceTestBlock for additional details. - * - * This may also be specified for a single query in the query's @c executionParameters property. - * - * A service instance for testing can also be created with @c +mockServiceWithFakedObject - */ -@property(nonatomic, copy, nullable) GTLRServiceTestBlock testBlock; - -#pragma mark Converting a Query to an NSURLRequest - -/** - * Creates a NSURLRequest from the query object and from properties on this service - * (additionalHTTPHeaders, additionalURLQueryParameters, APIKey) without executing - * it. This can be useful for using @c GTMSessionFetcher or @c NSURLSession to - * perform the fetch. - * - * For requests to non-public resources, the request will not yet be authorized; - * that can be done using the GTLR service's authorizer. Creating a @c GTMSessionFetcher - * from the GTLRService's @c fetcherService will take care of authorization as well. - * - * This works only for GET queries, and only for an individual query, not a batch query. - * - * @note @c Unlike executeQuery:, requestForQuery: does not release the query's callback blocks. - * - * @param query The query used to create the request. - * - * @return A request suitable for use with @c GTMSessionFetcher or @c NSURLSession - */ -- (NSMutableURLRequest *)requestForQuery:(GTLRQuery *)query; - -#pragma mark User Properties - -/** - * The service properties dictionary is copied to become the initial property dictionary - * for each ticket, augmented by a query's execution parameter's properties. - */ -@property(nonatomic, copy, nullable) NSDictionary<NSString *, id> *serviceProperties; - -#pragma mark JSON to GTLRObject Mapping - -/** - * Specifies subclasses to be created instead of standard library objects, allowing - * an app to add properties and methods to GTLR objects. - * - * This is just a helper method that sets the service's objectClassResolver:. - * - * Example: - * @code - * NSDictionary *surrogates = @{ - * [MyDriveFile class] : [GTLRDrive_File_Surrogate class], - * [MyDriveFileList class] : [GTLRDrive_FileList_Surrogate class] - * }; - * [service setSurrogates:surrogates]; - * @endcode - */ -- (void)setSurrogates:(NSDictionary <Class, Class>*)surrogates; - -/** - * Used to decide what GTLRObject subclass to make from the received JSON. - * - * This defaults to a resolver that will use any kindStringToClassMap the service - * provides. - * - * To use a standard resolver with a surrogates dictionary, invoke setSurrogates: instead - * of setting this property. - */ -@property(nonatomic, strong) id<GTLRObjectClassResolver> objectClassResolver; - -/** - * A dictionary mapping "kind" strings to the GTLObject subclasses that should - * be created for JSON with the given kind. - */ -+ (NSDictionary<NSString *, Class> *)kindStringToClassMap; - -#pragma mark Request Settings - -/** - * The queue used to invoked callbacks. By default, the main queue is used for callbacks. - */ -@property(nonatomic, retain) dispatch_queue_t callbackQueue; - -/** - * Allows the application to make non-SSL and localhost requests for testing. - * - * Default value is NO. - */ -@property(nonatomic, assign) BOOL allowInsecureQueries; - -/** - * The fetcher service creates the fetcher instances for this API service. - * - * Applications may set this to an authorized fetcher service created elsewhere - * in the app, or may take the fetcher service created by this GTLRService and use it - * to create fetchers independent of this service. - */ -@property(nonatomic, retain) GTMSessionFetcherService *fetcherService; - -#pragma mark Custom User Agents - -/** - * Applications needing an additional identifier in the server logs may specify one - * through this property and it will be added to the existing UserAgent. It should - * already be a valid identifier as no cleaning/validation is done. - */ -@property(nonatomic, copy, nullable) NSString *userAgentAddition; - -/** - * A base user-agent based on the application signature in the Info.plist settings. - * - * Most applications should not explicitly set this property. Any string provided will - * be cleaned of inappropriate characters. - */ -@property(nonatomic, copy, nullable) NSString *userAgent; - -/** - * The request user agent includes the library and OS version appended to the - * base userAgent, along with the optional addition string. - */ -@property(nonatomic, readonly, nullable) NSString *requestUserAgent; - -/** - * A precise base userAgent string identifying the application. No cleaning of characters - * is done. Library-specific details will be appended. - * - * @param userAgent A wire-ready user agent string. - */ -- (void)setExactUserAgent:(nullable NSString *)userAgent; - -/** - * A precise userAgent string to send on requests; no cleaning is done. When - * set, requestUserAgent will be exactly this, no library or system information - * will be auto added. - * - * @param requestUserAgent A wire-ready user agent string. - */ -- (void)overrideRequestUserAgent:(nullable NSString *)requestUserAgent; - -/** - * Any additional URL query parameters for the queries executed by this service. - * - * Individual queries may have additionalURLQueryParameters specified as well. - */ -@property(atomic, copy, nullable) NSDictionary<NSString *, NSString *> *additionalURLQueryParameters; - -/** - * Any additional HTTP headers for this queries executed by this service. - * - * Individual queries may have additionalHTTPHeaders specified as well. - */ -@property(atomic, copy, nullable) NSDictionary<NSString *, NSString *> *additionalHTTPHeaders; - -#pragma mark Request URL Construction - -/* - * The URL for where to send a Query is built out of these parts - * ( https://developers.google.com/discovery/v1/using#build-compose ) : - * - * service.rootURLString + service.servicePath + query.pathURITemplate - * - * Note: odds are these both should end in a '/', so make sure any value you - * provide will combine correctly with the above rules. - */ - -/** - * The scheme and host for the API server. This may be modified to point at a test server. - */ -@property(nonatomic, copy) NSString *rootURLString; - -/** - * The path for the specific API service instance, relative to the rootURLString. - */ -@property(nonatomic, copy) NSString *servicePath; - -/** - * A path fragment added in to URLs before "servicePath" to build - * the full URL used for resumable media uploads. - */ -@property(nonatomic, copy) NSString *resumableUploadPath; - -/** - * A path fragment added in to URLs before "servicePath" to build - * the full URL used for simple and multipart media uploads. - */ -@property(nonatomic, copy) NSString *simpleUploadPath; - -/** - * A path fragment added in to URLs before "servicePath" to build - * the full URL used for batch requests. - */ -@property(nonatomic, copy) NSString *batchPath; - -#pragma mark Resumable Uploads - -/** - * A block called to track upload progress. - * - * A query's service execution parameters may be used to override this. - */ -@property(nonatomic, copy, nullable) GTLRServiceUploadProgressBlock uploadProgressBlock; - -/** - * The default chunk size for resumable uploads. This defaults to kGTLRStandardUploadChunkSize - * for service subclasses that support chunked uploads. - */ -@property(nonatomic, assign) NSUInteger serviceUploadChunkSize; - -/** - * Service subclasses may override this to specify their own default chunk size for - * resumable uploads. - */ -+ (NSUInteger)defaultServiceUploadChunkSize; - -#pragma mark Internal -///////////////////////////////////////////////////////////////////////////////////////////// -// -// Properties below are used by the library and should not typically be set by client apps. -// -///////////////////////////////////////////////////////////////////////////////////////////// - -/** - * The queue used for parsing JSON responses. - * - * Applications should typically not change this. - */ -@property(nonatomic, retain) dispatch_queue_t parseQueue; - -/** - * If this service supports pretty printing the JSON on the wire, these are - * the names of the query params that enable it. If there are any values, - * the library disables pretty printing to save on bandwidth. - * - * Applications should typically not need change this; the ServiceGenerator - * will set this up when generating the custom subclass. - */ -@property(nonatomic, strong, nullable) NSArray<NSString *> *prettyPrintQueryParameterNames; - -/** - * This indicates if the API requires a "data" JSON element to wrap the payload - * on requests and responses. - * - * Applications should typically not change this. - */ -@property(nonatomic, assign, getter=isDataWrapperRequired) BOOL dataWrapperRequired; - -@end - -@interface GTLRService (TestingSupport) - -/** - * Convenience method to create a mock GTLR service just for testing. - * - * Queries executed by this mock service will not perform any network operation, - * but will invoke callbacks and provide the supplied object or error to the - * completion handler. - * - * You can make more customized mocks by setting the test block property of a service - * or a query's execution parameters. The test block can inspect the query as ticket.originalQuery - * to customize test behavior. - * - * See the description of @c GTLRServiceTestBlock for more details on customized testing. - * - * Example usage is in the unit test method @c testService_MockService_Succeeding - * - * @param object An object derived from GTLRObject to be passed to query completion handlers. - * @param error An error to be passed to query completion handlers. - * - * @return A mock instance of the service, suitable for unit testing. - */ -+ (instancetype)mockServiceWithFakedObject:(nullable id)object - fakedError:(nullable NSError *)error; - -/** - * Wait synchronously for fetch to complete (strongly discouraged) - * - * This method is intended for use only in unit tests and command-line tools. - * Unit tests may also use XCTest's waitForExpectationsWithTimeout: instead of - * or after this method. - * - * This method just runs the current event loop until the fetch completes - * or the timout limit is reached. This may discard unexpected events - * that occur while spinning, so it's really not appropriate for use - * in serious applications. - * - * Returns YES if an object was successfully fetched. If the wait - * timed out, returns NO and the returned error is nil. - * - * @param ticket The ticket being executed. - * @param timeoutInSeconds Maximum duration to wait. - * - * @return YES if the ticket completed or was cancelled; NO if the wait timed out. - */ -- (BOOL)waitForTicket:(GTLRServiceTicket *)ticket - timeout:(NSTimeInterval)timeoutInSeconds; - -@end - -#pragma mark - - -/** - * Service execution parameters may be set on an individual query - * to alter the service's settings. - */ -@interface GTLRServiceExecutionParameters : NSObject<NSCopying> - -/** - * Override the service's property @c shouldFetchNextPages for automatic pagination. - * - * A BOOL value should be specified. - */ -@property(atomic, strong, nullable) NSNumber *shouldFetchNextPages; - -/** - * Override the service's property @c shouldFetchNextPages for enabling automatic retries. - * - * A BOOL value should be specified. - * - * Retry is also enabled if the retryBlock is not nil - */ -@property(atomic, strong, nullable, getter=isRetryEnabled) NSNumber *retryEnabled; - -/** - * Override the service's property @c retryBlock for customizing automatic retries. - */ -@property(atomic, copy, nullable) GTLRServiceRetryBlock retryBlock; - -/** - * Override the service's property @c maxRetryInterval for customizing automatic retries. - * - * A NSTimeInterval (double) value should be specified. - */ -@property(atomic, strong, nullable) NSNumber *maxRetryInterval; - -/** - * Override the service's property @c uploadProgressBlock for monitoring upload progress. - */ -@property(atomic, copy, nullable) GTLRServiceUploadProgressBlock uploadProgressBlock; - -/** - * Override the service's property @c callbackQueue for invoking callbacks. - */ -@property(atomic, retain, nullable) dispatch_queue_t callbackQueue; - -/** - * Override the service's property @c testBlock for simulating query execution. - * - * See the description of @c GTLRServiceTestBlock for additional details. - */ -@property(atomic, copy, nullable) GTLRServiceTestBlock testBlock; - -/** - * Override the service's property @c objectClassResolver for controlling object class selection. - */ -@property(atomic, strong, nullable) id<GTLRObjectClassResolver> objectClassResolver; - -/** - * The ticket's properties are the service properties, with the execution parameter's - * ticketProperties added (replacing any keys already present from the service.) - */ -@property(atomic, copy, nullable) NSDictionary<NSString *, id> *ticketProperties; - -/** - * Indicates if any of the execution parameters properties are set. - */ -@property(nonatomic, readonly) BOOL hasParameters; - -@end - -/** - * A ticket tracks the progress of a query being executed. - */ -@interface GTLRServiceTicket : NSObject - -- (instancetype)init NS_UNAVAILABLE; - -/** - * The service that issued this ticket. - * - * This method may be invoked from any thread. - */ -@property(atomic, readonly) GTLRService *service; - -#pragma mark Execution Control - -/** - * Invoking cancelTicket stops the fetch if it is in progress. The query callbacks - * will not be invoked. - * - * This method may be invoked from any thread. - */ -- (void)cancelTicket; - -/** - * The time the ticket was created. - */ -@property(atomic, readonly) NSDate *creationDate; - -/** - * Pause the ticket execution. This is valid only for chunked, resumable upload queries. - */ -- (void)pauseUpload; - -/** - * Resume the ticket execution. This is valid only for chunked, resumable upload queries. - */ -- (void)resumeUpload; - -/** - * Checks if the ticket execution is paused. - */ -@property(nonatomic, readonly, getter=isUploadPaused) BOOL uploadPaused; - -/** - * The request being fetched for the query. - */ -@property(nonatomic, readonly, nullable) NSURLRequest *fetchRequest; - -/** - * The fetcher being used for the query request. - */ -@property(atomic, readonly, nullable) GTMSessionFetcher *objectFetcher; - -/** - * The queue used for query callbacks. - */ -@property(atomic, readonly) dispatch_queue_t callbackQueue; - -/** - * The API key used for the query requeat. - */ -@property(atomic, readonly, nullable) NSString *APIKey; - -/** - * The Bundle Identifier to use for the API key restriciton. - */ -@property(atomic, readonly, nullable) NSString *APIKeyRestrictionBundleID; - -#pragma mark Status - -/** - * The server's response status for the query's fetch, if available. - */ -@property(nonatomic, readonly) NSInteger statusCode; - -/** - * The error resulting from the query's fetch, if available. - */ -@property(nonatomic, readonly, nullable) NSError *fetchError; - -/** - * A flag indicating if the query's callbacks have been invoked. - */ -@property(nonatomic, readonly) BOOL hasCalledCallback; - -/** - * A flag indicating if the query execution was cancelled by the client app. - */ -@property(atomic, readonly, getter=isCancelled) BOOL cancelled; - -#pragma mark Pagination - -/** - * A flag indicating if automatic pagination is enabled for the query. - */ -@property(nonatomic, readonly) BOOL shouldFetchNextPages; - -/** - * The number of pages fetched, if automatic pagination is enabled for the query and multiple - * pages have been fetched. - */ -@property(nonatomic, readonly) NSUInteger pagesFetchedCounter; - -#pragma mark User Properties - -/** - * Ticket properties a way to pass values via the ticket for the convenience of the client app. - * - * Ticket properties are initialized from serviceProperties and augmented by the ticketProperties - * of the query's execution parameters. - */ -@property(nonatomic, readonly, nullable) NSDictionary<NSString *, id> *ticketProperties; - -#pragma mark Payload - -/** - * The object being uploaded via POST, PUT, or PATCH. - */ -@property(nonatomic, readonly, nullable) GTLRObject *postedObject; - -/** - * The object downloaded for the query, after parsing. - */ -@property(nonatomic, readonly, nullable) GTLRObject *fetchedObject; - -/** - * The query currently being fetched by this ticket. This may not be the original query when - * fetching a second or later pages. - */ -@property(atomic, readonly, nullable) id<GTLRQueryProtocol> executingQuery; - -/** - * The query used to create this ticket - */ -@property(atomic, readonly, nullable) id<GTLRQueryProtocol> originalQuery; - -/** - * The @c GTLRObjectClassResolver for controlling object class selection. - */ -@property(atomic, readonly, strong) id<GTLRObjectClassResolver> objectClassResolver; - -/** - * The query from within the ticket's batch request with the given ID. - * - * @param requestID The desired ticket's request ID. - * - * @return The query with the specified ID, if found. - */ -- (nullable GTLRQuery *)queryForRequestID:(NSString *)requestID; - -@end - -/** - * The library doesn't use GTLRObjectCollectionImpl, but it provides a concrete implementation - * so the methods do not cause private method errors in Xcode/AppStore review. - */ -@interface GTLRObjectCollectionImpl : GTLRObject -@property(nonatomic, copy) NSString *nextPageToken; -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleAPIClientForREST/Source/Objects/GTLRService.m b/Pods/GoogleAPIClientForREST/Source/Objects/GTLRService.m @@ -1,2883 +0,0 @@ -/* Copyright (c) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if !__has_feature(objc_arc) -#error "This file needs to be compiled with ARC enabled." -#endif - -#import <TargetConditionals.h> - -#if TARGET_OS_IPHONE -#import <UIKit/UIKit.h> -#endif - -#if !defined(GTLR_USE_FRAMEWORK_IMPORTS) - #if defined(COCOAPODS) && COCOAPODS - #define GTLR_USE_FRAMEWORK_IMPORTS 1 - #else - #define GTLR_USE_FRAMEWORK_IMPORTS 0 - #endif -#endif - -#import "GTLRService.h" - -#import "GTLRFramework.h" -#import "GTLRURITemplate.h" -#import "GTLRUtilities.h" - -#if GTLR_USE_FRAMEWORK_IMPORTS - #import <GTMSessionFetcher/GTMSessionFetcher.h> - #import <GTMSessionFetcher/GTMSessionFetcherService.h> - #import <GTMSessionFetcher/GTMMIMEDocument.h> -#else - #import "GTMSessionFetcher.h" - #import "GTMSessionFetcherService.h" - #import "GTMMIMEDocument.h" -#endif // GTLR_USE_FRAMEWORK_IMPORTS - - -#ifndef STRIP_GTM_FETCH_LOGGING - #error GTMSessionFetcher headers should have defaulted this if it wasn't already defined. -#endif - -NSString *const kGTLRServiceErrorDomain = @"com.google.GTLRServiceDomain"; -NSString *const kGTLRErrorObjectDomain = @"com.google.GTLRErrorObjectDomain"; -NSString *const kGTLRServiceErrorBodyDataKey = @"body"; -NSString *const kGTLRServiceErrorContentIDKey = @"contentID"; -NSString *const kGTLRStructuredErrorKey = @"GTLRStructuredError"; -NSString *const kGTLRETagWildcard = @"*"; - -NSString *const kGTLRServiceTicketStartedNotification = @"kGTLRServiceTicketStartedNotification"; -NSString *const kGTLRServiceTicketStoppedNotification = @"kGTLRServiceTicketStoppedNotification"; -NSString *const kGTLRServiceTicketParsingStartedNotification = @"kGTLRServiceTicketParsingStartedNotification"; -NSString *const kGTLRServiceTicketParsingStoppedNotification = @"kGTLRServiceTicketParsingStoppedNotification"; - -NSString *const kXIosBundleIdHeader = @"X-Ios-Bundle-Identifier"; - -static NSString *const kDeveloperAPIQueryParamKey = @"key"; - -static const NSUInteger kMaxNumberOfNextPagesFetched = 25; - -static const NSUInteger kMaxGETURLLength = 2048; - -// we'll enforce 50K chunks minimum just to avoid the server getting hit -// with too many small upload chunks -static const NSUInteger kMinimumUploadChunkSize = 50000; - -// Helper to get the ETag if it is defined on an object. -static NSString *ETagIfPresent(GTLRObject *obj) { - NSString *result = [obj.JSON objectForKey:@"etag"]; - return result; -} - -// Merge two dictionaries. Either may be nil. -// If both are nil, return nil. -// In case of a key collision, values of the second dictionary prevail. -static NSDictionary *MergeDictionaries(NSDictionary *recessiveDict, NSDictionary *dominantDict) { - if (!dominantDict) return recessiveDict; - if (!recessiveDict) return dominantDict; - - NSMutableDictionary *worker = [recessiveDict mutableCopy]; - [worker addEntriesFromDictionary:dominantDict]; - return worker; -} - -@interface GTLRServiceTicket () - -- (instancetype)initWithService:(GTLRService *)service - executionParameters:(GTLRServiceExecutionParameters *)params NS_DESIGNATED_INITIALIZER; - -// Thread safety: ticket properties are all publicly exposed as read-only. -// -// Service execution of a ticket is serial (started by the app, then executing on the fetcher -// callback queue and then the parse queue), so we don't need to worry about synchronization. -// -// One important exception is when the user invoked cancelTicket. During cancellation, ticket -// properties are released. This should be harmless even during the fetch start-parse-callback -// phase because nothing released in cancelTicket is used to begin a fetch, and the cancellation -// flag will prevent any application callbacks from being invoked. -// -// The cancel and objectFetcher properties are synchronized on the ticket. - -// Ticket properties exposed publicly as readonly. -@property(atomic, readwrite, nullable) id<GTLRQueryProtocol> originalQuery; -@property(atomic, readwrite, nullable) id<GTLRQueryProtocol> executingQuery; -@property(atomic, readwrite, nullable) GTMSessionFetcher *objectFetcher; -@property(nonatomic, readwrite, nullable) NSURLRequest *fetchRequest; -@property(nonatomic, readwrite, nullable) GTLRObject *postedObject; -@property(nonatomic, readwrite, nullable) GTLRObject *fetchedObject; -@property(nonatomic, readwrite, nullable) NSError *fetchError; -@property(nonatomic, readwrite) BOOL hasCalledCallback; -@property(nonatomic, readwrite) NSUInteger pagesFetchedCounter; -@property(readwrite, atomic, strong) id<GTLRObjectClassResolver> objectClassResolver; - -// Internal properties copied from the service. -@property(nonatomic, assign) BOOL allowInsecureQueries; -@property(nonatomic, strong) GTMSessionFetcherService *fetcherService; -@property(nonatomic, strong, nullable) id<GTMFetcherAuthorizationProtocol> authorizer; - -// Internal properties copied from serviceExecutionParameters. -@property(nonatomic, getter=isRetryEnabled) BOOL retryEnabled; -@property(nonatomic, readwrite) NSTimeInterval maxRetryInterval; -@property(nonatomic, strong, nullable) GTLRServiceRetryBlock retryBlock; -@property(nonatomic, strong, nullable) GTLRServiceUploadProgressBlock uploadProgressBlock; -@property(nonatomic, strong, nullable) GTLRServiceTestBlock testBlock; -@property(nonatomic, readwrite) BOOL shouldFetchNextPages; - -// Internal properties used by the service. -#if GTM_BACKGROUND_TASK_FETCHING -// Access to backgroundTaskIdentifier should be protected by @synchronized(self). -@property(nonatomic, assign) UIBackgroundTaskIdentifier backgroundTaskIdentifier; -#endif // GTM_BACKGROUND_TASK_FETCHING - -// Dispatch group enabling waitForTicket: to delay until async callbacks and notifications -// related to the ticket have completed. -@property(nonatomic, readonly) dispatch_group_t callbackGroup; - -// startBackgroundTask and endBackgroundTask do nothing if !GTM_BACKGROUND_TASK_FETCHING -- (void)startBackgroundTask; -- (void)endBackgroundTask; - -- (void)notifyStarting:(BOOL)isStarting; -- (void)releaseTicketCallbacks; - -// Posts a notification on the main queue using the ticket's dispatch group. -- (void)postNotificationOnMainThreadWithName:(NSString *)name - object:(id)object - userInfo:(NSDictionary *)userInfo; -@end - -#if !defined(GTLR_HAS_SESSION_UPLOAD_FETCHER_IMPORT) - #if defined(COCOAPODS) && COCOAPODS - #define GTLR_HAS_SESSION_UPLOAD_FETCHER_IMPORT 1 - #else - #define GTLR_HAS_SESSION_UPLOAD_FETCHER_IMPORT 0 - #endif -#endif - -#if GTLR_HAS_SESSION_UPLOAD_FETCHER_IMPORT - #if GTLR_USE_FRAMEWORK_IMPORTS - #import <GTMSessionFetcher/GTMSessionUploadFetcher.h> - #else - #import "GTMSessionUploadFetcher.h" - #endif // GTLR_USE_FRAMEWORK_IMPORTS -#else -// If the upload fetcher class is available, it can be used for chunked uploads -// -// We locally declare some methods of the upload fetcher so we -// do not need to import the header, as some projects may not have it available -@interface GTMSessionUploadFetcher : GTMSessionFetcher - -+ (instancetype)uploadFetcherWithRequest:(NSURLRequest *)request - uploadMIMEType:(NSString *)uploadMIMEType - chunkSize:(int64_t)chunkSize - fetcherService:(GTM_NULLABLE GTMSessionFetcherService *)fetcherServiceOrNil; - -+ (instancetype)uploadFetcherWithLocation:(NSURL *)uploadLocationURL - uploadMIMEType:(NSString *)uploadMIMEType - chunkSize:(int64_t)chunkSize - fetcherService:(GTM_NULLABLE GTMSessionFetcherService *)fetcherServiceOrNil; - -@property(strong) NSURL *uploadLocationURL; -@property(strong) NSData *uploadData; -@property(strong) NSURL *uploadFileURL; -@property(strong) NSFileHandle *uploadFileHandle; - -- (void)pauseFetching; -- (void)resumeFetching; -- (BOOL)isPaused; -@end -#endif // GTLR_HAS_SESSION_UPLOAD_FETCHER_IMPORT - - -@interface GTLRObject (StandardProperties) -// Common properties on GTLRObject that are invoked below. -@property(nonatomic, copy) NSString *nextPageToken; -@end - -// This class encapsulates the pieces of a single batch response, including -// inner http response code and message, inner headers, JSON body (parsed as a dictionary), -// or parsing NSError. -// -// See responsePartsWithMIMEParts: for an example of the wire format data used -// to populate this object. -@interface GTLRBatchResponsePart : NSObject -@property(nonatomic, copy) NSString *contentID; -@property(nonatomic, assign) NSInteger statusCode; -@property(nonatomic, copy) NSString *statusString; -@property(nonatomic, strong) NSDictionary *headers; -@property(nonatomic, strong) NSDictionary *JSON; -@property(nonatomic, strong) NSError *parseError; -@end - -@implementation GTLRBatchResponsePart -@synthesize contentID = _contentID, - headers = _headers, - JSON = _JSON, - parseError = _parseError, - statusCode = _statusCode, - statusString = _statusString; -#if DEBUG -- (NSString *)description { - return [NSString stringWithFormat:@"%@ %p: %@\n%ld %@\nheaders:%@\nJSON:%@\nerror:%@", - [self class], self, self.contentID, (long)self.statusCode, self.statusString, - self.headers, self.JSON, self.parseError]; -} -#endif -@end - -// GTLRResourceURLQuery is an internal class used as a query object placeholder -// when fetchObjectWithURL: is invoked by the client app. This lets the service's -// plumbing treat the request like other queries, without allowing users to -// set arbitrary query properties that may not work as anticipated. -@interface GTLRResourceURLQuery : GTLRQuery - -@property(nonatomic, strong, nullable) NSURL *resourceURL; - -+ (instancetype)queryWithResourceURL:(NSURL *)resourceURL - objectClass:(nullable Class)objectClass; - -@end - -@implementation GTLRService { - NSString *_userAgent; - NSString *_overrideUserAgent; - NSDictionary *_serviceProperties; // Properties retained for the convenience of the client app. - NSUInteger _uploadChunkSize; // Only applies to resumable chunked uploads. -} - -@synthesize additionalHTTPHeaders = _additionalHTTPHeaders, - additionalURLQueryParameters = _additionalURLQueryParameters, - allowInsecureQueries = _allowInsecureQueries, - callbackQueue = _callbackQueue, - APIKey = _apiKey, - APIKeyRestrictionBundleID = _apiKeyRestrictionBundleID, - batchPath = _batchPath, - dataWrapperRequired = _dataWrapperRequired, - fetcherService = _fetcherService, - maxRetryInterval = _maxRetryInterval, - parseQueue = _parseQueue, - prettyPrintQueryParameterNames = _prettyPrintQueryParameterNames, - resumableUploadPath = _resumableUploadPath, - retryBlock = _retryBlock, - retryEnabled = _retryEnabled, - rootURLString = _rootURLString, - servicePath = _servicePath, - shouldFetchNextPages = _shouldFetchNextPages, - simpleUploadPath = _simpleUploadPath, - objectClassResolver = _objectClassResolver, - testBlock = _testBlock, - uploadProgressBlock = _uploadProgressBlock, - userAgentAddition = _userAgentAddition; - -+ (Class)ticketClass { - return [GTLRServiceTicket class]; -} - -- (instancetype)init { - self = [super init]; - if (self) { - _parseQueue = dispatch_queue_create("com.google.GTLRServiceParse", DISPATCH_QUEUE_SERIAL); - _callbackQueue = dispatch_get_main_queue(); - _fetcherService = [[GTMSessionFetcherService alloc] init]; - - // Make the session fetcher use a background delegate queue instead of bouncing - // through the main queue for its callbacks from NSURLSession. This should improve - // performance, and eventually be the default behavior for the fetcher. - NSOperationQueue *delegateQueue = [[NSOperationQueue alloc] init]; - delegateQueue.maxConcurrentOperationCount = 1; - delegateQueue.name = @"com.google.GTLRServiceFetcherDelegate"; - _fetcherService.sessionDelegateQueue = delegateQueue; - - NSDictionary<NSString *, Class> *kindMap = [[self class] kindStringToClassMap]; - _objectClassResolver = [GTLRObjectClassResolver resolverWithKindMap:kindMap]; - } - return self; -} - -- (NSString *)requestUserAgent { - if (_overrideUserAgent != nil) { - return _overrideUserAgent; - } - - NSString *userAgent = self.userAgent; - if (userAgent.length == 0) { - // The service instance is missing an explicit user-agent; use the bundle ID - // or process name. Don't use the bundle ID of the library's framework. - NSBundle *owningBundle = [NSBundle bundleForClass:[self class]]; - if (owningBundle == nil - || [owningBundle.bundleIdentifier isEqual:@"com.google.GTLR"]) { - owningBundle = [NSBundle mainBundle]; - } - userAgent = GTMFetcherApplicationIdentifier(owningBundle); - } - - NSString *requestUserAgent = userAgent; - - // if the user agent already specifies the library version, we'll - // use it verbatim in the request - NSString *libraryString = @"google-api-objc-client"; - NSRange libRange = [userAgent rangeOfString:libraryString - options:NSCaseInsensitiveSearch]; - if (libRange.location == NSNotFound) { - // the user agent doesn't specify the client library, so append that - // information, and the system version - NSString *libVersionString = GTLRFrameworkVersionString(); - - NSString *systemString = GTMFetcherSystemVersionString(); - - // We don't clean this with GTMCleanedUserAgentString so spaces are - // preserved - NSString *userAgentAddition = self.userAgentAddition; - NSString *customString = userAgentAddition ? - [@" " stringByAppendingString:userAgentAddition] : @""; - - // Google servers look for gzip in the user agent before sending gzip- - // encoded responses. See Service.java - requestUserAgent = [NSString stringWithFormat:@"%@ %@/%@ %@%@ (gzip)", - userAgent, libraryString, libVersionString, systemString, customString]; - } - return requestUserAgent; -} - -- (void)setMainBundleIDRestrictionWithAPIKey:(NSString *)apiKey { - self.APIKey = apiKey; - self.APIKeyRestrictionBundleID = [[NSBundle mainBundle] bundleIdentifier]; -} - -- (NSMutableURLRequest *)requestForURL:(NSURL *)url - ETag:(NSString *)etag - httpMethod:(NSString *)httpMethod - ticket:(GTLRServiceTicket *)ticket { - - // subclasses may add headers to this - NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url - cachePolicy:NSURLRequestReloadIgnoringCacheData - timeoutInterval:60]; - NSString *requestUserAgent = self.requestUserAgent; - [request setValue:requestUserAgent forHTTPHeaderField:@"User-Agent"]; - - if (httpMethod.length > 0) { - [request setHTTPMethod:httpMethod]; - } - - if (etag.length > 0) { - - // it's rather unexpected for an etagged object to be provided for a GET, - // but we'll check for an etag anyway, similar to HttpGDataRequest.java, - // and if present use it to request only an unchanged resource - - BOOL isDoingHTTPGet = (httpMethod == nil - || [httpMethod caseInsensitiveCompare:@"GET"] == NSOrderedSame); - - if (isDoingHTTPGet) { - - // set the etag header, even if weak, indicating we don't want - // another copy of the resource if it's the same as the object - [request setValue:etag forHTTPHeaderField:@"If-None-Match"]; - - } else { - - // if we're doing PUT or DELETE, set the etag header indicating - // we only want to update the resource if our copy matches the current - // one (unless the etag is weak and so shouldn't be a constraint at all) - BOOL isWeakETag = [etag hasPrefix:@"W/"]; - - BOOL isModifying = - [httpMethod caseInsensitiveCompare:@"PUT"] == NSOrderedSame - || [httpMethod caseInsensitiveCompare:@"DELETE"] == NSOrderedSame - || [httpMethod caseInsensitiveCompare:@"PATCH"] == NSOrderedSame; - - if (isModifying && !isWeakETag) { - [request setValue:etag forHTTPHeaderField:@"If-Match"]; - } - } - } - - return request; -} - -// objectRequestForURL returns an NSMutableURLRequest for a GTLRObject -// -// the object is the object being sent to the server, or nil; -// the http method may be nil for get, or POST, PUT, DELETE - -- (NSMutableURLRequest *)objectRequestForURL:(NSURL *)url - object:(GTLRObject *)object - contentType:(NSString *)contentType - contentLength:(NSString *)contentLength - ETag:(NSString *)etag - httpMethod:(NSString *)httpMethod - additionalHeaders:(NSDictionary *)additionalHeaders - ticket:(GTLRServiceTicket *)ticket { - if (object) { - // if the object being sent has an etag, add it to the request header to - // avoid retrieving a duplicate or to avoid writing over an updated - // version of the resource on the server - // - // Typically, delete requests will provide an explicit ETag parameter, and - // other requests will have the ETag carried inside the object being updated - if (etag == nil) { - etag = ETagIfPresent(object); - } - } - - NSMutableURLRequest *request = [self requestForURL:url - ETag:etag - httpMethod:httpMethod - ticket:ticket]; - [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; - [request setValue:contentType forHTTPHeaderField:@"Content-Type"]; - - [request setValue:@"no-cache" forHTTPHeaderField:@"Cache-Control"]; - - if (contentLength) { - [request setValue:contentLength forHTTPHeaderField:@"Content-Length"]; - } - - // Add the additional http headers from the service, and then from the query - NSDictionary *headers = self.additionalHTTPHeaders; - for (NSString *key in headers) { - NSString *value = [headers objectForKey:key]; - [request setValue:value forHTTPHeaderField:key]; - } - - headers = additionalHeaders; - for (NSString *key in headers) { - NSString *value = [headers objectForKey:key]; - [request setValue:value forHTTPHeaderField:key]; - } - - return request; -} - -#pragma mark - - -- (NSMutableURLRequest *)requestForQuery:(GTLRQuery *)query { - GTLR_DEBUG_ASSERT(query.bodyObject == nil, - @"requestForQuery: supports only GET methods, but was passed: %@", query); - GTLR_DEBUG_ASSERT(query.uploadParameters == nil, - @"requestForQuery: does not support uploads, but was passed: %@", query); - - NSURL *url = [self URLFromQueryObject:query - usePartialPaths:NO - includeServiceURLQueryParams:YES]; - - // If there is a developer key, add it onto the url. - NSString *apiKey = self.APIKey; - if (apiKey.length > 0) { - NSDictionary *queryParameters; - queryParameters = @{ kDeveloperAPIQueryParamKey : apiKey }; - url = [GTLRService URLWithString:url.absoluteString - queryParameters:queryParameters]; - } - - NSMutableURLRequest *request = [self requestForURL:url - ETag:nil - httpMethod:query.httpMethod - ticket:nil]; - NSString *apiRestriction = self.APIKeyRestrictionBundleID; - if ([apiRestriction length] > 0) { - [request setValue:apiRestriction forHTTPHeaderField:kXIosBundleIdHeader]; - } - - NSDictionary *headers = self.additionalHTTPHeaders; - for (NSString *key in headers) { - NSString *value = [headers objectForKey:key]; - [request setValue:value forHTTPHeaderField:key]; - } - - headers = query.additionalHTTPHeaders; - for (NSString *key in headers) { - NSString *value = [headers objectForKey:key]; - [request setValue:value forHTTPHeaderField:key]; - } - - return request; -} - -// common fetch starting method - -- (GTLRServiceTicket *)fetchObjectWithURL:(NSURL *)targetURL - objectClass:(Class)objectClass - bodyObject:(GTLRObject *)bodyObject - dataToPost:(NSData *)dataToPost - ETag:(NSString *)etag - httpMethod:(NSString *)httpMethod - mayAuthorize:(BOOL)mayAuthorize - completionHandler:(GTLRServiceCompletionHandler)completionHandler - executingQuery:(id<GTLRQueryProtocol>)executingQuery - ticket:(GTLRServiceTicket *)ticket { - // Once inside this method, we should not access any service properties that may reasonably - // be changed by the app, as this method may execute multiple times during query execution - // and we want consistent behavior. Service properties should be copied to the ticket. - - GTLR_DEBUG_ASSERT(executingQuery != nil, - @"no query? service additionalURLQueryParameters needs to be added to targetURL"); - - GTLR_DEBUG_ASSERT(targetURL != nil, @"no url?"); - if (targetURL == nil) return nil; - - BOOL hasExecutionParams = [executingQuery hasExecutionParameters]; - GTLRServiceExecutionParameters *executionParams = (hasExecutionParams ? - executingQuery.executionParameters : nil); - - // We need to create a ticket unless one was created earlier (like during authentication.) - if (!ticket) { - ticket = [[[[self class] ticketClass] alloc] initWithService:self - executionParameters:executionParams]; - [ticket notifyStarting:YES]; - } - - // If there is a developer key, add it onto the URL. - NSString *apiKey = ticket.APIKey; - if (apiKey.length > 0) { - NSDictionary *queryParameters; - queryParameters = @{ kDeveloperAPIQueryParamKey : apiKey }; - targetURL = [GTLRService URLWithString:targetURL.absoluteString - queryParameters:queryParameters]; - } - - NSString *contentType = @"application/json; charset=utf-8"; - NSString *contentLength; // nil except for single-request uploads. - - if ([executingQuery isBatchQuery]) { - contentType = [NSString stringWithFormat:@"multipart/mixed; boundary=%@", - ((GTLRBatchQuery *)executingQuery).boundary]; - } - - - GTLRUploadParameters *uploadParams = executingQuery.uploadParameters; - - if (uploadParams.shouldUploadWithSingleRequest) { - NSData *uploadData = uploadParams.data; - NSString *uploadMIMEType = uploadParams.MIMEType; - if (!uploadData) { - GTLR_DEBUG_ASSERT(0, @"Uploading with a single request requires bytes to upload as NSData"); - } else { - if (uploadParams.shouldSendUploadOnly) { - contentType = uploadMIMEType; - dataToPost = uploadData; - contentLength = @(dataToPost.length).stringValue; - } else { - GTMMIMEDocument *mimeDoc = [GTMMIMEDocument MIMEDocument]; - if (dataToPost) { - // Include the object as metadata with the upload. - [mimeDoc addPartWithHeaders:@{ @"Content-Type" : contentType } - body:dataToPost]; - } - [mimeDoc addPartWithHeaders:@{ @"Content-Type" : uploadMIMEType } - body:uploadData]; - - dispatch_data_t mimeDispatchData; - unsigned long long mimeLength; - NSString *mimeBoundary; - [mimeDoc generateDispatchData:&mimeDispatchData - length:&mimeLength - boundary:&mimeBoundary]; - - contentType = [NSString stringWithFormat:@"multipart/related; boundary=%@", mimeBoundary]; - dataToPost = (NSData *)mimeDispatchData; - contentLength = @(mimeLength).stringValue; - } - } - } - - NSDictionary *additionalHeaders = nil; - NSString *restriction = self.APIKeyRestrictionBundleID; - if ([restriction length] > 0) { - additionalHeaders = @{ kXIosBundleIdHeader : restriction }; - } - - NSDictionary *queryAdditionalHeaders = executingQuery.additionalHTTPHeaders; - if (queryAdditionalHeaders) { - if (additionalHeaders) { - NSMutableDictionary *builder = [additionalHeaders mutableCopy]; - [builder addEntriesFromDictionary:queryAdditionalHeaders]; - additionalHeaders = builder; - } else { - additionalHeaders = queryAdditionalHeaders; - } - } - - NSURLRequest *request = [self objectRequestForURL:targetURL - object:bodyObject - contentType:contentType - contentLength:contentLength - ETag:etag - httpMethod:httpMethod - additionalHeaders:additionalHeaders - ticket:ticket]; - ticket.postedObject = bodyObject; - ticket.executingQuery = executingQuery; - - GTLRQuery *originalQuery = (GTLRQuery *)ticket.originalQuery; - if (originalQuery == nil) { - originalQuery = (GTLRQuery *)executingQuery; - ticket.originalQuery = originalQuery; - } - - // Some proxy servers (and some web servers) have issues with GET URLs being - // too long, trap that and move the query parameters into the body. The - // uploadParams and dataToPost should be nil for a GET, but playing it safe - // and confirming. - NSString *requestHTTPMethod = request.HTTPMethod; - BOOL isDoingHTTPGet = - (requestHTTPMethod == nil - || [requestHTTPMethod caseInsensitiveCompare:@"GET"] == NSOrderedSame); - if (isDoingHTTPGet && - (request.URL.absoluteString.length >= kMaxGETURLLength) && - (uploadParams == nil) && - (dataToPost == nil)) { - NSString *urlString = request.URL.absoluteString; - NSRange range = [urlString rangeOfString:@"?"]; - if (range.location != NSNotFound) { - NSURL *trimmedURL = [NSURL URLWithString:[urlString substringToIndex:range.location]]; - NSString *urlArgsString = [urlString substringFromIndex:(range.location + 1)]; - if (trimmedURL && (urlArgsString.length > 0)) { - dataToPost = [urlArgsString dataUsingEncoding:NSUTF8StringEncoding]; - NSMutableURLRequest *mutableRequest = [request mutableCopy]; - mutableRequest.URL = trimmedURL; - mutableRequest.HTTPMethod = @"POST"; - [mutableRequest setValue:@"GET" forHTTPHeaderField:@"X-HTTP-Method-Override"]; - [mutableRequest setValue:@"application/x-www-form-urlencoded" - forHTTPHeaderField:@"Content-Type"]; - [mutableRequest setValue:@(dataToPost.length).stringValue - forHTTPHeaderField:@"Content-Length"]; - request = mutableRequest; - } - } - } - ticket.fetchRequest = request; - - GTLRServiceTestBlock testBlock = ticket.testBlock; - if (testBlock) { - [self simulateFetchWithTicket:ticket - testBlock:testBlock - dataToPost:dataToPost - completionHandler:completionHandler]; - return ticket; - } - - GTMSessionFetcherService *fetcherService = ticket.fetcherService; - GTMSessionFetcher *fetcher; - - if (uploadParams == nil || uploadParams.shouldUploadWithSingleRequest) { - // Create a single-request fetcher. - fetcher = [fetcherService fetcherWithRequest:request]; - } else { - fetcher = [self uploadFetcherWithRequest:request - fetcherService:fetcherService - params:uploadParams]; - } - - if (ticket.allowInsecureQueries) { - fetcher.allowLocalhostRequest = YES; - fetcher.allowedInsecureSchemes = @[ @"http" ]; - } - - NSString *loggingName = executingQuery.loggingName; - if (loggingName.length > 0) { - NSUInteger pageNumber = ticket.pagesFetchedCounter + 1; - if (pageNumber > 1) { - loggingName = [loggingName stringByAppendingFormat:@", page %tu", pageNumber]; - } - fetcher.comment = loggingName; - } - - if (!mayAuthorize) { - fetcher.authorizer = nil; - } else { - fetcher.authorizer = ticket.authorizer; - } - - // copy the ticket's retry settings into the fetcher - fetcher.retryEnabled = ticket.retryEnabled; - fetcher.maxRetryInterval = ticket.maxRetryInterval; - - BOOL shouldExamineRetries = (ticket.retryBlock != nil); - if (shouldExamineRetries) { - GTLR_DEBUG_ASSERT(ticket.retryEnabled, @"Setting retry block without retry enabled."); - - fetcher.retryBlock = ^(BOOL suggestedWillRetry, NSError *error, - GTMSessionFetcherRetryResponse response) { - // The object fetcher may call into this retry block; this one invokes the - // selector provided by the user. - GTLRServiceRetryBlock retryBlock = ticket.retryBlock; - if (!retryBlock) { - response(suggestedWillRetry); - } else { - dispatch_group_async(ticket.callbackGroup, ticket.callbackQueue, ^{ - if (ticket.cancelled) { - response(NO); - return; - } - BOOL willRetry = retryBlock(ticket, suggestedWillRetry, error); - response(willRetry); - }); - } - }; - } - - // Remember the object fetcher in the ticket. - ticket.objectFetcher = fetcher; - - // Set the upload data. - fetcher.bodyData = dataToPost; - - // Have the fetcher call back on the parse queue. - fetcher.callbackQueue = self.parseQueue; - - // If this ticket is paging, end any ongoing background task immediately, and - // rely on the fetcher's background task now instead. - [ticket endBackgroundTask]; - - [fetcher beginFetchWithCompletionHandler:^(NSData * _Nullable data, NSError * _Nullable error) { - // We now have the JSON data for an object, or an error. - GTLR_ASSERT_CURRENT_QUEUE_DEBUG(self.parseQueue); - - // Until now, the only async operation has been the fetch, and we rely on the fetcher's - // background task on iOS to get us here if the app was backgrounded. - // - // Now we'll let the ticket create a background task so that the async parsing and call back to - // the app will happen if the app is sent to the background. The ticket is responsible for - // ending the background task. - [ticket startBackgroundTask]; - - if (ticket.cancelled) { - // If the user cancels the ticket, then cancelTicket will stop the fetcher so this - // callback probably won't occur. - // - // But just for safety, if we get here, skip any parsing steps by fabricating an error. - data = nil; - error = [NSError errorWithDomain:NSURLErrorDomain - code:NSURLErrorCancelled - userInfo:nil]; - } - - if (error == nil) { - // Successful fetch. - if (data.length > 0) { - [self prepareToParseObjectForFetcher:fetcher - executingQuery:executingQuery - ticket:ticket - error:error - defaultClass:objectClass - completionHandler:completionHandler]; - } else { - // no data (such as when deleting) - [self handleParsedObjectForFetcher:fetcher - executingQuery:executingQuery - ticket:ticket - error:nil - parsedObject:nil - hasSentParsingStartNotification:NO - completionHandler:completionHandler]; - } - return; - } - - // Failed fetch. - NSInteger status = [error code]; - if (status >= 300) { - // Return the HTTP error status code along with a more descriptive error - // from within the HTTP response payload. - NSData *responseData = fetcher.downloadedData; - if (responseData.length > 0) { - NSDictionary *responseHeaders = fetcher.responseHeaders; - NSString *responseContentType = [responseHeaders objectForKey:@"Content-Type"]; - - if (data.length > 0) { - if ([responseContentType hasPrefix:@"application/json"]) { - NSError *parseError = nil; - NSMutableDictionary *jsonWrapper = - [NSJSONSerialization JSONObjectWithData:(NSData * _Nonnull)data - options:NSJSONReadingMutableContainers - error:&parseError]; - if (parseError) { - // We could not parse the JSON payload - error = parseError; - } else { - // HTTP Streaming defined by Google services is is an array - // of requests and replies. This code never makes one of - // these requests; but, some GET apis can actually be to - // a Streaming result (for media?), so the errors can still - // come back in an array. - if ([jsonWrapper isKindOfClass:[NSArray class]]) { - NSArray *jsonWrapperAsArray = (NSArray *)jsonWrapper; -#if DEBUG - if (jsonWrapperAsArray.count > 1) { - GTLR_DEBUG_LOG(@"Got error array with >1 item, only using first. Full list: %@", - jsonWrapperAsArray); - } -#endif - // Use the first. - jsonWrapper = [jsonWrapperAsArray firstObject]; - } - - // Convert the JSON error payload into a structured error - NSMutableDictionary *errorJSON = [jsonWrapper valueForKey:@"error"]; - if (errorJSON) { - GTLRErrorObject *errorObject = [GTLRErrorObject objectWithJSON:errorJSON]; - error = [errorObject foundationError]; - } - } - } else { - // No structured JSON error was available; make a plaintext server - // error response visible in the error object. - NSString *reasonStr = [[NSString alloc] initWithData:(NSData * _Nonnull)data - encoding:NSUTF8StringEncoding]; - NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : reasonStr }; - error = [NSError errorWithDomain:kGTMSessionFetcherStatusDomain - code:status - userInfo:userInfo]; - } - } else { - // Response data length is zero; we'll settle for returning the - // fetcher's error. - } - } - } - - [self handleParsedObjectForFetcher:fetcher - executingQuery:executingQuery - ticket:ticket - error:error - parsedObject:nil - hasSentParsingStartNotification:NO - completionHandler:completionHandler]; - }]; // fetcher completion handler - - // If something weird happens and the networking callbacks have been called - // already synchronously, we don't want to return the ticket since the caller - // will never know when to stop retaining it, so we'll make sure the - // success/failure callbacks have not yet been called by checking the - // ticket - if (ticket.hasCalledCallback) { - return nil; - } - - return ticket; -} - -- (GTMSessionUploadFetcher *)uploadFetcherWithRequest:(NSURLRequest *)request - fetcherService:(GTMSessionFetcherService *)fetcherService - params:(GTLRUploadParameters *)uploadParams { - // Hang on to the user's requested chunk size, and ensure it's not tiny - NSUInteger uploadChunkSize = [self serviceUploadChunkSize]; - if (uploadChunkSize < kMinimumUploadChunkSize) { - uploadChunkSize = kMinimumUploadChunkSize; - } - - NSString *uploadClassName = GTLR_CLASSNAME_STR(GTMSessionUploadFetcher); - Class uploadClass = NSClassFromString(uploadClassName); - GTLR_ASSERT(uploadClass != nil, @"GTMSessionUploadFetcher needed"); - - NSString *uploadMIMEType = uploadParams.MIMEType; - NSData *uploadData = uploadParams.data; - NSURL *uploadFileURL = uploadParams.fileURL; - NSFileHandle *uploadFileHandle = uploadParams.fileHandle; - NSURL *uploadLocationURL = uploadParams.uploadLocationURL; - - // Create the upload fetcher. - GTMSessionUploadFetcher *fetcher; - if (uploadLocationURL) { - // Resuming with the session fetcher and a file URL. - GTLR_DEBUG_ASSERT(uploadFileURL != nil, @"Resume requires a file URL"); - fetcher = [uploadClass uploadFetcherWithLocation:uploadLocationURL - uploadMIMEType:uploadMIMEType - chunkSize:(int64_t)uploadChunkSize - fetcherService:fetcherService]; - fetcher.uploadFileURL = uploadFileURL; - } else { - fetcher = [uploadClass uploadFetcherWithRequest:request - uploadMIMEType:uploadMIMEType - chunkSize:(int64_t)uploadChunkSize - fetcherService:fetcherService]; - if (uploadFileURL) { - fetcher.uploadFileURL = uploadFileURL; - } else if (uploadData) { - fetcher.uploadData = uploadData; - } else if (uploadFileHandle) { -#if DEBUG - if (uploadParams.useBackgroundSession) { - GTLR_DEBUG_LOG(@"Warning: GTLRUploadParameters should be supplied an uploadFileURL rather" - @" than a file handle to support background uploads.\n %@", uploadParams); - } -#endif - fetcher.uploadFileHandle = uploadFileHandle; - } - } - fetcher.useBackgroundSession = uploadParams.useBackgroundSession; - return fetcher; -} - -#pragma mark - - -- (GTLRServiceTicket *)executeBatchQuery:(GTLRBatchQuery *)batchObj - completionHandler:(GTLRServiceCompletionHandler)completionHandler - ticket:(GTLRServiceTicket *)ticket { - // Copy the original batch object and each query inside so our working queries cannot be modified - // by the caller, and release the callback blocks from the supplied query objects. - GTLRBatchQuery *batchCopy = [batchObj copy]; - [batchObj invalidateQuery]; - - NSArray *queries = batchCopy.queries; - NSUInteger numberOfQueries = queries.count; - if (numberOfQueries == 0) return nil; - - // Create the batch of REST calls. - NSMutableSet *requestIDs = [NSMutableSet setWithCapacity:numberOfQueries]; - NSMutableSet *loggingNames = [NSMutableSet set]; - GTMMIMEDocument *mimeDoc = [GTMMIMEDocument MIMEDocument]; - - // Each batch part has two "header" sections, an outer and inner. - // The inner headers are preceded by a line specifying the http request. - // So a part looks like this: - // - // --END_OF_PART - // Content-ID: gtlr_3 - // Content-Transfer-Encoding: binary - // Content-Type: application/http - // - // POST https://www.googleapis.com/drive/v3/files/ - // Content-Length: 0 - // Content-Type: application/json - // - // { - // "id": "04109509152946699072k" - // } - - for (GTLRQuery *query in queries) { - GTLRObject *bodyObject = query.bodyObject; - NSDictionary *bodyJSON = bodyObject.JSON; - NSString *requestID = query.requestID; - - if (requestID.length == 0) { - GTLR_DEBUG_ASSERT(0, @"Invalid query ID: %@", [query class]); - return nil; - } - - if ([requestIDs containsObject:requestID]) { - GTLR_DEBUG_ASSERT(0, @"Duplicate request ID in batch: %@", requestID); - return nil; - } - [requestIDs addObject:requestID]; - - // Create the inner request, body, and headers. - - NSURL *requestURL = [self URLFromQueryObject:query - usePartialPaths:YES - includeServiceURLQueryParams:NO]; - NSString *requestURLString = requestURL.absoluteString; - - NSError *error = nil; - NSData *bodyData; - if (bodyJSON) { - bodyData = [NSJSONSerialization dataWithJSONObject:bodyJSON - options:0 - error:&error]; - if (bodyData == nil) { - GTLR_DEBUG_ASSERT(0, @"JSON generation error: %@\n JSON: %@", error, bodyJSON); - return nil; - } - } - - NSString *httpRequestString = [NSString stringWithFormat:@"%@ %@\r\n", - query.httpMethod ?: @"GET", requestURLString]; - NSDictionary *innerPartHeaders = @{ @"Content-Type" : @"application/json", - @"Content-Length" : @(bodyData.length).stringValue }; - - innerPartHeaders = MergeDictionaries(query.additionalHTTPHeaders, innerPartHeaders); - - NSData *innerPartHeadersData = [GTMMIMEDocument dataWithHeaders:innerPartHeaders]; - - NSMutableData *innerData = - [[httpRequestString dataUsingEncoding:NSUTF8StringEncoding] mutableCopy]; - [innerData appendData:innerPartHeadersData]; - if (bodyData) { - [innerData appendData:bodyData]; - } - - // Combine the outer headers with the inner headers and body data. - NSDictionary *outerPartHeaders = @{ @"Content-Type" : @"application/http", - @"Content-ID" : requestID, - @"Content-Transfer-Encoding" : @"binary" }; - - [mimeDoc addPartWithHeaders:outerPartHeaders - body:innerData]; - - NSString *loggingName = query.loggingName ?: [[query class] description]; - [loggingNames addObject:loggingName]; - } - -#if !STRIP_GTM_FETCH_LOGGING - // Set the fetcher log comment. - if (!batchCopy.loggingName) { - NSUInteger pageNumber = ticket.pagesFetchedCounter; - NSString *pageStr = @""; - if (pageNumber > 0) { - pageStr = [NSString stringWithFormat:@"page %tu, ", pageNumber + 1]; - } - batchCopy.loggingName = [NSString stringWithFormat:@"batch: %@ (%@%tu queries)", - [loggingNames.allObjects componentsJoinedByString:@", "], - pageStr, numberOfQueries]; - } -#endif - - dispatch_data_t mimeDispatchData; - unsigned long long mimeLength; - NSString *mimeBoundary; - [mimeDoc generateDispatchData:&mimeDispatchData - length:&mimeLength - boundary:&mimeBoundary]; - - batchCopy.boundary = mimeBoundary; - - BOOL mayAuthorize = (batchCopy ? !batchCopy.shouldSkipAuthorization : YES); - - NSString *rootURLString = self.rootURLString; - NSString *batchPath = self.batchPath ?: @""; - NSString *batchURLString = [rootURLString stringByAppendingString:batchPath]; - - GTLR_DEBUG_ASSERT(![batchPath hasPrefix:@"/"], - @"batchPath shouldn't start with a slash: %@", - batchPath); - - // Query parameters override service parameters. - NSDictionary *mergedQueryParams = MergeDictionaries(self.additionalURLQueryParameters, - batchObj.additionalURLQueryParameters); - NSURL *batchURL; - if (mergedQueryParams.count > 0) { - batchURL = [GTLRService URLWithString:batchURLString - queryParameters:mergedQueryParams]; - } else { - batchURL = [NSURL URLWithString:batchURLString]; - } - - GTLRServiceTicket *resultTicket = [self fetchObjectWithURL:batchURL - objectClass:[GTLRBatchResult class] - bodyObject:nil - dataToPost:(NSData *)mimeDispatchData - ETag:nil - httpMethod:@"POST" - mayAuthorize:mayAuthorize - completionHandler:completionHandler - executingQuery:batchCopy - ticket:ticket]; - return resultTicket; -} - -#pragma mark - - -// Raw REST fetch method. - -- (GTLRServiceTicket *)fetchObjectWithURL:(NSURL *)targetURL - objectClass:(Class)objectClass - bodyObject:(GTLRObject *)bodyObject - ETag:(NSString *)etag - httpMethod:(NSString *)httpMethod - mayAuthorize:(BOOL)mayAuthorize - completionHandler:(GTLRServiceCompletionHandler)completionHandler - executingQuery:(id<GTLRQueryProtocol>)executingQuery - ticket:(GTLRServiceTicket *)ticket { - // if no URL was supplied, treat this as if the fetch failed (below) - // and immediately return a nil ticket, skipping the callbacks - // - // this might be considered normal (say, updating a read-only entry - // that lacks an edit link) though higher-level calls may assert or - // return errors depending on the specific usage - if (targetURL == nil) return nil; - - NSData *dataToPost = nil; - if (bodyObject != nil && !executingQuery.uploadParameters.shouldSendUploadOnly) { - NSError *error = nil; - - NSDictionary *whatToSend; - NSDictionary *json = bodyObject.JSON; - if (json == nil) { - // Since a body object was provided, we'll ensure there's at least an empty dictionary. - json = [NSDictionary dictionary]; - } - if (_dataWrapperRequired) { - // create the top-level "data" object - whatToSend = @{ @"data" : json }; - } else { - whatToSend = json; - } - dataToPost = [NSJSONSerialization dataWithJSONObject:whatToSend - options:0 - error:&error]; - if (dataToPost == nil) { - GTLR_DEBUG_LOG(@"JSON generation error: %@", error); - } - } - - return [self fetchObjectWithURL:targetURL - objectClass:objectClass - bodyObject:bodyObject - dataToPost:dataToPost - ETag:etag - httpMethod:httpMethod - mayAuthorize:mayAuthorize - completionHandler:completionHandler - executingQuery:executingQuery - ticket:ticket]; -} - -- (void)invokeProgressCallbackForTicket:(GTLRServiceTicket *)ticket - deliveredBytes:(unsigned long long)numReadSoFar - totalBytes:(unsigned long long)total { - - GTLRServiceUploadProgressBlock block = ticket.uploadProgressBlock; - if (block) { - dispatch_group_async(ticket.callbackGroup, ticket.callbackQueue, ^{ - if (ticket.cancelled) return; - - block(ticket, numReadSoFar, total); - }); - } -} - -// Three methods handle parsing of the fetched JSON data: -// - prepareToParse posts a start notification and then spawns off parsing -// on the operation queue (if there's an operation queue) -// - parseObject does the parsing of the JSON string -// - handleParsedObject posts the stop notification and calls the callback -// with the parsed object or an error -// -// The middle method may run on a separate thread. - -- (void)prepareToParseObjectForFetcher:(GTMSessionFetcher *)fetcher - executingQuery:(id<GTLRQueryProtocol>)executingQuery - ticket:(GTLRServiceTicket *)ticket - error:(NSError *)error - defaultClass:(Class)defaultClass - completionHandler:(GTLRServiceCompletionHandler)completionHandler { - GTLR_ASSERT_CURRENT_QUEUE_DEBUG(self.parseQueue); - - [ticket postNotificationOnMainThreadWithName:kGTLRServiceTicketParsingStartedNotification - object:ticket - userInfo:nil]; - - // For unit tests to cancel during parsing, we need a synchronous notification posted. - // Because this notification is intended only for unit tests, there is no public symbol - // for the notification name. - NSNotificationCenter *nc =[NSNotificationCenter defaultCenter]; - [nc postNotificationName:@"kGTLRServiceTicketParsingStartedForTestNotification" - object:ticket - userInfo:nil]; - - NSDictionary *batchClassMap; - if ([executingQuery isBatchQuery]) { - // build a dictionary of expected classes for the batch responses - GTLRBatchQuery *batchQuery = (GTLRBatchQuery *)executingQuery; - NSArray *queries = batchQuery.queries; - batchClassMap = [NSMutableDictionary dictionaryWithCapacity:queries.count]; - for (GTLRQuery *singleQuery in queries) { - [batchClassMap setValue:singleQuery.expectedObjectClass - forKey:singleQuery.requestID]; - } - } - - [self parseObjectFromDataOfFetcher:fetcher - executingQuery:executingQuery - ticket:ticket - error:error - defaultClass:defaultClass - batchClassMap:batchClassMap - hasSentParsingStartNotification:YES - completionHandler:completionHandler]; -} - -- (void)parseObjectFromDataOfFetcher:(GTMSessionFetcher *)fetcher - executingQuery:(id<GTLRQueryProtocol>)executingQuery - ticket:(GTLRServiceTicket *)ticket - error:(NSError *)error - defaultClass:(Class)defaultClass - batchClassMap:(NSDictionary *)batchClassMap - hasSentParsingStartNotification:(BOOL)hasSentParsingStartNotification - completionHandler:(GTLRServiceCompletionHandler)completionHandler { - GTLR_ASSERT_CURRENT_QUEUE_DEBUG(self.parseQueue); - - NSError *fetchError = error; - - NSString *downloadAsDataObjectType = nil; - if (![executingQuery isBatchQuery]) { - GTLRQuery *singleQuery = (GTLRQuery *)executingQuery; - downloadAsDataObjectType = singleQuery.downloadAsDataObjectType; - } - - NSDictionary *responseHeaders = fetcher.responseHeaders; - NSString *contentType = [responseHeaders objectForKey:@"Content-Type"]; - NSData *data = fetcher.downloadedData; - BOOL hasData = data.length > 0; - BOOL isJSON = [contentType hasPrefix:@"application/json"]; - GTLRObject *parsedObject; - - if (hasData) { -#if GTLR_LOG_PERFORMANCE - NSTimeInterval secs1, secs2; - secs1 = [NSDate timeIntervalSinceReferenceDate]; -#endif - id<GTLRObjectClassResolver> objectClassResolver = ticket.objectClassResolver; - - if ((downloadAsDataObjectType.length != 0) && fetchError == nil) { - GTLRDataObject *dataObject = [GTLRDataObject object]; - dataObject.data = data; - dataObject.contentType = contentType; - parsedObject = dataObject; - } else if (isJSON) { - NSError *parseError = nil; - NSMutableDictionary *jsonWrapper = - [NSJSONSerialization JSONObjectWithData:data - options:NSJSONReadingMutableContainers - error:&parseError]; - if (jsonWrapper == nil) { - fetchError = parseError; - } else { - NSMutableDictionary *json; - - if (_dataWrapperRequired) { - json = [jsonWrapper valueForKey:@"data"]; - } else { - json = jsonWrapper; - } - - if (json != nil) { - parsedObject = [GTLRObject objectForJSON:json - defaultClass:defaultClass - objectClassResolver:objectClassResolver]; - } - } - } else { - // Has non-JSON data; it may be batch data. - NSString *boundary; - BOOL isBatchResponse = [self isContentTypeMultipart:contentType - boundary:&boundary]; - if (isBatchResponse) { - NSArray *mimeParts = [GTMMIMEDocument MIMEPartsWithBoundary:boundary - data:data]; - NSArray *responseParts = [self responsePartsWithMIMEParts:mimeParts]; - GTLRBatchResult *batchResult = [self batchResultWithResponseParts:responseParts - batchClassMap:batchClassMap - objectClassResolver:objectClassResolver]; - parsedObject = batchResult; - } else { - GTLR_DEBUG_ASSERT(0, @"Got unexpected content type '%@'", contentType); - } - } // isJSON - -#if GTLR_LOG_PERFORMANCE - secs2 = [NSDate timeIntervalSinceReferenceDate]; - NSLog(@"allocation of %@ took %f seconds", objectClass, secs2 - secs1); -#endif - } - - [self handleParsedObjectForFetcher:fetcher - executingQuery:executingQuery - ticket:ticket - error:fetchError - parsedObject:parsedObject - hasSentParsingStartNotification:hasSentParsingStartNotification - completionHandler:completionHandler]; -} - -- (void)handleParsedObjectForFetcher:(GTMSessionFetcher *)fetcher - executingQuery:(id<GTLRQueryProtocol>)executingQuery - ticket:(GTLRServiceTicket *)ticket - error:(NSError *)error - parsedObject:(GTLRObject *)object - hasSentParsingStartNotification:(BOOL)hasSentParsingStartNotification - completionHandler:(GTLRServiceCompletionHandler)completionHandler { - GTLR_ASSERT_CURRENT_QUEUE_DEBUG(self.parseQueue); - - BOOL isResourceURLQuery = [executingQuery isKindOfClass:[GTLRResourceURLQuery class]]; - - // There may not be an object due to a fetch or parsing error - BOOL shouldFetchNextPages = ticket.shouldFetchNextPages && !isResourceURLQuery; - GTLRObject *previousObject = ticket.fetchedObject; - BOOL isFirstPage = (previousObject == nil); - - if (shouldFetchNextPages && !isFirstPage && (object != nil)) { - // Accumulate new results - object = [self mergedNewResultObject:object - oldResultObject:previousObject - forQuery:executingQuery - ticket:ticket]; - } - - ticket.fetchedObject = object; - ticket.fetchError = error; - - if (hasSentParsingStartNotification) { - // we want to always balance the start and stop notifications - [ticket postNotificationOnMainThreadWithName:kGTLRServiceTicketParsingStoppedNotification - object:ticket - userInfo:nil]; - } - - BOOL shouldCallCallbacks = YES; - - if (error == nil) { - ++ticket.pagesFetchedCounter; - - // Use the nextPageToken to fetch any later pages for non-batch queries - // - // This assumes a pagination model where objects have entries in a known "items" - // field and a "nextPageToken" field, and queries support a "pageToken" - // parameter. - - if (shouldFetchNextPages) { - // Determine if we should fetch more pages of results - - GTLRQuery *nextPageQuery = - (GTLRQuery *)[self nextPageQueryForQuery:executingQuery - result:object - ticket:ticket]; - if (nextPageQuery) { - BOOL isFetchingMore = [self fetchNextPageWithQuery:nextPageQuery - completionHandler:completionHandler - ticket:ticket]; - if (isFetchingMore) { - shouldCallCallbacks = NO; - } - } else { - // nextPageQuery == nil; no more page tokens are present - #if DEBUG && !GTLR_SKIP_PAGES_WARNING - // Each next page followed to accumulate all pages of a feed takes up to - // a few seconds. When multiple pages are being fetched, that - // usually indicates that a larger page size (that is, more items per - // feed fetched) should be requested. - // - // To avoid fetching many pages, set query.maxResults so the feed - // requested is large enough to rarely need to follow next links. - NSUInteger pageCount = ticket.pagesFetchedCounter; - if (pageCount > 2) { - NSString *queryLabel; - if ([executingQuery isBatchQuery]) { - queryLabel = @"batch query"; - } else { - queryLabel = [[executingQuery class] description]; - } - GTLR_DEBUG_LOG(@"Executing %@ query required fetching %tu pages; use a query with" - @" a larger maxResults for faster results", queryLabel, pageCount); - } - #endif - } // nextPageQuery - } else { - // !ticket.shouldFetchNextPages - #if DEBUG && !GTLR_SKIP_PAGES_WARNING - // Let the developer know that there were additional pages that would have been - // fetched if shouldFetchNextPages was enabled. - // - // The client may specify a larger page size with the query's maxResults property, - // or enable automatic pagination by turning on shouldFetchNextPages on the service - // or on the query's executionParameters. - if ([executingQuery respondsToSelector:@selector(pageToken)] - && [object isKindOfClass:[GTLRCollectionObject class]] - && [object respondsToSelector:@selector(nextPageToken)] - && object.nextPageToken.length > 0) { - GTLR_DEBUG_LOG(@"Executing %@ has additional pages of results not fetched because" - @" shouldFetchNextPages is not enabled", [executingQuery class]); - } - #endif - } // ticket.shouldFetchNextPages - } // error == nil - - if (!isFirstPage) { - // Release callbacks from this completed page's query. - [executingQuery invalidateQuery]; - } - - // We no longer care about the queries for page 2 or later, so for the client - // inspecting the ticket in the callback, the executing query should be - // the original one - ticket.executingQuery = ticket.originalQuery; - - if (!shouldCallCallbacks) { - // More fetches are happening. - } else { - dispatch_group_async(ticket.callbackGroup, ticket.callbackQueue, ^{ - // First, call query-specific callback blocks. We do this before the - // fetch callback to let applications do any final clean-up (or update - // their UI) in the fetch callback. - GTLRQuery *originalQuery = (GTLRQuery *)ticket.originalQuery; - - if (!ticket.cancelled) { - if (![originalQuery isBatchQuery]) { - // Single query - GTLRServiceCompletionHandler completionBlock = originalQuery.completionBlock; - if (completionBlock) { - completionBlock(ticket, object, error); - } - } else { - [self invokeBatchCompletionsWithTicket:ticket - batchQuery:(GTLRBatchQuery *)originalQuery - batchResult:(GTLRBatchResult *)object - error:error]; - } - - if (completionHandler) { - completionHandler(ticket, object, error); - } - ticket.hasCalledCallback = YES; - } // !ticket.cancelled - - [ticket releaseTicketCallbacks]; - [ticket endBackgroundTask]; - - // Even if the ticket has been cancelled, it should notify that it's stopped. - [ticket notifyStarting:NO]; - - // Release query callback blocks. - [originalQuery invalidateQuery]; - }); - } -} - -- (BOOL)isContentTypeMultipart:(NSString *)contentType - boundary:(NSString **)outBoundary { - NSScanner *scanner = [NSScanner scannerWithString:contentType]; - // By default, the scanner skips leading whitespace. - if ([scanner scanString:@"multipart/mixed; boundary=" intoString:NULL] - && [scanner scanUpToCharactersFromSet:[NSCharacterSet newlineCharacterSet] - intoString:outBoundary]) { - return YES; - } - return NO; -} - -- (NSArray <GTLRBatchResponsePart *>*)responsePartsWithMIMEParts:(NSArray <GTMMIMEDocumentPart *>*)mimeParts { - NSMutableArray *resultParts = [NSMutableArray arrayWithCapacity:mimeParts.count]; - - for (GTMMIMEDocumentPart *mimePart in mimeParts) { - GTLRBatchResponsePart *responsePart = [self responsePartWithMIMEPart:mimePart]; - [resultParts addObject:responsePart]; - } - return resultParts; -} - -- (GTLRBatchResponsePart *)responsePartWithMIMEPart:(GTMMIMEDocumentPart *)mimePart { - // The MIME part body looks like - // - // Headers (from the MIME part): - // Content-Type: application/http - // Content-ID: response-gtlr_5 - // - // Body (including inner headers): - // HTTP/1.1 200 OK - // Content-Type: application/json; charset=UTF-8 - // Date: Sat, 16 Jan 2016 18:57:05 GMT - // Expires: Sat, 16 Jan 2016 18:57:05 GMT - // Cache-Control: private, max-age=0 - // Content-Length: 13459 - // - // {"kind":"drive#fileList", ...} - - GTLRBatchResponsePart *responsePart = [[GTLRBatchResponsePart alloc] init]; - - // The only header in the actual (outer) MIME multipart headers we want is Content-ID. - // - // The content ID in the response looks like - // - // Content-ID: response-gtlr_5 - // - // but we will strip the "response-" prefix. - NSDictionary *mimeHeaders = mimePart.headers; - NSString *responseContentID = mimeHeaders[@"Content-ID"]; - if ([responseContentID hasPrefix:@"response-"]) { - responseContentID = [responseContentID substringFromIndex:@"response-".length]; - } - responsePart.contentID = responseContentID; - - // Split the body from the inner headers at the first CRLFCRLF. - NSArray <NSNumber *>*offsets; - NSData *mimePartBody = mimePart.body; - [GTMMIMEDocument searchData:mimePartBody - targetBytes:"\r\n\r\n" - targetLength:4 - foundOffsets:&offsets]; - if (offsets.count == 0) { - // Parse error. - NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; - [userInfo setValue:mimePartBody forKey:kGTLRServiceErrorBodyDataKey]; - [userInfo setValue:responseContentID forKey:kGTLRServiceErrorContentIDKey]; - responsePart.parseError = [NSError errorWithDomain:kGTLRServiceErrorDomain - code:GTLRServiceErrorBatchResponseUnexpected - userInfo:userInfo]; - } else { - // Separate the status/inner headers and the actual body. - NSUInteger partBodyLength = mimePartBody.length; - NSUInteger separatorOffset = offsets[0].unsignedIntegerValue; - NSData *innerHeaderData = - [mimePartBody subdataWithRange:NSMakeRange(0, (NSUInteger)separatorOffset)]; - - NSData *partBodyData; - if (separatorOffset + 4 < partBodyLength) { - NSUInteger offsetToBodyData = separatorOffset + 4; - NSUInteger bodyLength = mimePartBody.length - offsetToBodyData; - partBodyData = [mimePartBody subdataWithRange:NSMakeRange(offsetToBodyData, bodyLength)]; - } - - // Parse to separate the status line and the inner headers (though we don't - // really do much with either.) - [GTMMIMEDocument searchData:innerHeaderData - targetBytes:"\r\n" - targetLength:2 - foundOffsets:&offsets]; - if (offsets.count < 2) { - // Lack of status line and inner headers is strange, but not fatal since - // if the JSON was delivered. - GTLR_DEBUG_LOG(@"GTLRService: Batch result cannot parse headers for request %@:\n%@", - responseContentID, - [[NSString alloc] initWithData:innerHeaderData - encoding:NSUTF8StringEncoding]); - } else { - NSString *statusString; - NSInteger statusCode; - [self getResponseLineFromData:innerHeaderData - statusCode:&statusCode - statusString:&statusString]; - responsePart.statusCode = statusCode; - responsePart.statusString = statusString; - - NSUInteger actualInnerHeaderOffset = offsets[0].unsignedIntegerValue + 2; - NSData *actualInnerHeaderData; - if (innerHeaderData.length - actualInnerHeaderOffset > 0) { - NSRange actualInnerHeaderRange = - NSMakeRange(actualInnerHeaderOffset, - innerHeaderData.length - actualInnerHeaderOffset); - actualInnerHeaderData = [innerHeaderData subdataWithRange:actualInnerHeaderRange]; - } - responsePart.headers = [GTMMIMEDocument headersWithData:actualInnerHeaderData]; - } - - // Create JSON from the body. - NSError *parseError = nil; - NSMutableDictionary *json; - if (partBodyData) { - json = [NSJSONSerialization JSONObjectWithData:partBodyData - options:NSJSONReadingMutableContainers - error:&parseError]; - } else { - parseError = [NSError errorWithDomain:kGTLRServiceErrorDomain - code:GTLRServiceErrorBatchResponseUnexpected - userInfo:nil]; - } - responsePart.JSON = json; - - if (!json) { - // Add our content ID and part body data to the parse error. - NSMutableDictionary *userInfo = - [NSMutableDictionary dictionaryWithDictionary:parseError.userInfo]; - [userInfo setValue:mimePartBody forKey:kGTLRServiceErrorBodyDataKey]; - [userInfo setValue:responseContentID forKey:kGTLRServiceErrorContentIDKey]; - responsePart.parseError = [NSError errorWithDomain:parseError.domain - code:parseError.code - userInfo:userInfo]; - } - } - return responsePart; -} - -- (void)getResponseLineFromData:(NSData *)data - statusCode:(NSInteger *)outStatusCode - statusString:(NSString **)outStatusString { - // Sample response line: - // HTTP/1.1 200 OK - - *outStatusCode = -1; - *outStatusString = @"???"; - NSString *responseLine = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - if (!responseLine) return; - - NSScanner *scanner = [NSScanner scannerWithString:responseLine]; - // Scanner by default skips whitespace when locating the start of the next characters to - // scan. - NSCharacterSet *wsSet = [NSCharacterSet whitespaceAndNewlineCharacterSet]; - NSCharacterSet *newlineSet = [NSCharacterSet newlineCharacterSet]; - NSString *httpVersion; - if ([scanner scanUpToCharactersFromSet:wsSet intoString:&httpVersion] - && [scanner scanInteger:outStatusCode] - && [scanner scanUpToCharactersFromSet:newlineSet intoString:outStatusString]) { - // Got it all. - } -} - -- (GTLRBatchResult *)batchResultWithResponseParts:(NSArray <GTLRBatchResponsePart *>*)parts - batchClassMap:(NSDictionary *)batchClassMap - objectClassResolver:(id<GTLRObjectClassResolver>)objectClassResolver { - // Allow the resolver to override the batch rules class also. - Class resultClass = - GTLRObjectResolveClass(objectClassResolver, - [NSDictionary dictionary], - [GTLRBatchResult class]); - GTLRBatchResult *batchResult = [resultClass object]; - - NSMutableDictionary *successes = [NSMutableDictionary dictionary]; - NSMutableDictionary *failures = [NSMutableDictionary dictionary]; - NSMutableDictionary *responseHeaders = [NSMutableDictionary dictionary]; - - for (GTLRBatchResponsePart *responsePart in parts) { - NSString *contentID = responsePart.contentID; - NSDictionary *json = responsePart.JSON; - NSError *parseError = responsePart.parseError; - NSInteger statusCode = responsePart.statusCode; - [responseHeaders setValue:responsePart.headers forKey:contentID]; - - if (parseError) { - GTLRErrorObject *parseErrorObject = [GTLRErrorObject objectWithFoundationError:parseError]; - [failures setValue:parseErrorObject forKey:contentID]; - } else { - // There is JSON. - NSMutableDictionary *errorJSON = [json objectForKey:@"error"]; - if (errorJSON) { - // A JSON error body should be the most informative error. - GTLRErrorObject *errorObject = [GTLRErrorObject objectWithJSON:errorJSON]; - [failures setValue:errorObject forKey:contentID]; - } else if (statusCode < 200 || statusCode > 399) { - // Report a fetch failure for this part that lacks a JSON error. - NSString *errorStr = responsePart.statusString; - NSDictionary *userInfo = @{ - NSLocalizedDescriptionKey : (errorStr ?: @"<unknown>"), - }; - NSError *httpError = [NSError errorWithDomain:kGTLRServiceErrorDomain - code:GTLRServiceErrorBatchResponseStatusCode - userInfo:userInfo]; - GTLRErrorObject *httpErrorObject = [GTLRErrorObject objectWithFoundationError:httpError]; - [failures setValue:httpErrorObject forKey:contentID]; - } else { - // The JSON represents a successful response. - Class defaultClass = batchClassMap[contentID]; - id resultObject = [GTLRObject objectForJSON:[json mutableCopy] - defaultClass:defaultClass - objectClassResolver:objectClassResolver]; - if (resultObject == nil) { - // Methods like delete return no object. - resultObject = [NSNull null]; - } - [successes setValue:resultObject forKey:contentID]; - } // errorJSON - } // parseError - } // for - batchResult.successes = successes; - batchResult.failures = failures; - batchResult.responseHeaders = responseHeaders; - return batchResult; -} - -- (void)invokeBatchCompletionsWithTicket:(GTLRServiceTicket *)ticket - batchQuery:(GTLRBatchQuery *)batchQuery - batchResult:(GTLRBatchResult *)batchResult - error:(NSError *)error { - // Batch query - // - // We'll step through the queries of the original batch, not of the - // batch result - GTLR_ASSERT_CURRENT_QUEUE_DEBUG(ticket.callbackQueue); - - NSDictionary *successes = batchResult.successes; - NSDictionary *failures = batchResult.failures; - - for (GTLRQuery *oneQuery in batchQuery.queries) { - GTLRServiceCompletionHandler completionBlock = oneQuery.completionBlock; - if (completionBlock) { - // If there was no networking error, look for a query-specific - // error or result - GTLRObject *oneResult = nil; - NSError *oneError = error; - if (oneError == nil) { - NSString *requestID = [oneQuery requestID]; - GTLRErrorObject *gtlrError = [failures objectForKey:requestID]; - if (gtlrError) { - oneError = [gtlrError foundationError]; - } else { - oneResult = [successes objectForKey:requestID]; - if (oneResult == nil) { - // We found neither a success nor a failure for this query, unexpectedly. - GTLR_DEBUG_LOG(@"GTLRService: Batch result missing for request %@", - requestID); - oneError = [NSError errorWithDomain:kGTLRServiceErrorDomain - code:GTLRServiceErrorQueryResultMissing - userInfo:nil]; - } - } - } - completionBlock(ticket, oneResult, oneError); - } - } -} - -- (void)simulateFetchWithTicket:(GTLRServiceTicket *)ticket - testBlock:(GTLRServiceTestBlock)testBlock - dataToPost:(NSData *)dataToPost - completionHandler:(GTLRServiceCompletionHandler)completionHandler { - - GTLRQuery *originalQuery = (GTLRQuery *)ticket.originalQuery; - ticket.executingQuery = originalQuery; - - testBlock(ticket, ^(id testObject, NSError *testError) { - dispatch_group_async(ticket.callbackGroup, ticket.callbackQueue, ^{ - if (!ticket.cancelled) { - if (testError) { - // During simulation, we invoke any retry block, but ignore the result. - const BOOL willRetry = NO; - GTLRServiceRetryBlock retryBlock = ticket.retryBlock; - if (retryBlock) { - (void)retryBlock(ticket, willRetry, testError); - } - } else { - // Simulate upload progress, calling back up to three times. - if (ticket.uploadProgressBlock) { - GTLRQuery *query = (GTLRQuery *)ticket.originalQuery; - unsigned long long uploadLength = [self simulatedUploadLengthForQuery:query - dataToPost:dataToPost]; - unsigned long long sendReportSize = uploadLength / 3 + 1; - unsigned long long totalSentSoFar = 0; - while (totalSentSoFar < uploadLength) { - unsigned long long bytesRemaining = uploadLength - totalSentSoFar; - sendReportSize = MIN(sendReportSize, bytesRemaining); - totalSentSoFar += sendReportSize; - - [self invokeProgressCallbackForTicket:ticket - deliveredBytes:(unsigned long long)totalSentSoFar - totalBytes:(unsigned long long)uploadLength]; - } - [ticket postNotificationOnMainThreadWithName:kGTLRServiceTicketParsingStartedNotification - object:ticket - userInfo:nil]; - [ticket postNotificationOnMainThreadWithName:kGTLRServiceTicketParsingStoppedNotification - object:ticket - userInfo:nil]; - } - } - - if (![originalQuery isBatchQuery]) { - // Single query - GTLRServiceCompletionHandler completionBlock = originalQuery.completionBlock; - if (completionBlock) { - completionBlock(ticket, testObject, testError); - } - } else { - // Batch query - GTLR_DEBUG_ASSERT(!testObject || [testObject isKindOfClass:[GTLRBatchResult class]], - @"Batch queries should have result objects of type GTLRBatchResult (not %@)", - [testObject class]); - - [self invokeBatchCompletionsWithTicket:ticket - batchQuery:(GTLRBatchQuery *)originalQuery - batchResult:(GTLRBatchResult *)testObject - error:testError]; - } // isBatchQuery - - if (completionHandler) { - completionHandler(ticket, testObject, testError); - } - ticket.hasCalledCallback = YES; - } // !ticket.cancelled - - // Even if the ticket has been cancelled, it should notify that it's stopped. - [ticket notifyStarting:NO]; - - // Release query callback blocks. - [originalQuery invalidateQuery]; - }); // dispatch_group_async - }); // testBlock -} - -- (unsigned long long)simulatedUploadLengthForQuery:(GTLRQuery *)query - dataToPost:(NSData *)dataToPost { - // We're uploading the body object and other posted metadata, plus optionally the - // data or file specified in the upload parameters. - unsigned long long uploadLength = dataToPost.length; - - GTLRUploadParameters *uploadParameters = query.uploadParameters; - if (uploadParameters) { - NSData *uploadData = uploadParameters.data; - if (uploadData) { - uploadLength += uploadData.length; - } else { - NSURL *fileURL = uploadParameters.fileURL; - if (fileURL) { - NSError *fileError = nil; - NSNumber *fileSizeNum = nil; - if ([fileURL getResourceValue:&fileSizeNum - forKey:NSURLFileSizeKey - error:&fileError]) { - uploadLength += fileSizeNum.unsignedLongLongValue; - } - } else { - NSFileHandle *fileHandle = uploadParameters.fileHandle; - unsigned long long fileLength = [fileHandle seekToEndOfFile]; - uploadLength += fileLength; - } - } - } - return uploadLength; -} - -#pragma mark - - -// Given a single or batch query and its result, make a new query -// for the next pages, if any. Returns nil if there's no additional -// query to make. -// -// This method calls itself recursively to make the individual next page -// queries for a batch query. -- (id <GTLRQueryProtocol>)nextPageQueryForQuery:(id<GTLRQueryProtocol>)query - result:(GTLRObject *)object - ticket:(GTLRServiceTicket *)ticket { - if (![query isBatchQuery]) { - // This is a single query - GTLRQuery *currentPageQuery = (GTLRQuery *)query; - - // Determine if we should fetch more pages of results - GTLRQuery *nextPageQuery = nil; - NSString *nextPageToken = nil; - - if ([object respondsToSelector:@selector(nextPageToken)] - && [currentPageQuery respondsToSelector:@selector(pageToken)]) { - nextPageToken = [object performSelector:@selector(nextPageToken)]; - } - - if (nextPageToken && [object isKindOfClass:[GTLRCollectionObject class]]) { - NSString *itemsKey = [[object class] collectionItemsKey]; - GTLR_DEBUG_ASSERT(itemsKey != nil, @"Missing accumulation items key for %@", [object class]); - - SEL itemsSel = NSSelectorFromString(itemsKey); - if ([object respondsToSelector:itemsSel]) { - // Make a query for the next page, preserving the request ID - nextPageQuery = [currentPageQuery copy]; - nextPageQuery.requestID = currentPageQuery.requestID; - - [nextPageQuery performSelector:@selector(setPageToken:) - withObject:nextPageToken]; - } else { - GTLR_DEBUG_ASSERT(0, @"%@ does not implement its collection items property \"%@\"", - [object class], itemsKey); - } - } - return nextPageQuery; - } else { - // This is a batch query - // - // Check if there's a next page to fetch for any of the success - // results by invoking this method recursively on each of those results - GTLRBatchResult *batchResult = (GTLRBatchResult *)object; - GTLRBatchQuery *nextPageBatchQuery = nil; - NSDictionary *successes = batchResult.successes; - - for (NSString *requestID in successes) { - GTLRObject *singleObject = [successes objectForKey:requestID]; - GTLRQuery *singleQuery = [ticket queryForRequestID:requestID]; - - GTLRQuery *newQuery = - (GTLRQuery *)[self nextPageQueryForQuery:singleQuery - result:singleObject - ticket:ticket]; - if (newQuery) { - // There is another query to fetch - if (nextPageBatchQuery == nil) { - nextPageBatchQuery = [GTLRBatchQuery batchQuery]; - } - [nextPageBatchQuery addQuery:newQuery]; - } - } - return nextPageBatchQuery; - } -} - -// When a ticket is set to fetch more pages for feeds, this routine -// initiates the fetch for each additional feed page -// -// Returns YES if fetching of the next page has started. -- (BOOL)fetchNextPageWithQuery:(GTLRQuery *)query - completionHandler:(GTLRServiceCompletionHandler)handler - ticket:(GTLRServiceTicket *)ticket { - // Sanity check the number of pages fetched already - if (ticket.pagesFetchedCounter > kMaxNumberOfNextPagesFetched) { - // Sanity check failed: way too many pages were fetched, so the query's - // page size should be bigger to avoid driving up networking and server - // overhead. - // - // The client should be querying with a higher max results per page - // to avoid this. - GTLR_DEBUG_ASSERT(0, @"Fetched too many next pages executing %@;" - @" increase maxResults page size to avoid this.", - [query class]); - return NO; - } - - GTLRServiceTicket *newTicket; - if ([query isBatchQuery]) { - newTicket = [self executeBatchQuery:(GTLRBatchQuery *)query - completionHandler:handler - ticket:ticket]; - } else { - BOOL mayAuthorize = !query.shouldSkipAuthorization; - NSURL *url = [self URLFromQueryObject:query - usePartialPaths:NO - includeServiceURLQueryParams:YES]; - newTicket = [self fetchObjectWithURL:url - objectClass:query.expectedObjectClass - bodyObject:query.bodyObject - ETag:nil - httpMethod:query.httpMethod - mayAuthorize:mayAuthorize - completionHandler:handler - executingQuery:query - ticket:ticket]; - } - - // In the bizarre case that the fetch didn't begin, newTicket will be - // nil. So long as the new ticket is the same as the ticket we're - // continuing, then we're happy. - GTLR_ASSERT(newTicket == ticket || newTicket == nil, - @"Pagination should not create an additional ticket: %@", newTicket); - - BOOL isFetchingNextPageWithCurrentTicket = (newTicket == ticket); - return isFetchingNextPageWithCurrentTicket; -} - -// Given a new single or batch result (meaning additional pages for a previous -// query result), merge it into the old result, and return the updated object. -// -// For a single result, this inserts the old result items into the new result. -// For batch results, this replaces some of the old items with new items. -// -// This method changes the objects passed in (the old result for batches, the new result -// for individual objects.) -- (GTLRObject *)mergedNewResultObject:(GTLRObject *)newResult - oldResultObject:(GTLRObject *)oldResult - forQuery:(id<GTLRQueryProtocol>)query - ticket:(GTLRServiceTicket *)ticket { - GTLR_DEBUG_ASSERT([oldResult isMemberOfClass:[newResult class]], - @"Trying to merge %@ and %@", [oldResult class], [newResult class]); - - if ([query isBatchQuery]) { - // Batch query result - // - // The new batch results are a subset of the old result's queries, since - // not all queries in the batch necessarily have additional pages. - // - // New success objects replace old success objects, with the old items - // prepended; new failure objects replace old success objects. - // We will update the old batch results with accumulated items, using the - // new objects, and return the old batch. - // - // We reuse the old batch results object because it may include some earlier - // results which did not have additional pages. - GTLRBatchResult *newBatchResult = (GTLRBatchResult *)newResult; - GTLRBatchResult *oldBatchResult = (GTLRBatchResult *)oldResult; - - NSDictionary *newSuccesses = newBatchResult.successes; - if (newSuccesses.count > 0) { - NSDictionary *oldSuccesses = oldBatchResult.successes; - NSMutableDictionary *mutableOldSuccesses = [oldSuccesses mutableCopy]; - - for (NSString *requestID in newSuccesses) { - GTLRObject *newObj = [newSuccesses objectForKey:requestID]; - GTLRObject *oldObj = [oldSuccesses objectForKey:requestID]; - - GTLRQuery *thisQuery = [ticket queryForRequestID:requestID]; - - // Recursively merge the single query's result object, appending new items to the old items. - GTLRObject *updatedObj = [self mergedNewResultObject:newObj - oldResultObject:oldObj - forQuery:thisQuery - ticket:ticket]; - - // In the old batch, replace the old result object with the new one. - [mutableOldSuccesses setObject:updatedObj forKey:requestID]; - } // for requestID - oldBatchResult.successes = mutableOldSuccesses; - } // newSuccesses.count > 0 - - NSDictionary *newFailures = newBatchResult.failures; - if (newFailures.count > 0) { - NSMutableDictionary *mutableOldSuccesses = [oldBatchResult.successes mutableCopy]; - NSMutableDictionary *mutableOldFailures = [oldBatchResult.failures mutableCopy]; - for (NSString *requestID in newFailures) { - // In the old batch, replace old successes or failures with the new failure. - GTLRErrorObject *newError = [newFailures objectForKey:requestID]; - [mutableOldFailures setObject:newError forKey:requestID]; - - [mutableOldSuccesses removeObjectForKey:requestID]; - } - oldBatchResult.failures = mutableOldFailures; - oldBatchResult.successes = mutableOldSuccesses; - } // newFailures.count > 0 - return oldBatchResult; - } else { - // Single query result - // - // Merge the items into the new object, and return the new object. - NSString *itemsKey = [[oldResult class] collectionItemsKey]; - - GTLR_DEBUG_ASSERT([oldResult respondsToSelector:NSSelectorFromString(itemsKey)], - @"Collection items key \"%@\" not implemented by %@", itemsKey, oldResult); - if (itemsKey) { - // Append the new items to the old items. - NSArray *oldItems = [oldResult valueForKey:itemsKey]; - NSArray *newItems = [newResult valueForKey:itemsKey]; - NSMutableArray *items = [NSMutableArray arrayWithArray:oldItems]; - [items addObjectsFromArray:newItems]; - [newResult setValue:items forKey:itemsKey]; - } else { - // This shouldn't happen. - newResult = oldResult; - } - return newResult; - } -} - -#pragma mark - - -// GTLRQuery methods. - -// Helper to create the URL from the parts. -- (NSURL *)URLFromQueryObject:(GTLRQuery *)query - usePartialPaths:(BOOL)usePartialPaths - includeServiceURLQueryParams:(BOOL)includeServiceURLQueryParams { - NSString *rootURLString = self.rootURLString; - - // Skip URI template expansion if the resource URL was provided. - if ([query isKindOfClass:[GTLRResourceURLQuery class]]) { - // Because the query is created by the service rather than by the user, - // query.additionalURLQueryParameters must be nil, and usePartialPaths - // is irrelevant as the query is not in a batch. - GTLR_DEBUG_ASSERT(!usePartialPaths, - @"Batch not supported with resource URL fetch"); - GTLR_DEBUG_ASSERT(!query.uploadParameters && !query.useMediaDownloadService - && !query.downloadAsDataObjectType && !query.additionalURLQueryParameters, - @"Unsupported query properties"); - NSURL *result = ((GTLRResourceURLQuery *)query).resourceURL; - if (includeServiceURLQueryParams) { - NSDictionary *additionalParams = self.additionalURLQueryParameters; - if (additionalParams.count) { - result = [GTLRService URLWithString:result.absoluteString - queryParameters:additionalParams]; - } - } - return result; - } - - // This is all the dance needed due to having query and path parameters for - // REST based queries. - NSDictionary *params = query.JSON; - NSString *queryFilledPathURI = [GTLRURITemplate expandTemplate:query.pathURITemplate - values:params]; - - // Per https://developers.google.com/discovery/v1/using#build-compose and - // https://developers.google.com/discovery/v1/using#discovery-doc-methods-mediadownload - // glue together the parts. - NSString *servicePath = self.servicePath ?: @""; - NSString *uploadPath = @""; - NSString *downloadPath = @""; - - GTLR_DEBUG_ASSERT([rootURLString hasSuffix:@"/"], - @"rootURLString should end in a slash: %@", rootURLString); - GTLR_DEBUG_ASSERT(((servicePath.length == 0) || - (![servicePath hasPrefix:@"/"] && [servicePath hasSuffix:@"/"])), - @"servicePath shouldn't start with a slash but should end with one: %@", - servicePath); - GTLR_DEBUG_ASSERT(![query.pathURITemplate hasPrefix:@"/"], - @"the queries's pathURITemplate should not start with a slash: %@", - query.pathURITemplate); - - GTLRUploadParameters *uploadParameters = query.uploadParameters; - if (uploadParameters != nil) { - // If there is an override, clear all the parts and just use it with the - // the rootURLString. - NSString *override = (uploadParameters.shouldUploadWithSingleRequest - ? query.simpleUploadPathURITemplateOverride - : query.resumableUploadPathURITemplateOverride); - if (override.length > 0) { - GTLR_DEBUG_ASSERT(![override hasPrefix:@"/"], - @"The query's %@UploadPathURITemplateOverride should not start with a slash: %@", - (uploadParameters.shouldUploadWithSingleRequest ? @"simple" : @"resumable"), - override); - queryFilledPathURI = [GTLRURITemplate expandTemplate:override - values:params]; - servicePath = @""; - } else { - if (uploadParameters.shouldUploadWithSingleRequest) { - uploadPath = self.simpleUploadPath ?: @""; - } else { - uploadPath = self.resumableUploadPath ?: @""; - } - GTLR_DEBUG_ASSERT(((uploadPath.length == 0) || - (![uploadPath hasPrefix:@"/"] && - [uploadPath hasSuffix:@"/"])), - @"%@UploadPath shouldn't start with a slash but should end with one: %@", - (uploadParameters.shouldUploadWithSingleRequest ? @"simple" : @"resumable"), - uploadPath); - } - } - - if (query.useMediaDownloadService && - (query.downloadAsDataObjectType.length > 0)) { - downloadPath = @"download/"; - GTLR_DEBUG_ASSERT(uploadPath.length == 0, - @"Uploading while also downloading via mediaDownService" - @" is not well defined."); - } - - if (usePartialPaths) rootURLString = @"/"; - - NSString *urlString = - [NSString stringWithFormat:@"%@%@%@%@%@", - rootURLString, downloadPath, uploadPath, servicePath, queryFilledPathURI]; - - // Remove the path parameters from the dictionary. - NSMutableDictionary *workingQueryParams = [NSMutableDictionary dictionaryWithDictionary:params]; - - NSArray *pathParameterNames = query.pathParameterNames; - if (pathParameterNames.count > 0) { - [workingQueryParams removeObjectsForKeys:pathParameterNames]; - } - - // Note: A developer can override the uploadType and alt query parameters via - // query.additionalURLQueryParameters since those are added afterwards. - if (uploadParameters.shouldUploadWithSingleRequest) { - NSString *uploadType = uploadParameters.shouldSendUploadOnly ? @"media" : @"multipart"; - [workingQueryParams setObject:uploadType forKey:@"uploadType"]; - } - NSString *downloadAsDataObjectType = query.downloadAsDataObjectType; - if (downloadAsDataObjectType.length > 0) { - [workingQueryParams setObject:downloadAsDataObjectType - forKey:@"alt"]; - } - - // Add any parameters the user added directly to the query. - NSDictionary *mergedParams = MergeDictionaries(workingQueryParams, - query.additionalURLQueryParameters); - if (includeServiceURLQueryParams) { - // Query parameters override service parameters. - mergedParams = MergeDictionaries(self.additionalURLQueryParameters, mergedParams); - } - - NSURL *result = [GTLRService URLWithString:urlString - queryParameters:mergedParams]; - return result; -} - -- (GTLRServiceTicket *)executeQuery:(id<GTLRQueryProtocol>)queryObj - delegate:(id)delegate - didFinishSelector:(SEL)finishedSelector { - GTMSessionFetcherAssertValidSelector(delegate, finishedSelector, - @encode(GTLRServiceTicket *), @encode(GTLRObject *), @encode(NSError *), 0); - GTLRServiceCompletionHandler completionHandler = ^(GTLRServiceTicket *ticket, - id object, - NSError *error) { - if (delegate && finishedSelector) { - NSMethodSignature *sig = [delegate methodSignatureForSelector:finishedSelector]; - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig]; - [invocation setSelector:(SEL)finishedSelector]; - [invocation setTarget:delegate]; - [invocation setArgument:&ticket atIndex:2]; - [invocation setArgument:&object atIndex:3]; - [invocation setArgument:&error atIndex:4]; - [invocation invoke]; - } - }; - return [self executeQuery:queryObj completionHandler:completionHandler]; -} - -- (GTLRServiceTicket *)executeQuery:(id<GTLRQueryProtocol>)queryObj - completionHandler:(void (^)(GTLRServiceTicket *ticket, id object, - NSError *error))handler { - if ([queryObj isBatchQuery]) { - GTLR_DEBUG_ASSERT([queryObj isKindOfClass:[GTLRBatchQuery class]], - @"GTLRBatchQuery required for batches (passed %@)", - [queryObj class]); - return [self executeBatchQuery:(GTLRBatchQuery *)queryObj - completionHandler:handler - ticket:nil]; - } - GTLR_DEBUG_ASSERT([queryObj isKindOfClass:[GTLRQuery class]], - @"GTLRQuery required for single queries (passed %@)", - [queryObj class]); - - // Copy the original query so our working query cannot be modified by the caller, - // and release the callback blocks from the supplied query object. - GTLRQuery *query = [(GTLRQuery *)queryObj copy]; - - GTLR_DEBUG_ASSERT(!query.queryInvalid, @"Query has already been executed: %@", query); - [queryObj invalidateQuery]; - - // For individual queries, we rely on the fetcher's log formatting so pretty-printing - // is not needed. Developers may override this in the query's additionalURLQueryParameters. - NSArray *prettyPrintNames = self.prettyPrintQueryParameterNames; - NSString *firstPrettyPrintName = prettyPrintNames.firstObject; - if (firstPrettyPrintName && (query.downloadAsDataObjectType.length == 0) - && ![query isKindOfClass:[GTLRResourceURLQuery class]]) { - NSDictionary *queryParams = query.additionalURLQueryParameters; - BOOL foundOne = NO; - for (NSString *name in prettyPrintNames) { - if ([queryParams objectForKey:name] != nil) { - foundOne = YES; - break; - } - } - if (!foundOne) { - NSMutableDictionary *worker = - [NSMutableDictionary dictionaryWithDictionary:queryParams]; - [worker setObject:@"false" forKey:firstPrettyPrintName]; - query.additionalURLQueryParameters = worker; - } - } - - BOOL mayAuthorize = !query.shouldSkipAuthorization; - NSURL *url = [self URLFromQueryObject:query - usePartialPaths:NO - includeServiceURLQueryParams:YES]; - - return [self fetchObjectWithURL:url - objectClass:query.expectedObjectClass - bodyObject:query.bodyObject - ETag:nil - httpMethod:query.httpMethod - mayAuthorize:mayAuthorize - completionHandler:handler - executingQuery:query - ticket:nil]; -} - -- (GTLRServiceTicket *)fetchObjectWithURL:(NSURL *)resourceURL - objectClass:(nullable Class)objectClass - executionParameters:(nullable GTLRServiceExecutionParameters *)executionParameters - completionHandler:(nullable GTLRServiceCompletionHandler)handler { - GTLRResourceURLQuery *query = [GTLRResourceURLQuery queryWithResourceURL:resourceURL - objectClass:objectClass]; - query.executionParameters = executionParameters; - - return [self executeQuery:query - completionHandler:handler]; -} - -#pragma mark - - -- (NSString *)userAgent { - return _userAgent; -} - -- (void)setExactUserAgent:(NSString *)userAgent { - _userAgent = [userAgent copy]; -} - -- (void)setUserAgent:(NSString *)userAgent { - // remove whitespace and unfriendly characters - NSString *str = GTMFetcherCleanedUserAgentString(userAgent); - [self setExactUserAgent:str]; -} - -- (void)overrideRequestUserAgent:(nullable NSString *)requestUserAgent { - _overrideUserAgent = [requestUserAgent copy]; -} - -#pragma mark - - -+ (NSDictionary<NSString *, Class> *)kindStringToClassMap { - // Generated services will provide custom ones. - return [NSDictionary dictionary]; -} - -#pragma mark - - -// The service properties becomes the initial value for each future ticket's -// properties -- (void)setServiceProperties:(NSDictionary *)dict { - _serviceProperties = [dict copy]; -} - -- (NSDictionary *)serviceProperties { - // be sure the returned pointer has the life of the autorelease pool, - // in case self is released immediately - __autoreleasing id props = _serviceProperties; - return props; -} - -- (void)setAuthorizer:(id <GTMFetcherAuthorizationProtocol>)authorizer { - self.fetcherService.authorizer = authorizer; -} - -- (id <GTMFetcherAuthorizationProtocol>)authorizer { - return self.fetcherService.authorizer; -} - -+ (NSUInteger)defaultServiceUploadChunkSize { - // Subclasses may override this method. - - // The upload server prefers multiples of 256K. - const NSUInteger kMegabyte = 4 * 256 * 1024; - -#if TARGET_OS_IPHONE - // For iOS, we're balancing a large upload size with limiting the memory - // used for the upload data buffer. - return 4 * kMegabyte; -#else - // A large upload chunk size minimizes http overhead and server effort. - return 25 * kMegabyte; -#endif -} - -- (NSUInteger)serviceUploadChunkSize { - if (_uploadChunkSize > 0) { - return _uploadChunkSize; - } - return [[self class] defaultServiceUploadChunkSize]; -} - -- (void)setServiceUploadChunkSize:(NSUInteger)val { - _uploadChunkSize = val; -} - -- (void)setSurrogates:(NSDictionary <Class, Class>*)surrogates { - NSDictionary *kindMap = [[self class] kindStringToClassMap]; - - self.objectClassResolver = [GTLRObjectClassResolver resolverWithKindMap:kindMap - surrogates:surrogates]; -} - -#pragma mark - Internal helper - -// If there are already query parameters on urlString, the new ones are simply -// appended after them. -+ (NSURL *)URLWithString:(NSString *)urlString - queryParameters:(NSDictionary *)queryParameters { - if (urlString.length == 0) return nil; - - NSString *fullURLString; - if (queryParameters.count > 0) { - // Use GTLRURITemplate by building up a template and then feeding in the - // values. The template is query expansion ('?'), and any key that is - // an array or dictionary gets tagged to explode them ('+'). - NSArray *sortedQueryParamKeys = - [queryParameters.allKeys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; - - NSMutableString *template = [@"{" mutableCopy]; - char joiner = '?'; - for (NSString *key in sortedQueryParamKeys) { - [template appendFormat:@"%c%@", joiner, key]; - id value = [queryParameters objectForKey:key]; - if ([value isKindOfClass:[NSArray class]] || - [value isKindOfClass:[NSDictionary class]]) { - [template appendString:@"+"]; - } - joiner = ','; - } - [template appendString:@"}"]; - NSString *urlArgs = - [GTLRURITemplate expandTemplate:template - values:queryParameters]; - urlArgs = [urlArgs substringFromIndex:1]; // Drop the '?' and use the joiner. - - BOOL missingQMark = ([urlString rangeOfString:@"?"].location == NSNotFound); - joiner = missingQMark ? '?' : '&'; - fullURLString = - [NSString stringWithFormat:@"%@%c%@", urlString, joiner, urlArgs]; - } else { - fullURLString = urlString; - } - NSURL *result = [NSURL URLWithString:fullURLString]; - return result; -} - -@end - -@implementation GTLRService (TestingSupport) - -+ (instancetype)mockServiceWithFakedObject:(id)objectOrNil - fakedError:(NSError *)errorOrNil { - GTLRService *service = [[GTLRService alloc] init]; - service.rootURLString = @"https://example.invalid/"; - service.testBlock = ^(GTLRServiceTicket *ticket, GTLRServiceTestResponse testResponse) { - testResponse(objectOrNil, errorOrNil); - }; - return service; -} - -- (BOOL)waitForTicket:(GTLRServiceTicket *)ticket - timeout:(NSTimeInterval)timeoutInSeconds { - // Loop until the fetch completes or is cancelled, or until the timeout has expired. - NSDate *giveUpDate = [NSDate dateWithTimeIntervalSinceNow:timeoutInSeconds]; - - BOOL hasTimedOut = NO; - while (1) { - int64_t delta = (int64_t)(100 * NSEC_PER_MSEC); // 100 ms - BOOL areCallbacksPending = - (dispatch_group_wait(ticket.callbackGroup, dispatch_time(DISPATCH_TIME_NOW, delta)) != 0); - - if (!areCallbacksPending && (ticket.hasCalledCallback || ticket.cancelled)) break; - - hasTimedOut = (giveUpDate.timeIntervalSinceNow <= 0); - if (hasTimedOut) { - if (areCallbacksPending) { - // A timeout while waiting for the dispatch group to finish is seriously unexpected. - GTLR_DEBUG_LOG(@"%s timed out while waiting for the dispatch group", __PRETTY_FUNCTION__); - } else { - GTLR_DEBUG_LOG(@"%s timed out without callbacks pending", __PRETTY_FUNCTION__); - } - break; - } - - // Run the current run loop 1/1000 of a second to give the networking - // code a chance to work. - NSDate *stopDate = [NSDate dateWithTimeIntervalSinceNow:0.001]; - [[NSRunLoop currentRunLoop] runUntilDate:stopDate]; - } - return !hasTimedOut; -} - -@end - -@implementation GTLRServiceTicket { - GTLRService *_service; - NSDictionary *_ticketProperties; - GTLRServiceUploadProgressBlock _uploadProgressBlock; - BOOL _needsStopNotification; -} - -@synthesize APIKey = _apiKey, - APIKeyRestrictionBundleID = _apiKeyRestrictionBundleID, - allowInsecureQueries = _allowInsecureQueries, - authorizer = _authorizer, - cancelled = _cancelled, - callbackGroup = _callbackGroup, - callbackQueue = _callbackQueue, - creationDate = _creationDate, - executingQuery = _executingQuery, - fetchedObject = _fetchedObject, - fetchError = _fetchError, - fetchRequest = _fetchRequest, - fetcherService = _fetcherService, - hasCalledCallback = _hasCalledCallback, - maxRetryInterval = _maxRetryInterval, - objectFetcher = _objectFetcher, - originalQuery = _originalQuery, - pagesFetchedCounter = _pagesFetchedCounter, - postedObject = _postedObject, - retryBlock = _retryBlock, - retryEnabled = _retryEnabled, - shouldFetchNextPages = _shouldFetchNextPages, - objectClassResolver = _objectClassResolver, - testBlock = _testBlock; - -#if GTM_BACKGROUND_TASK_FETCHING -@synthesize backgroundTaskIdentifier = _backgroundTaskIdentifier; -#endif - -#if DEBUG -- (instancetype)init { - [self doesNotRecognizeSelector:_cmd]; - self = nil; - return self; -} -#endif - -#if GTM_BACKGROUND_TASK_FETCHING && DEBUG -- (void)dealloc { - GTLR_DEBUG_ASSERT(_backgroundTaskIdentifier == UIBackgroundTaskInvalid, - @"Background task not ended"); -} -#endif // GTM_BACKGROUND_TASK_FETCHING && DEBUG - - -- (instancetype)initWithService:(GTLRService *)service - executionParameters:(GTLRServiceExecutionParameters *)params { - self = [super init]; - if (self) { - // ivars set at init time and never changed are exposed as atomic readonly properties. - _service = service; - _fetcherService = service.fetcherService; - _authorizer = service.authorizer; - - _ticketProperties = MergeDictionaries(service.serviceProperties, params.ticketProperties); - - _objectClassResolver = params.objectClassResolver ?: service.objectClassResolver; - - _retryEnabled = ((params.retryEnabled != nil) ? params.retryEnabled.boolValue : service.retryEnabled); - _maxRetryInterval = ((params.maxRetryInterval != nil) ? - params.maxRetryInterval.doubleValue : service.maxRetryInterval); - _shouldFetchNextPages = ((params.shouldFetchNextPages != nil)? - params.shouldFetchNextPages.boolValue : service.shouldFetchNextPages); - - GTLRServiceUploadProgressBlock uploadProgressBlock = - params.uploadProgressBlock ?: service.uploadProgressBlock; - _uploadProgressBlock = [uploadProgressBlock copy]; - - GTLRServiceRetryBlock retryBlock = params.retryBlock ?: service.retryBlock; - _retryBlock = [retryBlock copy]; - if (_retryBlock) { - _retryEnabled = YES; - } - - _testBlock = params.testBlock ?: service.testBlock; - - _callbackQueue = ((_Nonnull dispatch_queue_t)params.callbackQueue) ?: service.callbackQueue; - _callbackGroup = dispatch_group_create(); - - _apiKey = [service.APIKey copy]; - _apiKeyRestrictionBundleID = [service.APIKeyRestrictionBundleID copy]; - _allowInsecureQueries = service.allowInsecureQueries; - -#if GTM_BACKGROUND_TASK_FETCHING - _backgroundTaskIdentifier = UIBackgroundTaskInvalid; -#endif - - _creationDate = [NSDate date]; - } - return self; -} - -- (NSString *)description { - NSString *devKeyInfo = @""; - if (_apiKey != nil) { - devKeyInfo = [NSString stringWithFormat:@" devKey:%@", _apiKey]; - } - NSString *keyRestrictionInfo = @""; - if (_apiKeyRestrictionBundleID != nil) { - keyRestrictionInfo = [NSString stringWithFormat:@" restriction:%@", - _apiKeyRestrictionBundleID]; - } - - NSString *authorizerInfo = @""; - id <GTMFetcherAuthorizationProtocol> authorizer = self.objectFetcher.authorizer; - if (authorizer != nil) { - authorizerInfo = [NSString stringWithFormat:@" authorizer:%@", authorizer]; - } - - return [NSString stringWithFormat:@"%@ %p: {service:%@%@%@%@ fetcher:%@ }", - [self class], self, - _service, devKeyInfo, keyRestrictionInfo, authorizerInfo, _objectFetcher]; -} - -- (void)postNotificationOnMainThreadWithName:(NSString *)name - object:(id)object - userInfo:(NSDictionary *)userInfo { - // We always post these async to ensure they remain in order. - dispatch_group_async(self.callbackGroup, dispatch_get_main_queue(), ^{ - [[NSNotificationCenter defaultCenter] postNotificationName:name - object:object - userInfo:userInfo]; - }); -} - -- (void)pauseUpload { - GTMSessionFetcher *fetcher = self.objectFetcher; - BOOL canPause = [fetcher respondsToSelector:@selector(pauseFetching)]; - GTLR_DEBUG_ASSERT(canPause, @"tickets can be paused only for chunked resumable uploads"); - - if (canPause) { - [(GTMSessionUploadFetcher *)fetcher pauseFetching]; - } -} - -- (void)resumeUpload { - GTMSessionFetcher *fetcher = self.objectFetcher; - BOOL canResume = [fetcher respondsToSelector:@selector(resumeFetching)]; - GTLR_DEBUG_ASSERT(canResume, @"tickets can be resumed only for chunked resumable uploads"); - - if (canResume) { - [(GTMSessionUploadFetcher *)fetcher resumeFetching]; - } -} - -- (BOOL)isUploadPaused { - BOOL isPausable = [_objectFetcher respondsToSelector:@selector(isPaused)]; - GTLR_DEBUG_ASSERT(isPausable, @"tickets can be paused only for chunked resumable uploads"); - - if (isPausable) { - return [(GTMSessionUploadFetcher *)_objectFetcher isPaused]; - } - return NO; -} - -- (BOOL)isCancelled { - @synchronized(self) { - return _cancelled; - } -} - -- (void)cancelTicket { - @synchronized(self) { - _cancelled = YES; - } - - [_objectFetcher stopFetching]; - - self.objectFetcher = nil; - self.fetchRequest = nil; - _ticketProperties = nil; - - [self releaseTicketCallbacks]; - [self endBackgroundTask]; - - [self.executingQuery invalidateQuery]; - - id<GTLRQueryProtocol> originalQuery = self.originalQuery; - self.executingQuery = originalQuery; - [originalQuery invalidateQuery]; - - _service = nil; - _fetcherService = nil; - _authorizer = nil; - _testBlock = nil; -} - -#if GTM_BACKGROUND_TASK_FETCHING -// When the fetcher's substitute UIApplication object is present, GTLRService -// will use that instead of UIApplication. This is just to reduce duplicating -// that plumbing for testing. -+ (nullable id<GTMUIApplicationProtocol>)fetcherUIApplication { - id<GTMUIApplicationProtocol> app = [GTMSessionFetcher substituteUIApplication]; - if (app) return app; - - static Class applicationClass = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - BOOL isAppExtension = [[[NSBundle mainBundle] bundlePath] hasSuffix:@".appex"]; - if (!isAppExtension) { - Class cls = NSClassFromString(@"UIApplication"); - if (cls && [cls respondsToSelector:NSSelectorFromString(@"sharedApplication")]) { - applicationClass = cls; - } - } - }); - - if (applicationClass) { - app = (id<GTMUIApplicationProtocol>)[applicationClass sharedApplication]; - } - return app; -} -#endif // GTM_BACKGROUND_TASK_FETCHING - -- (void)startBackgroundTask { -#if GTM_BACKGROUND_TASK_FETCHING - GTLR_DEBUG_ASSERT(self.backgroundTaskIdentifier == UIBackgroundTaskInvalid, - @"Redundant GTLRService background task: %tu", self.backgroundTaskIdentifier); - - NSString *taskName = [[self.executingQuery class] description]; - - id<GTMUIApplicationProtocol> app = [[self class] fetcherUIApplication]; - - // We'll use a locally-scoped task ID variable so the expiration block is guaranteed - // to refer to this task rather than to whatever task the property has. - __block UIBackgroundTaskIdentifier bgTaskID = - [app beginBackgroundTaskWithName:taskName - expirationHandler:^{ - // Background task expiration callback. This block is always invoked by - // UIApplication on the main thread. - if (bgTaskID != UIBackgroundTaskInvalid) { - @synchronized(self) { - if (bgTaskID == self.backgroundTaskIdentifier) { - self.backgroundTaskIdentifier = UIBackgroundTaskInvalid; - } - } - // This explicitly ends the captured bgTaskID rather than the backgroundTaskIdentifier - // property to ensure expiration is handled even if the property has changed. - [app endBackgroundTask:bgTaskID]; - } - }]; - @synchronized(self) { - self.backgroundTaskIdentifier = bgTaskID; - } -#endif // GTM_BACKGROUND_TASK_FETCHING -} - -- (void)endBackgroundTask { -#if GTM_BACKGROUND_TASK_FETCHING - // Whenever the connection stops or a next page is about to be fetched, - // tell UIApplication we're done. - UIBackgroundTaskIdentifier bgTaskID; - @synchronized(self) { - bgTaskID = self.backgroundTaskIdentifier; - self.backgroundTaskIdentifier = UIBackgroundTaskInvalid; - } - if (bgTaskID != UIBackgroundTaskInvalid) { - [[[self class] fetcherUIApplication] endBackgroundTask:bgTaskID]; - } -#endif // GTM_BACKGROUND_TASK_FETCHING -} - -- (void)releaseTicketCallbacks { - self.uploadProgressBlock = nil; - self.retryBlock = nil; -} - -- (void)notifyStarting:(BOOL)isStarting { - GTLR_DEBUG_ASSERT(!GTLR_AreBoolsEqual(isStarting, _needsStopNotification), - @"Notification mismatch (isStarting=%d)", isStarting); - if (GTLR_AreBoolsEqual(isStarting, _needsStopNotification)) return; - - NSString *name; - if (isStarting) { - name = kGTLRServiceTicketStartedNotification; - _needsStopNotification = YES; - } else { - name = kGTLRServiceTicketStoppedNotification; - _needsStopNotification = NO; - } - [self postNotificationOnMainThreadWithName:name - object:self - userInfo:nil]; -} - -- (id)service { - return _service; -} - -- (void)setObjectFetcher:(GTMSessionFetcher *)fetcher { - @synchronized(self) { - _objectFetcher = fetcher; - } - - [self updateObjectFetcherProgressCallbacks]; -} - -- (GTMSessionFetcher *)objectFetcher { - @synchronized(self) { - return _objectFetcher; - } -} - -- (NSDictionary *)ticketProperties { - // be sure the returned pointer has the life of the autorelease pool, - // in case self is released immediately - __autoreleasing id props = _ticketProperties; - return props; -} - -- (GTLRServiceUploadProgressBlock)uploadProgressBlock { - return _uploadProgressBlock; -} - -- (void)setUploadProgressBlock:(GTLRServiceUploadProgressBlock)block { - if (_uploadProgressBlock != block) { - _uploadProgressBlock = [block copy]; - - [self updateObjectFetcherProgressCallbacks]; - } -} - -- (void)updateObjectFetcherProgressCallbacks { - // Internal method. Do not override. - GTMSessionFetcher *fetcher = [self objectFetcher]; - - if (_uploadProgressBlock) { - // Use a local block variable to avoid a spurious retain cycle warning. - GTMSessionFetcherSendProgressBlock fetcherSentDataBlock = ^(int64_t bytesSent, - int64_t totalBytesSent, - int64_t totalBytesExpectedToSend) { - [self->_service invokeProgressCallbackForTicket:self - deliveredBytes:(unsigned long long)totalBytesSent - totalBytes:(unsigned long long)totalBytesExpectedToSend]; - }; - - fetcher.sendProgressBlock = fetcherSentDataBlock; - } else { - fetcher.sendProgressBlock = nil; - } -} - -- (NSInteger)statusCode { - return [_objectFetcher statusCode]; -} - -- (GTLRQuery *)queryForRequestID:(NSString *)requestID { - id<GTLRQueryProtocol> queryObj = self.executingQuery; - if ([queryObj isBatchQuery]) { - GTLRBatchQuery *batch = (GTLRBatchQuery *)queryObj; - GTLRQuery *result = [batch queryForRequestID:requestID]; - return result; - } else { - GTLR_DEBUG_ASSERT(0, @"just use ticket.executingQuery"); - return nil; - } -} - -@end - -@implementation GTLRServiceExecutionParameters - -@synthesize maxRetryInterval = _maxRetryInterval, - retryEnabled = _retryEnabled, - retryBlock = _retryBlock, - shouldFetchNextPages = _shouldFetchNextPages, - objectClassResolver = _objectClassResolver, - testBlock = _testBlock, - ticketProperties = _ticketProperties, - uploadProgressBlock = _uploadProgressBlock, - callbackQueue = _callbackQueue; - -- (id)copyWithZone:(NSZone *)zone { - GTLRServiceExecutionParameters *newObject = [[self class] allocWithZone:zone]; - newObject.maxRetryInterval = self.maxRetryInterval; - newObject.retryEnabled = self.retryEnabled; - newObject.retryBlock = self.retryBlock; - newObject.shouldFetchNextPages = self.shouldFetchNextPages; - newObject.objectClassResolver = self.objectClassResolver; - newObject.testBlock = self.testBlock; - newObject.ticketProperties = self.ticketProperties; - newObject.uploadProgressBlock = self.uploadProgressBlock; - newObject.callbackQueue = self.callbackQueue; - return newObject; -} - -- (BOOL)hasParameters { - if (self.maxRetryInterval != nil) return YES; - if (self.retryEnabled != nil) return YES; - if (self.retryBlock) return YES; - if (self.shouldFetchNextPages != nil) return YES; - if (self.objectClassResolver) return YES; - if (self.testBlock) return YES; - if (self.ticketProperties) return YES; - if (self.uploadProgressBlock) return YES; - if (self.callbackQueue) return YES; - return NO; -} - -@end - - -@implementation GTLRResourceURLQuery - -@synthesize resourceURL = _resourceURL; - -+ (instancetype)queryWithResourceURL:(NSURL *)resourceURL - objectClass:(Class)objectClass { - GTLRResourceURLQuery *query = [[self alloc] initWithPathURITemplate:@"_usingGTLRResourceURLQuery_" - HTTPMethod:nil - pathParameterNames:nil]; - query.expectedObjectClass = objectClass; - query.resourceURL = resourceURL; - return query; -} - -- (instancetype)copyWithZone:(NSZone *)zone { - GTLRResourceURLQuery *result = [super copyWithZone:zone]; - result->_resourceURL = self->_resourceURL; - return result; -} - -// TODO: description - -@end - -@implementation GTLRObjectCollectionImpl -@dynamic nextPageToken; -@end diff --git a/Pods/GoogleAPIClientForREST/Source/Objects/GTLRUploadParameters.h b/Pods/GoogleAPIClientForREST/Source/Objects/GTLRUploadParameters.h @@ -1,124 +0,0 @@ -/* Copyright (c) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// Uploading documentation: -// https://github.com/google/google-api-objectivec-client-for-rest/wiki#uploading-files - -#import <Foundation/Foundation.h> - -#import "GTLRDefines.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - * Upload parameters are required for chunked-resumable or simple/multipart uploads. - * - * The MIME type and one source for data (@c NSData, file URL, or @c NSFileHandle) must - * be specified. - */ -@interface GTLRUploadParameters : NSObject <NSCopying> - -/** - * The type of media being uploaded. - */ -@property(atomic, copy, nullable) NSString *MIMEType; - -/** - * The media to be uploaded, represented as @c NSData. - */ -@property(atomic, retain, nullable) NSData *data; - -/** - * The URL for the local file to be uploaded. - */ -@property(atomic, retain, nullable) NSURL *fileURL; - -/** - * The media to be uploaded, represented as @c NSFileHandle. - * - * @note This property is provided for compatibility with older code. - * Uploading using @c fileURL is preferred over @c fileHandle - */ -@property(atomic, retain, nullable) NSFileHandle *fileHandle; - -/** - * Resuming an in-progress resumable, chunked upload is done with the upload location URL, - * and requires a file URL or file handle for uploading. - */ -@property(atomic, retain, nullable) NSURL *uploadLocationURL; - -/** - * Small uploads (for example, under 200K) can be done with a single multipart upload - * request. The upload body must be provided as NSData, not a file URL or file handle. - * - * Default value is NO. - */ -@property(atomic, assign) BOOL shouldUploadWithSingleRequest; - -/** - * Uploads may be done without a JSON body as metadata in the initial request. - * - * Default value is NO. - */ -@property(atomic, assign) BOOL shouldSendUploadOnly; - -/** - * Uploads may use a background session when uploading via GTMSessionUploadFetcher. - * Since background session fetches are slower than foreground fetches, this defaults - * to NO. - * - * It's reasonable for an application to set this to YES for a rare upload of a large file. - * - * Default value is NO. - * - * For more information about the hazards of background sessions, see the header comments for - * the GTMSessionFetcher useBackgroundSession property. - */ -@property(atomic, assign) BOOL useBackgroundSession; - -/** - * Constructor for uploading from @c NSData. - * - * @param data The data to uploaded. - * @param mimeType The media's type. - * - * @return The upload parameters object. - */ -+ (instancetype)uploadParametersWithData:(NSData *)data - MIMEType:(NSString *)mimeType; - -/** - * Constructor for uploading from a file URL. - * - * @param fileURL The file to upload. - * @param mimeType The media's type. - * - * @return The upload parameters object. - */ -+ (instancetype)uploadParametersWithFileURL:(NSURL *)fileURL - MIMEType:(NSString *)mimeType; - -/** - * Constructor for uploading from a file handle. - * - * @note This method is provided for compatibility with older code. To upload files, - * use a file URL. - */ -+ (instancetype)uploadParametersWithFileHandle:(NSFileHandle *)fileHandle - MIMEType:(NSString *)mimeType; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleAPIClientForREST/Source/Objects/GTLRUploadParameters.m b/Pods/GoogleAPIClientForREST/Source/Objects/GTLRUploadParameters.m @@ -1,119 +0,0 @@ -/* Copyright (c) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if !__has_feature(objc_arc) -#error "This file needs to be compiled with ARC enabled." -#endif - -#include <objc/runtime.h> - -#import "GTLRUploadParameters.h" - -@implementation GTLRUploadParameters - -@synthesize MIMEType = _MIMEType, - data = _data, - fileHandle = _fileHandle, - uploadLocationURL = _uploadLocationURL, - fileURL = _fileURL, - shouldUploadWithSingleRequest = _shouldUploadWithSingleRequest, - shouldSendUploadOnly = _shouldSendUploadOnly, - useBackgroundSession = _useBackgroundSession; - -+ (instancetype)uploadParametersWithData:(NSData *)data - MIMEType:(NSString *)mimeType { - GTLRUploadParameters *params = [[self alloc] init]; - params.data = data; - params.MIMEType = mimeType; - return params; -} - -+ (instancetype)uploadParametersWithFileHandle:(NSFileHandle *)fileHandle - MIMEType:(NSString *)mimeType { - GTLRUploadParameters *params = [[self alloc] init]; - params.fileHandle = fileHandle; - params.MIMEType = mimeType; - return params; -} - -+ (instancetype)uploadParametersWithFileURL:(NSURL *)fileURL - MIMEType:(NSString *)mimeType { - GTLRUploadParameters *params = [[self alloc] init]; - params.fileURL = fileURL; - params.MIMEType = mimeType; - return params; -} - -- (id)copyWithZone:(NSZone *)zone { - GTLRUploadParameters *newParams = [[[self class] allocWithZone:zone] init]; - newParams.MIMEType = self.MIMEType; - newParams.data = self.data; - newParams.fileHandle = self.fileHandle; - newParams.fileURL = self.fileURL; - newParams.uploadLocationURL = self.uploadLocationURL; - newParams.shouldUploadWithSingleRequest = self.shouldUploadWithSingleRequest; - newParams.shouldSendUploadOnly = self.shouldSendUploadOnly; - newParams.useBackgroundSession = self.useBackgroundSession; - return newParams; -} - -#if DEBUG -- (NSString *)description { - NSMutableArray *array = [NSMutableArray array]; - NSString *str = [NSString stringWithFormat:@"MIMEType:%@", _MIMEType]; - [array addObject:str]; - - if (_data) { - str = [NSString stringWithFormat:@"data:%llu bytes", - (unsigned long long)_data.length]; - [array addObject:str]; - } - - if (_fileHandle) { - str = [NSString stringWithFormat:@"fileHandle:%@", _fileHandle]; - [array addObject:str]; - } - - if (_fileURL) { - str = [NSString stringWithFormat:@"file:%@", [_fileURL path]]; - [array addObject:str]; - } - - if (_uploadLocationURL) { - str = [NSString stringWithFormat:@"uploadLocation:%@", - [_uploadLocationURL absoluteString]]; - [array addObject:str]; - } - - if (_shouldSendUploadOnly) { - [array addObject:@"shouldSendUploadOnly"]; - } - - if (_shouldUploadWithSingleRequest) { - [array addObject:@"uploadWithSingleRequest"]; - } - - if (_useBackgroundSession) { - [array addObject:@"useBackgroundSession"]; - } - - NSString *descStr = [array componentsJoinedByString:@", "]; - str = [NSString stringWithFormat:@"%@ %p: {%@}", - [self class], self, descStr]; - return str; -} -#endif // DEBUG - -@end diff --git a/Pods/GoogleAPIClientForREST/Source/Utilities/GTLRBase64.h b/Pods/GoogleAPIClientForREST/Source/Utilities/GTLRBase64.h @@ -1,29 +0,0 @@ -/* Copyright (c) 2012 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -NS_ASSUME_NONNULL_BEGIN - -NSData * _Nullable GTLRDecodeBase64(NSString * _Nullable base64Str); -NSString * _Nullable GTLREncodeBase64(NSData * _Nullable data); - -// "Web-safe" encoding substitutes - and _ for + and / in the encoding table, -// per http://www.ietf.org/rfc/rfc4648.txt section 5. - -NSData * _Nullable GTLRDecodeWebSafeBase64(NSString * _Nullable base64Str); -NSString * _Nullable GTLREncodeWebSafeBase64(NSData * _Nullable data); - -NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleAPIClientForREST/Source/Utilities/GTLRBase64.m b/Pods/GoogleAPIClientForREST/Source/Utilities/GTLRBase64.m @@ -1,143 +0,0 @@ -/* Copyright (c) 2012 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if !__has_feature(objc_arc) -#error "This file needs to be compiled with ARC enabled." -#endif - -#import "GTLRBase64.h" - -// Based on Cyrus Najmabadi's elegent little encoder and decoder from -// http://www.cocoadev.com/index.pl?BaseSixtyFour - -static char gStandardEncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -static char gWebSafeEncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; - -#pragma mark Encode - -static NSString *EncodeBase64StringCommon(NSData *data, const char *table) { - if (data == nil) return nil; - - const uint8_t* input = data.bytes; - NSUInteger length = data.length; - - NSUInteger bufferSize = ((length + 2) / 3) * 4; - NSMutableData* buffer = [NSMutableData dataWithLength:bufferSize]; - - int8_t *output = buffer.mutableBytes; - - for (NSUInteger i = 0; i < length; i += 3) { - NSUInteger value = 0; - for (NSUInteger j = i; j < (i + 3); j++) { - value <<= 8; - - if (j < length) { - value |= (0xFF & input[j]); - } - } - - NSInteger idx = (i / 3) * 4; - output[idx + 0] = table[(value >> 18) & 0x3F]; - output[idx + 1] = table[(value >> 12) & 0x3F]; - output[idx + 2] = (i + 1) < length ? table[(value >> 6) & 0x3F] : '='; - output[idx + 3] = (i + 2) < length ? table[(value >> 0) & 0x3F] : '='; - } - - NSString *result = [[NSString alloc] initWithData:buffer - encoding:NSASCIIStringEncoding]; - return result; -} - -NSString *GTLREncodeBase64(NSData *data) { - return EncodeBase64StringCommon(data, gStandardEncodingTable); -} - -NSString *GTLREncodeWebSafeBase64(NSData *data) { - return EncodeBase64StringCommon(data, gWebSafeEncodingTable); -} - -#pragma mark Decode - -static void CreateDecodingTable(const char *encodingTable, - size_t encodingTableSize, char *decodingTable) { - memset(decodingTable, 0, 128); - for (unsigned int i = 0; i < encodingTableSize; i++) { - decodingTable[(unsigned int) encodingTable[i]] = (char)i; - } -} - -static NSData *DecodeBase64StringCommon(NSString *base64Str, - char *decodingTable) { - // The input string should be plain ASCII - const char *cString = [base64Str cStringUsingEncoding:NSASCIIStringEncoding]; - if (cString == nil) return nil; - - NSInteger inputLength = (NSInteger)strlen(cString); - if (inputLength % 4 != 0) return nil; - if (inputLength == 0) return [NSData data]; - - while (inputLength > 0 && cString[inputLength - 1] == '=') { - inputLength--; - } - - NSInteger outputLength = inputLength * 3 / 4; - NSMutableData* data = [NSMutableData dataWithLength:(NSUInteger)outputLength]; - uint8_t *output = data.mutableBytes; - - NSInteger inputPoint = 0; - NSInteger outputPoint = 0; - char *table = decodingTable; - - while (inputPoint < inputLength) { - int i0 = cString[inputPoint++]; - int i1 = cString[inputPoint++]; - int i2 = inputPoint < inputLength ? cString[inputPoint++] : 'A'; // 'A' will decode to \0 - int i3 = inputPoint < inputLength ? cString[inputPoint++] : 'A'; - - output[outputPoint++] = (uint8_t)((table[i0] << 2) | (table[i1] >> 4)); - if (outputPoint < outputLength) { - output[outputPoint++] = (uint8_t)(((table[i1] & 0xF) << 4) | (table[i2] >> 2)); - } - if (outputPoint < outputLength) { - output[outputPoint++] = (uint8_t)(((table[i2] & 0x3) << 6) | table[i3]); - } - } - - return data; -} - -NSData *GTLRDecodeBase64(NSString *base64Str) { - static char decodingTable[128]; - static BOOL hasInited = NO; - - if (!hasInited) { - CreateDecodingTable(gStandardEncodingTable, sizeof(gStandardEncodingTable), - decodingTable); - hasInited = YES; - } - return DecodeBase64StringCommon(base64Str, decodingTable); -} - -NSData *GTLRDecodeWebSafeBase64(NSString *base64Str) { - static char decodingTable[128]; - static BOOL hasInited = NO; - - if (!hasInited) { - CreateDecodingTable(gWebSafeEncodingTable, sizeof(gWebSafeEncodingTable), - decodingTable); - hasInited = YES; - } - return DecodeBase64StringCommon(base64Str, decodingTable); -} diff --git a/Pods/GoogleAPIClientForREST/Source/Utilities/GTLRFramework.h b/Pods/GoogleAPIClientForREST/Source/Utilities/GTLRFramework.h @@ -1,34 +0,0 @@ -/* Copyright (c) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -#import "GTLRDefines.h" - -NS_ASSUME_NONNULL_BEGIN - -// Returns the version of the framework. Major and minor should -// match the bundle version in the Info.plist file. -// -// Pass NULL to ignore any of the parameters. - -void GTLRFrameworkVersion(NSUInteger * _Nullable major, - NSUInteger * _Nullable minor, - NSUInteger * _Nullable release); - -// Returns the version in @"a.b" or @"a.b.c" format -NSString *GTLRFrameworkVersionString(void); - -NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleAPIClientForREST/Source/Utilities/GTLRFramework.m b/Pods/GoogleAPIClientForREST/Source/Utilities/GTLRFramework.m @@ -1,44 +0,0 @@ -/* Copyright (c) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if !__has_feature(objc_arc) -#error "This file needs to be compiled with ARC enabled." -#endif - -#include "GTLRFramework.h" - -void GTLRFrameworkVersion(NSUInteger* major, NSUInteger* minor, NSUInteger* release) { - // version 3.0.0 - if (major) *major = 3; - if (minor) *minor = 0; - if (release) *release = 0; -} - -NSString *GTLRFrameworkVersionString(void) { - NSUInteger major, minor, release; - NSString *libVersionString; - - GTLRFrameworkVersion(&major, &minor, &release); - - // most library releases will have a release value of zero - if (release != 0) { - libVersionString = [NSString stringWithFormat:@"%d.%d.%d", - (int)major, (int)minor, (int)release]; - } else { - libVersionString = [NSString stringWithFormat:@"%d.%d", - (int)major, (int)minor]; - } - return libVersionString; -} diff --git a/Pods/GoogleAPIClientForREST/Source/Utilities/GTLRURITemplate.h b/Pods/GoogleAPIClientForREST/Source/Utilities/GTLRURITemplate.h @@ -1,48 +0,0 @@ -/* Copyright (c) 2010 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -#ifndef SKIP_GTLR_DEFINES - #import "GTLRDefines.h" -#endif - -NS_ASSUME_NONNULL_BEGIN - -// -// URI Template -// -// http://tools.ietf.org/html/draft-gregorio-uritemplate-04 -// -// NOTE: This implemention is only a subset of the spec. It should be able -// to parse any tempate that matches the spec, but if the template makes use -// of a feature that is not supported, it will fail with an error. -// - -@interface GTLRURITemplate : NSObject - -// Process the template. If the template uses an unsupported feature, it will -// throw an exception to help catch that limitation. Currently unsupported -// feature is partial result modifiers (prefix/suffix). -// -// valueProvider should be anything that implements -objectForKey:. At the -// simplest level, this can be an NSDictionary. However, a custom class that -// implements valueForKey my be better for some uses. -+ (NSString *)expandTemplate:(NSString *)URITemplate - values:(NSDictionary *)valueProvider; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleAPIClientForREST/Source/Utilities/GTLRURITemplate.m b/Pods/GoogleAPIClientForREST/Source/Utilities/GTLRURITemplate.m @@ -1,511 +0,0 @@ -/* Copyright (c) 2010 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if !__has_feature(objc_arc) -#error "This file needs to be compiled with ARC enabled." -#endif - -#import "GTLRURITemplate.h" - -// Key constants for handling variables. -static NSString *const kVariable = @"variable"; // NSString -static NSString *const kExplode = @"explode"; // NSString -static NSString *const kPartial = @"partial"; // NSString -static NSString *const kPartialValue = @"partialValue"; // NSNumber - -// Help for passing the Expansion info in one shot. -struct ExpansionInfo { - // Constant for the whole expansion. - unichar expressionOperator; - __unsafe_unretained NSString *joiner; - BOOL allowReservedInEscape; - - // Update for each variable. - __unsafe_unretained NSString *explode; -}; - -// Helper just to shorten the lines when needed. -static NSString *UnescapeString(NSString *str) { - return [str stringByRemovingPercentEncoding]; -} - -static NSString *EscapeString(NSString *str, BOOL allowReserved) { - // The spec is a little hard to map onto the charsets, so force - // reserved bits in/out. - NSMutableCharacterSet *cs = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy]; - NSString * const kReservedChars = @":/?#[]@!$&'()*+,;="; - if (allowReserved) { - [cs addCharactersInString:kReservedChars]; - } else { - [cs removeCharactersInString:kReservedChars]; - } - NSString *resultStr = [str stringByAddingPercentEncodingWithAllowedCharacters:cs]; - return resultStr; -} - -static NSString *StringFromNSNumber(NSNumber *rawValue) { - NSString *strValue; - // NSNumber doesn't expose a way to tell if it is holding a BOOL or something - // else. -[NSNumber objCType] for a BOOL is the same as @encoding(char), but - // in the 64bit runtine @encoding(BOOL) (or for "bool") won't match that as - // the 64bit runtime actually has a true boolean type. Instead we reply on - // checking if the numbers are the CFBoolean constants to force true/value - // values. - if ((rawValue == (NSNumber *)kCFBooleanTrue) || - (rawValue == (NSNumber *)kCFBooleanFalse)) { - strValue = (rawValue.boolValue ? @"true" : @"false"); - } else { - strValue = [rawValue stringValue]; - } - return strValue; -} - -@implementation GTLRURITemplate - -#pragma mark Internal Helpers - -+ (BOOL)parseExpression:(NSString *)expression - expressionOperator:(unichar*)outExpressionOperator - variables:(NSMutableArray **)outVariables - defaultValues:(NSMutableDictionary **)outDefaultValues { - - // Please see the spec for full details, but here are the basics: - // - // URI-Template = *( literals / expression ) - // expression = "{" [ operator ] variable-list "}" - // variable-list = varspec *( "," varspec ) - // varspec = varname [ modifier ] [ "=" default ] - // varname = varchar *( varchar / "." ) - // modifier = explode / partial - // explode = ( "*" / "+" ) - // partial = ( substring / remainder ) offset - // - // Examples: - // http://www.example.com/foo{?query,number} - // http://maps.com/mapper{?address*} - // http://directions.org/directions{?from+,to+} - // http://search.org/query{?terms+=none} - // - - // http://tools.ietf.org/html/draft-gregorio-uritemplate-04#section-2.2 - // Operator and op-reserve characters - static NSCharacterSet *operatorSet = nil; - // http://tools.ietf.org/html/draft-gregorio-uritemplate-04#section-2.4.1 - // Explode characters - static NSCharacterSet *explodeSet = nil; - // http://tools.ietf.org/html/draft-gregorio-uritemplate-04#section-2.4.2 - // Partial (prefix/subset) characters - static NSCharacterSet *partialSet = nil; - - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - operatorSet = [NSCharacterSet characterSetWithCharactersInString:@"+./;?|!@"]; - explodeSet = [NSCharacterSet characterSetWithCharactersInString:@"*+"]; - partialSet = [NSCharacterSet characterSetWithCharactersInString:@":^"]; - }); - - // http://tools.ietf.org/html/draft-gregorio-uritemplate-04#section-3.3 - // Empty expression inlines the expression. - if (expression.length == 0) return NO; - - // Pull off any operator. - *outExpressionOperator = 0; - unichar firstChar = [expression characterAtIndex:0]; - if ([operatorSet characterIsMember:firstChar]) { - *outExpressionOperator = firstChar; - expression = [expression substringFromIndex:1]; - } - - if (expression.length == 0) return NO; - - // Need to find atleast one varspec for the expresssion to be considered - // valid. - BOOL gotAVarspec = NO; - - // Split the variable list. - NSArray *varspecs = [expression componentsSeparatedByString:@","]; - - // Extract the defaults, explodes and modifiers from the varspecs. - *outVariables = [NSMutableArray arrayWithCapacity:varspecs.count]; - for (__strong NSString *varspec in varspecs) { - NSString *defaultValue = nil; - - if (varspec.length == 0) continue; - - NSMutableDictionary *varInfo = - [NSMutableDictionary dictionaryWithCapacity:4]; - - // Check for a default (foo=bar). - NSRange range = [varspec rangeOfString:@"="]; - if (range.location != NSNotFound) { - defaultValue = - UnescapeString([varspec substringFromIndex:range.location + 1]); - varspec = [varspec substringToIndex:range.location]; - - if (varspec.length == 0) continue; - } - - // Check for explode (foo*). - NSUInteger lenLessOne = varspec.length - 1; - if ([explodeSet characterIsMember:[varspec characterAtIndex:lenLessOne]]) { - [varInfo setObject:[varspec substringFromIndex:lenLessOne] forKey:kExplode]; - varspec = [varspec substringToIndex:lenLessOne]; - if (varspec.length == 0) continue; - } else { - // Check for partial (prefix/suffix) (foo:12). - range = [varspec rangeOfCharacterFromSet:partialSet]; - if (range.location != NSNotFound) { - NSString *partialMode = [varspec substringWithRange:range]; - NSString *valueStr = [varspec substringFromIndex:range.location + 1]; - // If there wasn't a value for the partial, ignore it. - if (valueStr.length > 0) { - [varInfo setObject:partialMode forKey:kPartial]; - // TODO: Should validate valueStr is just a number... - [varInfo setObject:[NSNumber numberWithInteger:[valueStr integerValue]] - forKey:kPartialValue]; - } - varspec = [varspec substringToIndex:range.location]; - if (varspec.length == 0) continue; - } - } - - // Spec allows percent escaping in names, so undo that. - varspec = UnescapeString(varspec); - - // Save off the cleaned up variable name. - [varInfo setObject:varspec forKey:kVariable]; - [*outVariables addObject:varInfo]; - gotAVarspec = YES; - - // Now that the variable has been cleaned up, store its default. - if (defaultValue) { - if (*outDefaultValues == nil) { - *outDefaultValues = [NSMutableDictionary dictionary]; - } - [*outDefaultValues setObject:defaultValue forKey:varspec]; - } - } - // All done. - return gotAVarspec; -} - -+ (NSString *)expandVariables:(NSArray *)variables - expressionOperator:(unichar)expressionOperator - values:(NSDictionary *)valueProvider - defaultValues:(NSMutableDictionary *)defaultValues { - NSString *prefix = nil; - struct ExpansionInfo expansionInfo = { - .expressionOperator = expressionOperator, - .joiner = nil, - .allowReservedInEscape = NO, - .explode = nil, - }; - switch (expressionOperator) { - case 0: - expansionInfo.joiner = @","; - prefix = @""; - break; - case '+': - expansionInfo.joiner = @","; - prefix = @""; - // The reserved character are safe from escaping. - expansionInfo.allowReservedInEscape = YES; - break; - case '.': - expansionInfo.joiner = @"."; - prefix = @"."; - break; - case '/': - expansionInfo.joiner = @"/"; - prefix = @"/"; - break; - case ';': - expansionInfo.joiner = @";"; - prefix = @";"; - break; - case '?': - expansionInfo.joiner = @"&"; - prefix = @"?"; - break; - default: - [NSException raise:@"GTLRURITemplateUnsupported" - format:@"Unknown expression operator '%C'", expressionOperator]; - break; - } - - NSMutableArray *results = [NSMutableArray arrayWithCapacity:variables.count]; - - for (NSDictionary *varInfo in variables) { - NSString *variable = [varInfo objectForKey:kVariable]; - - expansionInfo.explode = [varInfo objectForKey:kExplode]; - // Look up the variable value. - id rawValue = [valueProvider objectForKey:variable]; - - // If the value is an empty array or dictionary, the default is still used. - if (([rawValue isKindOfClass:[NSArray class]] - || [rawValue isKindOfClass:[NSDictionary class]]) - && ((NSArray *)rawValue).count == 0) { - rawValue = nil; - } - - // Got nothing? Check defaults. - if (rawValue == nil) { - rawValue = [defaultValues objectForKey:variable]; - } - - // If we didn't get any value, on to the next thing. - if (!rawValue) { - continue; - } - - // Time do to the work... - NSString *result = nil; - if ([rawValue isKindOfClass:[NSString class]]) { - result = [self expandString:rawValue - variableName:variable - expansionInfo:&expansionInfo]; - } else if ([rawValue isKindOfClass:[NSNumber class]]) { - // Turn the number into a string and send it on its way. - NSString *strValue = StringFromNSNumber(rawValue); - result = [self expandString:strValue - variableName:variable - expansionInfo:&expansionInfo]; - } else if ([rawValue isKindOfClass:[NSArray class]]) { - result = [self expandArray:rawValue - variableName:variable - expansionInfo:&expansionInfo]; - } else if ([rawValue isKindOfClass:[NSDictionary class]]) { - result = [self expandDictionary:rawValue - variableName:variable - expansionInfo:&expansionInfo]; - } else { - [NSException raise:@"GTLRURITemplateUnsupported" - format:@"Variable returned unsupported type (%@)", - NSStringFromClass([rawValue class])]; - } - - // Did it generate anything? - if (result == nil) - continue; - - // Apply partial. - // Defaults should get partial applied? - // ( http://tools.ietf.org/html/draft-gregorio-uritemplate-04#section-2.5 ) - NSString *partial = [varInfo objectForKey:kPartial]; - if (partial.length > 0) { - [NSException raise:@"GTLRURITemplateUnsupported" - format:@"Unsupported partial on expansion %@", partial]; - } - - // Add the result - [results addObject:result]; - } - - // Join and add any needed prefix. - NSString *joinedResults = - [results componentsJoinedByString:expansionInfo.joiner]; - if ((prefix.length > 0) && (joinedResults.length > 0)) { - return [prefix stringByAppendingString:joinedResults]; - } - return joinedResults; -} - -+ (NSString *)expandString:(NSString *)valueStr - variableName:(NSString *)variableName - expansionInfo:(struct ExpansionInfo *)expansionInfo { - NSString *escapedValue = - EscapeString(valueStr, expansionInfo->allowReservedInEscape); - switch (expansionInfo->expressionOperator) { - case ';': - case '?': - if (valueStr.length > 0) { - return [NSString stringWithFormat:@"%@=%@", variableName, escapedValue]; - } - return variableName; - default: - return escapedValue; - } -} - -+ (NSString *)expandArray:(NSArray *)valueArray - variableName:(NSString *)variableName - expansionInfo:(struct ExpansionInfo *)expansionInfo { - NSMutableArray *results = [NSMutableArray arrayWithCapacity:valueArray.count]; - // When joining variable with value, use "var.val" except for 'path' and - // 'form' style expression, use 'var=val' then. - char variableValueJoiner = '.'; - unichar expressionOperator = expansionInfo->expressionOperator; - if ((expressionOperator == ';') || (expressionOperator == '?')) { - variableValueJoiner = '='; - } - // Loop over the values. - for (id rawValue in valueArray) { - NSString *value; - if ([rawValue isKindOfClass:[NSNumber class]]) { - value = StringFromNSNumber((id)rawValue); - } else if ([rawValue isKindOfClass:[NSString class]]) { - value = rawValue; - } else { - [NSException raise:@"GTLRURITemplateUnsupported" - format:@"Variable '%@' returned NSArray with unsupported type (%@), array: %@", - variableName, NSStringFromClass([rawValue class]), valueArray]; - } - // Escape it. - value = EscapeString(value, expansionInfo->allowReservedInEscape); - // Should variable names be used? - if ([expansionInfo->explode isEqual:@"+"]) { - value = [NSString stringWithFormat:@"%@%c%@", - variableName, variableValueJoiner, value]; - } - [results addObject:value]; - } - if (results.count > 0) { - // Use the default joiner unless there was no explode request, then a list - // always gets comma seperated. - NSString *joiner = expansionInfo->joiner; - if (expansionInfo->explode == nil) { - joiner = @","; - } - // Join the values. - NSString *joined = [results componentsJoinedByString:joiner]; - // 'form' style without an explode gets the variable name set to the - // joined list of values. - if ((expressionOperator == '?') && (expansionInfo->explode == nil)) { - return [NSString stringWithFormat:@"%@=%@", variableName, joined]; - } - return joined; - } - return nil; -} - -+ (NSString *)expandDictionary:(NSDictionary *)valueDict - variableName:(NSString *)variableName - expansionInfo:(struct ExpansionInfo *)expansionInfo { - NSMutableArray *results = [NSMutableArray arrayWithCapacity:valueDict.count]; - // When joining variable with value: - // - Default to the joiner... - // - No explode, always comma... - // - For 'path' and 'form' style expression, use 'var=val'. - NSString *keyValueJoiner = expansionInfo->joiner; - unichar expressionOperator = expansionInfo->expressionOperator; - if (expansionInfo->explode == nil) { - keyValueJoiner = @","; - } else if ((expressionOperator == ';') || (expressionOperator == '?')) { - keyValueJoiner = @"="; - } - // Loop over the sorted keys. - NSArray *sortedKeys = [valueDict.allKeys sortedArrayUsingSelector:@selector(compare:)]; - for (__strong NSString *key in sortedKeys) { - NSString *value = [valueDict objectForKey:key]; - // Escape them. - key = EscapeString(key, expansionInfo->allowReservedInEscape); - value = EscapeString(value, expansionInfo->allowReservedInEscape); - // Should variable names be used? - if ([expansionInfo->explode isEqual:@"+"]) { - key = [NSString stringWithFormat:@"%@.%@", variableName, key]; - } - if ((expressionOperator == '?' || expressionOperator == ';') - && (value.length == 0)) { - [results addObject:key]; - } else { - NSString *pair = [NSString stringWithFormat:@"%@%@%@", - key, keyValueJoiner, value]; - [results addObject:pair]; - } - } - if (results.count) { - // Use the default joiner unless there was no explode request, then a list - // always gets comma seperated. - NSString *joiner = expansionInfo->joiner; - if (expansionInfo->explode == nil) { - joiner = @","; - } - // Join the values. - NSString *joined = [results componentsJoinedByString:joiner]; - // 'form' style without an explode gets the variable name set to the - // joined list of values. - if ((expressionOperator == '?') && (expansionInfo->explode == nil)) { - return [NSString stringWithFormat:@"%@=%@", variableName, joined]; - } - return joined; - } - return nil; -} - -#pragma mark Public API - -+ (NSString *)expandTemplate:(NSString *)uriTemplate - values:(NSDictionary *)valueProvider { - NSMutableString *result = - [NSMutableString stringWithCapacity:uriTemplate.length]; - - NSScanner *scanner = [NSScanner scannerWithString:uriTemplate]; - [scanner setCharactersToBeSkipped:nil]; - - // Defaults have to live through the full evaluation, so if any are encoured - // they are reused throughout the expansion calls. - NSMutableDictionary *defaultValues = nil; - - // Pull out the expressions for processing. - while (![scanner isAtEnd]) { - NSString *skipped = nil; - // Find the next '{'. - if ([scanner scanUpToString:@"{" intoString:&skipped]) { - // Add anything before it to the result. - [result appendString:skipped]; - } - // Advance over the '{'. - [scanner scanString:@"{" intoString:nil]; - // Collect the expression. - NSString *expression = nil; - if ([scanner scanUpToString:@"}" intoString:&expression]) { - // Collect the trailing '}' on the expression. - BOOL hasTrailingBrace = [scanner scanString:@"}" intoString:nil]; - - // Parse the expression. - NSMutableArray *variables = nil; - unichar expressionOperator = 0; - if ([self parseExpression:expression - expressionOperator:&expressionOperator - variables:&variables - defaultValues:&defaultValues]) { - // Do the expansion. - NSString *substitution = [self expandVariables:variables - expressionOperator:expressionOperator - values:valueProvider - defaultValues:defaultValues]; - if (substitution) { - [result appendString:substitution]; - } - } else { - // Failed to parse, add the raw expression to the output. - if (hasTrailingBrace) { - [result appendFormat:@"{%@}", expression]; - } else { - [result appendFormat:@"{%@", expression]; - } - } - } else if (![scanner isAtEnd]) { - // Empty expression ('{}'). Copy over the opening brace and the trailing - // one will be copied by the next cycle of the loop. - [result appendString:@"{"]; - } - } - - return result; -} - -@end diff --git a/Pods/GoogleAPIClientForREST/Source/Utilities/GTLRUtilities.h b/Pods/GoogleAPIClientForREST/Source/Utilities/GTLRUtilities.h @@ -1,52 +0,0 @@ -/* Copyright (c) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -#ifndef SKIP_GTLR_DEFINES - #import "GTLRDefines.h" -#endif - -NS_ASSUME_NONNULL_BEGIN - -// Helper functions for implementing isEqual: -BOOL GTLR_AreEqualOrBothNil(id _Nullable obj1, id _Nullable obj2); -BOOL GTLR_AreBoolsEqual(BOOL b1, BOOL b2); - -// Helper to ensure a number is a number. -// -// The Google API servers will send numbers >53 bits as strings to avoid -// bugs in some JavaScript implementations. Work around this by catching -// the string and turning it back into a number. -NSNumber *GTLR_EnsureNSNumber(NSNumber *num); - -@interface GTLRUtilities : NSObject - -// Key-value coding searches in an array -// -// Utilities to get from an array objects having a known value (or nil) -// at a keyPath - -+ (NSArray *)objectsFromArray:(NSArray *)sourceArray - withValue:(id)desiredValue - forKeyPath:(NSString *)keyPath; - -+ (nullable id)firstObjectFromArray:(NSArray *)sourceArray - withValue:(id)desiredValue - forKeyPath:(NSString *)keyPath; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleAPIClientForREST/Source/Utilities/GTLRUtilities.m b/Pods/GoogleAPIClientForREST/Source/Utilities/GTLRUtilities.m @@ -1,117 +0,0 @@ -/* Copyright (c) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if !__has_feature(objc_arc) -#error "This file needs to be compiled with ARC enabled." -#endif - -#import "GTLRUtilities.h" - -#include <objc/runtime.h> - -@implementation GTLRUtilities - -#pragma mark Key-Value Coding Searches in an Array - -+ (NSArray *)objectsFromArray:(NSArray *)sourceArray - withValue:(id)desiredValue - forKeyPath:(NSString *)keyPath { - // Step through all entries, get the value from - // the key path, and see if it's equal to the - // desired value - NSMutableArray *results = [NSMutableArray array]; - - for(id obj in sourceArray) { - id val = [obj valueForKeyPath:keyPath]; - if (GTLR_AreEqualOrBothNil(val, desiredValue)) { - - // found a match; add it to the results array - [results addObject:obj]; - } - } - return results; -} - -+ (id)firstObjectFromArray:(NSArray *)sourceArray - withValue:(id)desiredValue - forKeyPath:(NSString *)keyPath { - for (id obj in sourceArray) { - id val = [obj valueForKeyPath:keyPath]; - if (GTLR_AreEqualOrBothNil(val, desiredValue)) { - // found a match; return it - return obj; - } - } - return nil; -} - -#pragma mark Version helpers - -@end - -// isEqual: has the fatal flaw that it doesn't deal well with the receiver -// being nil. We'll use this utility instead. -BOOL GTLR_AreEqualOrBothNil(id obj1, id obj2) { - if (obj1 == obj2) { - return YES; - } - if (obj1 && obj2) { - BOOL areEqual = [(NSObject *)obj1 isEqual:obj2]; - return areEqual; - } - return NO; -} - -BOOL GTLR_AreBoolsEqual(BOOL b1, BOOL b2) { - // avoid comparison problems with boolean types by negating - // both booleans - return (!b1 == !b2); -} - -NSNumber *GTLR_EnsureNSNumber(NSNumber *num) { - // If the server returned a string object where we expect a number, try - // to make a number object. - if ([num isKindOfClass:[NSString class]]) { - NSNumber *newNum; - NSString *str = (NSString *)num; - if ([str rangeOfString:@"."].location != NSNotFound) { - // This is a floating-point number. - // Force the parser to use '.' as the decimal separator. - static NSLocale *usLocale = nil; - @synchronized([GTLRUtilities class]) { - if (usLocale == nil) { - usLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]; - } - newNum = [NSDecimalNumber decimalNumberWithString:(NSString*)num - locale:(id)usLocale]; - } - } else { - // NSDecimalNumber +decimalNumberWithString:locale: - // does not correctly create an NSNumber for large values like - // 71100000000007780. - if ([str hasPrefix:@"-"]) { - newNum = @([str longLongValue]); - } else { - const char *utf8 = str.UTF8String; - unsigned long long ull = strtoull(utf8, NULL, 10); - newNum = @(ull); - } - } - if (newNum != nil) { - num = newNum; - } - } - return num; -} diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.framework/GoogleAppMeasurement b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.framework/GoogleAppMeasurement Binary files differ. diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.framework/Modules/module.modulemap b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.framework/Modules/module.modulemap @@ -1,9 +0,0 @@ -framework module GoogleAppMeasurement { - export * - module * { export *} - link "sqlite3" - link "z" - link framework "Security" - link framework "StoreKit" - link framework "SystemConfiguration" - link framework "UIKit"} diff --git a/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/GULAppDelegateSwizzler.m b/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/GULAppDelegateSwizzler.m @@ -1,718 +0,0 @@ -// Copyright 2018 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#import "TargetConditionals.h" - -#if TARGET_OS_IOS - -#import <GoogleUtilities/GULAppEnvironmentUtil.h> -#import <GoogleUtilities/GULLogger.h> -#import <GoogleUtilities/GULMutableDictionary.h> -#import "../Common/GULLoggerCodes.h" -#import "Internal/GULAppDelegateSwizzler_Private.h" -#import "Private/GULAppDelegateSwizzler.h" - -#import <UIKit/UIKit.h> -#import <objc/runtime.h> - -// Implementations need to be typed before calling the implementation directly to cast the -// arguments and the return types correctly. Otherwise, it will crash the app. -typedef BOOL (*GULRealOpenURLSourceApplicationAnnotationIMP)( - id, SEL, UIApplication *, NSURL *, NSString *, id); - -typedef BOOL (*GULRealOpenURLOptionsIMP)( - id, SEL, UIApplication *, NSURL *, NSDictionary<NSString *, id> *); - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wstrict-prototypes" -typedef void (*GULRealHandleEventsForBackgroundURLSessionIMP)( - id, SEL, UIApplication *, NSString *, void (^)()); -#pragma clang diagnostic pop - -// This is needed to for the library to be warning free on iOS versions < 8. -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" -typedef BOOL (*GULRealContinueUserActivityIMP)( - id, SEL, UIApplication *, NSUserActivity *, void (^)(NSArray *restorableObjects)); -#pragma clang diagnostic pop - -typedef void (^GULAppDelegateInterceptorCallback)(id<UIApplicationDelegate>); - -// The strings below are the keys for associated objects. -static char const *const kGULContinueUserActivityIMPKey = "GUL_continueUserActivityIMP"; -static char const *const kGULHandleBackgroundSessionIMPKey = "GUL_handleBackgroundSessionIMP"; -static char const *const kGULOpenURLOptionsIMPKey = "GUL_openURLOptionsIMP"; -static char const *const kGULOpenURLOptionsSourceAnnotationsIMPKey = - "GUL_openURLSourceApplicationAnnotationIMP"; -static char const *const kGULRealClassKey = "GUL_realClass"; -static NSString *const kGULAppDelegateKeyPath = @"delegate"; - -static GULLoggerService kGULLoggerSwizzler = @"[GoogleUtilities/AppDelegateSwizzler]"; - -// Since Firebase SDKs also use this for app delegate proxying, in order to not be a breaking change -// we disable App Delegate proxying when either of these two flags are set to NO. - -/** Plist key that allows Firebase developers to disable App Delegate Proxying. */ -static NSString *const kGULFirebaseAppDelegateProxyEnabledPlistKey = - @"FirebaseAppDelegateProxyEnabled"; - -/** Plist key that allows developers not using Firebase to disable App Delegate Proxying. */ -static NSString *const kGULGoogleUtilitiesAppDelegateProxyEnabledPlistKey = - @"GoogleUtilitiesAppDelegateProxyEnabled"; - -/** The prefix of the App Delegate. */ -static NSString *const kGULAppDelegatePrefix = @"GUL_"; - -/** The original instance of App Delegate. */ -static id<UIApplicationDelegate> gOriginalAppDelegate; - -/** - * This class is necessary to store the delegates in an NSArray without retaining them. - * [NSValue valueWithNonRetainedObject] also provides this functionality, but does not provide a - * zeroing pointer. This will cause EXC_BAD_ACCESS when trying to access the object after it is - * dealloced. Instead, this container stores a weak, zeroing reference to the object, which - * automatically is set to nil by the runtime when the object is dealloced. - */ -@interface GULZeroingWeakContainer : NSObject - -/** Stores a weak object. */ -@property(nonatomic, weak) id object; - -@end - -@implementation GULZeroingWeakContainer -@end - -@interface GULAppDelegateObserver : NSObject -@end - -@implementation GULAppDelegateObserver { - BOOL _isObserving; -} - -+ (GULAppDelegateObserver *)sharedInstance { - static GULAppDelegateObserver *instance; - static dispatch_once_t once; - dispatch_once(&once, ^{ - instance = [[GULAppDelegateObserver alloc] init]; - }); - return instance; -} - -- (void)observeUIApplication { - if (_isObserving) { - return; - } - [[GULAppDelegateSwizzler sharedApplication] - addObserver:self - forKeyPath:kGULAppDelegateKeyPath - options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld - context:nil]; - _isObserving = YES; -} - -- (void)observeValueForKeyPath:(NSString *)keyPath - ofObject:(id)object - change:(NSDictionary *)change - context:(void *)context { - if ([keyPath isEqual:kGULAppDelegateKeyPath]) { - id newValue = change[NSKeyValueChangeNewKey]; - id oldValue = change[NSKeyValueChangeOldKey]; - if ([newValue isEqual:oldValue]) { - return; - } - // Free the stored app delegate instance because it has been changed to a different instance to - // avoid keeping it alive forever. - if ([oldValue isEqual:gOriginalAppDelegate]) { - gOriginalAppDelegate = nil; - // Remove the observer. Parse it to NSObject to avoid warning. - [[GULAppDelegateSwizzler sharedApplication] removeObserver:self - forKeyPath:kGULAppDelegateKeyPath]; - _isObserving = NO; - } - } -} - -@end - -@implementation GULAppDelegateSwizzler - -static dispatch_once_t sProxyAppDelegateOnceToken; - -#pragma mark - Public methods - -+ (BOOL)isAppDelegateProxyEnabled { - NSDictionary *infoDictionary = [NSBundle mainBundle].infoDictionary; - - id isFirebaseProxyEnabledPlistValue = infoDictionary[kGULFirebaseAppDelegateProxyEnabledPlistKey]; - id isGoogleProxyEnabledPlistValue = - infoDictionary[kGULGoogleUtilitiesAppDelegateProxyEnabledPlistKey]; - - // Enabled by default. - BOOL isFirebaseAppDelegateProxyEnabled = YES; - BOOL isGoogleUtilitiesAppDelegateProxyEnabled = YES; - - if ([isFirebaseProxyEnabledPlistValue isKindOfClass:[NSNumber class]]) { - isFirebaseAppDelegateProxyEnabled = [isFirebaseProxyEnabledPlistValue boolValue]; - } - - if ([isGoogleProxyEnabledPlistValue isKindOfClass:[NSNumber class]]) { - isGoogleUtilitiesAppDelegateProxyEnabled = [isGoogleProxyEnabledPlistValue boolValue]; - } - - // Only deactivate the proxy if it is explicitly disabled by app developers using either one of - // the plist flags. - return isFirebaseAppDelegateProxyEnabled && isGoogleUtilitiesAppDelegateProxyEnabled; -} - -+ (GULAppDelegateInterceptorID)registerAppDelegateInterceptor: - (id<UIApplicationDelegate>)interceptor { - NSAssert(interceptor, @"AppDelegateProxy cannot add nil interceptor"); - NSAssert([interceptor conformsToProtocol:@protocol(UIApplicationDelegate)], - @"AppDelegateProxy interceptor does not conform to UIApplicationDelegate"); - - if (!interceptor) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling000], - @"AppDelegateProxy cannot add nil interceptor."); - return nil; - } - if (![interceptor conformsToProtocol:@protocol(UIApplicationDelegate)]) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling001], - @"AppDelegateProxy interceptor does not conform to UIApplicationDelegate"); - return nil; - } - - // The ID should be the same given the same interceptor object. - NSString *interceptorID = [NSString stringWithFormat:@"%@%p", kGULAppDelegatePrefix, interceptor]; - if (!interceptorID.length) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling002], - @"AppDelegateProxy cannot create Interceptor ID."); - return nil; - } - GULZeroingWeakContainer *weakObject = [[GULZeroingWeakContainer alloc] init]; - weakObject.object = interceptor; - [GULAppDelegateSwizzler interceptors][interceptorID] = weakObject; - return interceptorID; -} - -+ (void)unregisterAppDelegateInterceptorWithID:(GULAppDelegateInterceptorID)interceptorID { - NSAssert(interceptorID, @"AppDelegateProxy cannot unregister nil interceptor ID."); - NSAssert(((NSString *)interceptorID).length != 0, - @"AppDelegateProxy cannot unregister empty interceptor ID."); - - if (!interceptorID) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling003], - @"AppDelegateProxy cannot unregister empty interceptor ID."); - return; - } - - GULZeroingWeakContainer *weakContainer = [GULAppDelegateSwizzler interceptors][interceptorID]; - if (!weakContainer.object) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling004], - @"AppDelegateProxy cannot unregister interceptor that was not registered. " - "Interceptor ID %@", - interceptorID); - return; - } - - [[GULAppDelegateSwizzler interceptors] removeObjectForKey:interceptorID]; -} - -+ (void)proxyOriginalDelegate { - dispatch_once(&sProxyAppDelegateOnceToken, ^{ - id<UIApplicationDelegate> originalDelegate = - [GULAppDelegateSwizzler sharedApplication].delegate; - [GULAppDelegateSwizzler proxyAppDelegate:originalDelegate]; - }); -} - -#pragma mark - Create proxy - -+ (UIApplication *)sharedApplication { - if ([GULAppEnvironmentUtil isAppExtension]) { - return nil; - } - id sharedApplication = nil; - Class uiApplicationClass = NSClassFromString(@"UIApplication"); - if (uiApplicationClass && - [uiApplicationClass respondsToSelector:(NSSelectorFromString(@"sharedApplication"))]) { - sharedApplication = [uiApplicationClass sharedApplication]; - } - return sharedApplication; -} - -#pragma mark - Override default methods - -/** Creates a new subclass of the class of the given object and sets the isa value of the given - * object to the new subclass. Additionally this copies methods to that new subclass that allow us - * to intercept UIApplicationDelegate methods. This is better known as isa swizzling. - * - * @param anObject The object to which you want to isa swizzle. This has to conform to the - * UIApplicationDelegate subclass. - */ -+ (void)createSubclassWithObject:(id<UIApplicationDelegate>)anObject { - Class realClass = [anObject class]; - - // Create GUL_<RealAppDelegate>_<timestampMs> - NSString *classNameWithPrefix = - [kGULAppDelegatePrefix stringByAppendingString:NSStringFromClass(realClass)]; - NSTimeInterval timestamp = [NSDate date].timeIntervalSince1970; - NSString *newClassName = - [NSString stringWithFormat:@"%@-%0.0f", classNameWithPrefix, timestamp * 1000]; - - if (NSClassFromString(newClassName)) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling005], - @"Cannot create a proxy for App Delegate. Subclass already exists. Original Class: " - @"%@, subclass: %@", - NSStringFromClass(realClass), newClassName); - return; - } - - // Register the new class as subclass of the real one. Do not allocate more than the real class - // size. - Class appDelegateSubClass = objc_allocateClassPair(realClass, newClassName.UTF8String, 0); - if (appDelegateSubClass == Nil) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling006], - @"Cannot create a proxy for App Delegate. Subclass already exists. Original Class: " - @"%@, subclass: Nil", - NSStringFromClass(realClass)); - return; - } - - // Add the following methods from GULAppDelegate class, and store the real implementation so it - // can forward to the real one. - // For application:openURL:options: - NSValue *openURLOptionsIMPPointer; - SEL applicationOpenURLOptionsSEL = @selector(application:openURL:options:); - if ([anObject respondsToSelector:applicationOpenURLOptionsSEL]) { - // Only add the application:openURL:options: method if the original AppDelegate implements it. - // This fixes a bug if an app only implements application:openURL:sourceApplication:annotation: - // (if we add the `options` method, iOS sees that one exists and does not call the - // `sourceApplication` method, which in this case is the only one the app implements). - - [GULAppDelegateSwizzler addInstanceMethodWithSelector:applicationOpenURLOptionsSEL - fromClass:[GULAppDelegateSwizzler class] - toClass:appDelegateSubClass]; - GULRealOpenURLOptionsIMP openURLOptionsIMP = (GULRealOpenURLOptionsIMP) - [GULAppDelegateSwizzler implementationOfMethodSelector:applicationOpenURLOptionsSEL - fromClass:realClass]; - openURLOptionsIMPPointer = [NSValue valueWithPointer:openURLOptionsIMP]; - } - - // For application:continueUserActivity:restorationHandler: - SEL continueUserActivitySEL = @selector(application:continueUserActivity:restorationHandler:); - [GULAppDelegateSwizzler addInstanceMethodWithSelector:continueUserActivitySEL - fromClass:[GULAppDelegateSwizzler class] - toClass:appDelegateSubClass]; - GULRealContinueUserActivityIMP continueUserActivityIMP = (GULRealContinueUserActivityIMP) - [GULAppDelegateSwizzler implementationOfMethodSelector:continueUserActivitySEL - fromClass:realClass]; - NSValue *continueUserActivityIMPPointer = [NSValue valueWithPointer:continueUserActivityIMP]; - - // For application:openURL:sourceApplication:annotation: - SEL openURLSourceApplicationAnnotationSEL = @selector(application: - openURL:sourceApplication:annotation:); - [GULAppDelegateSwizzler addInstanceMethodWithSelector:openURLSourceApplicationAnnotationSEL - fromClass:[GULAppDelegateSwizzler class] - toClass:appDelegateSubClass]; - GULRealOpenURLSourceApplicationAnnotationIMP openURLSourceApplicationAnnotationIMP = - (GULRealOpenURLSourceApplicationAnnotationIMP)[GULAppDelegateSwizzler - implementationOfMethodSelector:openURLSourceApplicationAnnotationSEL - fromClass:realClass]; - NSValue *openURLSourceAppAnnotationIMPPointer = - [NSValue valueWithPointer:openURLSourceApplicationAnnotationIMP]; - - // For application:handleEventsForBackgroundURLSession:completionHandler: - SEL handleEventsForBackgroundURLSessionSEL = @selector(application: - handleEventsForBackgroundURLSession:completionHandler:); - [GULAppDelegateSwizzler addInstanceMethodWithSelector:handleEventsForBackgroundURLSessionSEL - fromClass:[GULAppDelegateSwizzler class] - toClass:appDelegateSubClass]; - GULRealHandleEventsForBackgroundURLSessionIMP handleBackgroundSessionIMP = - (GULRealHandleEventsForBackgroundURLSessionIMP)[GULAppDelegateSwizzler - implementationOfMethodSelector:handleEventsForBackgroundURLSessionSEL - fromClass:realClass]; - NSValue *handleBackgroundSessionIMPPointer = - [NSValue valueWithPointer:handleBackgroundSessionIMP]; - - // Override the description too so the custom class name will not show up. - [GULAppDelegateSwizzler addInstanceMethodWithDestinationSelector:@selector(description) - withImplementationFromSourceSelector:@selector(fakeDescription) - fromClass:[self class] - toClass:appDelegateSubClass]; - - // Create fake properties for the real app delegate object. - objc_setAssociatedObject(anObject, &kGULContinueUserActivityIMPKey, - continueUserActivityIMPPointer, OBJC_ASSOCIATION_RETAIN_NONATOMIC); - objc_setAssociatedObject(anObject, &kGULHandleBackgroundSessionIMPKey, - handleBackgroundSessionIMPPointer, OBJC_ASSOCIATION_RETAIN_NONATOMIC); - if (openURLOptionsIMPPointer) { - objc_setAssociatedObject(anObject, &kGULOpenURLOptionsIMPKey, openURLOptionsIMPPointer, - OBJC_ASSOCIATION_RETAIN_NONATOMIC); - } - objc_setAssociatedObject(anObject, &kGULOpenURLOptionsSourceAnnotationsIMPKey, - openURLSourceAppAnnotationIMPPointer, OBJC_ASSOCIATION_RETAIN_NONATOMIC); - objc_setAssociatedObject(anObject, &kGULRealClassKey, realClass, - OBJC_ASSOCIATION_RETAIN_NONATOMIC); - - // The subclass size has to be exactly the same size with the original class size. The subclass - // cannot have more ivars/properties than its superclass since it will cause an offset in memory - // that can lead to overwriting the isa of an object in the next frame. - if (class_getInstanceSize(realClass) != class_getInstanceSize(appDelegateSubClass)) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling007], - @"Cannot create subclass of App Delegate, because the created subclass is not the " - @"same size. %@", - NSStringFromClass(realClass)); - NSAssert(NO, @"Classes must be the same size to swizzle isa"); - return; - } - - // Make the newly created class to be the subclass of the real App Delegate class. - objc_registerClassPair(appDelegateSubClass); - if (object_setClass(anObject, appDelegateSubClass)) { - GULLogDebug(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling008], - @"Successfully created App Delegate Proxy automatically. To disable the " - @"proxy, set the flag %@ to NO (Boolean) in the Info.plist", - [GULAppDelegateSwizzler correctAppDelegateProxyKey]); - } - - // We have to do this to invalidate the cache that caches the original respondsToSelector of - // openURL handlers. Without this, it won't call the default implementations because the system - // checks and caches them. - // Register KVO only once. Otherwise, the observing method will be called as many times as - // being registered. - id<UIApplicationDelegate> delegate = [GULAppDelegateSwizzler sharedApplication].delegate; - [GULAppDelegateSwizzler sharedApplication].delegate = nil; - [GULAppDelegateSwizzler sharedApplication].delegate = delegate; - gOriginalAppDelegate = delegate; - [[GULAppDelegateObserver sharedInstance] observeUIApplication]; -} - -#pragma mark - Helper methods - -+ (GULMutableDictionary *)interceptors { - static dispatch_once_t onceToken; - static GULMutableDictionary *sInterceptors; - dispatch_once(&onceToken, ^{ - sInterceptors = [[GULMutableDictionary alloc] init]; - }); - return sInterceptors; -} - -/** Copies a method identified by the methodSelector from one class to the other. After this method - * is called, performing [toClassInstance methodSelector] will be similar to calling - * [fromClassInstance methodSelector]. This method does nothing if toClass already has a method - * identified by methodSelector. - * - * @param methodSelector The SEL that identifies both the method on the fromClass as well as the - * one on the toClass. - * @param fromClass The class from which a method is sourced. - * @param toClass The class to which the method is added. If the class already has a method with - * the same selector, this has no effect. - */ -+ (void)addInstanceMethodWithSelector:(SEL)methodSelector - fromClass:(Class)fromClass - toClass:(Class)toClass { - [self addInstanceMethodWithDestinationSelector:methodSelector - withImplementationFromSourceSelector:methodSelector - fromClass:fromClass - toClass:toClass]; -} - -/** Copies a method identified by the sourceSelector from the fromClass as a method for the - * destinationSelector on the toClass. After this method is called, performing - * [toClassInstance destinationSelector] will be similar to calling - * [fromClassInstance sourceSelector]. This method does nothing if toClass already has a method - * identified by destinationSelector. - * - * @param destinationSelector The SEL that identifies the method on the toClass. - * @param sourceSelector The SEL that identifies the method on the fromClass. - * @param fromClass The class from which a method is sourced. - * @param toClass The class to which the method is added. If the class already has a method with - * the same selector, this has no effect. - */ -+ (void)addInstanceMethodWithDestinationSelector:(SEL)destinationSelector - withImplementationFromSourceSelector:(SEL)sourceSelector - fromClass:(Class)fromClass - toClass:(Class)toClass { - Method method = class_getInstanceMethod(fromClass, sourceSelector); - IMP methodIMP = method_getImplementation(method); - const char *types = method_getTypeEncoding(method); - if (!class_addMethod(toClass, destinationSelector, methodIMP, types)) { - GULLogWarning(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling009], - @"Cannot copy method to destination selector %@ as it already exists", - NSStringFromSelector(destinationSelector)); - } -} - -/** Gets the IMP of the instance method on the class identified by the selector. - * - * @param selector The selector of which the IMP is to be fetched. - * @param aClass The class from which the IMP is to be fetched. - * @return The IMP of the instance method identified by selector and aClass. - */ -+ (IMP)implementationOfMethodSelector:(SEL)selector fromClass:(Class)aClass { - Method aMethod = class_getInstanceMethod(aClass, selector); - return method_getImplementation(aMethod); -} - -/** Enumerates through all the interceptors and if they respond to a given selector, executes a - * GULAppDelegateInterceptorCallback with the interceptor. - * - * @param methodSelector The SEL to check if an interceptor responds to. - * @param callback the GULAppDelegateInterceptorCallback. - */ -+ (void)notifyInterceptorsWithMethodSelector:(SEL)methodSelector - callback:(GULAppDelegateInterceptorCallback)callback { - if (!callback) { - return; - } - - NSDictionary *interceptors = [GULAppDelegateSwizzler interceptors].dictionary; - [interceptors enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { - GULZeroingWeakContainer *interceptorContainer = obj; - id interceptor = interceptorContainer.object; - if (!interceptor) { - GULLogWarning( - kGULLoggerSwizzler, NO, - [NSString - stringWithFormat:@"I-SWZ%06ld", (long)kGULSwizzlerMessageCodeAppDelegateSwizzling010], - @"AppDelegateProxy cannot find interceptor with ID %@. Removing the interceptor.", key); - [[GULAppDelegateSwizzler interceptors] removeObjectForKey:key]; - return; - } - if ([interceptor respondsToSelector:methodSelector]) { - callback(interceptor); - } - }]; -} - -// The methods below are donor methods which are added to the dynamic subclass of the App Delegate. -// They are called within the scope of the real App Delegate so |self| does not refer to the -// GULAppDelegateSwizzler instance but the real App Delegate instance. - -#pragma mark - [Donor Methods] Overridden instance description method - -- (NSString *)fakeDescription { - Class realClass = objc_getAssociatedObject(self, &kGULRealClassKey); - return [NSString stringWithFormat:@"<%@: %p>", realClass, self]; -} - -#pragma mark - [Donor Methods] URL overridden handler methods - -- (BOOL)application:(UIApplication *)application - openURL:(NSURL *)url - options:(NSDictionary<NSString *, id> *)options { - // Call the real implementation if the real App Delegate has any. - NSValue *openURLIMPPointer = objc_getAssociatedObject(self, &kGULOpenURLOptionsIMPKey); - GULRealOpenURLOptionsIMP openURLOptionsIMP = [openURLIMPPointer pointerValue]; - - __block BOOL returnedValue = NO; - SEL methodSelector = @selector(application:openURL:options:); - -// This is needed to for the library to be warning free on iOS versions < 9. -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" - [GULAppDelegateSwizzler - notifyInterceptorsWithMethodSelector:methodSelector - callback:^(id<UIApplicationDelegate> interceptor) { - returnedValue |= [interceptor application:application - openURL:url - options:options]; - }]; -#pragma clang diagnostic pop - if (openURLOptionsIMP) { - returnedValue |= openURLOptionsIMP(self, methodSelector, application, url, options); - } - return returnedValue; -} - -- (BOOL)application:(UIApplication *)application - openURL:(NSURL *)url - sourceApplication:(NSString *)sourceApplication - annotation:(id)annotation { - // Call the real implementation if the real App Delegate has any. - NSValue *openURLSourceAppAnnotationIMPPointer = - objc_getAssociatedObject(self, &kGULOpenURLOptionsSourceAnnotationsIMPKey); - GULRealOpenURLSourceApplicationAnnotationIMP openURLSourceApplicationAnnotationIMP = - [openURLSourceAppAnnotationIMPPointer pointerValue]; - - __block BOOL returnedValue = NO; - SEL methodSelector = @selector(application:openURL:sourceApplication:annotation:); - [GULAppDelegateSwizzler - notifyInterceptorsWithMethodSelector:methodSelector - callback:^(id<UIApplicationDelegate> interceptor) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - returnedValue |= [interceptor application:application - openURL:url - sourceApplication:sourceApplication - annotation:annotation]; -#pragma clang diagnostic pop - }]; - if (openURLSourceApplicationAnnotationIMP) { - returnedValue |= openURLSourceApplicationAnnotationIMP(self, methodSelector, application, url, - sourceApplication, annotation); - } - return returnedValue; -} - -#pragma mark - [Donor Methods] Network overridden handler methods - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wstrict-prototypes" -- (void)application:(UIApplication *)application - handleEventsForBackgroundURLSession:(NSString *)identifier - completionHandler:(void (^)())completionHandler API_AVAILABLE(ios(7.0)) { -#pragma clang diagnostic pop - NSValue *handleBackgroundSessionPointer = - objc_getAssociatedObject(self, &kGULHandleBackgroundSessionIMPKey); - GULRealHandleEventsForBackgroundURLSessionIMP handleBackgroundSessionIMP = - [handleBackgroundSessionPointer pointerValue]; - - // Notify interceptors. - SEL methodSelector = @selector(application: - handleEventsForBackgroundURLSession:completionHandler:); - [GULAppDelegateSwizzler - notifyInterceptorsWithMethodSelector:methodSelector - callback:^(id<UIApplicationDelegate> interceptor) { - [interceptor application:application - handleEventsForBackgroundURLSession:identifier - completionHandler:completionHandler]; - }]; - // Call the real implementation if the real App Delegate has any. - if (handleBackgroundSessionIMP) { - handleBackgroundSessionIMP(self, methodSelector, application, identifier, completionHandler); - } -} - -#pragma mark - [Donor Methods] User Activities overridden handler methods - -// This is needed to for the library to be warning free on iOS versions < 8. -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" -- (BOOL)application:(UIApplication *)application - continueUserActivity:(NSUserActivity *)userActivity - restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler { - NSValue *continueUserActivityIMPPointer = - objc_getAssociatedObject(self, &kGULContinueUserActivityIMPKey); - GULRealContinueUserActivityIMP continueUserActivityIMP = - continueUserActivityIMPPointer.pointerValue; - - __block BOOL returnedValue = NO; - SEL methodSelector = @selector(application:continueUserActivity:restorationHandler:); - [GULAppDelegateSwizzler - notifyInterceptorsWithMethodSelector:methodSelector - callback:^(id<UIApplicationDelegate> interceptor) { - returnedValue |= [interceptor application:application - continueUserActivity:userActivity - restorationHandler:restorationHandler]; - }]; - // Call the real implementation if the real App Delegate has any. - if (continueUserActivityIMP) { - returnedValue |= continueUserActivityIMP(self, methodSelector, application, userActivity, - restorationHandler); - } - return returnedValue; -} -#pragma clang diagnostic pop - -+ (void)proxyAppDelegate:(id<UIApplicationDelegate>)appDelegate { - id<UIApplicationDelegate> originalDelegate = appDelegate; - // Do not create a subclass if it is not enabled. - if (![GULAppDelegateSwizzler isAppDelegateProxyEnabled]) { - GULLogNotice(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling011], - @"App Delegate Proxy is disabled. %@", - [GULAppDelegateSwizzler correctAlternativeWhenAppDelegateProxyNotCreated]); - return; - } - // Do not accept nil delegate. - if (!originalDelegate) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling012], - @"Cannot create App Delegate Proxy because App Delegate instance is nil. %@", - [GULAppDelegateSwizzler correctAlternativeWhenAppDelegateProxyNotCreated]); - return; - } - - @try { - [self createSubclassWithObject:originalDelegate]; - } @catch (NSException *exception) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling013], - @"Cannot create App Delegate Proxy. %@", - [GULAppDelegateSwizzler correctAlternativeWhenAppDelegateProxyNotCreated]); - return; - } -} - -#pragma mark - Methods to print correct debug logs - -+ (NSString *)correctAppDelegateProxyKey { - return NSClassFromString(@"FIRCore") ? kGULFirebaseAppDelegateProxyEnabledPlistKey - : kGULGoogleUtilitiesAppDelegateProxyEnabledPlistKey; -} - -+ (NSString *)correctAlternativeWhenAppDelegateProxyNotCreated { - return NSClassFromString(@"FIRCore") - ? @"To log deep link campaigns manually, call the methods in " - @"FIRAnalytics+AppDelegate.h." - : @""; -} - -#pragma mark - Private Methods for Testing - -#ifdef GUL_APP_DELEGATE_TESTING - -+ (void)clearInterceptors { - [[self interceptors] removeAllObjects]; -} - -+ (void)resetProxyOriginalDelegateOnceToken { - sProxyAppDelegateOnceToken = 0; -} - -+ (id<UIApplicationDelegate>)originalDelegate { - return gOriginalAppDelegate; -} - -#endif // GUL_APP_DELEGATE_TESTING - -@end - -#endif // TARGET_OS_IOS diff --git a/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Internal/GULAppDelegateSwizzler_Private.h b/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Internal/GULAppDelegateSwizzler_Private.h @@ -1,64 +0,0 @@ -/* - * Copyright 2018 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <GoogleUtilities/GULAppDelegateSwizzler.h> -#import <GoogleUtilities/GULMutableDictionary.h> - -@class UIApplication; - -NS_ASSUME_NONNULL_BEGIN - -@interface GULAppDelegateSwizzler () - -/** Returns the current sharedApplication. - * - * @return the current UIApplication if in an app, or nil if in extension or if it doesn't exist. - */ -+ (nullable UIApplication *)sharedApplication; - -/** ISA Swizzles the given appDelegate as the original app delegate would be. - * - * @param appDelegate The object that needs to be isa swizzled. This should conform to the - * UIApplicationDelegate protocol. - */ -+ (void)proxyAppDelegate:(id<UIApplicationDelegate>)appDelegate; - -/** Returns a dictionary containing interceptor IDs mapped to a GULZeroingWeakContainer. - * - * @return A dictionary of the form {NSString : GULZeroingWeakContainer}, where the NSString is - * the interceptorID. - */ -+ (GULMutableDictionary *)interceptors; - -#ifdef GUL_APP_DELEGATE_TESTING // Methods only used in tests. - -/** Deletes all the registered interceptors. */ -+ (void)clearInterceptors; - -/** Resets the token that prevents the app delegate proxy from being isa swizzled multiple times. */ -+ (void)resetProxyOriginalDelegateOnceToken; - -/** Returns the original app delegate that was proxied. - * - * @return The original app delegate instance that was proxied. - */ -+ (id<UIApplicationDelegate>)originalDelegate; - -#endif // GUL_APP_DELEGATE_TESTING - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Private/GULAppDelegateSwizzler.h b/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Private/GULAppDelegateSwizzler.h @@ -1,63 +0,0 @@ -/* - * Copyright 2018 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -@protocol UIApplicationDelegate; - -NS_ASSUME_NONNULL_BEGIN - -typedef NSString *const GULAppDelegateInterceptorID; - -/** This class contains methods that isa swizzle the app delegate. */ -@interface GULAppDelegateSwizzler : NSProxy - -/** Registers an app delegate interceptor whose methods will be invoked as they're invoked on the - * original app delegate. - * - * @param interceptor An instance of a class that conforms to the UIApplicationDelegate protocol. - * The interceptor is NOT retained. - * @return A unique GULAppDelegateInterceptorID if interceptor was successfully registered; nil - * if it fails. - */ -+ (nullable GULAppDelegateInterceptorID)registerAppDelegateInterceptor: - (id<UIApplicationDelegate>)interceptor; - -/** Unregisters an interceptor with the given ID if it exists. - * - * @param interceptorID The object that was generated when the interceptor was registered. - */ -+ (void)unregisterAppDelegateInterceptorWithID:(GULAppDelegateInterceptorID)interceptorID; - -/** This method ensures that the original app delegate has been proxied. Call this before - * registering your interceptor. This method is safe to call multiple times (but it only proxies - * the app delegate once). - */ -+ (void)proxyOriginalDelegate NS_EXTENSION_UNAVAILABLE( - "App delegate proxy doesn't support extensions."); - -/** Indicates whether app delegate proxy is explicitly disabled or enabled. Enabled by default. - * - * @return YES if AppDelegateProxy is Enabled, NO otherwise. - */ -+ (BOOL)isAppDelegateProxyEnabled; - -/** Do not initialize this class. */ -- (instancetype)init NS_UNAVAILABLE; - -NS_ASSUME_NONNULL_END - -@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/Common/GULLoggerCodes.h b/Pods/GoogleUtilities/GoogleUtilities/Common/GULLoggerCodes.h @@ -1,36 +0,0 @@ -/* - * Copyright 2018 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -typedef NS_ENUM(NSInteger, GULSwizzlerMessageCode) { - // App Delegate Swizzling. - kGULSwizzlerMessageCodeAppDelegateSwizzling000 = 1000, // I-SWZ001000 - kGULSwizzlerMessageCodeAppDelegateSwizzling001 = 1001, // I-SWZ001001 - kGULSwizzlerMessageCodeAppDelegateSwizzling002 = 1002, // I-SWZ001002 - kGULSwizzlerMessageCodeAppDelegateSwizzling003 = 1003, // I-SWZ001003 - kGULSwizzlerMessageCodeAppDelegateSwizzling004 = 1004, // I-SWZ001004 - kGULSwizzlerMessageCodeAppDelegateSwizzling005 = 1005, // I-SWZ001005 - kGULSwizzlerMessageCodeAppDelegateSwizzling006 = 1006, // I-SWZ001006 - kGULSwizzlerMessageCodeAppDelegateSwizzling007 = 1007, // I-SWZ001007 - kGULSwizzlerMessageCodeAppDelegateSwizzling008 = 1008, // I-SWZ001008 - kGULSwizzlerMessageCodeAppDelegateSwizzling009 = 1009, // I-SWZ001009 - kGULSwizzlerMessageCodeAppDelegateSwizzling010 = 1010, // I-SWZ001010 - kGULSwizzlerMessageCodeAppDelegateSwizzling011 = 1011, // I-SWZ001011 - kGULSwizzlerMessageCodeAppDelegateSwizzling012 = 1012, // I-SWZ001012 - kGULSwizzlerMessageCodeAppDelegateSwizzling013 = 1013, // I-SWZ001013 - - // Method Swizzling. - kGULSwizzlerMessageCodeMethodSwizzling000 = 2000, // I-SWZ002000 -}; diff --git a/Pods/GoogleUtilities/GoogleUtilities/Environment/third_party/GULAppEnvironmentUtil.h b/Pods/GoogleUtilities/GoogleUtilities/Environment/third_party/GULAppEnvironmentUtil.h @@ -1,43 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -@interface GULAppEnvironmentUtil : NSObject - -/// Indicates whether the app is from Apple Store or not. Returns NO if the app is on simulator, -/// development environment or sideloaded. -+ (BOOL)isFromAppStore; - -/// Indicates whether the app is a Testflight app. Returns YES if the app has sandbox receipt. -/// Returns NO otherwise. -+ (BOOL)isAppStoreReceiptSandbox; - -/// Indicates whether the app is on simulator or not at runtime depending on the device -/// architecture. -+ (BOOL)isSimulator; - -/// The current device model. Returns an empty string if device model cannot be retrieved. -+ (NSString *)deviceModel; - -/// The current operating system version. Returns an empty string if the system version cannot be -/// retrieved. -+ (NSString *)systemVersion; - -/// Indicates whether it is running inside an extension or an app. -+ (BOOL)isAppExtension; - -@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/Environment/third_party/GULAppEnvironmentUtil.m b/Pods/GoogleUtilities/GoogleUtilities/Environment/third_party/GULAppEnvironmentUtil.m @@ -1,250 +0,0 @@ -// Copyright 2017 Google -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#import "GULAppEnvironmentUtil.h" - -#import <Foundation/Foundation.h> -#import <dlfcn.h> -#import <mach-o/dyld.h> -#import <sys/utsname.h> - -#if TARGET_OS_IOS -#import <UIKit/UIKit.h> -#endif - -/// The encryption info struct and constants are missing from the iPhoneSimulator SDK, but not from -/// the iPhoneOS or Mac OS X SDKs. Since one doesn't ever ship a Simulator binary, we'll just -/// provide the definitions here. -#if TARGET_OS_SIMULATOR && !defined(LC_ENCRYPTION_INFO) -#define LC_ENCRYPTION_INFO 0x21 -struct encryption_info_command { - uint32_t cmd; - uint32_t cmdsize; - uint32_t cryptoff; - uint32_t cryptsize; - uint32_t cryptid; -}; -#endif - -@implementation GULAppEnvironmentUtil - -/// A key for the Info.plist to enable or disable checking if the App Store is running in a sandbox. -/// This will affect your data integrity when using Firebase Analytics, as it will disable some -/// necessary checks. -static NSString *const kFIRAppStoreReceiptURLCheckEnabledKey = - @"FirebaseAppStoreReceiptURLCheckEnabled"; - -/// The file name of the sandbox receipt. This is available on iOS >= 8.0 -static NSString *const kFIRAIdentitySandboxReceiptFileName = @"sandboxReceipt"; - -/// The following copyright from Landon J. Fuller applies to the isAppEncrypted function. -/// -/// Copyright (c) 2017 Landon J. Fuller <landon@landonf.org> -/// All rights reserved. -/// -/// Permission is hereby granted, free of charge, to any person obtaining a copy of this software -/// and associated documentation files (the "Software"), to deal in the Software without -/// restriction, including without limitation the rights to use, copy, modify, merge, publish, -/// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in all copies or -/// substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -/// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -/// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -/// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -/// -/// Comment from <a href="http://iphonedevwiki.net/index.php/Crack_prevention">iPhone Dev Wiki -/// Crack Prevention</a>: -/// App Store binaries are signed by both their developer and Apple. This encrypts the binary so -/// that decryption keys are needed in order to make the binary readable. When iOS executes the -/// binary, the decryption keys are used to decrypt the binary into a readable state where it is -/// then loaded into memory and executed. iOS can tell the encryption status of a binary via the -/// cryptid structure member of LC_ENCRYPTION_INFO MachO load command. If cryptid is a non-zero -/// value then the binary is encrypted. -/// -/// 'Cracking' works by letting the kernel decrypt the binary then siphoning the decrypted data into -/// a new binary file, resigning, and repackaging. This will only work on jailbroken devices as -/// codesignature validation has been removed. Resigning takes place because while the codesignature -/// doesn't have to be valid thanks to the jailbreak, it does have to be in place unless you have -/// AppSync or similar to disable codesignature checks. -/// -/// More information at <a href="http://landonf.org/2009/02/index.html">Landon Fuller's blog</a> -static BOOL IsAppEncrypted() { - const struct mach_header *executableHeader = NULL; - for (uint32_t i = 0; i < _dyld_image_count(); i++) { - const struct mach_header *header = _dyld_get_image_header(i); - if (header && header->filetype == MH_EXECUTE) { - executableHeader = header; - break; - } - } - - if (!executableHeader) { - return NO; - } - - BOOL is64bit = (executableHeader->magic == MH_MAGIC_64); - uintptr_t cursor = (uintptr_t)executableHeader + - (is64bit ? sizeof(struct mach_header_64) : sizeof(struct mach_header)); - const struct segment_command *segmentCommand = NULL; - uint32_t i = 0; - - while (i++ < executableHeader->ncmds) { - segmentCommand = (struct segment_command *)cursor; - - if (!segmentCommand) { - continue; - } - - if ((!is64bit && segmentCommand->cmd == LC_ENCRYPTION_INFO) || - (is64bit && segmentCommand->cmd == LC_ENCRYPTION_INFO_64)) { - if (is64bit) { - struct encryption_info_command_64 *cryptCmd = - (struct encryption_info_command_64 *)segmentCommand; - return cryptCmd && cryptCmd->cryptid != 0; - } else { - struct encryption_info_command *cryptCmd = (struct encryption_info_command *)segmentCommand; - return cryptCmd && cryptCmd->cryptid != 0; - } - } - cursor += segmentCommand->cmdsize; - } - - return NO; -} - -static BOOL HasSCInfoFolder() { -#if TARGET_OS_IOS || TARGET_OS_TV - NSString *bundlePath = [NSBundle mainBundle].bundlePath; - NSString *scInfoPath = [bundlePath stringByAppendingPathComponent:@"SC_Info"]; - return [[NSFileManager defaultManager] fileExistsAtPath:scInfoPath]; -#elif TARGET_OS_OSX - return NO; -#endif -} - -static BOOL HasEmbeddedMobileProvision() { -#if TARGET_OS_IOS || TARGET_OS_TV - return [[NSBundle mainBundle] pathForResource:@"embedded" ofType:@"mobileprovision"].length > 0; -#elif TARGET_OS_OSX - return NO; -#endif -} - -+ (BOOL)isFromAppStore { - static dispatch_once_t isEncryptedOnce; - static BOOL isEncrypted = NO; - - dispatch_once(&isEncryptedOnce, ^{ - isEncrypted = IsAppEncrypted(); - }); - - if ([GULAppEnvironmentUtil isSimulator]) { - return NO; - } - - // If an app contain the sandboxReceipt file, it means its coming from TestFlight - // This must be checked before the SCInfo Folder check below since TestFlight apps may - // also have an SCInfo folder. - if ([GULAppEnvironmentUtil isAppStoreReceiptSandbox]) { - return NO; - } - - if (HasSCInfoFolder()) { - // When iTunes downloads a .ipa, it also gets a customized .sinf file which is added to the - // main SC_Info directory. - return YES; - } - - // For iOS >= 8.0, iTunesMetadata.plist is moved outside of the sandbox. Any attempt to read - // the iTunesMetadata.plist outside of the sandbox will be rejected by Apple. - // If the app does not contain the embedded.mobileprovision which is stripped out by Apple when - // the app is submitted to store, then it is highly likely that it is from Apple Store. - return isEncrypted && !HasEmbeddedMobileProvision(); -} - -+ (BOOL)isAppStoreReceiptSandbox { - // Since checking the App Store's receipt URL can be memory intensive, check the option in the - // Info.plist if developers opted out of this check. - id enableSandboxCheck = - [[NSBundle mainBundle] objectForInfoDictionaryKey:kFIRAppStoreReceiptURLCheckEnabledKey]; - if (enableSandboxCheck && [enableSandboxCheck isKindOfClass:[NSNumber class]] && - ![enableSandboxCheck boolValue]) { - return NO; - } -// The #else is for pre Xcode 9 where @available is not yet implemented. -#if __has_builtin(__builtin_available) - if (@available(iOS 7.0, *)) { -#else - if ([[UIDevice currentDevice].systemVersion integerValue] >= 7) { -#endif - NSURL *appStoreReceiptURL = [NSBundle mainBundle].appStoreReceiptURL; - NSString *appStoreReceiptFileName = appStoreReceiptURL.lastPathComponent; - return [appStoreReceiptFileName isEqualToString:kFIRAIdentitySandboxReceiptFileName]; - } - return NO; -} - -+ (BOOL)isSimulator { -#if TARGET_OS_IOS || TARGET_OS_TV - NSString *platform = [GULAppEnvironmentUtil deviceModel]; - return [platform isEqual:@"x86_64"] || [platform isEqual:@"i386"]; -#elif TARGET_OS_OSX - return NO; -#endif -} - -+ (NSString *)deviceModel { - static dispatch_once_t once; - static NSString *deviceModel; - - dispatch_once(&once, ^{ - struct utsname systemInfo; - if (uname(&systemInfo) == 0) { - deviceModel = [NSString stringWithUTF8String:systemInfo.machine]; - } - }); - return deviceModel; -} - -+ (NSString *)systemVersion { -#if TARGET_OS_IOS - return [UIDevice currentDevice].systemVersion; -#elif TARGET_OS_OSX || TARGET_OS_TV - // Assemble the systemVersion, excluding the patch version if it's 0. - NSOperatingSystemVersion osVersion = [NSProcessInfo processInfo].operatingSystemVersion; - NSMutableString *versionString = [[NSMutableString alloc] - initWithFormat:@"%ld.%ld", (long)osVersion.majorVersion, (long)osVersion.minorVersion]; - if (osVersion.patchVersion != 0) { - [versionString appendFormat:@".%ld", (long)osVersion.patchVersion]; - } - return versionString; -#endif -} - -+ (BOOL)isAppExtension { -#if TARGET_OS_IOS || TARGET_OS_TV - // Documented by <a href="https://goo.gl/RRB2Up">Apple</a> - BOOL appExtension = [[[NSBundle mainBundle] bundlePath] hasSuffix:@".appex"]; - return appExtension; -#elif TARGET_OS_OSX - return NO; -#endif -} - -@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/Logger/GULLogger.m b/Pods/GoogleUtilities/GoogleUtilities/Logger/GULLogger.m @@ -1,209 +0,0 @@ -// Copyright 2018 Google -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#import "Private/GULLogger.h" - -#include <asl.h> - -#import <GoogleUtilities/GULAppEnvironmentUtil.h> -#import "Public/GULLoggerLevel.h" - -/// ASL client facility name used by GULLogger. -const char *kGULLoggerASLClientFacilityName = "com.google.utilities.logger"; - -static dispatch_once_t sGULLoggerOnceToken; - -static aslclient sGULLoggerClient; - -static dispatch_queue_t sGULClientQueue; - -static BOOL sGULLoggerDebugMode; - -static GULLoggerLevel sGULLoggerMaximumLevel; - -// Allow clients to register a version to include in the log. -static const char *sVersion = ""; - -static GULLoggerService kGULLoggerLogger = @"[GULLogger]"; - -#ifdef DEBUG -/// The regex pattern for the message code. -static NSString *const kMessageCodePattern = @"^I-[A-Z]{3}[0-9]{6}$"; -static NSRegularExpression *sMessageCodeRegex; -#endif - -void GULLoggerInitializeASL(void) { - dispatch_once(&sGULLoggerOnceToken, ^{ - NSInteger majorOSVersion = [[GULAppEnvironmentUtil systemVersion] integerValue]; - uint32_t aslOptions = ASL_OPT_STDERR; -#if TARGET_OS_SIMULATOR - // The iOS 11 simulator doesn't need the ASL_OPT_STDERR flag. - if (majorOSVersion >= 11) { - aslOptions = 0; - } -#else - // Devices running iOS 10 or higher don't need the ASL_OPT_STDERR flag. - if (majorOSVersion >= 10) { - aslOptions = 0; - } -#endif // TARGET_OS_SIMULATOR - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" // asl is deprecated - // Initialize the ASL client handle. - sGULLoggerClient = asl_open(NULL, kGULLoggerASLClientFacilityName, aslOptions); - sGULLoggerMaximumLevel = GULLoggerLevelNotice; - - // Set the filter used by system/device log. Initialize in default mode. - asl_set_filter(sGULLoggerClient, ASL_FILTER_MASK_UPTO(ASL_LEVEL_NOTICE)); - - sGULClientQueue = dispatch_queue_create("GULLoggingClientQueue", DISPATCH_QUEUE_SERIAL); - dispatch_set_target_queue(sGULClientQueue, - dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)); -#ifdef DEBUG - sMessageCodeRegex = [NSRegularExpression regularExpressionWithPattern:kMessageCodePattern - options:0 - error:NULL]; -#endif - }); -} - -void GULLoggerEnableSTDERR(void) { - asl_add_log_file(sGULLoggerClient, STDERR_FILENO); -} - -void GULLoggerForceDebug(void) { - // We should enable debug mode if we're not running from App Store. - if (![GULAppEnvironmentUtil isFromAppStore]) { - sGULLoggerDebugMode = YES; - GULSetLoggerLevel(GULLoggerLevelDebug); - } -} - -__attribute__((no_sanitize("thread"))) void GULSetLoggerLevel(GULLoggerLevel loggerLevel) { - if (loggerLevel < GULLoggerLevelMin || loggerLevel > GULLoggerLevelMax) { - GULLogError(kGULLoggerLogger, NO, @"I-COR000023", @"Invalid logger level, %ld", - (long)loggerLevel); - return; - } - GULLoggerInitializeASL(); - // We should not raise the logger level if we are running from App Store. - if (loggerLevel >= GULLoggerLevelNotice && [GULAppEnvironmentUtil isFromAppStore]) { - return; - } - - sGULLoggerMaximumLevel = loggerLevel; - dispatch_async(sGULClientQueue, ^{ - asl_set_filter(sGULLoggerClient, ASL_FILTER_MASK_UPTO(loggerLevel)); - }); -} - -/** - * Check if the level is high enough to be loggable. - */ -__attribute__((no_sanitize("thread"))) BOOL GULIsLoggableLevel(GULLoggerLevel loggerLevel) { - GULLoggerInitializeASL(); - if (sGULLoggerDebugMode) { - return YES; - } - return (BOOL)(loggerLevel <= sGULLoggerMaximumLevel); -} - -#ifdef DEBUG -void GULResetLogger() { - sGULLoggerOnceToken = 0; -} - -aslclient getGULLoggerClient() { - return sGULLoggerClient; -} - -dispatch_queue_t getGULClientQueue() { - return sGULClientQueue; -} - -BOOL getGULLoggerDebugMode() { - return sGULLoggerDebugMode; -} -#endif - -void GULLoggerRegisterVersion(const char *version) { - sVersion = version; -} - -void GULLogBasic(GULLoggerLevel level, - GULLoggerService service, - BOOL forceLog, - NSString *messageCode, - NSString *message, - va_list args_ptr) { - GULLoggerInitializeASL(); - if (!(level <= sGULLoggerMaximumLevel || sGULLoggerDebugMode || forceLog)) { - return; - } - -#ifdef DEBUG - NSCAssert(messageCode.length == 11, @"Incorrect message code length."); - NSRange messageCodeRange = NSMakeRange(0, messageCode.length); - NSUInteger numberOfMatches = [sMessageCodeRegex numberOfMatchesInString:messageCode - options:0 - range:messageCodeRange]; - NSCAssert(numberOfMatches == 1, @"Incorrect message code format."); -#endif - NSString *logMsg = [[NSString alloc] initWithFormat:message arguments:args_ptr]; - logMsg = [NSString stringWithFormat:@"%s - %@[%@] %@", sVersion, service, messageCode, logMsg]; - dispatch_async(sGULClientQueue, ^{ - asl_log(sGULLoggerClient, NULL, level, "%s", logMsg.UTF8String); - }); -} -#pragma clang diagnostic pop - -/** - * Generates the logging functions using macros. - * - * Calling GULLogError(kGULLoggerCore, @"I-COR000001", @"Configure %@ failed.", @"blah") shows: - * yyyy-mm-dd hh:mm:ss.SSS sender[PID] <Error> [{service}][I-COR000001] Configure blah failed. - * Calling GULLogDebug(kGULLoggerCore, @"I-COR000001", @"Configure succeed.") shows: - * yyyy-mm-dd hh:mm:ss.SSS sender[PID] <Debug> [{service}][I-COR000001] Configure succeed. - */ -#define GUL_LOGGING_FUNCTION(level) \ - void GULLog##level(GULLoggerService service, BOOL force, NSString *messageCode, \ - NSString *message, ...) { \ - va_list args_ptr; \ - va_start(args_ptr, message); \ - GULLogBasic(GULLoggerLevel##level, service, force, messageCode, message, args_ptr); \ - va_end(args_ptr); \ - } - -GUL_LOGGING_FUNCTION(Error) -GUL_LOGGING_FUNCTION(Warning) -GUL_LOGGING_FUNCTION(Notice) -GUL_LOGGING_FUNCTION(Info) -GUL_LOGGING_FUNCTION(Debug) - -#undef GUL_MAKE_LOGGER - -#pragma mark - GULLoggerWrapper - -@implementation GULLoggerWrapper - -+ (void)logWithLevel:(GULLoggerLevel)level - withService:(GULLoggerService)service - withCode:(NSString *)messageCode - withMessage:(NSString *)message - withArgs:(va_list)args { - GULLogBasic(level, service, NO, messageCode, message, args); -} - -@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/Logger/Private/GULLogger.h b/Pods/GoogleUtilities/GoogleUtilities/Logger/Private/GULLogger.h @@ -1,159 +0,0 @@ -/* - * Copyright 2018 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -#import <GoogleUtilities/GULLoggerLevel.h> - -NS_ASSUME_NONNULL_BEGIN - -/** - * The services used in the logger. - */ -typedef NSString *const GULLoggerService; - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -/** - * Initialize GULLogger. - */ -extern void GULLoggerInitializeASL(void); - -/** - * Override log level to Debug. - */ -void GULLoggerForceDebug(void); - -/** - * Turn on logging to STDERR. - */ -extern void GULLoggerEnableSTDERR(void); - -/** - * Changes the default logging level of GULLoggerLevelNotice to a user-specified level. - * The default level cannot be set above GULLoggerLevelNotice if the app is running from App Store. - * (required) log level (one of the GULLoggerLevel enum values). - */ -extern void GULSetLoggerLevel(GULLoggerLevel loggerLevel); - -/** - * Checks if the specified logger level is loggable given the current settings. - * (required) log level (one of the GULLoggerLevel enum values). - */ -extern BOOL GULIsLoggableLevel(GULLoggerLevel loggerLevel); - -/** - * Register version to include in logs. - * (required) version - */ -extern void GULLoggerRegisterVersion(const char *version); - -/** - * Logs a message to the Xcode console and the device log. If running from AppStore, will - * not log any messages with a level higher than GULLoggerLevelNotice to avoid log spamming. - * (required) log level (one of the GULLoggerLevel enum values). - * (required) service name of type GULLoggerService. - * (required) message code starting with "I-" which means iOS, followed by a capitalized - * three-character service identifier and a six digit integer message ID that is unique - * within the service. - * An example of the message code is @"I-COR000001". - * (required) message string which can be a format string. - * (optional) variable arguments list obtained from calling va_start, used when message is a format - * string. - */ -extern void GULLogBasic(GULLoggerLevel level, - GULLoggerService service, - BOOL forceLog, - NSString *messageCode, - NSString *message, -// On 64-bit simulators, va_list is not a pointer, so cannot be marked nullable -// See: http://stackoverflow.com/q/29095469 -#if __LP64__ && TARGET_OS_SIMULATOR || TARGET_OS_OSX - va_list args_ptr -#else - va_list _Nullable args_ptr -#endif -); - -/** - * The following functions accept the following parameters in order: - * (required) service name of type GULLoggerService. - * (required) message code starting from "I-" which means iOS, followed by a capitalized - * three-character service identifier and a six digit integer message ID that is unique - * within the service. - * An example of the message code is @"I-COR000001". - * See go/firebase-log-proposal for details. - * (required) message string which can be a format string. - * (optional) the list of arguments to substitute into the format string. - * Example usage: - * GULLogError(kGULLoggerCore, @"I-COR000001", @"Configuration of %@ failed.", app.name); - */ -extern void GULLogError(GULLoggerService service, - BOOL force, - NSString *messageCode, - NSString *message, - ...) NS_FORMAT_FUNCTION(4, 5); -extern void GULLogWarning(GULLoggerService service, - BOOL force, - NSString *messageCode, - NSString *message, - ...) NS_FORMAT_FUNCTION(4, 5); -extern void GULLogNotice(GULLoggerService service, - BOOL force, - NSString *messageCode, - NSString *message, - ...) NS_FORMAT_FUNCTION(4, 5); -extern void GULLogInfo(GULLoggerService service, - BOOL force, - NSString *messageCode, - NSString *message, - ...) NS_FORMAT_FUNCTION(4, 5); -extern void GULLogDebug(GULLoggerService service, - BOOL force, - NSString *messageCode, - NSString *message, - ...) NS_FORMAT_FUNCTION(4, 5); - -#ifdef __cplusplus -} // extern "C" -#endif // __cplusplus - -@interface GULLoggerWrapper : NSObject - -/** - * Objective-C wrapper for GULLogBasic to allow weak linking to GULLogger - * (required) log level (one of the GULLoggerLevel enum values). - * (required) service name of type GULLoggerService. - * (required) message code starting with "I-" which means iOS, followed by a capitalized - * three-character service identifier and a six digit integer message ID that is unique - * within the service. - * An example of the message code is @"I-COR000001". - * (required) message string which can be a format string. - * (optional) variable arguments list obtained from calling va_start, used when message is a format - * string. - */ - -+ (void)logWithLevel:(GULLoggerLevel)level - withService:(GULLoggerService)service - withCode:(NSString *)messageCode - withMessage:(NSString *)message - withArgs:(va_list)args; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleUtilities/GoogleUtilities/Logger/Public/GULLoggerLevel.h b/Pods/GoogleUtilities/GoogleUtilities/Logger/Public/GULLoggerLevel.h @@ -1,35 +0,0 @@ -/* - * Copyright 2018 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * The log levels used by internal logging. - */ -typedef NS_ENUM(NSInteger, GULLoggerLevel) { - /** Error level, matches ASL_LEVEL_ERR. */ - GULLoggerLevelError = 3, - /** Warning level, matches ASL_LEVEL_WARNING. */ - GULLoggerLevelWarning = 4, - /** Notice level, matches ASL_LEVEL_NOTICE. */ - GULLoggerLevelNotice = 5, - /** Info level, matches ASL_LEVEL_INFO. */ - GULLoggerLevelInfo = 6, - /** Debug level, matches ASL_LEVEL_DEBUG. */ - GULLoggerLevelDebug = 7, - /** Minimum log level. */ - GULLoggerLevelMin = GULLoggerLevelError, - /** Maximum log level. */ - GULLoggerLevelMax = GULLoggerLevelDebug -} NS_SWIFT_NAME(GoogleLoggerLevel); diff --git a/Pods/GoogleUtilities/GoogleUtilities/MethodSwizzler/GULSwizzler.m b/Pods/GoogleUtilities/GoogleUtilities/MethodSwizzler/GULSwizzler.m @@ -1,185 +0,0 @@ -// Copyright 2018 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#import "Private/GULSwizzler.h" - -#import <objc/runtime.h> - -#import <GoogleUtilities/GULLogger.h> -#import "../Common/GULLoggerCodes.h" - -#ifdef GUL_UNSWIZZLING_ENABLED -#import <GoogleUtilities/GULSwizzlingCache.h> -// We need a private method for an assert. -#import <GoogleUtilities/GULSwizzlingCache_Private.h> -#endif - -static GULLoggerService kGULLoggerSwizzler = @"[GoogleUtilites/MethodSwizzler]"; - -dispatch_queue_t GetGULSwizzlingQueue() { - static dispatch_queue_t queue; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - queue = dispatch_queue_create("com.google.GULSwizzler", DISPATCH_QUEUE_SERIAL); - }); - return queue; -} - -@implementation GULSwizzler - -+ (void)swizzleClass:(Class)aClass - selector:(SEL)selector - isClassSelector:(BOOL)isClassSelector - withBlock:(nullable id)block { - dispatch_sync(GetGULSwizzlingQueue(), ^{ - NSAssert(selector, @"The selector cannot be NULL"); - NSAssert(aClass, @"The class cannot be Nil"); - Class resolvedClass = aClass; - Method method = nil; - if (isClassSelector) { - method = class_getClassMethod(aClass, selector); - resolvedClass = object_getClass(aClass); - } else { - method = class_getInstanceMethod(aClass, selector); - } - NSAssert(method, @"You're attempting to swizzle a method that doesn't exist. (%@, %@)", - NSStringFromClass(resolvedClass), NSStringFromSelector(selector)); - IMP newImp = imp_implementationWithBlock(block); - -#ifdef GUL_UNSWIZZLING_ENABLED - IMP currentImp = class_getMethodImplementation(resolvedClass, selector); - [[GULSwizzlingCache sharedInstance] cacheCurrentIMP:currentImp - forNewIMP:newImp - forClass:resolvedClass - withSelector:selector]; -#endif - - const char *typeEncoding = method_getTypeEncoding(method); - __unused IMP originalImpOfClass = - class_replaceMethod(resolvedClass, selector, newImp, typeEncoding); - -#ifdef GUL_UNSWIZZLING_ENABLED - // If !originalImpOfClass, then the IMP came from a superclass. - if (originalImpOfClass) { - if (originalImpOfClass != - [[GULSwizzlingCache sharedInstance] originalIMPOfCurrentIMP:currentImp]) { - GULLogWarning(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeMethodSwizzling000], - @"Swizzling class: %@ SEL:%@ after it has been previously been swizzled.", - NSStringFromClass(resolvedClass), NSStringFromSelector(selector)); - } - } -#endif - }); -} - -+ (void)unswizzleClass:(Class)aClass selector:(SEL)selector isClassSelector:(BOOL)isClassSelector { -#ifdef GUL_UNSWIZZLING_ENABLED - dispatch_sync(GetGULSwizzlingQueue(), ^{ - NSAssert(aClass != nil && selector != nil, @"You cannot unswizzle a nil class or selector."); - Method method = nil; - Class resolvedClass = aClass; - if (isClassSelector) { - resolvedClass = object_getClass(aClass); - method = class_getClassMethod(aClass, selector); - } else { - method = class_getInstanceMethod(aClass, selector); - } - NSAssert(method, @"Couldn't find the method you're unswizzling in the runtime."); - IMP originalImp = [[GULSwizzlingCache sharedInstance] cachedIMPForClass:resolvedClass - withSelector:selector]; - NSAssert(originalImp, @"This class/selector combination hasn't been swizzled"); - IMP currentImp = method_setImplementation(method, originalImp); - BOOL didRemoveBlock = imp_removeBlock(currentImp); - NSAssert(didRemoveBlock, @"Wasn't able to remove the block of a swizzled IMP."); - [[GULSwizzlingCache sharedInstance] clearCacheForSwizzledIMP:currentImp - selector:selector - aClass:resolvedClass]; - }); -#else - NSAssert(NO, @"Unswizzling is disabled."); -#endif -} - -+ (nullable IMP)originalImplementationForClass:(Class)aClass - selector:(SEL)selector - isClassSelector:(BOOL)isClassSelector { -#ifdef GUL_UNSWIZZLING_ENABLED - __block IMP originalImp = nil; - dispatch_sync(GetGULSwizzlingQueue(), ^{ - Class resolvedClass = isClassSelector ? object_getClass(aClass) : aClass; - originalImp = [[GULSwizzlingCache sharedInstance] cachedIMPForClass:resolvedClass - withSelector:selector]; - NSAssert(originalImp, @"The IMP for this class/selector combo doesn't exist (%@, %@).", - NSStringFromClass(resolvedClass), NSStringFromSelector(selector)); - }); - return originalImp; -#else - NSAssert(NO, @"Unswizzling is disabled and the original IMP is not cached."); - return nil; -#endif -} - -+ (nullable IMP)currentImplementationForClass:(Class)aClass - selector:(SEL)selector - isClassSelector:(BOOL)isClassSelector { - NSAssert(selector, @"The selector cannot be NULL"); - NSAssert(aClass, @"The class cannot be Nil"); - if (selector == NULL || aClass == nil) { - return nil; - } - __block IMP currentIMP = nil; - dispatch_sync(GetGULSwizzlingQueue(), ^{ - Method method = nil; - if (isClassSelector) { - method = class_getClassMethod(aClass, selector); - } else { - method = class_getInstanceMethod(aClass, selector); - } - NSAssert(method, @"The Method for this class/selector combo doesn't exist (%@, %@).", - NSStringFromClass(aClass), NSStringFromSelector(selector)); - if (method == nil) { - return; - } - currentIMP = method_getImplementation(method); - NSAssert(currentIMP, @"The IMP for this class/selector combo doesn't exist (%@, %@).", - NSStringFromClass(aClass), NSStringFromSelector(selector)); - }); - return currentIMP; -} - -+ (BOOL)selector:(SEL)selector existsInClass:(Class)aClass isClassSelector:(BOOL)isClassSelector { - Method method = isClassSelector ? class_getClassMethod(aClass, selector) - : class_getInstanceMethod(aClass, selector); - return method != nil; -} - -+ (NSArray<id> *)ivarObjectsForObject:(id)object { - NSMutableArray *array = [NSMutableArray array]; - unsigned int count; - Ivar *vars = class_copyIvarList([object class], &count); - for (NSUInteger i = 0; i < count; i++) { - const char *typeEncoding = ivar_getTypeEncoding(vars[i]); - // Check to see if the ivar is an object. - if (strncmp(typeEncoding, "@", 1) == 0) { - id ivarObject = object_getIvar(object, vars[i]); - [array addObject:ivarObject]; - } - } - free(vars); - return array; -} - -@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/MethodSwizzler/Private/GULOriginalIMPConvenienceMacros.h b/Pods/GoogleUtilities/GoogleUtilities/MethodSwizzler/Private/GULOriginalIMPConvenienceMacros.h @@ -1,207 +0,0 @@ -/* - * Copyright 2018 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * GULOriginalIMPConvenienceMacros.h - * - * This header contains convenience macros for invoking the original IMP of a swizzled method. - */ - -/** - * Invokes original IMP when the original selector takes no arguments. - * - * @param __receivingObject The object on which the IMP is invoked. - * @param __swizzledSEL The selector used for swizzling. - * @param __returnType The return type of the original implementation. - * @param __originalIMP The original IMP. - */ -#define GUL_INVOKE_ORIGINAL_IMP0(__receivingObject, __swizzledSEL, __returnType, __originalIMP) \ - ((__returnType(*)(id, SEL))__originalIMP)(__receivingObject, __swizzledSEL) - -/** - * Invokes original IMP when the original selector takes 1 argument. - * - * @param __receivingObject The object on which the IMP is invoked. - * @param __swizzledSEL The selector used for swizzling. - * @param __returnType The return type of the original implementation. - * @param __originalIMP The original IMP. - * @param __arg1 The first argument. - */ -#define GUL_INVOKE_ORIGINAL_IMP1(__receivingObject, __swizzledSEL, __returnType, __originalIMP, \ - __arg1) \ - ((__returnType(*)(id, SEL, __typeof__(__arg1)))__originalIMP)(__receivingObject, __swizzledSEL, \ - __arg1) - -/** - * Invokes original IMP when the original selector takes 2 arguments. - * - * @param __receivingObject The object on which the IMP is invoked. - * @param __swizzledSEL The selector used for swizzling. - * @param __returnType The return type of the original implementation. - * @param __originalIMP The original IMP. - * @param __arg1 The first argument. - * @param __arg2 The second argument. - */ -#define GUL_INVOKE_ORIGINAL_IMP2(__receivingObject, __swizzledSEL, __returnType, __originalIMP, \ - __arg1, __arg2) \ - ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2)))__originalIMP)( \ - __receivingObject, __swizzledSEL, __arg1, __arg2) - -/** - * Invokes original IMP when the original selector takes 3 arguments. - * - * @param __receivingObject The object on which the IMP is invoked. - * @param __swizzledSEL The selector used for swizzling. - * @param __returnType The return type of the original implementation. - * @param __originalIMP The original IMP. - * @param __arg1 The first argument. - * @param __arg2 The second argument. - * @param __arg3 The third argument. - */ -#define GUL_INVOKE_ORIGINAL_IMP3(__receivingObject, __swizzledSEL, __returnType, __originalIMP, \ - __arg1, __arg2, __arg3) \ - ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2), \ - __typeof__(__arg3)))__originalIMP)(__receivingObject, __swizzledSEL, __arg1, \ - __arg2, __arg3) - -/** - * Invokes original IMP when the original selector takes 4 arguments. - * - * @param __receivingObject The object on which the IMP is invoked. - * @param __swizzledSEL The selector used for swizzling. - * @param __returnType The return type of the original implementation. - * @param __originalIMP The original IMP. - * @param __arg1 The first argument. - * @param __arg2 The second argument. - * @param __arg3 The third argument. - * @param __arg4 The fourth argument. - */ -#define GUL_INVOKE_ORIGINAL_IMP4(__receivingObject, __swizzledSEL, __returnType, __originalIMP, \ - __arg1, __arg2, __arg3, __arg4) \ - ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2), __typeof__(__arg3), \ - __typeof__(__arg4)))__originalIMP)(__receivingObject, __swizzledSEL, __arg1, \ - __arg2, __arg3, __arg4) - -/** - * Invokes original IMP when the original selector takes 5 arguments. - * - * @param __receivingObject The object on which the IMP is invoked. - * @param __swizzledSEL The selector used for swizzling. - * @param __returnType The return type of the original implementation. - * @param __originalIMP The original IMP. - * @param __arg1 The first argument. - * @param __arg2 The second argument. - * @param __arg3 The third argument. - * @param __arg4 The fourth argument. - * @param __arg5 The fifth argument. - */ -#define GUL_INVOKE_ORIGINAL_IMP5(__receivingObject, __swizzledSEL, __returnType, __originalIMP, \ - __arg1, __arg2, __arg3, __arg4, __arg5) \ - ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2), __typeof__(__arg3), \ - __typeof__(__arg4), __typeof__(__arg5)))__originalIMP)( \ - __receivingObject, __swizzledSEL, __arg1, __arg2, __arg3, __arg4, __arg5) - -/** - * Invokes original IMP when the original selector takes 6 arguments. - * - * @param __receivingObject The object on which the IMP is invoked. - * @param __swizzledSEL The selector used for swizzling. - * @param __returnType The return type of the original implementation. - * @param __originalIMP The original IMP. - * @param __arg1 The first argument. - * @param __arg2 The second argument. - * @param __arg3 The third argument. - * @param __arg4 The fourth argument. - * @param __arg5 The fifth argument. - * @param __arg6 The sixth argument. - */ -#define GUL_INVOKE_ORIGINAL_IMP6(__receivingObject, __swizzledSEL, __returnType, __originalIMP, \ - __arg1, __arg2, __arg3, __arg4, __arg5, __arg6) \ - ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2), __typeof__(__arg3), \ - __typeof__(__arg4), __typeof__(__arg5), __typeof__(__arg6)))__originalIMP)( \ - __receivingObject, __swizzledSEL, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6) - -/** - * Invokes original IMP when the original selector takes 7 arguments. - * - * @param __receivingObject The object on which the IMP is invoked. - * @param __swizzledSEL The selector used for swizzling. - * @param __returnType The return type of the original implementation. - * @param __originalIMP The original IMP. - * @param __arg1 The first argument. - * @param __arg2 The second argument. - * @param __arg3 The third argument. - * @param __arg4 The fourth argument. - * @param __arg5 The fifth argument. - * @param __arg6 The sixth argument. - * @param __arg7 The seventh argument. - */ -#define GUL_INVOKE_ORIGINAL_IMP7(__receivingObject, __swizzledSEL, __returnType, __originalIMP, \ - __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7) \ - ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2), __typeof__(__arg3), \ - __typeof__(__arg4), __typeof__(__arg5), __typeof__(__arg6), \ - __typeof__(__arg7)))__originalIMP)( \ - __receivingObject, __swizzledSEL, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7) - -/** - * Invokes original IMP when the original selector takes 8 arguments. - * - * @param __receivingObject The object on which the IMP is invoked. - * @param __swizzledSEL The selector used for swizzling. - * @param __returnType The return type of the original implementation. - * @param __originalIMP The original IMP. - * @param __arg1 The first argument. - * @param __arg2 The second argument. - * @param __arg3 The third argument. - * @param __arg4 The fourth argument. - * @param __arg5 The fifth argument. - * @param __arg6 The sixth argument. - * @param __arg7 The seventh argument. - * @param __arg8 The eighth argument. - */ -#define GUL_INVOKE_ORIGINAL_IMP8(__receivingObject, __swizzledSEL, __returnType, __originalIMP, \ - __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7, __arg8) \ - ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2), __typeof__(__arg3), \ - __typeof__(__arg4), __typeof__(__arg5), __typeof__(__arg6), \ - __typeof__(__arg7), __typeof__(__arg8)))__originalIMP)( \ - __receivingObject, __swizzledSEL, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7, \ - __arg8) - -/** - * Invokes original IMP when the original selector takes 9 arguments. - * - * @param __receivingObject The object on which the IMP is invoked. - * @param __swizzledSEL The selector used for swizzling. - * @param __returnType The return type of the original implementation. - * @param __originalIMP The original IMP. - * @param __arg1 The first argument. - * @param __arg2 The second argument. - * @param __arg3 The third argument. - * @param __arg4 The fourth argument. - * @param __arg5 The fifth argument. - * @param __arg6 The sixth argument. - * @param __arg7 The seventh argument. - * @param __arg8 The eighth argument. - * @param __arg9 The ninth argument. - */ -#define GUL_INVOKE_ORIGINAL_IMP9(__receivingObject, __swizzledSEL, __returnType, __originalIMP, \ - __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7, __arg8, \ - __arg9) \ - ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2), __typeof__(__arg3), \ - __typeof__(__arg4), __typeof__(__arg5), __typeof__(__arg6), \ - __typeof__(__arg7), __typeof__(__arg8), __typeof__(__arg9)))__originalIMP)( \ - __receivingObject, __swizzledSEL, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7, \ - __arg8, __arg9) diff --git a/Pods/GoogleUtilities/GoogleUtilities/MethodSwizzler/Private/GULSwizzler.h b/Pods/GoogleUtilities/GoogleUtilities/MethodSwizzler/Private/GULSwizzler.h @@ -1,91 +0,0 @@ -/* - * Copyright 2018 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -NS_ASSUME_NONNULL_BEGIN - -/** This class handles the runtime manipulation necessary to instrument selectors. It stores the - * classes and selectors that have been swizzled, and runs all operations on its own queue. - */ -@interface GULSwizzler : NSObject - -/** Manipulates the Objective-C runtime to replace the original IMP with the supplied block. - * - * @param aClass The class to swizzle. - * @param selector The selector of the class to swizzle. - * @param isClassSelector A BOOL specifying whether the selector is a class or instance selector. - * @param block The block that replaces the original IMP. - */ -+ (void)swizzleClass:(Class)aClass - selector:(SEL)selector - isClassSelector:(BOOL)isClassSelector - withBlock:(nullable id)block; - -/** Restores the original implementation. - * - * @param aClass The class to unswizzle. - * @param selector The selector to restore the original implementation of. - * @param isClassSelector A BOOL specifying whether the selector is a class or instance selector. - */ -+ (void)unswizzleClass:(Class)aClass selector:(SEL)selector isClassSelector:(BOOL)isClassSelector; - -/** Returns the current IMP for the given class and selector. - * - * @param aClass The class to use. - * @param selector The selector to find the implementation of. - * @param isClassSelector A BOOL specifying whether the selector is a class or instance selector. - * @return The implementation of the selector in the runtime. - */ -+ (nullable IMP)currentImplementationForClass:(Class)aClass - selector:(SEL)selector - isClassSelector:(BOOL)isClassSelector; - -/** Returns the original IMP for the given class and selector. - * - * @param aClass The class to use. - * @param selector The selector to find the implementation of. - * @param isClassSelector A BOOL specifying whether the selector is a class or instance selector. - * @return The implementation of the selector in the runtime before any consumer or GULSwizzler - * swizzled. - */ -+ (nullable IMP)originalImplementationForClass:(Class)aClass - selector:(SEL)selector - isClassSelector:(BOOL)isClassSelector; - -/** Checks the runtime to see if a selector exists on a class. If a property is declared as - * @dynamic, we have a reverse swizzling situation, where the implementation of a method exists - * only in concrete subclasses, and NOT in the superclass. We can detect that situation using - * this helper method. Similarly, we can detect situations where a class doesn't implement a - * protocol method. - * - * @param selector The selector to check for. - * @param aClass The class to check. - * @param isClassSelector A BOOL specifying whether the selector is a class or instance selector. - * @return YES if the method was found in this selector/class combination, NO otherwise. - */ -+ (BOOL)selector:(SEL)selector existsInClass:(Class)aClass isClassSelector:(BOOL)isClassSelector; - -/** Returns a list of all Objective-C (and not primitive) ivars contained by the given object. - * - * @param object The object whose ivars will be iterated. - * @return The list of ivar objects. - */ -+ (NSArray<id> *)ivarObjectsForObject:(id)object; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleUtilities/GoogleUtilities/NSData+zlib/GULNSData+zlib.h b/Pods/GoogleUtilities/GoogleUtilities/NSData+zlib/GULNSData+zlib.h @@ -1,49 +0,0 @@ -// Copyright 2018 Google -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#import <Foundation/Foundation.h> - -/// This is a copy of Google Toolbox for Mac library to avoid creating an extra framework. - -// NOTE: For 64bit, none of these apis handle input sizes >32bits, they will return nil when given -// such data. To handle data of that size you really should be streaming it rather then doing it all -// in memory. - -@interface NSData (GULGzip) - -/// Returns an data as the result of decompressing the payload of |data|.The data to decompress must -/// be a gzipped payloads. -+ (NSData *)gul_dataByInflatingGzippedData:(NSData *)data error:(NSError **)error; - -/// Returns an compressed data with the result of gzipping the payload of |data|. Uses the default -/// compression level. -+ (NSData *)gul_dataByGzippingData:(NSData *)data error:(NSError **)error; - -FOUNDATION_EXPORT NSString *const GULNSDataZlibErrorDomain; -FOUNDATION_EXPORT NSString *const GULNSDataZlibErrorKey; // NSNumber -FOUNDATION_EXPORT NSString *const GULNSDataZlibRemainingBytesKey; // NSNumber - -typedef NS_ENUM(NSInteger, GULNSDataZlibError) { - GULNSDataZlibErrorGreaterThan32BitsToCompress = 1024, - // An internal zlib error. - // GULNSDataZlibErrorKey will contain the error value. - // NSLocalizedDescriptionKey may contain an error string from zlib. - // Look in zlib.h for list of errors. - GULNSDataZlibErrorInternal, - // There was left over data in the buffer that was not used. - // GULNSDataZlibRemainingBytesKey will contain number of remaining bytes. - GULNSDataZlibErrorDataRemaining -}; - -@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/NSData+zlib/GULNSData+zlib.m b/Pods/GoogleUtilities/GoogleUtilities/NSData+zlib/GULNSData+zlib.m @@ -1,207 +0,0 @@ -// Copyright 2018 Google -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#import "GULNSData+zlib.h" - -#import <zlib.h> - -#define kChunkSize 1024 -#define Z_DEFAULT_COMPRESSION (-1) - -NSString *const GULNSDataZlibErrorDomain = @"com.google.GULNSDataZlibErrorDomain"; -NSString *const GULNSDataZlibErrorKey = @"GULNSDataZlibErrorKey"; -NSString *const GULNSDataZlibRemainingBytesKey = @"GULNSDataZlibRemainingBytesKey"; - -@implementation NSData (GULGzip) - -+ (NSData *)gul_dataByInflatingGzippedData:(NSData *)data error:(NSError **)error { - const void *bytes = [data bytes]; - NSUInteger length = [data length]; - if (!bytes || !length) { - return nil; - } - -#if defined(__LP64__) && __LP64__ - // Don't support > 32bit length for 64 bit, see note in header. - if (length > UINT_MAX) { - return nil; - } -#endif - - z_stream strm; - bzero(&strm, sizeof(z_stream)); - - // Setup the input. - strm.avail_in = (unsigned int)length; - strm.next_in = (unsigned char *)bytes; - - int windowBits = 15; // 15 to enable any window size - windowBits += 32; // and +32 to enable zlib or gzip header detection. - - int retCode; - if ((retCode = inflateInit2(&strm, windowBits)) != Z_OK) { - if (error) { - NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode] - forKey:GULNSDataZlibErrorKey]; - *error = [NSError errorWithDomain:GULNSDataZlibErrorDomain - code:GULNSDataZlibErrorInternal - userInfo:userInfo]; - } - return nil; - } - - // Hint the size at 4x the input size. - NSMutableData *result = [NSMutableData dataWithCapacity:(length * 4)]; - unsigned char output[kChunkSize]; - - // Loop to collect the data. - do { - // Update what we're passing in. - strm.avail_out = kChunkSize; - strm.next_out = output; - retCode = inflate(&strm, Z_NO_FLUSH); - if ((retCode != Z_OK) && (retCode != Z_STREAM_END)) { - if (error) { - NSMutableDictionary *userInfo = - [NSMutableDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode] - forKey:GULNSDataZlibErrorKey]; - if (strm.msg) { - NSString *message = [NSString stringWithUTF8String:strm.msg]; - if (message) { - [userInfo setObject:message forKey:NSLocalizedDescriptionKey]; - } - } - *error = [NSError errorWithDomain:GULNSDataZlibErrorDomain - code:GULNSDataZlibErrorInternal - userInfo:userInfo]; - } - inflateEnd(&strm); - return nil; - } - // Collect what we got. - unsigned gotBack = kChunkSize - strm.avail_out; - if (gotBack > 0) { - [result appendBytes:output length:gotBack]; - } - - } while (retCode == Z_OK); - - // Make sure there wasn't more data tacked onto the end of a valid compressed stream. - if (strm.avail_in != 0) { - if (error) { - NSDictionary *userInfo = - [NSDictionary dictionaryWithObject:[NSNumber numberWithUnsignedInt:strm.avail_in] - forKey:GULNSDataZlibRemainingBytesKey]; - *error = [NSError errorWithDomain:GULNSDataZlibErrorDomain - code:GULNSDataZlibErrorDataRemaining - userInfo:userInfo]; - } - result = nil; - } - // The only way out of the loop was by hitting the end of the stream. - NSAssert(retCode == Z_STREAM_END, - @"Thought we finished inflate w/o getting a result of stream end, code %d", retCode); - - // Clean up. - inflateEnd(&strm); - - return result; -} - -+ (NSData *)gul_dataByGzippingData:(NSData *)data error:(NSError **)error { - const void *bytes = [data bytes]; - NSUInteger length = [data length]; - - int level = Z_DEFAULT_COMPRESSION; - if (!bytes || !length) { - return nil; - } - -#if defined(__LP64__) && __LP64__ - // Don't support > 32bit length for 64 bit, see note in header. - if (length > UINT_MAX) { - if (error) { - *error = [NSError errorWithDomain:GULNSDataZlibErrorDomain - code:GULNSDataZlibErrorGreaterThan32BitsToCompress - userInfo:nil]; - } - return nil; - } -#endif - - z_stream strm; - bzero(&strm, sizeof(z_stream)); - - int memLevel = 8; // Default. - int windowBits = 15 + 16; // Enable gzip header instead of zlib header. - - int retCode; - if ((retCode = deflateInit2(&strm, level, Z_DEFLATED, windowBits, memLevel, - Z_DEFAULT_STRATEGY)) != Z_OK) { - if (error) { - NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode] - forKey:GULNSDataZlibErrorKey]; - *error = [NSError errorWithDomain:GULNSDataZlibErrorDomain - code:GULNSDataZlibErrorInternal - userInfo:userInfo]; - } - return nil; - } - - // Hint the size at 1/4 the input size. - NSMutableData *result = [NSMutableData dataWithCapacity:(length / 4)]; - unsigned char output[kChunkSize]; - - // Setup the input. - strm.avail_in = (unsigned int)length; - strm.next_in = (unsigned char *)bytes; - - // Collect the data. - do { - // update what we're passing in - strm.avail_out = kChunkSize; - strm.next_out = output; - retCode = deflate(&strm, Z_FINISH); - if ((retCode != Z_OK) && (retCode != Z_STREAM_END)) { - if (error) { - NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode] - forKey:GULNSDataZlibErrorKey]; - *error = [NSError errorWithDomain:GULNSDataZlibErrorDomain - code:GULNSDataZlibErrorInternal - userInfo:userInfo]; - } - deflateEnd(&strm); - return nil; - } - // Collect what we got. - unsigned gotBack = kChunkSize - strm.avail_out; - if (gotBack > 0) { - [result appendBytes:output length:gotBack]; - } - - } while (retCode == Z_OK); - - // If the loop exits, it used all input and the stream ended. - NSAssert(strm.avail_in == 0, - @"Should have finished deflating without using all input, %u bytes left", strm.avail_in); - NSAssert(retCode == Z_STREAM_END, - @"thought we finished deflate w/o getting a result of stream end, code %d", retCode); - - // Clean up. - deflateEnd(&strm); - - return result; -} - -@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/Network/GULMutableDictionary.m b/Pods/GoogleUtilities/GoogleUtilities/Network/GULMutableDictionary.m @@ -1,97 +0,0 @@ -// Copyright 2017 Google -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#import "Private/GULMutableDictionary.h" - -@implementation GULMutableDictionary { - /// The mutable dictionary. - NSMutableDictionary *_objects; - - /// Serial synchronization queue. All reads should use dispatch_sync, while writes use - /// dispatch_async. - dispatch_queue_t _queue; -} - -- (instancetype)init { - self = [super init]; - - if (self) { - _objects = [[NSMutableDictionary alloc] init]; - _queue = dispatch_queue_create("GULMutableDictionary", DISPATCH_QUEUE_SERIAL); - } - - return self; -} - -- (NSString *)description { - __block NSString *description; - dispatch_sync(_queue, ^{ - description = self->_objects.description; - }); - return description; -} - -- (id)objectForKey:(id)key { - __block id object; - dispatch_sync(_queue, ^{ - object = self->_objects[key]; - }); - return object; -} - -- (void)setObject:(id)object forKey:(id<NSCopying>)key { - dispatch_async(_queue, ^{ - self->_objects[key] = object; - }); -} - -- (void)removeObjectForKey:(id)key { - dispatch_async(_queue, ^{ - [self->_objects removeObjectForKey:key]; - }); -} - -- (void)removeAllObjects { - dispatch_async(_queue, ^{ - [self->_objects removeAllObjects]; - }); -} - -- (NSUInteger)count { - __block NSUInteger count; - dispatch_sync(_queue, ^{ - count = self->_objects.count; - }); - return count; -} - -- (id)objectForKeyedSubscript:(id<NSCopying>)key { - // The method this calls is already synchronized. - return [self objectForKey:key]; -} - -- (void)setObject:(id)obj forKeyedSubscript:(id<NSCopying>)key { - // The method this calls is already synchronized. - [self setObject:obj forKey:key]; -} - -- (NSDictionary *)dictionary { - __block NSDictionary *dictionary; - dispatch_sync(_queue, ^{ - dictionary = [self->_objects copy]; - }); - return dictionary; -} - -@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/Network/GULNetwork.m b/Pods/GoogleUtilities/GoogleUtilities/Network/GULNetwork.m @@ -1,389 +0,0 @@ -// Copyright 2017 Google -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#import "Private/GULNetwork.h" -#import "Private/GULNetworkMessageCode.h" - -#import <GoogleUtilities/GULLogger.h> -#import <GoogleUtilities/GULNSData+zlib.h> -#import <GoogleUtilities/GULReachabilityChecker.h> -#import "Private/GULMutableDictionary.h" -#import "Private/GULNetworkConstants.h" - -/// Constant string for request header Content-Encoding. -static NSString *const kGULNetworkContentCompressionKey = @"Content-Encoding"; - -/// Constant string for request header Content-Encoding value. -static NSString *const kGULNetworkContentCompressionValue = @"gzip"; - -/// Constant string for request header Content-Length. -static NSString *const kGULNetworkContentLengthKey = @"Content-Length"; - -/// Constant string for request header Content-Type. -static NSString *const kGULNetworkContentTypeKey = @"Content-Type"; - -/// Constant string for request header Content-Type value. -static NSString *const kGULNetworkContentTypeValue = @"application/x-www-form-urlencoded"; - -/// Constant string for GET request method. -static NSString *const kGULNetworkGETRequestMethod = @"GET"; - -/// Constant string for POST request method. -static NSString *const kGULNetworkPOSTRequestMethod = @"POST"; - -/// Default constant string as a prefix for network logger. -static NSString *const kGULNetworkLogTag = @"Google/Utilities/Network"; - -@interface GULNetwork () <GULReachabilityDelegate, GULNetworkLoggerDelegate> -@end - -@implementation GULNetwork { - /// Network reachability. - GULReachabilityChecker *_reachability; - - /// The dictionary of requests by session IDs { NSString : id }. - GULMutableDictionary *_requests; -} - -- (instancetype)init { - return [self initWithReachabilityHost:kGULNetworkReachabilityHost]; -} - -- (instancetype)initWithReachabilityHost:(NSString *)reachabilityHost { - self = [super init]; - if (self) { - // Setup reachability. - _reachability = [[GULReachabilityChecker alloc] initWithReachabilityDelegate:self - withHost:reachabilityHost]; - if (![_reachability start]) { - return nil; - } - - _requests = [[GULMutableDictionary alloc] init]; - _timeoutInterval = kGULNetworkTimeOutInterval; - } - return self; -} - -- (void)dealloc { - _reachability.reachabilityDelegate = nil; - [_reachability stop]; -} - -#pragma mark - External Methods - -+ (void)handleEventsForBackgroundURLSessionID:(NSString *)sessionID - completionHandler:(GULNetworkSystemCompletionHandler)completionHandler { - [GULNetworkURLSession handleEventsForBackgroundURLSessionID:sessionID - completionHandler:completionHandler]; -} - -- (NSString *)postURL:(NSURL *)url - payload:(NSData *)payload - queue:(dispatch_queue_t)queue - usingBackgroundSession:(BOOL)usingBackgroundSession - completionHandler:(GULNetworkCompletionHandler)handler { - if (!url.absoluteString.length) { - [self handleErrorWithCode:GULErrorCodeNetworkInvalidURL queue:queue withHandler:handler]; - return nil; - } - - NSTimeInterval timeOutInterval = _timeoutInterval ?: kGULNetworkTimeOutInterval; - - NSMutableURLRequest *request = - [[NSMutableURLRequest alloc] initWithURL:url - cachePolicy:NSURLRequestReloadIgnoringLocalCacheData - timeoutInterval:timeOutInterval]; - - if (!request) { - [self handleErrorWithCode:GULErrorCodeNetworkSessionTaskCreation - queue:queue - withHandler:handler]; - return nil; - } - - NSError *compressError = nil; - NSData *compressedData = [NSData gul_dataByGzippingData:payload error:&compressError]; - if (!compressedData || compressError) { - if (compressError || payload.length > 0) { - // If the payload is not empty but it fails to compress the payload, something has been wrong. - [self handleErrorWithCode:GULErrorCodeNetworkPayloadCompression - queue:queue - withHandler:handler]; - return nil; - } - compressedData = [[NSData alloc] init]; - } - - NSString *postLength = @(compressedData.length).stringValue; - - // Set up the request with the compressed data. - [request setValue:postLength forHTTPHeaderField:kGULNetworkContentLengthKey]; - request.HTTPBody = compressedData; - request.HTTPMethod = kGULNetworkPOSTRequestMethod; - [request setValue:kGULNetworkContentTypeValue forHTTPHeaderField:kGULNetworkContentTypeKey]; - [request setValue:kGULNetworkContentCompressionValue - forHTTPHeaderField:kGULNetworkContentCompressionKey]; - - GULNetworkURLSession *fetcher = [[GULNetworkURLSession alloc] initWithNetworkLoggerDelegate:self]; - fetcher.backgroundNetworkEnabled = usingBackgroundSession; - - __weak GULNetwork *weakSelf = self; - NSString *requestID = [fetcher - sessionIDFromAsyncPOSTRequest:request - completionHandler:^(NSHTTPURLResponse *response, NSData *data, - NSString *sessionID, NSError *error) { - GULNetwork *strongSelf = weakSelf; - if (!strongSelf) { - return; - } - dispatch_queue_t queueToDispatch = queue ? queue : dispatch_get_main_queue(); - dispatch_async(queueToDispatch, ^{ - if (sessionID.length) { - [strongSelf->_requests removeObjectForKey:sessionID]; - } - if (handler) { - handler(response, data, error); - } - }); - }]; - if (!requestID) { - [self handleErrorWithCode:GULErrorCodeNetworkSessionTaskCreation - queue:queue - withHandler:handler]; - return nil; - } - - [self GULNetwork_logWithLevel:kGULNetworkLogLevelDebug - messageCode:kGULNetworkMessageCodeNetwork000 - message:@"Uploading data. Host" - context:url]; - _requests[requestID] = fetcher; - return requestID; -} - -- (NSString *)getURL:(NSURL *)url - headers:(NSDictionary *)headers - queue:(dispatch_queue_t)queue - usingBackgroundSession:(BOOL)usingBackgroundSession - completionHandler:(GULNetworkCompletionHandler)handler { - if (!url.absoluteString.length) { - [self handleErrorWithCode:GULErrorCodeNetworkInvalidURL queue:queue withHandler:handler]; - return nil; - } - - NSTimeInterval timeOutInterval = _timeoutInterval ?: kGULNetworkTimeOutInterval; - NSMutableURLRequest *request = - [[NSMutableURLRequest alloc] initWithURL:url - cachePolicy:NSURLRequestReloadIgnoringLocalCacheData - timeoutInterval:timeOutInterval]; - - if (!request) { - [self handleErrorWithCode:GULErrorCodeNetworkSessionTaskCreation - queue:queue - withHandler:handler]; - return nil; - } - - request.HTTPMethod = kGULNetworkGETRequestMethod; - request.allHTTPHeaderFields = headers; - - GULNetworkURLSession *fetcher = [[GULNetworkURLSession alloc] initWithNetworkLoggerDelegate:self]; - fetcher.backgroundNetworkEnabled = usingBackgroundSession; - - __weak GULNetwork *weakSelf = self; - NSString *requestID = [fetcher - sessionIDFromAsyncGETRequest:request - completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSString *sessionID, - NSError *error) { - GULNetwork *strongSelf = weakSelf; - if (!strongSelf) { - return; - } - dispatch_queue_t queueToDispatch = queue ? queue : dispatch_get_main_queue(); - dispatch_async(queueToDispatch, ^{ - if (sessionID.length) { - [strongSelf->_requests removeObjectForKey:sessionID]; - } - if (handler) { - handler(response, data, error); - } - }); - }]; - - if (!requestID) { - [self handleErrorWithCode:GULErrorCodeNetworkSessionTaskCreation - queue:queue - withHandler:handler]; - return nil; - } - - [self GULNetwork_logWithLevel:kGULNetworkLogLevelDebug - messageCode:kGULNetworkMessageCodeNetwork001 - message:@"Downloading data. Host" - context:url]; - _requests[requestID] = fetcher; - return requestID; -} - -- (BOOL)hasUploadInProgress { - return _requests.count > 0; -} - -#pragma mark - Network Reachability - -/// Tells reachability delegate to call reachabilityDidChangeToStatus: to notify the network -/// reachability has changed. -- (void)reachability:(GULReachabilityChecker *)reachability - statusChanged:(GULReachabilityStatus)status { - _networkConnected = (status == kGULReachabilityViaCellular || status == kGULReachabilityViaWifi); - [_reachabilityDelegate reachabilityDidChange]; -} - -#pragma mark - Network logger delegate - -- (void)setLoggerDelegate:(id<GULNetworkLoggerDelegate>)loggerDelegate { - // Explicitly check whether the delegate responds to the methods because conformsToProtocol does - // not work correctly even though the delegate does respond to the methods. - if (!loggerDelegate || - ![loggerDelegate respondsToSelector:@selector(GULNetwork_logWithLevel: - messageCode:message:contexts:)] || - ![loggerDelegate respondsToSelector:@selector(GULNetwork_logWithLevel: - messageCode:message:context:)] || - ![loggerDelegate respondsToSelector:@selector(GULNetwork_logWithLevel: - messageCode:message:)]) { - GULLogError(kGULLoggerNetwork, NO, - [NSString stringWithFormat:@"I-NET%06ld", (long)kGULNetworkMessageCodeNetwork002], - @"Cannot set the network logger delegate: delegate does not conform to the network " - "logger protocol."); - return; - } - _loggerDelegate = loggerDelegate; -} - -#pragma mark - Private methods - -/// Handles network error and calls completion handler with the error. -- (void)handleErrorWithCode:(NSInteger)code - queue:(dispatch_queue_t)queue - withHandler:(GULNetworkCompletionHandler)handler { - NSDictionary *userInfo = @{kGULNetworkErrorContext : @"Failed to create network request"}; - NSError *error = [[NSError alloc] initWithDomain:kGULNetworkErrorDomain - code:code - userInfo:userInfo]; - [self GULNetwork_logWithLevel:kGULNetworkLogLevelWarning - messageCode:kGULNetworkMessageCodeNetwork002 - message:@"Failed to create network request. Code, error" - contexts:@[ @(code), error ]]; - if (handler) { - dispatch_queue_t queueToDispatch = queue ? queue : dispatch_get_main_queue(); - dispatch_async(queueToDispatch, ^{ - handler(nil, nil, error); - }); - } -} - -#pragma mark - Network logger - -- (void)GULNetwork_logWithLevel:(GULNetworkLogLevel)logLevel - messageCode:(GULNetworkMessageCode)messageCode - message:(NSString *)message - contexts:(NSArray *)contexts { - // Let the delegate log the message if there is a valid logger delegate. Otherwise, just log - // errors/warnings/info messages to the console log. - if (_loggerDelegate) { - [_loggerDelegate GULNetwork_logWithLevel:logLevel - messageCode:messageCode - message:message - contexts:contexts]; - return; - } - if (_isDebugModeEnabled || logLevel == kGULNetworkLogLevelError || - logLevel == kGULNetworkLogLevelWarning || logLevel == kGULNetworkLogLevelInfo) { - NSString *formattedMessage = GULStringWithLogMessage(message, logLevel, contexts); - NSLog(@"%@", formattedMessage); - GULLogBasic((GULLoggerLevel)logLevel, kGULLoggerNetwork, NO, - [NSString stringWithFormat:@"I-NET%06ld", (long)messageCode], formattedMessage, - NULL); - } -} - -- (void)GULNetwork_logWithLevel:(GULNetworkLogLevel)logLevel - messageCode:(GULNetworkMessageCode)messageCode - message:(NSString *)message - context:(id)context { - if (_loggerDelegate) { - [_loggerDelegate GULNetwork_logWithLevel:logLevel - messageCode:messageCode - message:message - context:context]; - return; - } - NSArray *contexts = context ? @[ context ] : @[]; - [self GULNetwork_logWithLevel:logLevel messageCode:messageCode message:message contexts:contexts]; -} - -- (void)GULNetwork_logWithLevel:(GULNetworkLogLevel)logLevel - messageCode:(GULNetworkMessageCode)messageCode - message:(NSString *)message { - if (_loggerDelegate) { - [_loggerDelegate GULNetwork_logWithLevel:logLevel messageCode:messageCode message:message]; - return; - } - [self GULNetwork_logWithLevel:logLevel messageCode:messageCode message:message contexts:@[]]; -} - -/// Returns a string for the given log level (e.g. kGULNetworkLogLevelError -> @"ERROR"). -static NSString *GULLogLevelDescriptionFromLogLevel(GULNetworkLogLevel logLevel) { - static NSDictionary *levelNames = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - levelNames = @{ - @(kGULNetworkLogLevelError) : @"ERROR", - @(kGULNetworkLogLevelWarning) : @"WARNING", - @(kGULNetworkLogLevelInfo) : @"INFO", - @(kGULNetworkLogLevelDebug) : @"DEBUG" - }; - }); - return levelNames[@(logLevel)]; -} - -/// Returns a formatted string to be used for console logging. -static NSString *GULStringWithLogMessage(NSString *message, - GULNetworkLogLevel logLevel, - NSArray *contexts) { - if (!message) { - message = @"(Message was nil)"; - } else if (!message.length) { - message = @"(Message was empty)"; - } - NSMutableString *result = [[NSMutableString alloc] - initWithFormat:@"<%@/%@> %@", kGULNetworkLogTag, GULLogLevelDescriptionFromLogLevel(logLevel), - message]; - - if (!contexts.count) { - return result; - } - - NSMutableArray *formattedContexts = [[NSMutableArray alloc] init]; - for (id item in contexts) { - [formattedContexts addObject:(item != [NSNull null] ? item : @"(nil)")]; - } - - [result appendString:@": "]; - [result appendString:[formattedContexts componentsJoinedByString:@", "]]; - return result; -} - -@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/Network/GULNetworkConstants.m b/Pods/GoogleUtilities/GoogleUtilities/Network/GULNetworkConstants.m @@ -1,40 +0,0 @@ -// Copyright 2017 Google -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#import "Private/GULNetworkConstants.h" - -#import <Foundation/Foundation.h> - -NSString *const kGULNetworkBackgroundSessionConfigIDPrefix = @"com.gul.network.background-upload"; -NSString *const kGULNetworkApplicationSupportSubdirectory = @"GUL/Network"; -NSString *const kGULNetworkTempDirectoryName = @"GULNetworkTemporaryDirectory"; -const NSTimeInterval kGULNetworkTempFolderExpireTime = 60 * 60; // 1 hour -const NSTimeInterval kGULNetworkTimeOutInterval = 60; // 1 minute. -NSString *const kGULNetworkReachabilityHost = @"app-measurement.com"; -NSString *const kGULNetworkErrorContext = @"Context"; - -const int kGULNetworkHTTPStatusOK = 200; -const int kGULNetworkHTTPStatusNoContent = 204; -const int kGULNetworkHTTPStatusCodeMultipleChoices = 300; -const int kGULNetworkHTTPStatusCodeMovedPermanently = 301; -const int kGULNetworkHTTPStatusCodeFound = 302; -const int kGULNetworkHTTPStatusCodeNotModified = 304; -const int kGULNetworkHTTPStatusCodeMovedTemporarily = 307; -const int kGULNetworkHTTPStatusCodeNotFound = 404; -const int kGULNetworkHTTPStatusCodeCannotAcceptTraffic = 429; -const int kGULNetworkHTTPStatusCodeUnavailable = 503; - -NSString *const kGULNetworkErrorDomain = @"com.gul.network.ErrorDomain"; - -GULLoggerService kGULLoggerNetwork = @"[GULNetwork]"; diff --git a/Pods/GoogleUtilities/GoogleUtilities/Network/GULNetworkURLSession.m b/Pods/GoogleUtilities/GoogleUtilities/Network/GULNetworkURLSession.m @@ -1,740 +0,0 @@ -// Copyright 2017 Google -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#import <Foundation/Foundation.h> - -#import "Private/GULNetworkURLSession.h" - -#import <GoogleUtilities/GULLogger.h> -#import "Private/GULMutableDictionary.h" -#import "Private/GULNetworkConstants.h" -#import "Private/GULNetworkMessageCode.h" - -@interface GULNetworkURLSession () <NSURLSessionDelegate, - NSURLSessionTaskDelegate, - NSURLSessionDownloadDelegate> -@end - -@implementation GULNetworkURLSession { - /// The handler to be called when the request completes or error has occurs. - GULNetworkURLSessionCompletionHandler _completionHandler; - - /// Session ID generated randomly with a fixed prefix. - NSString *_sessionID; - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" - /// The session configuration. NSURLSessionConfiguration' is only available on iOS 7.0 or newer. - NSURLSessionConfiguration *_sessionConfig; - - /// The current NSURLSession. - NSURLSession *__weak _Nullable _URLSession; -#pragma clang diagnostic pop - - /// The path to the directory where all temporary files are stored before uploading. - NSURL *_networkDirectoryURL; - - /// The downloaded data from fetching. - NSData *_downloadedData; - - /// The path to the temporary file which stores the uploading data. - NSURL *_uploadingFileURL; - - /// The current request. - NSURLRequest *_request; -} - -#pragma mark - Init - -- (instancetype)initWithNetworkLoggerDelegate:(id<GULNetworkLoggerDelegate>)networkLoggerDelegate { - self = [super init]; - if (self) { - // Create URL to the directory where all temporary files to upload have to be stored. - NSArray *paths = - NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); - NSString *applicationSupportDirectory = paths.firstObject; - NSArray *tempPathComponents = @[ - applicationSupportDirectory, kGULNetworkApplicationSupportSubdirectory, - kGULNetworkTempDirectoryName - ]; - _networkDirectoryURL = [NSURL fileURLWithPathComponents:tempPathComponents]; - _sessionID = [NSString stringWithFormat:@"%@-%@", kGULNetworkBackgroundSessionConfigIDPrefix, - [[NSUUID UUID] UUIDString]]; - _loggerDelegate = networkLoggerDelegate; - } - return self; -} - -#pragma mark - External Methods - -#pragma mark - To be called from AppDelegate - -+ (void)handleEventsForBackgroundURLSessionID:(NSString *)sessionID - completionHandler: - (GULNetworkSystemCompletionHandler)systemCompletionHandler { - // The session may not be Analytics background. Ignore those that do not have the prefix. - if (![sessionID hasPrefix:kGULNetworkBackgroundSessionConfigIDPrefix]) { - return; - } - GULNetworkURLSession *fetcher = [self fetcherWithSessionIdentifier:sessionID]; - if (fetcher != nil) { - [fetcher addSystemCompletionHandler:systemCompletionHandler forSession:sessionID]; - } else { - GULLogError(kGULLoggerNetwork, NO, - [NSString stringWithFormat:@"I-NET%06ld", (long)kGULNetworkMessageCodeNetwork003], - @"Failed to retrieve background session with ID %@ after app is relaunched.", - sessionID); - } -} - -#pragma mark - External Methods - -/// Sends an async POST request using NSURLSession for iOS >= 7.0, and returns an ID of the -/// connection. -- (nullable NSString *)sessionIDFromAsyncPOSTRequest:(NSURLRequest *)request - completionHandler:(GULNetworkURLSessionCompletionHandler)handler - API_AVAILABLE(ios(7.0)) { - // NSURLSessionUploadTask does not work with NSData in the background. - // To avoid this issue, write the data to a temporary file to upload it. - // Make a temporary file with the data subset. - _uploadingFileURL = [self temporaryFilePathWithSessionID:_sessionID]; - NSError *writeError; - NSURLSessionUploadTask *postRequestTask; - NSURLSession *session; - BOOL didWriteFile = NO; - - // Clean up the entire temp folder to avoid temp files that remain in case the previous session - // crashed and did not clean up. - [self maybeRemoveTempFilesAtURL:_networkDirectoryURL - expiringTime:kGULNetworkTempFolderExpireTime]; - - // If there is no background network enabled, no need to write to file. This will allow default - // network session which runs on the foreground. - if (_backgroundNetworkEnabled && [self ensureTemporaryDirectoryExists]) { - didWriteFile = [request.HTTPBody writeToFile:_uploadingFileURL.path - options:NSDataWritingAtomic - error:&writeError]; - - if (writeError) { - [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelError - messageCode:kGULNetworkMessageCodeURLSession000 - message:@"Failed to write request data to file" - context:writeError]; - } - } - - if (didWriteFile) { - // Exclude this file from backing up to iTunes. There are conflicting reports that excluding - // directory from backing up does not exclude files of that directory from backing up. - [self excludeFromBackupForURL:_uploadingFileURL]; - - _sessionConfig = [self backgroundSessionConfigWithSessionID:_sessionID]; - [self populateSessionConfig:_sessionConfig withRequest:request]; - session = [NSURLSession sessionWithConfiguration:_sessionConfig - delegate:self - delegateQueue:[NSOperationQueue mainQueue]]; - postRequestTask = [session uploadTaskWithRequest:request fromFile:_uploadingFileURL]; - } else { - // If we cannot write to file, just send it in the foreground. - _sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; - [self populateSessionConfig:_sessionConfig withRequest:request]; - session = [NSURLSession sessionWithConfiguration:_sessionConfig - delegate:self - delegateQueue:[NSOperationQueue mainQueue]]; - postRequestTask = [session uploadTaskWithRequest:request fromData:request.HTTPBody]; - } - - if (!session || !postRequestTask) { - NSError *error = [[NSError alloc] - initWithDomain:kGULNetworkErrorDomain - code:GULErrorCodeNetworkRequestCreation - userInfo:@{kGULNetworkErrorContext : @"Cannot create network session"}]; - [self callCompletionHandler:handler withResponse:nil data:nil error:error]; - return nil; - } - - _URLSession = session; - - // Save the session into memory. - [[self class] setSessionInFetcherMap:self forSessionID:_sessionID]; - - _request = [request copy]; - - // Store completion handler because background session does not accept handler block but custom - // delegate. - _completionHandler = [handler copy]; - [postRequestTask resume]; - - return _sessionID; -} - -/// Sends an async GET request using NSURLSession for iOS >= 7.0, and returns an ID of the session. -- (nullable NSString *)sessionIDFromAsyncGETRequest:(NSURLRequest *)request - completionHandler:(GULNetworkURLSessionCompletionHandler)handler - API_AVAILABLE(ios(7.0)) { - if (_backgroundNetworkEnabled) { - _sessionConfig = [self backgroundSessionConfigWithSessionID:_sessionID]; - } else { - _sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; - } - - [self populateSessionConfig:_sessionConfig withRequest:request]; - - // Do not cache the GET request. - _sessionConfig.URLCache = nil; - - NSURLSession *session = [NSURLSession sessionWithConfiguration:_sessionConfig - delegate:self - delegateQueue:[NSOperationQueue mainQueue]]; - NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request]; - - if (!session || !downloadTask) { - NSError *error = [[NSError alloc] - initWithDomain:kGULNetworkErrorDomain - code:GULErrorCodeNetworkRequestCreation - userInfo:@{kGULNetworkErrorContext : @"Cannot create network session"}]; - [self callCompletionHandler:handler withResponse:nil data:nil error:error]; - return nil; - } - - _URLSession = session; - - // Save the session into memory. - [[self class] setSessionInFetcherMap:self forSessionID:_sessionID]; - - _request = [request copy]; - - _completionHandler = [handler copy]; - [downloadTask resume]; - - return _sessionID; -} - -#pragma mark - NSURLSessionTaskDelegate - -/// Called by the NSURLSession once the download task is completed. The file is saved in the -/// provided URL so we need to read the data and store into _downloadedData. Once the session is -/// completed, URLSession:task:didCompleteWithError will be called and the completion handler will -/// be called with the downloaded data. -- (void)URLSession:(NSURLSession *)session - downloadTask:(NSURLSessionDownloadTask *)task - didFinishDownloadingToURL:(NSURL *)url API_AVAILABLE(ios(7.0)) { - if (!url.path) { - [_loggerDelegate - GULNetwork_logWithLevel:kGULNetworkLogLevelError - messageCode:kGULNetworkMessageCodeURLSession001 - message:@"Unable to read downloaded data from empty temp path"]; - _downloadedData = nil; - return; - } - - NSError *error; - _downloadedData = [NSData dataWithContentsOfFile:url.path options:0 error:&error]; - - if (error) { - [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelError - messageCode:kGULNetworkMessageCodeURLSession002 - message:@"Cannot read the content of downloaded data" - context:error]; - _downloadedData = nil; - } -} - -#if TARGET_OS_IOS || TARGET_OS_TV -- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session - API_AVAILABLE(ios(7.0)) { - [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelDebug - messageCode:kGULNetworkMessageCodeURLSession003 - message:@"Background session finished" - context:session.configuration.identifier]; - [self callSystemCompletionHandler:session.configuration.identifier]; -} -#endif - -- (void)URLSession:(NSURLSession *)session - task:(NSURLSessionTask *)task - didCompleteWithError:(NSError *)error API_AVAILABLE(ios(7.0)) { - // Avoid any chance of recursive behavior leading to it being used repeatedly. - GULNetworkURLSessionCompletionHandler handler = _completionHandler; - _completionHandler = nil; - - if (task.response) { - // The following assertion should always be true for HTTP requests, see https://goo.gl/gVLxT7. - NSAssert([task.response isKindOfClass:[NSHTTPURLResponse class]], @"URL response must be HTTP"); - - // The server responded so ignore the error created by the system. - error = nil; - } else if (!error) { - error = [[NSError alloc] - initWithDomain:kGULNetworkErrorDomain - code:GULErrorCodeNetworkInvalidResponse - userInfo:@{kGULNetworkErrorContext : @"Network Error: Empty network response"}]; - } - - [self callCompletionHandler:handler - withResponse:(NSHTTPURLResponse *)task.response - data:_downloadedData - error:error]; - - // Remove the temp file to avoid trashing devices with lots of temp files. - [self removeTempItemAtURL:_uploadingFileURL]; - - // Try to clean up stale files again. - [self maybeRemoveTempFilesAtURL:_networkDirectoryURL - expiringTime:kGULNetworkTempFolderExpireTime]; - - // This is called without checking the sessionID here since non-background sessions - // won't have an ID. - [session finishTasksAndInvalidate]; - - // Explicitly remove the session so it won't be reused. The weak map table should - // remove the session on deallocation, but dealloc may not happen immediately after - // calling `finishTasksAndInvalidate`. - NSString *sessionID = session.configuration.identifier; - [[self class] setSessionInFetcherMap:nil forSessionID:sessionID]; -} - -- (void)URLSession:(NSURLSession *)session - task:(NSURLSessionTask *)task - didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge - completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, - NSURLCredential *credential))completionHandler - API_AVAILABLE(ios(7.0)) { - // The handling is modeled after GTMSessionFetcher. - if ([challenge.protectionSpace.authenticationMethod - isEqualToString:NSURLAuthenticationMethodServerTrust]) { - SecTrustRef serverTrust = challenge.protectionSpace.serverTrust; - if (serverTrust == NULL) { - [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelDebug - messageCode:kGULNetworkMessageCodeURLSession004 - message:@"Received empty server trust for host. Host" - context:_request.URL]; - completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); - return; - } - NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust]; - if (!credential) { - [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelWarning - messageCode:kGULNetworkMessageCodeURLSession005 - message:@"Unable to verify server identity. Host" - context:_request.URL]; - completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil); - return; - } - - [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelDebug - messageCode:kGULNetworkMessageCodeURLSession006 - message:@"Received SSL challenge for host. Host" - context:_request.URL]; - - void (^callback)(BOOL) = ^(BOOL allow) { - if (allow) { - completionHandler(NSURLSessionAuthChallengeUseCredential, credential); - } else { - [self->_loggerDelegate - GULNetwork_logWithLevel:kGULNetworkLogLevelDebug - messageCode:kGULNetworkMessageCodeURLSession007 - message:@"Cancelling authentication challenge for host. Host" - context:self->_request.URL]; - completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil); - } - }; - - // Retain the trust object to avoid a SecTrustEvaluate() crash on iOS 7. - CFRetain(serverTrust); - - // Evaluate the certificate chain. - // - // The delegate queue may be the main thread. Trust evaluation could cause some - // blocking network activity, so we must evaluate async, as documented at - // https://developer.apple.com/library/ios/technotes/tn2232/ - dispatch_queue_t evaluateBackgroundQueue = - dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); - - dispatch_async(evaluateBackgroundQueue, ^{ - SecTrustResultType trustEval = kSecTrustResultInvalid; - BOOL shouldAllow; - OSStatus trustError; - - @synchronized([GULNetworkURLSession class]) { - trustError = SecTrustEvaluate(serverTrust, &trustEval); - } - - if (trustError != errSecSuccess) { - [self->_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelError - messageCode:kGULNetworkMessageCodeURLSession008 - message:@"Cannot evaluate server trust. Error, host" - contexts:@[ @(trustError), self->_request.URL ]]; - shouldAllow = NO; - } else { - // Having a trust level "unspecified" by the user is the usual result, described at - // https://developer.apple.com/library/mac/qa/qa1360 - shouldAllow = - (trustEval == kSecTrustResultUnspecified || trustEval == kSecTrustResultProceed); - } - - // Call the call back with the permission. - callback(shouldAllow); - - CFRelease(serverTrust); - }); - return; - } - - // Default handling for other Auth Challenges. - completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); -} - -#pragma mark - Internal Methods - -/// Stores system completion handler with session ID as key. -- (void)addSystemCompletionHandler:(GULNetworkSystemCompletionHandler)handler - forSession:(NSString *)identifier { - if (!handler) { - [_loggerDelegate - GULNetwork_logWithLevel:kGULNetworkLogLevelError - messageCode:kGULNetworkMessageCodeURLSession009 - message:@"Cannot store nil system completion handler in network"]; - return; - } - - if (!identifier.length) { - [_loggerDelegate - GULNetwork_logWithLevel:kGULNetworkLogLevelError - messageCode:kGULNetworkMessageCodeURLSession010 - message:@"Cannot store system completion handler with empty network " - "session identifier"]; - return; - } - - GULMutableDictionary *systemCompletionHandlers = - [[self class] sessionIDToSystemCompletionHandlerDictionary]; - if (systemCompletionHandlers[identifier]) { - [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelWarning - messageCode:kGULNetworkMessageCodeURLSession011 - message:@"Got multiple system handlers for a single session ID" - context:identifier]; - } - - systemCompletionHandlers[identifier] = handler; -} - -/// Calls the system provided completion handler with the session ID stored in the dictionary. -/// The handler will be removed from the dictionary after being called. -- (void)callSystemCompletionHandler:(NSString *)identifier { - GULMutableDictionary *systemCompletionHandlers = - [[self class] sessionIDToSystemCompletionHandlerDictionary]; - GULNetworkSystemCompletionHandler handler = [systemCompletionHandlers objectForKey:identifier]; - - if (handler) { - [systemCompletionHandlers removeObjectForKey:identifier]; - - dispatch_async(dispatch_get_main_queue(), ^{ - handler(); - }); - } -} - -/// Sets or updates the session ID of this session. -- (void)setSessionID:(NSString *)sessionID { - _sessionID = [sessionID copy]; -} - -/// Creates a background session configuration with the session ID using the supported method. -- (NSURLSessionConfiguration *)backgroundSessionConfigWithSessionID:(NSString *)sessionID - API_AVAILABLE(ios(7.0)) { -#if (TARGET_OS_OSX && defined(MAC_OS_X_VERSION_10_10) && \ - MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10) || \ - TARGET_OS_TV || \ - (TARGET_OS_IOS && defined(__IPHONE_8_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0) - - // iOS 8/10.10 builds require the new backgroundSessionConfiguration method name. - return [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:sessionID]; - -#elif (TARGET_OS_OSX && defined(MAC_OS_X_VERSION_10_10) && \ - MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_10) || \ - (TARGET_OS_IOS && defined(__IPHONE_8_0) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0) - - // Do a runtime check to avoid a deprecation warning about using - // +backgroundSessionConfiguration: on iOS 8. - if ([NSURLSessionConfiguration - respondsToSelector:@selector(backgroundSessionConfigurationWithIdentifier:)]) { - // Running on iOS 8+/OS X 10.10+. -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" - return [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:sessionID]; -#pragma clang diagnostic pop - } else { - // Running on iOS 7/OS X 10.9. - return [NSURLSessionConfiguration backgroundSessionConfiguration:sessionID]; - } - -#else - // Building with an SDK earlier than iOS 8/OS X 10.10. - return [NSURLSessionConfiguration backgroundSessionConfiguration:sessionID]; -#endif -} - -- (void)maybeRemoveTempFilesAtURL:(NSURL *)folderURL expiringTime:(NSTimeInterval)staleTime { - if (!folderURL.absoluteString.length) { - return; - } - - NSFileManager *fileManager = [NSFileManager defaultManager]; - NSError *error = nil; - - NSArray *properties = @[ NSURLCreationDateKey ]; - NSArray *directoryContent = - [fileManager contentsOfDirectoryAtURL:folderURL - includingPropertiesForKeys:properties - options:NSDirectoryEnumerationSkipsSubdirectoryDescendants - error:&error]; - if (error && error.code != NSFileReadNoSuchFileError) { - [_loggerDelegate - GULNetwork_logWithLevel:kGULNetworkLogLevelDebug - messageCode:kGULNetworkMessageCodeURLSession012 - message:@"Cannot get files from the temporary network folder. Error" - context:error]; - return; - } - - if (!directoryContent.count) { - return; - } - - NSTimeInterval now = [NSDate date].timeIntervalSince1970; - for (NSURL *tempFile in directoryContent) { - NSDate *creationDate; - BOOL getCreationDate = [tempFile getResourceValue:&creationDate - forKey:NSURLCreationDateKey - error:NULL]; - if (!getCreationDate) { - continue; - } - NSTimeInterval creationTimeInterval = creationDate.timeIntervalSince1970; - if (fabs(now - creationTimeInterval) > staleTime) { - [self removeTempItemAtURL:tempFile]; - } - } -} - -/// Removes the temporary file written to disk for sending the request. It has to be cleaned up -/// after the session is done. -- (void)removeTempItemAtURL:(NSURL *)fileURL { - if (!fileURL.absoluteString.length) { - return; - } - - NSFileManager *fileManager = [NSFileManager defaultManager]; - NSError *error = nil; - - if (![fileManager removeItemAtURL:fileURL error:&error] && error.code != NSFileNoSuchFileError) { - [_loggerDelegate - GULNetwork_logWithLevel:kGULNetworkLogLevelError - messageCode:kGULNetworkMessageCodeURLSession013 - message:@"Failed to remove temporary uploading data file. Error" - context:error.localizedDescription]; - } -} - -/// Gets the fetcher with the session ID. -+ (instancetype)fetcherWithSessionIdentifier:(NSString *)sessionIdentifier { - GULNetworkURLSession *session = [self sessionFromFetcherMapForSessionID:sessionIdentifier]; - if (!session && [sessionIdentifier hasPrefix:kGULNetworkBackgroundSessionConfigIDPrefix]) { - session = [[GULNetworkURLSession alloc] initWithNetworkLoggerDelegate:nil]; - [session setSessionID:sessionIdentifier]; - [self setSessionInFetcherMap:session forSessionID:sessionIdentifier]; - } - return session; -} - -/// Returns a map of the fetcher by session ID. Creates a map if it is not created. -/// When reading and writing from/to the session map, don't use this method directly. -/// To avoid thread safety issues, use one of the helper methods at the bottom of the -/// file: setSessionInFetcherMap:forSessionID:, sessionFromFetcherMapForSessionID: -+ (NSMapTable<NSString *, GULNetworkURLSession *> *)sessionIDToFetcherMap { - static NSMapTable *sessionIDToFetcherMap; - - static dispatch_once_t sessionMapOnceToken; - dispatch_once(&sessionMapOnceToken, ^{ - sessionIDToFetcherMap = [NSMapTable strongToWeakObjectsMapTable]; - }); - return sessionIDToFetcherMap; -} - -+ (NSLock *)sessionIDToFetcherMapReadWriteLock { - static NSLock *lock; - - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - lock = [[NSLock alloc] init]; - }); - return lock; -} - -/// Returns a map of system provided completion handler by session ID. Creates a map if it is not -/// created. -+ (GULMutableDictionary *)sessionIDToSystemCompletionHandlerDictionary { - static GULMutableDictionary *systemCompletionHandlers; - - static dispatch_once_t systemCompletionHandlerOnceToken; - dispatch_once(&systemCompletionHandlerOnceToken, ^{ - systemCompletionHandlers = [[GULMutableDictionary alloc] init]; - }); - return systemCompletionHandlers; -} - -- (NSURL *)temporaryFilePathWithSessionID:(NSString *)sessionID { - NSString *tempName = [NSString stringWithFormat:@"GULUpload_temp_%@", sessionID]; - return [_networkDirectoryURL URLByAppendingPathComponent:tempName]; -} - -/// Makes sure that the directory to store temp files exists. If not, tries to create it and returns -/// YES. If there is anything wrong, returns NO. -- (BOOL)ensureTemporaryDirectoryExists { - NSFileManager *fileManager = [NSFileManager defaultManager]; - NSError *error = nil; - - // Create a temporary directory if it does not exist or was deleted. - if ([_networkDirectoryURL checkResourceIsReachableAndReturnError:&error]) { - return YES; - } - - if (error && error.code != NSFileReadNoSuchFileError) { - [_loggerDelegate - GULNetwork_logWithLevel:kGULNetworkLogLevelWarning - messageCode:kGULNetworkMessageCodeURLSession014 - message:@"Error while trying to access Network temp folder. Error" - context:error]; - } - - NSError *writeError = nil; - - [fileManager createDirectoryAtURL:_networkDirectoryURL - withIntermediateDirectories:YES - attributes:nil - error:&writeError]; - if (writeError) { - [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelError - messageCode:kGULNetworkMessageCodeURLSession015 - message:@"Cannot create temporary directory. Error" - context:writeError]; - return NO; - } - - // Set the iCloud exclusion attribute on the Documents URL. - [self excludeFromBackupForURL:_networkDirectoryURL]; - - return YES; -} - -- (void)excludeFromBackupForURL:(NSURL *)url { - if (!url.path) { - return; - } - - // Set the iCloud exclusion attribute on the Documents URL. - NSError *preventBackupError = nil; - [url setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:&preventBackupError]; - if (preventBackupError) { - [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelError - messageCode:kGULNetworkMessageCodeURLSession016 - message:@"Cannot exclude temporary folder from iTunes backup"]; - } -} - -- (void)URLSession:(NSURLSession *)session - task:(NSURLSessionTask *)task - willPerformHTTPRedirection:(NSHTTPURLResponse *)response - newRequest:(NSURLRequest *)request - completionHandler:(void (^)(NSURLRequest *))completionHandler API_AVAILABLE(ios(7.0)) { - NSArray *nonAllowedRedirectionCodes = @[ - @(kGULNetworkHTTPStatusCodeFound), @(kGULNetworkHTTPStatusCodeMovedPermanently), - @(kGULNetworkHTTPStatusCodeMovedTemporarily), @(kGULNetworkHTTPStatusCodeMultipleChoices) - ]; - - // Allow those not in the non allowed list to be followed. - if (![nonAllowedRedirectionCodes containsObject:@(response.statusCode)]) { - completionHandler(request); - return; - } - - // Do not allow redirection if the response code is in the non-allowed list. - NSURLRequest *newRequest = request; - - if (response) { - newRequest = nil; - } - - completionHandler(newRequest); -} - -#pragma mark - Helper Methods - -+ (void)setSessionInFetcherMap:(GULNetworkURLSession *)session forSessionID:(NSString *)sessionID { - [[self sessionIDToFetcherMapReadWriteLock] lock]; - GULNetworkURLSession *existingSession = - [[[self class] sessionIDToFetcherMap] objectForKey:sessionID]; - if (existingSession) { - if (session) { - NSString *message = [NSString stringWithFormat:@"Discarding session: %@", existingSession]; - [existingSession->_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelInfo - messageCode:kGULNetworkMessageCodeURLSession019 - message:message]; - } - [existingSession->_URLSession finishTasksAndInvalidate]; - } - if (session) { - [[[self class] sessionIDToFetcherMap] setObject:session forKey:sessionID]; - } else { - [[[self class] sessionIDToFetcherMap] removeObjectForKey:sessionID]; - } - [[self sessionIDToFetcherMapReadWriteLock] unlock]; -} - -+ (nullable GULNetworkURLSession *)sessionFromFetcherMapForSessionID:(NSString *)sessionID { - [[self sessionIDToFetcherMapReadWriteLock] lock]; - GULNetworkURLSession *session = [[[self class] sessionIDToFetcherMap] objectForKey:sessionID]; - [[self sessionIDToFetcherMapReadWriteLock] unlock]; - return session; -} - -- (void)callCompletionHandler:(GULNetworkURLSessionCompletionHandler)handler - withResponse:(NSHTTPURLResponse *)response - data:(NSData *)data - error:(NSError *)error { - if (error) { - [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelError - messageCode:kGULNetworkMessageCodeURLSession017 - message:@"Encounter network error. Code, error" - contexts:@[ @(error.code), error ]]; - } - - if (handler) { - dispatch_async(dispatch_get_main_queue(), ^{ - handler(response, data, self->_sessionID, error); - }); - } -} - -// Always use the request parameters even if the default session configuration is more restrictive. -- (void)populateSessionConfig:(NSURLSessionConfiguration *)sessionConfig - withRequest:(NSURLRequest *)request API_AVAILABLE(ios(7.0)) { - sessionConfig.HTTPAdditionalHeaders = request.allHTTPHeaderFields; - sessionConfig.timeoutIntervalForRequest = request.timeoutInterval; - sessionConfig.timeoutIntervalForResource = request.timeoutInterval; - sessionConfig.requestCachePolicy = request.cachePolicy; -} - -@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/Network/Private/GULMutableDictionary.h b/Pods/GoogleUtilities/GoogleUtilities/Network/Private/GULMutableDictionary.h @@ -1,46 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -/// A mutable dictionary that provides atomic accessor and mutators. -@interface GULMutableDictionary : NSObject - -/// Returns an object given a key in the dictionary or nil if not found. -- (id)objectForKey:(id)key; - -/// Updates the object given its key or adds it to the dictionary if it is not in the dictionary. -- (void)setObject:(id)object forKey:(id<NSCopying>)key; - -/// Removes the object given its session ID from the dictionary. -- (void)removeObjectForKey:(id)key; - -/// Removes all objects. -- (void)removeAllObjects; - -/// Returns the number of current objects in the dictionary. -- (NSUInteger)count; - -/// Returns an object given a key in the dictionary or nil if not found. -- (id)objectForKeyedSubscript:(id<NSCopying>)key; - -/// Updates the object given its key or adds it to the dictionary if it is not in the dictionary. -- (void)setObject:(id)obj forKeyedSubscript:(id<NSCopying>)key; - -/// Returns the immutable dictionary. -- (NSDictionary *)dictionary; - -@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/Network/Private/GULNetwork.h b/Pods/GoogleUtilities/GoogleUtilities/Network/Private/GULNetwork.h @@ -1,87 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -#import "GULNetworkConstants.h" -#import "GULNetworkLoggerProtocol.h" -#import "GULNetworkURLSession.h" - -/// Delegate protocol for GULNetwork events. -@protocol GULNetworkReachabilityDelegate - -/// Tells the delegate to handle events when the network reachability changes to connected or not -/// connected. -- (void)reachabilityDidChange; - -@end - -/// The Network component that provides network status and handles network requests and responses. -/// This is not thread safe. -/// -/// NOTE: -/// User must add FIRAnalytics handleEventsForBackgroundURLSessionID:completionHandler to the -/// AppDelegate application:handleEventsForBackgroundURLSession:completionHandler: -@interface GULNetwork : NSObject - -/// Indicates if network connectivity is available. -@property(nonatomic, readonly, getter=isNetworkConnected) BOOL networkConnected; - -/// Indicates if there are any uploads in progress. -@property(nonatomic, readonly, getter=hasUploadInProgress) BOOL uploadInProgress; - -/// An optional delegate that can be used in the event when network reachability changes. -@property(nonatomic, weak) id<GULNetworkReachabilityDelegate> reachabilityDelegate; - -/// An optional delegate that can be used to log messages, warnings or errors that occur in the -/// network operations. -@property(nonatomic, weak) id<GULNetworkLoggerDelegate> loggerDelegate; - -/// Indicates whether the logger should display debug messages. -@property(nonatomic, assign) BOOL isDebugModeEnabled; - -/// The time interval in seconds for the network request to timeout. -@property(nonatomic, assign) NSTimeInterval timeoutInterval; - -/// Initializes with the default reachability host. -- (instancetype)init; - -/// Initializes with a custom reachability host. -- (instancetype)initWithReachabilityHost:(NSString *)reachabilityHost; - -/// Handles events when background session with the given ID has finished. -+ (void)handleEventsForBackgroundURLSessionID:(NSString *)sessionID - completionHandler:(GULNetworkSystemCompletionHandler)completionHandler; - -/// Compresses and sends a POST request with the provided data to the URL. The session will be -/// background session if usingBackgroundSession is YES. Otherwise, the POST session is default -/// session. Returns a session ID or nil if an error occurs. -- (NSString *)postURL:(NSURL *)url - payload:(NSData *)payload - queue:(dispatch_queue_t)queue - usingBackgroundSession:(BOOL)usingBackgroundSession - completionHandler:(GULNetworkCompletionHandler)handler; - -/// Sends a GET request with the provided data to the URL. The session will be background session -/// if usingBackgroundSession is YES. Otherwise, the GET session is default session. Returns a -/// session ID or nil if an error occurs. -- (NSString *)getURL:(NSURL *)url - headers:(NSDictionary *)headers - queue:(dispatch_queue_t)queue - usingBackgroundSession:(BOOL)usingBackgroundSession - completionHandler:(GULNetworkCompletionHandler)handler; - -@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/Network/Private/GULNetworkConstants.h b/Pods/GoogleUtilities/GoogleUtilities/Network/Private/GULNetworkConstants.h @@ -1,79 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> -#import <GoogleUtilities/GULLogger.h> - -/// Error codes in Firebase Network error domain. -/// Note: these error codes should never change. It would make it harder to decode the errors if -/// we inadvertently altered any of these codes in a future SDK version. -typedef NS_ENUM(NSInteger, GULNetworkErrorCode) { - /// Unknown error. - GULNetworkErrorCodeUnknown = 0, - /// Error occurs when the request URL is invalid. - GULErrorCodeNetworkInvalidURL = 1, - /// Error occurs when request cannot be constructed. - GULErrorCodeNetworkRequestCreation = 2, - /// Error occurs when payload cannot be compressed. - GULErrorCodeNetworkPayloadCompression = 3, - /// Error occurs when session task cannot be created. - GULErrorCodeNetworkSessionTaskCreation = 4, - /// Error occurs when there is no response. - GULErrorCodeNetworkInvalidResponse = 5 -}; - -#pragma mark - Network constants - -/// The prefix of the ID of the background session. -extern NSString *const kGULNetworkBackgroundSessionConfigIDPrefix; - -/// The sub directory to store the files of data that is being uploaded in the background. -extern NSString *const kGULNetworkApplicationSupportSubdirectory; - -/// Name of the temporary directory that stores files for background uploading. -extern NSString *const kGULNetworkTempDirectoryName; - -/// The period when the temporary uploading file can stay. -extern const NSTimeInterval kGULNetworkTempFolderExpireTime; - -/// The default network request timeout interval. -extern const NSTimeInterval kGULNetworkTimeOutInterval; - -/// The host to check the reachability of the network. -extern NSString *const kGULNetworkReachabilityHost; - -/// The key to get the error context of the UserInfo. -extern NSString *const kGULNetworkErrorContext; - -#pragma mark - Network Status Code - -extern const int kGULNetworkHTTPStatusOK; -extern const int kGULNetworkHTTPStatusNoContent; -extern const int kGULNetworkHTTPStatusCodeMultipleChoices; -extern const int kGULNetworkHTTPStatusCodeMovedPermanently; -extern const int kGULNetworkHTTPStatusCodeFound; -extern const int kGULNetworkHTTPStatusCodeNotModified; -extern const int kGULNetworkHTTPStatusCodeMovedTemporarily; -extern const int kGULNetworkHTTPStatusCodeNotFound; -extern const int kGULNetworkHTTPStatusCodeCannotAcceptTraffic; -extern const int kGULNetworkHTTPStatusCodeUnavailable; - -#pragma mark - Error Domain - -extern NSString *const kGULNetworkErrorDomain; - -/// The logger service for GULNetwork. -extern GULLoggerService kGULLoggerNetwork; diff --git a/Pods/GoogleUtilities/GoogleUtilities/Network/Private/GULNetworkLoggerProtocol.h b/Pods/GoogleUtilities/GoogleUtilities/Network/Private/GULNetworkLoggerProtocol.h @@ -1,51 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -#import <GoogleUtilities/GULLoggerLevel.h> - -#import "GULNetworkMessageCode.h" - -/// The log levels used by GULNetworkLogger. -typedef NS_ENUM(NSInteger, GULNetworkLogLevel) { - kGULNetworkLogLevelError = GULLoggerLevelError, - kGULNetworkLogLevelWarning = GULLoggerLevelWarning, - kGULNetworkLogLevelInfo = GULLoggerLevelInfo, - kGULNetworkLogLevelDebug = GULLoggerLevelDebug, -}; - -@protocol GULNetworkLoggerDelegate <NSObject> - -@required -/// Tells the delegate to log a message with an array of contexts and the log level. -- (void)GULNetwork_logWithLevel:(GULNetworkLogLevel)logLevel - messageCode:(GULNetworkMessageCode)messageCode - message:(NSString *)message - contexts:(NSArray *)contexts; - -/// Tells the delegate to log a message with a context and the log level. -- (void)GULNetwork_logWithLevel:(GULNetworkLogLevel)logLevel - messageCode:(GULNetworkMessageCode)messageCode - message:(NSString *)message - context:(id)context; - -/// Tells the delegate to log a message with the log level. -- (void)GULNetwork_logWithLevel:(GULNetworkLogLevel)logLevel - messageCode:(GULNetworkMessageCode)messageCode - message:(NSString *)message; - -@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/Network/Private/GULNetworkMessageCode.h b/Pods/GoogleUtilities/GoogleUtilities/Network/Private/GULNetworkMessageCode.h @@ -1,45 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// Make sure these codes do not overlap with any contained in the FIRAMessageCode enum. -typedef NS_ENUM(NSInteger, GULNetworkMessageCode) { - // GULNetwork.m - kGULNetworkMessageCodeNetwork000 = 900000, // I-NET900000 - kGULNetworkMessageCodeNetwork001 = 900001, // I-NET900001 - kGULNetworkMessageCodeNetwork002 = 900002, // I-NET900002 - kGULNetworkMessageCodeNetwork003 = 900003, // I-NET900003 - // GULNetworkURLSession.m - kGULNetworkMessageCodeURLSession000 = 901000, // I-NET901000 - kGULNetworkMessageCodeURLSession001 = 901001, // I-NET901001 - kGULNetworkMessageCodeURLSession002 = 901002, // I-NET901002 - kGULNetworkMessageCodeURLSession003 = 901003, // I-NET901003 - kGULNetworkMessageCodeURLSession004 = 901004, // I-NET901004 - kGULNetworkMessageCodeURLSession005 = 901005, // I-NET901005 - kGULNetworkMessageCodeURLSession006 = 901006, // I-NET901006 - kGULNetworkMessageCodeURLSession007 = 901007, // I-NET901007 - kGULNetworkMessageCodeURLSession008 = 901008, // I-NET901008 - kGULNetworkMessageCodeURLSession009 = 901009, // I-NET901009 - kGULNetworkMessageCodeURLSession010 = 901010, // I-NET901010 - kGULNetworkMessageCodeURLSession011 = 901011, // I-NET901011 - kGULNetworkMessageCodeURLSession012 = 901012, // I-NET901012 - kGULNetworkMessageCodeURLSession013 = 901013, // I-NET901013 - kGULNetworkMessageCodeURLSession014 = 901014, // I-NET901014 - kGULNetworkMessageCodeURLSession015 = 901015, // I-NET901015 - kGULNetworkMessageCodeURLSession016 = 901016, // I-NET901016 - kGULNetworkMessageCodeURLSession017 = 901017, // I-NET901017 - kGULNetworkMessageCodeURLSession018 = 901018, // I-NET901018 - kGULNetworkMessageCodeURLSession019 = 901019, // I-NET901019 -}; diff --git a/Pods/GoogleUtilities/GoogleUtilities/Network/Private/GULNetworkURLSession.h b/Pods/GoogleUtilities/GoogleUtilities/Network/Private/GULNetworkURLSession.h @@ -1,62 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> - -#import "GULNetworkLoggerProtocol.h" - -NS_ASSUME_NONNULL_BEGIN - -typedef void (^GULNetworkCompletionHandler)(NSHTTPURLResponse *_Nullable response, - NSData *_Nullable data, - NSError *_Nullable error); -typedef void (^GULNetworkURLSessionCompletionHandler)(NSHTTPURLResponse *_Nullable response, - NSData *_Nullable data, - NSString *sessionID, - NSError *_Nullable error); -typedef void (^GULNetworkSystemCompletionHandler)(void); - -/// The protocol that uses NSURLSession for iOS >= 7.0 to handle requests and responses. -@interface GULNetworkURLSession : NSObject - -/// Indicates whether the background network is enabled. Default value is NO. -@property(nonatomic, getter=isBackgroundNetworkEnabled) BOOL backgroundNetworkEnabled; - -/// The logger delegate to log message, errors or warnings that occur during the network operations. -@property(nonatomic, weak, nullable) id<GULNetworkLoggerDelegate> loggerDelegate; - -/// Calls the system provided completion handler after the background session is finished. -+ (void)handleEventsForBackgroundURLSessionID:(NSString *)sessionID - completionHandler:(GULNetworkSystemCompletionHandler)completionHandler; - -/// Initializes with logger delegate. -- (instancetype)initWithNetworkLoggerDelegate: - (nullable id<GULNetworkLoggerDelegate>)networkLoggerDelegate NS_DESIGNATED_INITIALIZER; - -- (instancetype)init NS_UNAVAILABLE; - -/// Sends an asynchronous POST request and calls the provided completion handler when the request -/// completes or when errors occur, and returns an ID of the session/connection. -- (nullable NSString *)sessionIDFromAsyncPOSTRequest:(NSURLRequest *)request - completionHandler:(GULNetworkURLSessionCompletionHandler)handler; - -/// Sends an asynchronous GET request and calls the provided completion handler when the request -/// completes or when errors occur, and returns an ID of the session. -- (nullable NSString *)sessionIDFromAsyncGETRequest:(NSURLRequest *)request - completionHandler:(GULNetworkURLSessionCompletionHandler)handler; - -NS_ASSUME_NONNULL_END -@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/Reachability/GULReachabilityChecker+Internal.h b/Pods/GoogleUtilities/GoogleUtilities/Reachability/GULReachabilityChecker+Internal.h @@ -1,47 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <GoogleUtilities/GULReachabilityChecker.h> - -typedef SCNetworkReachabilityRef (*GULReachabilityCreateWithNameFn)(CFAllocatorRef allocator, - const char *host); - -typedef Boolean (*GULReachabilitySetCallbackFn)(SCNetworkReachabilityRef target, - SCNetworkReachabilityCallBack callback, - SCNetworkReachabilityContext *context); -typedef Boolean (*GULReachabilityScheduleWithRunLoopFn)(SCNetworkReachabilityRef target, - CFRunLoopRef runLoop, - CFStringRef runLoopMode); -typedef Boolean (*GULReachabilityUnscheduleFromRunLoopFn)(SCNetworkReachabilityRef target, - CFRunLoopRef runLoop, - CFStringRef runLoopMode); - -typedef void (*GULReachabilityReleaseFn)(CFTypeRef cf); - -struct GULReachabilityApi { - GULReachabilityCreateWithNameFn createWithNameFn; - GULReachabilitySetCallbackFn setCallbackFn; - GULReachabilityScheduleWithRunLoopFn scheduleWithRunLoopFn; - GULReachabilityUnscheduleFromRunLoopFn unscheduleFromRunLoopFn; - GULReachabilityReleaseFn releaseFn; -}; - -@interface GULReachabilityChecker (Internal) - -- (const struct GULReachabilityApi *)reachabilityApi; -- (void)setReachabilityApi:(const struct GULReachabilityApi *)reachabilityApi; - -@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/Reachability/GULReachabilityChecker.m b/Pods/GoogleUtilities/GoogleUtilities/Reachability/GULReachabilityChecker.m @@ -1,240 +0,0 @@ -// Copyright 2017 Google -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#import <Foundation/Foundation.h> - -#import "GULReachabilityChecker+Internal.h" -#import "Private/GULReachabilityChecker.h" -#import "Private/GULReachabilityMessageCode.h" - -#import <GoogleUtilities/GULLogger.h> -#import <GoogleUtilities/GULReachabilityChecker.h> - -static GULLoggerService kGULLoggerReachability = @"[GULReachability]"; - -static void ReachabilityCallback(SCNetworkReachabilityRef reachability, - SCNetworkReachabilityFlags flags, - void *info); - -static const struct GULReachabilityApi kGULDefaultReachabilityApi = { - SCNetworkReachabilityCreateWithName, - SCNetworkReachabilitySetCallback, - SCNetworkReachabilityScheduleWithRunLoop, - SCNetworkReachabilityUnscheduleFromRunLoop, - CFRelease, -}; - -static NSString *const kGULReachabilityUnknownStatus = @"Unknown"; -static NSString *const kGULReachabilityConnectedStatus = @"Connected"; -static NSString *const kGULReachabilityDisconnectedStatus = @"Disconnected"; - -@interface GULReachabilityChecker () - -@property(nonatomic, assign) const struct GULReachabilityApi *reachabilityApi; -@property(nonatomic, assign) GULReachabilityStatus reachabilityStatus; -@property(nonatomic, copy) NSString *host; -@property(nonatomic, assign) SCNetworkReachabilityRef reachability; - -@end - -@implementation GULReachabilityChecker - -@synthesize reachabilityApi = reachabilityApi_; -@synthesize reachability = reachability_; - -- (const struct GULReachabilityApi *)reachabilityApi { - return reachabilityApi_; -} - -- (void)setReachabilityApi:(const struct GULReachabilityApi *)reachabilityApi { - if (reachability_) { - GULLogError(kGULLoggerReachability, NO, - [NSString stringWithFormat:@"I-REA%06ld", (long)kGULReachabilityMessageCode000], - @"Cannot change reachability API while reachability is running. " - @"Call stop first."); - return; - } - reachabilityApi_ = reachabilityApi; -} - -@synthesize reachabilityStatus = reachabilityStatus_; -@synthesize host = host_; -@synthesize reachabilityDelegate = reachabilityDelegate_; - -- (BOOL)isActive { - return reachability_ != nil; -} - -- (void)setReachabilityDelegate:(id<GULReachabilityDelegate>)reachabilityDelegate { - if (reachabilityDelegate && - (![(NSObject *)reachabilityDelegate conformsToProtocol:@protocol(GULReachabilityDelegate)])) { - GULLogError(kGULLoggerReachability, NO, - [NSString stringWithFormat:@"I-NET%06ld", (long)kGULReachabilityMessageCode005], - @"Reachability delegate doesn't conform to Reachability protocol."); - return; - } - reachabilityDelegate_ = reachabilityDelegate; -} - -- (instancetype)initWithReachabilityDelegate:(id<GULReachabilityDelegate>)reachabilityDelegate - withHost:(NSString *)host { - self = [super init]; - - if (!host || !host.length) { - GULLogError(kGULLoggerReachability, NO, - [NSString stringWithFormat:@"I-REA%06ld", (long)kGULReachabilityMessageCode001], - @"Invalid host specified"); - return nil; - } - if (self) { - [self setReachabilityDelegate:reachabilityDelegate]; - reachabilityApi_ = &kGULDefaultReachabilityApi; - reachabilityStatus_ = kGULReachabilityUnknown; - host_ = [host copy]; - reachability_ = nil; - } - return self; -} - -- (void)dealloc { - reachabilityDelegate_ = nil; - [self stop]; -} - -- (BOOL)start { - if (!reachability_) { - reachability_ = reachabilityApi_->createWithNameFn(kCFAllocatorDefault, [host_ UTF8String]); - if (!reachability_) { - return NO; - } - SCNetworkReachabilityContext context = { - 0, /* version */ - (__bridge void *)(self), /* info (passed as last parameter to reachability callback) */ - NULL, /* retain */ - NULL, /* release */ - NULL /* copyDescription */ - }; - if (!reachabilityApi_->setCallbackFn(reachability_, ReachabilityCallback, &context) || - !reachabilityApi_->scheduleWithRunLoopFn(reachability_, CFRunLoopGetMain(), - kCFRunLoopCommonModes)) { - reachabilityApi_->releaseFn(reachability_); - reachability_ = nil; - - GULLogError(kGULLoggerReachability, NO, - [NSString stringWithFormat:@"I-REA%06ld", (long)kGULReachabilityMessageCode002], - @"Failed to start reachability handle"); - return NO; - } - } - GULLogDebug(kGULLoggerReachability, NO, - [NSString stringWithFormat:@"I-REA%06ld", (long)kGULReachabilityMessageCode003], - @"Monitoring the network status"); - return YES; -} - -- (void)stop { - if (reachability_) { - reachabilityStatus_ = kGULReachabilityUnknown; - reachabilityApi_->unscheduleFromRunLoopFn(reachability_, CFRunLoopGetMain(), - kCFRunLoopCommonModes); - reachabilityApi_->releaseFn(reachability_); - reachability_ = nil; - } -} - -- (GULReachabilityStatus)statusForFlags:(SCNetworkReachabilityFlags)flags { - GULReachabilityStatus status = kGULReachabilityNotReachable; - // If the Reachable flag is not set, we definitely don't have connectivity. - if (flags & kSCNetworkReachabilityFlagsReachable) { - // Reachable flag is set. Check further flags. - if (!(flags & kSCNetworkReachabilityFlagsConnectionRequired)) { -// Connection required flag is not set, so we have connectivity. -#if TARGET_OS_IOS || TARGET_OS_TV - status = (flags & kSCNetworkReachabilityFlagsIsWWAN) ? kGULReachabilityViaCellular - : kGULReachabilityViaWifi; -#elif TARGET_OS_OSX - status = kGULReachabilityViaWifi; -#endif - } else if ((flags & (kSCNetworkReachabilityFlagsConnectionOnDemand | - kSCNetworkReachabilityFlagsConnectionOnTraffic)) && - !(flags & kSCNetworkReachabilityFlagsInterventionRequired)) { -// If the connection on demand or connection on traffic flag is set, and user intervention -// is not required, we have connectivity. -#if TARGET_OS_IOS || TARGET_OS_TV - status = (flags & kSCNetworkReachabilityFlagsIsWWAN) ? kGULReachabilityViaCellular - : kGULReachabilityViaWifi; -#elif TARGET_OS_OSX - status = kGULReachabilityViaWifi; -#endif - } - } - return status; -} - -- (void)reachabilityFlagsChanged:(SCNetworkReachabilityFlags)flags { - GULReachabilityStatus status = [self statusForFlags:flags]; - if (reachabilityStatus_ != status) { - NSString *reachabilityStatusString; - if (status == kGULReachabilityUnknown) { - reachabilityStatusString = kGULReachabilityUnknownStatus; - } else { - reachabilityStatusString = (status == kGULReachabilityNotReachable) - ? kGULReachabilityDisconnectedStatus - : kGULReachabilityConnectedStatus; - } - - GULLogDebug(kGULLoggerReachability, NO, - [NSString stringWithFormat:@"I-REA%06ld", (long)kGULReachabilityMessageCode004], - @"Network status has changed. Code:%@, status:%@", @(status), - reachabilityStatusString); - reachabilityStatus_ = status; - [reachabilityDelegate_ reachability:self statusChanged:reachabilityStatus_]; - } -} - -@end - -static void ReachabilityCallback(SCNetworkReachabilityRef reachability, - SCNetworkReachabilityFlags flags, - void *info) { - GULReachabilityChecker *checker = (__bridge GULReachabilityChecker *)info; - [checker reachabilityFlagsChanged:flags]; -} - -// This function used to be at the top of the file, but it was moved here -// as a workaround for a suspected compiler bug. When compiled in Release mode -// and run on an iOS device with WiFi disabled, the reachability code crashed -// when calling SCNetworkReachabilityScheduleWithRunLoop, or shortly thereafter. -// After unsuccessfully trying to diagnose the cause of the crash, it was -// discovered that moving this function to the end of the file magically fixed -// the crash. If you are going to edit this file, exercise caution and make sure -// to test thoroughly with an iOS device under various network conditions. -const NSString *GULReachabilityStatusString(GULReachabilityStatus status) { - switch (status) { - case kGULReachabilityUnknown: - return @"Reachability Unknown"; - - case kGULReachabilityNotReachable: - return @"Not reachable"; - - case kGULReachabilityViaWifi: - return @"Reachable via Wifi"; - - case kGULReachabilityViaCellular: - return @"Reachable via Cellular Data"; - - default: - return [NSString stringWithFormat:@"Invalid reachability status %d", (int)status]; - } -} diff --git a/Pods/GoogleUtilities/GoogleUtilities/Reachability/Private/GULReachabilityChecker.h b/Pods/GoogleUtilities/GoogleUtilities/Reachability/Private/GULReachabilityChecker.h @@ -1,77 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import <Foundation/Foundation.h> -#import <SystemConfiguration/SystemConfiguration.h> - -/// Reachability Status -typedef enum { - kGULReachabilityUnknown, ///< Have not yet checked or been notified whether host is reachable. - kGULReachabilityNotReachable, ///< Host is not reachable. - kGULReachabilityViaWifi, ///< Host is reachable via Wifi. - kGULReachabilityViaCellular, ///< Host is reachable via cellular. -} GULReachabilityStatus; - -const NSString *GULReachabilityStatusString(GULReachabilityStatus status); - -@class GULReachabilityChecker; - -/// Google Analytics iOS Reachability Checker. -@protocol GULReachabilityDelegate -@required -/// Called when network status has changed. -- (void)reachability:(GULReachabilityChecker *)reachability - statusChanged:(GULReachabilityStatus)status; -@end - -/// Google Analytics iOS Network Status Checker. -@interface GULReachabilityChecker : NSObject - -/// The last known reachability status, or GULReachabilityStatusUnknown if the -/// checker is not active. -@property(nonatomic, readonly) GULReachabilityStatus reachabilityStatus; -/// The host to which reachability status is to be checked. -@property(nonatomic, copy, readonly) NSString *host; -/// The delegate to be notified of reachability status changes. -@property(nonatomic, weak) id<GULReachabilityDelegate> reachabilityDelegate; -/// `YES` if the reachability checker is active, `NO` otherwise. -@property(nonatomic, readonly) BOOL isActive; - -/// Initialize the reachability checker. Note that you must call start to begin checking for and -/// receiving notifications about network status changes. -/// -/// @param reachabilityDelegate The delegate to be notified when reachability status to host -/// changes. -/// -/// @param host The name of the host. -/// -- (instancetype)initWithReachabilityDelegate:(id<GULReachabilityDelegate>)reachabilityDelegate - withHost:(NSString *)host; - -- (instancetype)init NS_UNAVAILABLE; - -/// Start checking for reachability to the specified host. This has no effect if the status -/// checker is already checking for connectivity. -/// -/// @return `YES` if initiating status checking was successful or the status checking has already -/// been initiated, `NO` otherwise. -- (BOOL)start; - -/// Stop checking for reachability to the specified host. This has no effect if the status -/// checker is not checking for connectivity. -- (void)stop; - -@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/Reachability/Private/GULReachabilityMessageCode.h b/Pods/GoogleUtilities/GoogleUtilities/Reachability/Private/GULReachabilityMessageCode.h @@ -1,27 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// Make sure these codes do not overlap with any contained in the FIRAMessageCode enum. -typedef NS_ENUM(NSInteger, GULReachabilityMessageCode) { - // GULReachabilityChecker.m - kGULReachabilityMessageCode000 = 902000, // I-NET902000 - kGULReachabilityMessageCode001 = 902001, // I-NET902001 - kGULReachabilityMessageCode002 = 902002, // I-NET902002 - kGULReachabilityMessageCode003 = 902003, // I-NET902003 - kGULReachabilityMessageCode004 = 902004, // I-NET902004 - kGULReachabilityMessageCode005 = 902005, // I-NET902005 - kGULReachabilityMessageCode006 = 902006, // I-NET902006 -}; diff --git a/Pods/GoogleUtilities/GoogleUtilities/UserDefaults/GULUserDefaults.m b/Pods/GoogleUtilities/GoogleUtilities/UserDefaults/GULUserDefaults.m @@ -1,235 +0,0 @@ -// Copyright 2018 Google -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#import "Private/GULUserDefaults.h" - -#import <GoogleUtilities/GULLogger.h> - -NS_ASSUME_NONNULL_BEGIN - -static NSTimeInterval const kGULSynchronizeInterval = 1.0; - -static NSString *const kGULLogFormat = @"I-GUL%06ld"; - -static GULLoggerService kGULLogUserDefaultsService = @"[GoogleUtilities/UserDefaults]"; - -typedef NS_ENUM(NSInteger, GULUDMessageCode) { - GULUDMessageCodeInvalidKeyGet = 1, - GULUDMessageCodeInvalidKeySet = 2, - GULUDMessageCodeInvalidObjectSet = 3, - GULUDMessageCodeSynchronizeFailed = 4, -}; - -@interface GULUserDefaults () - -/// Equivalent to the suite name for NSUserDefaults. -@property(readonly) CFStringRef appNameRef; - -@property(atomic) BOOL isPreferenceFileExcluded; - -@end - -@implementation GULUserDefaults { - // The application name is the same with the suite name of the NSUserDefaults, and it is used for - // preferences. - CFStringRef _appNameRef; -} - -+ (GULUserDefaults *)standardUserDefaults { - static GULUserDefaults *standardUserDefaults; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - standardUserDefaults = [[GULUserDefaults alloc] init]; - }); - return standardUserDefaults; -} - -- (instancetype)init { - return [self initWithSuiteName:nil]; -} - -- (instancetype)initWithSuiteName:(nullable NSString *)suiteName { - self = [super init]; - - NSString *name = [suiteName copy]; - - if (self) { - // `kCFPreferencesCurrentApplication` maps to the same defaults database as - // `[NSUserDefaults standardUserDefaults]`. - _appNameRef = - name.length ? (__bridge_retained CFStringRef)name : kCFPreferencesCurrentApplication; - } - - return self; -} - -- (void)dealloc { - // If we're using a custom `_appNameRef` it needs to be released. If it's a constant, it shouldn't - // need to be released since we don't own it. - if (CFStringCompare(_appNameRef, kCFPreferencesCurrentApplication, 0) != kCFCompareEqualTo) { - CFRelease(_appNameRef); - } - - [NSObject cancelPreviousPerformRequestsWithTarget:self - selector:@selector(synchronize) - object:nil]; -} - -- (nullable id)objectForKey:(NSString *)defaultName { - NSString *key = [defaultName copy]; - if (![key isKindOfClass:[NSString class]] || !key.length) { - GULLogWarning(@"<GoogleUtilities>", NO, - [NSString stringWithFormat:kGULLogFormat, (long)GULUDMessageCodeInvalidKeyGet], - @"Cannot get object for invalid user default key."); - return nil; - } - return (__bridge_transfer id)CFPreferencesCopyAppValue((__bridge CFStringRef)key, _appNameRef); -} - -- (void)setObject:(nullable id)value forKey:(NSString *)defaultName { - NSString *key = [defaultName copy]; - if (![key isKindOfClass:[NSString class]] || !key.length) { - GULLogWarning(kGULLogUserDefaultsService, NO, - [NSString stringWithFormat:kGULLogFormat, (long)GULUDMessageCodeInvalidKeySet], - @"Cannot set object for invalid user default key."); - return; - } - if (!value) { - CFPreferencesSetAppValue((__bridge CFStringRef)key, NULL, _appNameRef); - [self scheduleSynchronize]; - return; - } - BOOL isAcceptableValue = - [value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]] || - [value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSDictionary class]] || - [value isKindOfClass:[NSDate class]] || [value isKindOfClass:[NSData class]]; - if (!isAcceptableValue) { - GULLogWarning(kGULLogUserDefaultsService, NO, - [NSString stringWithFormat:kGULLogFormat, (long)GULUDMessageCodeInvalidObjectSet], - @"Cannot set invalid object to user defaults. Must be a string, number, array, " - @"dictionary, date, or data. Value: %@", - value); - return; - } - - CFPreferencesSetAppValue((__bridge CFStringRef)key, (__bridge CFStringRef)value, _appNameRef); - [self scheduleSynchronize]; -} - -- (void)removeObjectForKey:(NSString *)key { - [self setObject:nil forKey:key]; -} - -#pragma mark - Getters - -- (NSInteger)integerForKey:(NSString *)defaultName { - NSNumber *object = [self objectForKey:defaultName]; - return object.integerValue; -} - -- (float)floatForKey:(NSString *)defaultName { - NSNumber *object = [self objectForKey:defaultName]; - return object.floatValue; -} - -- (double)doubleForKey:(NSString *)defaultName { - NSNumber *object = [self objectForKey:defaultName]; - return object.doubleValue; -} - -- (BOOL)boolForKey:(NSString *)defaultName { - NSNumber *object = [self objectForKey:defaultName]; - return object.boolValue; -} - -- (nullable NSString *)stringForKey:(NSString *)defaultName { - return [self objectForKey:defaultName]; -} - -- (nullable NSArray *)arrayForKey:(NSString *)defaultName { - return [self objectForKey:defaultName]; -} - -- (nullable NSDictionary<NSString *, id> *)dictionaryForKey:(NSString *)defaultName { - return [self objectForKey:defaultName]; -} - -#pragma mark - Setters - -- (void)setInteger:(NSInteger)integer forKey:(NSString *)defaultName { - [self setObject:@(integer) forKey:defaultName]; -} - -- (void)setFloat:(float)value forKey:(NSString *)defaultName { - [self setObject:@(value) forKey:defaultName]; -} - -- (void)setDouble:(double)doubleNumber forKey:(NSString *)defaultName { - [self setObject:@(doubleNumber) forKey:defaultName]; -} - -- (void)setBool:(BOOL)boolValue forKey:(NSString *)defaultName { - [self setObject:@(boolValue) forKey:defaultName]; -} - -#pragma mark - Save data - -- (void)synchronize { - if (!CFPreferencesAppSynchronize(_appNameRef)) { - GULLogError(kGULLogUserDefaultsService, NO, - [NSString stringWithFormat:kGULLogFormat, (long)GULUDMessageCodeSynchronizeFailed], - @"Cannot synchronize user defaults to disk"); - } -} - -#pragma mark - Private methods - -/// Removes all values from the search list entry specified by 'domainName', the current user, and -/// any host. The change is persistent. Equivalent to -removePersistentDomainForName: of -/// NSUserDefaults. -- (void)clearAllData { - // On macOS, using `kCFPreferencesCurrentHost` will not set all the keys necessary to match - // `NSUserDefaults`. -#if TARGET_OS_OSX - CFStringRef host = kCFPreferencesAnyHost; -#else - CFStringRef host = kCFPreferencesCurrentHost; -#endif // TARGET_OS_OSX - - CFArrayRef keyList = CFPreferencesCopyKeyList(_appNameRef, kCFPreferencesCurrentUser, host); - if (!keyList) { - return; - } - - CFPreferencesSetMultiple(NULL, keyList, _appNameRef, kCFPreferencesCurrentUser, host); - CFRelease(keyList); - [self scheduleSynchronize]; -} - -- (void)scheduleSynchronize { - // Synchronize data using a timer so that multiple set... calls can be coalesced under one - // synchronize. - [NSObject cancelPreviousPerformRequestsWithTarget:self - selector:@selector(synchronize) - object:nil]; - // This method may be called on multiple queues (due to set... methods can be called on any queue) - // synchronize can be scheduled on different queues, so make sure that it does not crash. If this - // instance goes away, self will be released also, no one will retain it and the schedule won't be - // called. - [self performSelector:@selector(synchronize) withObject:nil afterDelay:kGULSynchronizeInterval]; -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleUtilities/GoogleUtilities/UserDefaults/Private/GULUserDefaults.h b/Pods/GoogleUtilities/GoogleUtilities/UserDefaults/Private/GULUserDefaults.h @@ -1,110 +0,0 @@ -// Copyright 2018 Google -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#import <Foundation/Foundation.h> - -NS_ASSUME_NONNULL_BEGIN - -/// A thread-safe user defaults that uses C functions from CFPreferences.h instead of -/// `NSUserDefaults`. This is to avoid sending an `NSNotification` when it's changed from a -/// background thread to avoid crashing. // TODO: Insert radar number here. -@interface GULUserDefaults : NSObject - -/// A shared user defaults similar to +[NSUserDefaults standardUserDefaults] and accesses the same -/// data of the standardUserDefaults. -+ (GULUserDefaults *)standardUserDefaults; - -/// Initializes preferences with a suite name that is the same with the NSUserDefaults' suite name. -/// Both of CFPreferences and NSUserDefaults share the same plist file so their data will exactly -/// the same. -/// -/// @param suiteName The name of the suite of the user defaults. -- (instancetype)initWithSuiteName:(nullable NSString *)suiteName; - -#pragma mark - Getters - -/// Searches the receiver's search list for a default with the key 'defaultName' and return it. If -/// another process has changed defaults in the search list, NSUserDefaults will automatically -/// update to the latest values. If the key in question has been marked as ubiquitous via a Defaults -/// Configuration File, the latest value may not be immediately available, and the registered value -/// will be returned instead. -- (nullable id)objectForKey:(NSString *)defaultName; - -/// Equivalent to -objectForKey:, except that it will return nil if the value is not an NSArray. -- (nullable NSArray *)arrayForKey:(NSString *)defaultName; - -/// Equivalent to -objectForKey:, except that it will return nil if the value -/// is not an NSDictionary. -- (nullable NSDictionary<NSString *, id> *)dictionaryForKey:(NSString *)defaultName; - -/// Equivalent to -objectForKey:, except that it will convert NSNumber values to their NSString -/// representation. If a non-string non-number value is found, nil will be returned. -- (nullable NSString *)stringForKey:(NSString *)defaultName; - -/// Equivalent to -objectForKey:, except that it converts the returned value to an NSInteger. If the -/// value is an NSNumber, the result of -integerValue will be returned. If the value is an NSString, -/// it will be converted to NSInteger if possible. If the value is a boolean, it will be converted -/// to either 1 for YES or 0 for NO. If the value is absent or can't be converted to an integer, 0 -/// will be returned. -- (NSInteger)integerForKey:(NSString *)defaultName; - -/// Similar to -integerForKey:, except that it returns a float, and boolean values will not be -/// converted. -- (float)floatForKey:(NSString *)defaultName; - -/// Similar to -integerForKey:, except that it returns a double, and boolean values will not be -/// converted. -- (double)doubleForKey:(NSString *)defaultName; - -/// Equivalent to -objectForKey:, except that it converts the returned value to a BOOL. If the value -/// is an NSNumber, NO will be returned if the value is 0, YES otherwise. If the value is an -/// NSString, values of "YES" or "1" will return YES, and values of "NO", "0", or any other string -/// will return NO. If the value is absent or can't be converted to a BOOL, NO will be returned. -- (BOOL)boolForKey:(NSString *)defaultName; - -#pragma mark - Setters - -/// Immediately stores a value (or removes the value if `nil` is passed as the value) for the -/// provided key in the search list entry for the receiver's suite name in the current user and any -/// host, then asynchronously stores the value persistently, where it is made available to other -/// processes. -- (void)setObject:(nullable id)value forKey:(NSString *)defaultName; - -/// Equivalent to -setObject:forKey: except that the value is converted from a float to an NSNumber. -- (void)setFloat:(float)value forKey:(NSString *)defaultName; - -/// Equivalent to -setObject:forKey: except that the value is converted from a double to an -/// NSNumber. -- (void)setDouble:(double)value forKey:(NSString *)defaultName; - -/// Equivalent to -setObject:forKey: except that the value is converted from an NSInteger to an -/// NSNumber. -- (void)setInteger:(NSInteger)value forKey:(NSString *)defaultName; - -/// Equivalent to -setObject:forKey: except that the value is converted from a BOOL to an NSNumber. -- (void)setBool:(BOOL)value forKey:(NSString *)defaultName; - -#pragma mark - Removing Defaults - -/// Equivalent to -[... setObject:nil forKey:defaultName] -- (void)removeObjectForKey:(NSString *)defaultName; - -#pragma mark - Save data - -/// Blocks the calling thread until all in-progress set operations have completed. -- (void)synchronize; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleUtilities/LICENSE b/Pods/GoogleUtilities/LICENSE @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Pods/GoogleUtilities/README.md b/Pods/GoogleUtilities/README.md @@ -1,193 +0,0 @@ -# Firebase iOS Open Source Development [![Build Status](https://travis-ci.org/firebase/firebase-ios-sdk.svg?branch=master)](https://travis-ci.org/firebase/firebase-ios-sdk) - -This repository contains a subset of the Firebase iOS SDK source. It currently -includes FirebaseCore, FirebaseAuth, FirebaseDatabase, FirebaseFirestore, -FirebaseFunctions, FirebaseInAppMessagingDisplay, FirebaseMessaging and -FirebaseStorage. - -The repository also includes GoogleUtilities source. The -[GoogleUtilities](GoogleUtilities/README.md) pod is -a set of utilities used by Firebase and other Google products. - -Firebase is an app development platform with tools to help you build, grow and -monetize your app. More information about Firebase can be found at -[https://firebase.google.com](https://firebase.google.com). - -## Installation - -See the three subsections for details about three different installation methods. -1. [Standard pod install](README.md#standard-pod-install) -1. [Installing from the GitHub repo](README.md#installing-from-github) -1. [Experimental Carthage](README.md#carthage-ios-only) - -### Standard pod install - -Go to -[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup). - -### Installing from GitHub - -For releases starting with 5.0.0, the source for each release is also deployed -to CocoaPods master and available via standard -[CocoaPods Podfile syntax](https://guides.cocoapods.org/syntax/podfile.html#pod). - -These instructions can be used to access the Firebase repo at other branches, -tags, or commits. - -#### Background - -See -[the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod) -for instructions and options about overriding pod source locations. - -#### Accessing Firebase Source Snapshots - -All of the official releases are tagged in this repo and available via CocoaPods. To access a local -source snapshot or unreleased branch, use Podfile directives like the following: - -To access FirebaseFirestore via a branch: -``` -pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' -pod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' -``` - -To access FirebaseMessaging via a checked out version of the firebase-ios-sdk repo do: - -``` -pod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk' -pod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk' -``` - -### Carthage (iOS only) - -Instructions for the experimental Carthage distribution are at -[Carthage](Carthage.md). - -### Rome - -Instructions for installing binary frameworks via -[Rome](https://github.com/CocoaPods/Rome) are at [Rome](Rome.md). - -## Development - -Follow the subsequent instructions to develop, debug, unit test, run integration -tests, and try out reference samples: - -``` -$ git clone git@github.com:firebase/firebase-ios-sdk.git -$ cd firebase-ios-sdk/Example -$ pod update -$ open Firebase.xcworkspace -``` - -Firestore and Functions have self contained Xcode projects. See -[Firestore/README.md](Firestore/README.md) and -[Functions/README.md](Functions/README.md). - -### Code Formatting - -Travis will verify that any code changes are done in a style compliant way. Install -`clang-format` and `swiftformat`. -This command will get the right `clang-format` version: - -`brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/773cb75d360b58f32048f5964038d09825a507c8/Formula/clang-format.rb` - -### Running Unit Tests - -Select a scheme and press Command-u to build a component and run its unit tests. - -### Running Sample Apps -In order to run the sample apps and integration tests, you'll need valid -`GoogleService-Info.plist` files for those samples. The Firebase Xcode project contains dummy plist -files without real values, but can be replaced with real plist files. To get your own -`GoogleService-Info.plist` files: - -1. Go to the [Firebase Console](https://console.firebase.google.com/) -2. Create a new Firebase project, if you don't already have one -3. For each sample app you want to test, create a new Firebase app with the sample app's bundle -identifier (e.g. `com.google.Database-Example`) -4. Download the resulting `GoogleService-Info.plist` and replace the appropriate dummy plist file -(e.g. in [Example/Database/App/](Example/Database/App/)); - -Some sample apps like Firebase Messaging ([Example/Messaging/App](Example/Messaging/App)) require -special Apple capabilities, and you will have to change the sample app to use a unique bundle -identifier that you can control in your own Apple Developer account. - -## Specific Component Instructions -See the sections below for any special instructions for those components. - -### Firebase Auth - -If you're doing specific Firebase Auth development, see -[the Auth Sample README](Example/Auth/README.md) for instructions about -building and running the FirebaseAuth pod along with various samples and tests. - -### Firebase Database - -To run the Database Integration tests, make your database authentication rules -[public](https://firebase.google.com/docs/database/security/quickstart). - -### Firebase Storage - -To run the Storage Integration tests, follow the instructions in -[FIRStorageIntegrationTests.m](Example/Storage/Tests/Integration/FIRStorageIntegrationTests.m). - -#### Push Notifications - -Push notifications can only be delivered to specially provisioned App IDs in the developer portal. -In order to actually test receiving push notifications, you will need to: - -1. Change the bundle identifier of the sample app to something you own in your Apple Developer -account, and enable that App ID for push notifications. -2. You'll also need to -[upload your APNs Provider Authentication Key or certificate to the Firebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs) -at **Project Settings > Cloud Messaging > [Your Firebase App]**. -3. Ensure your iOS device is added to your Apple Developer portal as a test device. - -#### iOS Simulator - -The iOS Simulator cannot register for remote notifications, and will not receive push notifications. -In order to receive push notifications, you'll have to follow the steps above and run the app on a -physical device. - -## Community Supported Efforts - -We've seen an amazing amount of interest and contributions to improve the Firebase SDKs, and we are -very grateful! We'd like to empower as many developers as we can to be able to use Firebase and -participate in the Firebase community. - -### macOS and tvOS -FirebaseAuth, FirebaseCore, FirebaseDatabase and FirebaseStorage now compile, run unit tests, and -work on macOS and tvOS, thanks to contributions from the community. There are a few tweaks needed, -like ensuring iOS-only, macOS-only, or tvOS-only code is correctly guarded with checks for -`TARGET_OS_IOS`, `TARGET_OS_OSX` and `TARGET_OS_TV`. - -For tvOS, checkout the [Sample](Example/tvOSSample). - -Keep in mind that macOS and tvOS are not officially supported by Firebase, and this repository is -actively developed primarily for iOS. While we can catch basic unit test issues with Travis, there -may be some changes where the SDK no longer works as expected on macOS or tvOS. If you encounter -this, please [file an issue](https://github.com/firebase/firebase-ios-sdk/issues). - -For installation instructions, see [above](README.md#accessing-firebase-source-snapshots). - -Note that the Firebase pod is not available for macOS and tvOS. Install a selection of the -`FirebaseAuth`, `FirebaseCore`, `FirebaseDatabase` and `FirebaseStorage` CocoaPods. - -## Roadmap - -See [Roadmap](ROADMAP.md) for more about the Firebase iOS SDK Open Source -plans and directions. - -## Contributing - -See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase -iOS SDK. - -## License - -The contents of this repository is licensed under the -[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). - -Your use of Firebase is governed by the -[Terms of Service for Firebase Services](https://firebase.google.com/terms/). diff --git a/Pods/Headers/Private/Firebase/Firebase.h b/Pods/Headers/Private/Firebase/Firebase.h @@ -1 +0,0 @@ -../../../Firebase/CoreOnly/Sources/Firebase.h -\ No newline at end of file diff --git a/Pods/Headers/Public/Firebase/Firebase.h b/Pods/Headers/Public/Firebase/Firebase.h @@ -1 +0,0 @@ -../../../Firebase/CoreOnly/Sources/Firebase.h -\ No newline at end of file diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock @@ -1,91 +1,3 @@ -PODS: - - Firebase/Core (5.18.0): - - Firebase/CoreOnly - - FirebaseAnalytics (= 5.7.0) - - Firebase/CoreOnly (5.18.0): - - FirebaseCore (= 5.3.1) - - FirebaseAnalytics (5.7.0): - - FirebaseCore (~> 5.3) - - FirebaseInstanceID (~> 3.6) - - GoogleAppMeasurement (= 5.7.0) - - GoogleUtilities/AppDelegateSwizzler (~> 5.2) - - GoogleUtilities/MethodSwizzler (~> 5.2) - - GoogleUtilities/Network (~> 5.2) - - "GoogleUtilities/NSData+zlib (~> 5.2)" - - nanopb (~> 0.3) - - FirebaseCore (5.3.1): - - GoogleUtilities/Logger (~> 5.2) - - FirebaseInstanceID (3.7.0): - - FirebaseCore (~> 5.2) - - GoogleUtilities/Environment (~> 5.2) - - GoogleUtilities/UserDefaults (~> 5.2) - - GoogleAPIClientForREST/Core (1.3.8): - - GTMSessionFetcher (>= 1.1.7) - - GoogleAPIClientForREST/Sheets (1.3.8): - - GoogleAPIClientForREST/Core - - GTMSessionFetcher (>= 1.1.7) - - GoogleAppMeasurement (5.7.0): - - GoogleUtilities/AppDelegateSwizzler (~> 5.2) - - GoogleUtilities/MethodSwizzler (~> 5.2) - - GoogleUtilities/Network (~> 5.2) - - "GoogleUtilities/NSData+zlib (~> 5.2)" - - nanopb (~> 0.3) - - GoogleUtilities/AppDelegateSwizzler (5.3.7): - - GoogleUtilities/Environment - - GoogleUtilities/Logger - - GoogleUtilities/Network - - GoogleUtilities/Environment (5.3.7) - - GoogleUtilities/Logger (5.3.7): - - GoogleUtilities/Environment - - GoogleUtilities/MethodSwizzler (5.3.7): - - GoogleUtilities/Logger - - GoogleUtilities/Network (5.3.7): - - GoogleUtilities/Logger - - "GoogleUtilities/NSData+zlib" - - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (5.3.7)" - - GoogleUtilities/Reachability (5.3.7): - - GoogleUtilities/Logger - - GoogleUtilities/UserDefaults (5.3.7): - - GoogleUtilities/Logger - - GTMSessionFetcher (1.2.1): - - GTMSessionFetcher/Full (= 1.2.1) - - GTMSessionFetcher/Core (1.2.1) - - GTMSessionFetcher/Full (1.2.1): - - GTMSessionFetcher/Core (= 1.2.1) - - nanopb (0.3.901): - - nanopb/decode (= 0.3.901) - - nanopb/encode (= 0.3.901) - - nanopb/decode (0.3.901) - - nanopb/encode (0.3.901) - -DEPENDENCIES: - - Firebase/Core - - GoogleAPIClientForREST/Sheets - -SPEC REPOS: - https://github.com/cocoapods/specs.git: - - Firebase - - FirebaseAnalytics - - FirebaseCore - - FirebaseInstanceID - - GoogleAPIClientForREST - - GoogleAppMeasurement - - GoogleUtilities - - GTMSessionFetcher - - nanopb - -SPEC CHECKSUMS: - Firebase: 02f3281965c075426141a0ce1277e9de6649cab9 - FirebaseAnalytics: 23851fe602c872130a2c5c55040b302120346cc2 - FirebaseCore: 52f851b30e11360f1e67cf04b1edfebf0a47a2d3 - FirebaseInstanceID: bd6fc5a258884e206fd5c474ebe4f5b00e21770e - GoogleAPIClientForREST: 5447a194eae517986cafe6421a5330b80b820591 - GoogleAppMeasurement: 6cf307834da065863f9faf4c0de0a936d81dd832 - GoogleUtilities: 111a012f4c3a29c9e7c954c082fafd6ee3c999c0 - GTMSessionFetcher: 32aeca0aa144acea523e1c8e053089dec2cb98ca - nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 - -PODFILE CHECKSUM: 4852c02225a8d343844dd5ce2a4039dcb525ad3c +PODFILE CHECKSUM: 63ac3d21ea92db5b9ad2b6028ed0e73c7741657d COCOAPODS: 1.6.1 diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj @@ -6,709 +6,49 @@ objectVersion = 48; objects = { -/* Begin PBXAggregateTarget section */ - 232D00D8ED7797390FB38004DE01723B /* FirebaseAnalytics */ = { - isa = PBXAggregateTarget; - buildConfigurationList = F7B9206E26DEB0994836EBA1FC0E2DE6 /* Build configuration list for PBXAggregateTarget "FirebaseAnalytics" */; - buildPhases = ( - ); - dependencies = ( - CA20CC0CC8595F02B384BCF03BBE9452 /* PBXTargetDependency */, - 9C390500C3C568F59A8589C455BFF4D5 /* PBXTargetDependency */, - AA9052A974DA4ECF27CC38A7633849E0 /* PBXTargetDependency */, - 7AEF416F1165E14B97A1CD16C71D4F0C /* PBXTargetDependency */, - A545116FEA98CB2DC602ECFE976A5146 /* PBXTargetDependency */, - ); - name = FirebaseAnalytics; - }; - 57B9E0A892EAB5C13D4AE7D4B1DE0C16 /* GoogleAppMeasurement */ = { - isa = PBXAggregateTarget; - buildConfigurationList = D714EFAF91AF42119B673C282ADF2B13 /* Build configuration list for PBXAggregateTarget "GoogleAppMeasurement" */; - buildPhases = ( - ); - dependencies = ( - 03C5D1361123B1B19A913F4F89661FDB /* PBXTargetDependency */, - 3BDD26DF1C76A2717767412BFEFD633E /* PBXTargetDependency */, - ); - name = GoogleAppMeasurement; - }; - 799B29F9D6DCE28B98CC259440382F20 /* Firebase */ = { - isa = PBXAggregateTarget; - buildConfigurationList = D5F445878D2BF274AA19BE3720E017FD /* Build configuration list for PBXAggregateTarget "Firebase" */; - buildPhases = ( - ); - dependencies = ( - 7AEC0D15EF11C1415A94D769184AD812 /* PBXTargetDependency */, - CB67FB062DE8CAF07E20E144CB621739 /* PBXTargetDependency */, - ); - name = Firebase; - }; -/* End PBXAggregateTarget section */ - /* Begin PBXBuildFile section */ - 0059C3A34002842E58E7A96B79ECD15C /* FIRInstanceIDCheckinPreferences.h in Headers */ = {isa = PBXBuildFile; fileRef = 17CCF5036BBF759B3851A291325A58DD /* FIRInstanceIDCheckinPreferences.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 01D879EED839FAE13BE060638310A23E /* FIRComponentContainerInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 72A68E1354B8F68044AB4DD21E274D55 /* FIRComponentContainerInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 02262A3E212C0EB9ACBC055C1FB08E3D /* FIRInstanceIDTokenFetchOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 6980A1AC965054D472E7A754E0433A29 /* FIRInstanceIDTokenFetchOperation.m */; }; - 033BDE177CE4158DBD1D93B86E0DA68C /* FirebaseInstanceID-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 87191E9BA56B22A703AD591A7963F5E3 /* FirebaseInstanceID-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 0467A4AB857C1EA04F142878E6B5F7D7 /* FIRInstanceIDConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 347A040A0C9EF78AE6E2CC3305BA6394 /* FIRInstanceIDConstants.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 05927EA99CFB71B69E8B3851D143526B /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D669732E0BA0105016B0BFAF2C9EEE1 /* Security.framework */; }; - 05F0BE6D01F6317AB56399068AA03408 /* GULNetworkURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 6924954BD2F30993FB8230C4F0B6A5F5 /* GULNetworkURLSession.m */; }; - 06716C4D82C54A67EE2FC8558AC001D3 /* FIRInstanceIDCheckinStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BBF3A739B0E8360360E868AA65D007D /* FIRInstanceIDCheckinStore.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 06DE8D644B4500C4F25871F5817E9B30 /* GULUserDefaults.h in Headers */ = {isa = PBXBuildFile; fileRef = F5CF16EA7D24BA0445B470F3104A38C2 /* GULUserDefaults.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 09BA2B85B4D3A18F7D1E57BB80828BD9 /* GULNetworkConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 74F65B52CC04DEB89684D01BB66C6E41 /* GULNetworkConstants.m */; }; - 09E4B4EBE4FBA72C30564F3E3DA2081F /* GTLRFramework.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F12DC4DF7E7F8A371738879B374FFF5 /* GTLRFramework.m */; }; - 0A84CCA22F1C8173E6B37F2069950093 /* Pods-TeachersAssistantTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 176E21E234D1EF72C0869C40836ECBCC /* Pods-TeachersAssistantTests-dummy.m */; }; - 0AA1516C53AF76061CBAB2646F3AFFE8 /* pb.h in Headers */ = {isa = PBXBuildFile; fileRef = 26B79195C4C8B553F57B3D3535D34328 /* pb.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 0BE43A5E3B4F77F37B8343CAFB34785F /* FIRInstanceIDKeyPairUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 500B9CE6A2B5ECC69A261EE855D14BDC /* FIRInstanceIDKeyPairUtilities.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 0DC5A104F5C14D11C8CA9F2EBEB41725 /* GTLRUploadParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = B5047997309AE128643CDACF85D5C260 /* GTLRUploadParameters.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 102658B33FEC7C008C1C8229F40351F9 /* GTMSessionFetcherService.h in Headers */ = {isa = PBXBuildFile; fileRef = CF8C86C20862941343D914D49B5DE74C /* GTMSessionFetcherService.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 11FC0A073774C034685F68FC4DBFAD71 /* FIRInstanceIDTokenStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 85599DEC750671534D9582042B8D286B /* FIRInstanceIDTokenStore.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 131C584CC42207AE38C9B02CCA93BC20 /* FIRLibrary.h in Headers */ = {isa = PBXBuildFile; fileRef = 374883FE51263B2BD861B86677BF5ECA /* FIRLibrary.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 161DA7FD58D2B4BD6788ED1A1EC4D4D9 /* GoogleUtilities-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = BF158F186A2E83AA478BC8C6ECB96907 /* GoogleUtilities-dummy.m */; }; - 167EC0D6E6CA8F0A13B6CB28FCDFB2D3 /* FIRLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 6DE4621B5BF4A7F747C7A66937E79855 /* FIRLogger.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 1752930EA1F0BD6E9408C8298F178491 /* GTMMIMEDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = 4370B2DFACB00E7DEC0868A68AA87DBD /* GTMMIMEDocument.m */; }; - 17C8EF1758E18D4BC2CDC094579C17AC /* FIRConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 07C940E5390B103F4CE2892BFFBC987A /* FIRConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1B76EA90F9022A327F46E8E13D367B81 /* GULNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = A2672AB4665EB890F1F2E052DC068B0D /* GULNetwork.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 1C13102930FBAE48D3508BE1166A7254 /* FIRVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = 357B0ECED3D296D4A9739C22E28FF76D /* FIRVersion.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 1DBEB4345285DDD0576C9205C1607F45 /* FIRComponentType.h in Headers */ = {isa = PBXBuildFile; fileRef = 26B7B16A2741E588921CA76370A6E0C6 /* FIRComponentType.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 2057D78059437EADF8E509FB3A4E3463 /* FIRLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 745F466B0E0CFD0057D71D440A6D7D4D /* FIRLogger.m */; }; - 20A087E51101B8CB92AD91F7248A5AF3 /* pb_decode.h in Headers */ = {isa = PBXBuildFile; fileRef = 734E5DCCCE857FFA34745EB5C2D6C5EA /* pb_decode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 20A5A8E9A67B9FF611833437B7C5EA4B /* FIRAppAssociationRegistration.h in Headers */ = {isa = PBXBuildFile; fileRef = A62C33CAAD941D27993CFB927857A476 /* FIRAppAssociationRegistration.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 20F3EC5F96CECCC418924F80B181053B /* nanopb-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 41F647164C5CA7901E4BFE7741255A55 /* nanopb-dummy.m */; }; - 2120FC11F12792CCF30112ABF6AECDC2 /* FIRLoggerLevel.h in Headers */ = {isa = PBXBuildFile; fileRef = 20BB64A0D3C190E922B42A7DABDF4351 /* FIRLoggerLevel.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 225CD805988CB60469B5BF834F3D9CF2 /* FIRInstanceIDTokenInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = D96D27B23ED456F3F91185B0591AA335 /* FIRInstanceIDTokenInfo.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 22C2EC4924A727034D60B942E9FB3B76 /* FIRInstanceIDCheckinService.h in Headers */ = {isa = PBXBuildFile; fileRef = C509EB270A3FE03A71169745013D5768 /* FIRInstanceIDCheckinService.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 2300C13FB133313D32DFFB0D57C25ECC /* GTMSessionUploadFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = AD9455B83D23BDB4915ED6A130D1C8C4 /* GTMSessionUploadFetcher.m */; }; - 2390AF73CF77000D9FFA4F7E71F87709 /* FIRInstanceIDKeyPairUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 3895CC74E7806861C8DB5D96CD95C007 /* FIRInstanceIDKeyPairUtilities.m */; }; - 250394D1E8BA232672EDB0720E269F26 /* GULAppEnvironmentUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C7078467D0A33F3EBEFE639202A278A /* GULAppEnvironmentUtil.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 26FE54055CE40CA8B7B8556919C21149 /* GTLRDateTime.m in Sources */ = {isa = PBXBuildFile; fileRef = F22DC88B182B57DE12E328AAEF3F023C /* GTLRDateTime.m */; }; - 28FD68E488D4EB3F967E24EB321A3D8C /* FIRInstanceIDAuthKeyChain.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E8692905552E367BFE89057E3905DB9 /* FIRInstanceIDAuthKeyChain.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 29D6BF1387573FF76079F4370615F42F /* FIRDependency.h in Headers */ = {isa = PBXBuildFile; fileRef = 2702574391D7BC669EE01BBCB336A64C /* FIRDependency.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 2C104E24C5AD39EAEA527722426513D0 /* FIRInstanceIDConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 2897AC5168624488338884B7C36B5865 /* FIRInstanceIDConstants.m */; }; - 2C992FD410CB75581BF435EA7A66C903 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1DBB860A02D6C05F0481A5858569152 /* Foundation.framework */; }; - 2E4BF72932067C69FF51DB6AC0790798 /* GULUserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 0AEFDB9DD19C098BAA39381962D72398 /* GULUserDefaults.m */; }; - 2ECE32250F9379832BA31C5788E02EBC /* GTLRSheetsService.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DEDD6F11A6592A96F72E6E90EC1FD73 /* GTLRSheetsService.m */; }; - 2F4F0E5F03828E47ACDB08F50C32750A /* pb_common.h in Headers */ = {isa = PBXBuildFile; fileRef = E63ABD34201B77F662B8D9B9DA44CDC6 /* pb_common.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 3114C26A42681313B7F292DEFEA4AB23 /* FIRAnalyticsConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = F047222C8056B6A3AD7E289C9EE21D28 /* FIRAnalyticsConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 3186A8F692C6DCA34411EBCED965DA5C /* GULOriginalIMPConvenienceMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B6E82FA3B095C371861788955184AAA /* GULOriginalIMPConvenienceMacros.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 319C57F799237E5E10948965A2A94843 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1DBB860A02D6C05F0481A5858569152 /* Foundation.framework */; }; - 3358337525AF2964298F3C2457BAA271 /* FIRInstanceIDAPNSInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 1331D13DD4DE386BCEDBC001F6B10B28 /* FIRInstanceIDAPNSInfo.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 350A5A886E6A58D8CDCDD4253BC38BDC /* nanopb-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C00A42C8667CADDFB41282D26A16227 /* nanopb-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 35D665B3D90C6BE89DEC067A5ED94F57 /* GULNetworkConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 2060C1F4AD9CA43E0B2EA2B28F55A284 /* GULNetworkConstants.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 376B561BE4A9CF76B656848C439B8DE7 /* NSError+FIRInstanceID.h in Headers */ = {isa = PBXBuildFile; fileRef = 54C93ABAE1D2705DC66F2D99C41F09C5 /* NSError+FIRInstanceID.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 38AE6B968DC0DE94A749503C4FF43E51 /* GTMMIMEDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 88278CB0E802158640AF8B0E24FAD79A /* GTMMIMEDocument.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 3B68F1157F767E0A567E3342BE503D66 /* FIRErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = 8CA5A0BB0A7F36E8F7189D91C8B29728 /* FIRErrors.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 3BB343D149E94DCA9736241B605534AA /* GULAppEnvironmentUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 294D8D5384102F5EC8F36C99BD40B553 /* GULAppEnvironmentUtil.m */; }; - 3C650CC5DFF8B2369B0326CF9EFA3B74 /* GTLRFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = 217305076F6C446D80ECEE650D6FF336 /* GTLRFramework.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 3C7B678AE30C0CFDF2F6230C4182405B /* FIRInstanceID+Testing.h in Headers */ = {isa = PBXBuildFile; fileRef = CDECB42CD69FE8C441A88EB09E5E41B1 /* FIRInstanceID+Testing.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 3E3765FEDEFB49732071DF7CCFDA4F18 /* NSError+FIRInstanceID.m in Sources */ = {isa = PBXBuildFile; fileRef = FB866184F9DB8C552543637E0980B4FA /* NSError+FIRInstanceID.m */; }; - 3F5F0473B00C277797303FA939E6DBAB /* GULMutableDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 83537337655F0E50082CD7E2603EFCCA /* GULMutableDictionary.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 40F36D2E46BA807F50F3E49F1A3F14A0 /* FirebaseInstanceID.h in Headers */ = {isa = PBXBuildFile; fileRef = 15D8C40F17E82EDAAA2FD2FEE97387AD /* FirebaseInstanceID.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4113F1C1982CB9F61B0877D8E2A3C982 /* GTMGatherInputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BC9D2775C1E7A3C43A2D9FB68FD6140 /* GTMGatherInputStream.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 43A96F3C7695AE0E52B91FFD50FFB008 /* FIRInstanceIDStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 559A7AF75C7825A882D221F994EDE0FE /* FIRInstanceIDStore.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 45BF0F342DD18D393CF71EA76BCAF831 /* FIRInstanceIDKeyPair.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FBB2D1B3717FA3F20CC83DA53908482 /* FIRInstanceIDKeyPair.m */; }; - 46FFA8D318E8298B80CFF968BD58A1DE /* FIRInstanceIDKeyPairStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 63CA82E29BA583AD0A52D7A37558E2F9 /* FIRInstanceIDKeyPairStore.m */; }; - 49EA6B4459F2B9C1CE0E1DCAE261FDEF /* GULNetworkURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = A8CEB8453EFC3EBB8CC7F816596220DD /* GULNetworkURLSession.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4AEAF2548FD03171132E796282A5A71A /* FIRBundleUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = C99E6C3748A149B14ABA4CF063DD4F52 /* FIRBundleUtil.m */; }; - 4BA3FA7832147EC2B3EE59FD01CC2CAE /* GULReachabilityChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CCAEF0B1870F052EDE7D124EE35E5F2 /* GULReachabilityChecker.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4CD69ED3DFC0C9AE77A59B70AF7FE036 /* pb_encode.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C217B0FC3899164615FD61D788E7FBA /* pb_encode.c */; settings = {COMPILER_FLAGS = "-fno-objc-arc -fno-objc-arc"; }; }; - 4DB3785D5FF90EE291AD9E6888678568 /* FIRErrorCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 637245938FD074F3B9AE443C80D0A34E /* FIRErrorCode.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4DF83A76C578938051AFFAC51A0E1471 /* pb_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 3CAC70B7C1A8906857FA3FC99C1BD4EC /* pb_common.c */; settings = {COMPILER_FLAGS = "-fno-objc-arc -fno-objc-arc -fno-objc-arc"; }; }; - 4F6EF06D616D2AEDAEAC81ECDE2C488E /* GTLRUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = B999E5AD02D47AC06D46363EEC291140 /* GTLRUtilities.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 50D319FF764331FCABB481C1A7D835E5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1DBB860A02D6C05F0481A5858569152 /* Foundation.framework */; }; - 526B347701CC61AA8D42C5004F5DACDD /* FIRInstanceIDTokenOperation+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 29BA6B4B3A27AAF40CE91D7F460B4C09 /* FIRInstanceIDTokenOperation+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 529E198E8565F59B3BE1364522AAEC87 /* GTLRSheetsService.h in Headers */ = {isa = PBXBuildFile; fileRef = EEF2A1FD563D62873F1FE536E3F72F91 /* GTLRSheetsService.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 531D80A0B9967E698C050D4621953516 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1DBB860A02D6C05F0481A5858569152 /* Foundation.framework */; }; - 55E0ADCA640BB3322559794AED57F451 /* GTMSessionFetcherLogging.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CA616F95FA0F7EB03F1582C09FCD657 /* GTMSessionFetcherLogging.m */; }; - 564FB83D43683D79E3DF91EC972184D8 /* GTLRObject.m in Sources */ = {isa = PBXBuildFile; fileRef = DEFA1AB5522EACA4F67A002CF883955E /* GTLRObject.m */; }; - 56BAB83EAE402801FA7BA3911CCF67D7 /* FIRInstanceIDAuthKeyChain.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F06F1782AC0D2EF8E359A25024009A7 /* FIRInstanceIDAuthKeyChain.m */; }; - 57600D38E2FDA193B83876BC5357B486 /* FIRInstanceIDKeyPair.h in Headers */ = {isa = PBXBuildFile; fileRef = E9E92D24EC1A5967CA10893102360920 /* FIRInstanceIDKeyPair.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 57C2471A37561E07AE381E7E346F77B3 /* GTLRSheetsObjects.h in Headers */ = {isa = PBXBuildFile; fileRef = BA38906194CC3F29E0F1F97D1A889161 /* GTLRSheetsObjects.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 57C854E399EE2DDEA121CD54EE49CB07 /* Pods-TeachersAssistant-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 3DFABC77294AE1B3C79891E913990217 /* Pods-TeachersAssistant-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5803D830BEAB4B1992945388A716537D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1DBB860A02D6C05F0481A5858569152 /* Foundation.framework */; }; - 5992ECFCB7E99F063A2D36AE73F44D60 /* GTMSessionFetcherService.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BBAFAC2A9A529CD28ED16BCF13AECE4 /* GTMSessionFetcherService.m */; }; - 59CEC609B2677DAC48C94403C96404CD /* FIRInstanceIDKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 7943A53065BB0DF789C3CDEEC1004CD9 /* FIRInstanceIDKeychain.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 5A84786CE0B0F1A1F8090E765B046C4D /* FIRAppInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 042BE6629EC9A2E9F87D17CED7AACB6A /* FIRAppInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 5AE38B0A395E28D92DF14A261A9EBE45 /* FIRInstanceIDKeyPairStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 290A38F9B7BEF687F3DBB3C3255CC233 /* FIRInstanceIDKeyPairStore.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 5B469132FE6F3D6BD781A223B88A5F41 /* FIROptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C62C59F592BBF3BA1637FDA859BE9A6 /* FIROptions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5BA1BBD448693996005C28B6F23F9860 /* FIRInstanceIDCheckinPreferences+Internal.m in Sources */ = {isa = PBXBuildFile; fileRef = DB676188CF095CD4CF367F5EBC478EA7 /* FIRInstanceIDCheckinPreferences+Internal.m */; }; - 5D2B3289AB0C9082A36E106B6FC1A1C9 /* GTLRErrorObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 4673860D113355AAD052F21D1D4399F7 /* GTLRErrorObject.m */; }; - 5DE36E758B1620E0A005E2038548BFE8 /* FIRInstanceIDTokenOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 39DE45AADB09BA42C0F26F4A09E7BBEE /* FIRInstanceIDTokenOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 5E638B27DC537F86FE14FD7E312A350E /* FIRVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = 321D5E4C31CED38A5BE1C3397595E7F5 /* FIRVersion.m */; }; - 5F2485A11C7E0A6818B2FB30C4B2146D /* FIRInstanceIDStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 61C9D32696A6761D07B73E8E6A1B0603 /* FIRInstanceIDStore.m */; }; - 60070AAFBCB471BDF2A5903E309BF939 /* GTMSessionFetcher-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 09CF74BB4F08D9BA981B0FCB07128326 /* GTMSessionFetcher-dummy.m */; }; - 60D21973F190744E3DC7BE8B088679C3 /* FirebaseInstanceID-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 2EDD142F7B8EDBDDDDB5BF548CD9DED8 /* FirebaseInstanceID-dummy.m */; }; - 61B23F7031A1C5919E7338E490C116E7 /* FIRInstanceIDKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CF4F8A5BE53C6A071CEA011E4022665 /* FIRInstanceIDKeychain.m */; }; - 62D28905E5357811247084EA63BBF4DA /* GULNetwork.m in Sources */ = {isa = PBXBuildFile; fileRef = DD8C5B5B378C757D7F3D05B7BBF50F99 /* GULNetwork.m */; }; - 63CBC280596E3A453DF91743EBBC898A /* GTLRDuration.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CA56DE4B76F14F33BDA8853272D8366 /* GTLRDuration.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 63E86A46BDB0362808FB9BA64DE35DA5 /* FIRInstanceIDDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BC4FA64AE2079B4E811849A1860A4A6 /* FIRInstanceIDDefines.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 656F3D54ACD64C547F9594F124FA2D5E /* GTLRUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E92A8BA31159E11D52BAF17FD3D11F2 /* GTLRUtilities.m */; }; - 689CA019D0B329049875601AD99A0C04 /* GTLRSheets.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E9773C37D034C604399ABF8364696FC /* GTLRSheets.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 69F46ADB15D518B3F0323377AFEE974E /* GTLRBatchQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = 74EF9C835171D35F298E15ACA4B38506 /* GTLRBatchQuery.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6AA5596E1B32B6664794B84C8D53BB3C /* GULMutableDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 1201678D8F7875046192E6EF9294A1C4 /* GULMutableDictionary.m */; }; - 6B80256F23FA1918E977CEDE91CE3697 /* GTLRDuration.m in Sources */ = {isa = PBXBuildFile; fileRef = E296AF2AA89291E5567866849C26499D /* GTLRDuration.m */; }; - 6C571A236A1EBAA0111698DE1FC4D0A4 /* Pods-TeachersAssistantTests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 029A66B7819D4FD2C4DD1328C5488419 /* Pods-TeachersAssistantTests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C8C3F762C321C7FCF5D7A91E0CBD4B1 /* GULNetworkLoggerProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 00061B4668B2781E6A386D5E815509C2 /* GULNetworkLoggerProtocol.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 6D61C466E6E69A842B65285DE2261213 /* GTLRService.m in Sources */ = {isa = PBXBuildFile; fileRef = B9EDA8960D68B07F4E048AFDDA68BCA0 /* GTLRService.m */; }; - 6DEE0C82F00E41474F70E54D39C1337D /* GTLRSheetsQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = 20CB19971EEB7403662B8D6D969AAA1B /* GTLRSheetsQuery.m */; }; - 6EC07394A547C7982468ED9069AAB53B /* FIRInstanceIDVersionUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = E83DAD359A051E38E0DCAAC7824D73BE /* FIRInstanceIDVersionUtilities.m */; }; - 6FD0FBAB532F0C93B7B8909FC99BFE97 /* FIRInstanceIDBackupExcludedPlist.h in Headers */ = {isa = PBXBuildFile; fileRef = 108C5CDFDC3BEA327489B1E055ED7470 /* FIRInstanceIDBackupExcludedPlist.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 723B1DEC2C8098017A02DF898B87E8D0 /* GULLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 21E1BF177C744299F7CB68726168AE6D /* GULLogger.m */; }; - 730879B4705522202D09520FBDEE11A5 /* GTLRDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 56CE98F133AB2BA1382EB2FAB97B0AF8 /* GTLRDefines.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 76478F8839B3E900D460C0DE15D21F53 /* FIRErrors.m in Sources */ = {isa = PBXBuildFile; fileRef = FB0DA168C2F41D42C624551BC2C23F9D /* FIRErrors.m */; }; - 764B2AE2F2B17F964F6437AE468C0F15 /* FIRInstanceIDTokenOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 571008D58CCCDD41BFC7992FC649BC4D /* FIRInstanceIDTokenOperation.m */; }; - 7B4645279AD67C809174C1B58AD6F915 /* FIRInstanceIDTokenStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 6DF78EC6817986F64D37F229896D32E8 /* FIRInstanceIDTokenStore.m */; }; - 7D1EE73692570398E3148C707E474265 /* GTLRErrorObject.h in Headers */ = {isa = PBXBuildFile; fileRef = F6D4CCD7AF5F1B7C6D6D88509BAB7785 /* GTLRErrorObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 7D49364D45BC35C596753015EED2158D /* FIRInstanceIDTokenManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F7812E7B55B6200DF820251D9207F56 /* FIRInstanceIDTokenManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 7E169F6567DADEB4C0269E64A51E6DA4 /* GULReachabilityMessageCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7DA698D652FCFAC16C9EEFCA83C85E72 /* GULReachabilityMessageCode.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 7F6426897180E49EE98F3A6CE8F24D58 /* FIRInstanceIDLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 43D7AEB5BE9D344529D075789E88E926 /* FIRInstanceIDLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 7FB4AACD60131CB28B62F5EDB531AAA4 /* FIRInstanceIDCheckinPreferences+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A6EFE17E8C1D2435651AA1CF3C3314CB /* FIRInstanceIDCheckinPreferences+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 7FE7DA15DFBB03C6F320F4137F0284ED /* GULSwizzler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B5032812C848FA7747EE94B157813B2 /* GULSwizzler.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 8343914CF540F43454F0A80F319961E8 /* FIRAnalyticsConfiguration+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = ED74DCD72556A6C8618B511D2910AB18 /* FIRAnalyticsConfiguration+Internal.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 854834B0636DAEB384EAC5BBFA00993A /* FIRComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 499E59FADC4F9A4FD57637B40A7E0AEB /* FIRComponent.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 876F2110FD88F97EDECF6652D7193836 /* FIRIMessageCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4094FA6772FCD62F992E63FD03A145DC /* FIRIMessageCode.h */; settings = {ATTRIBUTES = (Project, ); }; }; - 88B58642B5770D7313961DB5AAC02C58 /* GULReachabilityChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = 5422968193C250477308AB011920863A /* GULReachabilityChecker.m */; }; - 8E0A60B68DDAD2843111B1C139A1C29E /* GTLRDateTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 0810102125B8C9E4FBBF7EF7D58409CC /* GTLRDateTime.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8F07CBB8F46A54B2AE38082096AAC033 /* GTLRQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = 91FD3DD45495B59CF1AD18C2F1C5664A /* GTLRQuery.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9043BA2AD19DEE4622D0572578355D84 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1DBB860A02D6C05F0481A5858569152 /* Foundation.framework */; }; - 90B3B87D94A9F9F6A90C2222E7516DC9 /* GTMSessionUploadFetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E8A41DFF31FE019B30BF0B9770BE14D /* GTMSessionUploadFetcher.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 90BA3209CD339006E7B46A3410F4CD47 /* GULLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = CD7867B1787870FFF4445F7C463304EC /* GULLogger.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 90FF5AE27672B3705B540430627AAE1A /* FIRApp.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AAFBE6129D7F7EE3751814049C55310 /* FIRApp.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 93942FEE248D34A1409BA4C09935228D /* FIRInstanceIDStringEncoding.m in Sources */ = {isa = PBXBuildFile; fileRef = D3389939168D7E16A07E06299C2D2CC6 /* FIRInstanceIDStringEncoding.m */; }; - 93F238A3CBF92469EAB23AA952814B9E /* GoogleAPIClientForREST-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 359D1387EF23CF339959AB5D298D182D /* GoogleAPIClientForREST-dummy.m */; }; - 9597B01BCD32158B7674DA270A77A05D /* GTLRBase64.m in Sources */ = {isa = PBXBuildFile; fileRef = A12B17E00FB8FCB54E94D10975B5302C /* GTLRBase64.m */; }; - 98C8F3CD30D7FC179619C4297EDFA954 /* FIRComponentContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8AF638AC9C581DA7EAF1350F43C6E347 /* FIRComponentContainer.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 98E8C4DA7467C8A63B31CA042446E2E6 /* pb_encode.h in Headers */ = {isa = PBXBuildFile; fileRef = 2F783D0C9291771FE7CD74A47090BDE4 /* pb_encode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9A1C90B1E05093DDF8B89EF59A6727AE /* GULSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = E141DD28AFD58761041D850CDAE0C508 /* GULSwizzler.m */; }; - 9B06D94D480832601A64BE7F6D29532C /* FIRInstanceIDCheckinPreferences.m in Sources */ = {isa = PBXBuildFile; fileRef = B2CE9C8D3C9509E03742DAAC7D484973 /* FIRInstanceIDCheckinPreferences.m */; }; - 9BBC4EFFC569655FBA0A52C627D674F0 /* GTLRQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = 54F922D095E5B9A857BABDE9A29D2EA7 /* GTLRQuery.m */; }; - 9CB382D049F3DBBFEB176BEF0543DA34 /* FirebaseCore-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 7110D63F53E9A413E26235ED20E973C9 /* FirebaseCore-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9E31E2EBECBBEE07EFC16DF386D6AE4E /* GULNSData+zlib.m in Sources */ = {isa = PBXBuildFile; fileRef = 09B65EA9CD18054C3731D78BF06AFBBC /* GULNSData+zlib.m */; }; - A0779DD555A5A31F2302853261F22548 /* FIRInstanceID.h in Headers */ = {isa = PBXBuildFile; fileRef = 30630E98C2C2879DE2C1248CA2C52F19 /* FIRInstanceID.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A14D03FFE5AB2DDE88377934063BF951 /* FirebaseCore-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 312A54AECBD7450DEF1199ACE70B112A /* FirebaseCore-dummy.m */; }; - A3A05DE0E3AEB3299F7606F0F8BD7756 /* GTMSessionFetcherLogging.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A9E981E17F06280BA9E8358D8FB90FD /* GTMSessionFetcherLogging.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A4077CB32B233FA9A612685884A231A5 /* GULAppDelegateSwizzler.h in Headers */ = {isa = PBXBuildFile; fileRef = F171712428FC85037E9F00703B7F2E22 /* GULAppDelegateSwizzler.h */; settings = {ATTRIBUTES = (Private, ); }; }; - A64F4FE4D9093E1AE9EFEE5094DC0E43 /* FIRInstanceIDCheckinStore.m in Sources */ = {isa = PBXBuildFile; fileRef = DF5BFCC018CAF9606683F89394C3B25B /* FIRInstanceIDCheckinStore.m */; }; - A764BBEB0892656245FE139E4F6EA311 /* FIRInstanceIDURLQueryItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 03CAC1CE04C75824406C3CB91E3A6CB2 /* FIRInstanceIDURLQueryItem.m */; }; - A8EB0C6CA4D63005360D86AA889A518A /* GULReachabilityChecker+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E00DA041CCC31B6AEC875C52444A935 /* GULReachabilityChecker+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; - A8F30A21B9C02C553EDA86290D8C896F /* GULAppDelegateSwizzler_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = A3EAF3AA8E5BADD73BCE0D2B8CC69B98 /* GULAppDelegateSwizzler_Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; - AA969B6FE2ED5EE3ACE1C2AC005701C0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1DBB860A02D6C05F0481A5858569152 /* Foundation.framework */; }; - ABA437DFA30B41D0B77E0592682739FE /* GTLRBase64.h in Headers */ = {isa = PBXBuildFile; fileRef = 632CEDCB8B1B6CADF8FA17EE175367B8 /* GTLRBase64.h */; settings = {ATTRIBUTES = (Public, ); }; }; - ABBA4D1A08A1D18ECF18CFCEC1D683DE /* FIRApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 271F6CEBA30B3B7191840DEDD47F81FC /* FIRApp.m */; }; - AE273C13E5C6707E77A6B4EBFA096DA1 /* FIRInstanceIDUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = DFE9A713C35D87D3276D66BDED99B818 /* FIRInstanceIDUtilities.m */; }; - B078F7C21362CC2EC03671646B46739F /* FIRDependency.m in Sources */ = {isa = PBXBuildFile; fileRef = 0508F9F459470F87AE900EE671A33683 /* FIRDependency.m */; }; - B1A5C2FE1615E297E4A245C34B7F6762 /* GTMSessionFetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 504D2264E8585EE42A61DCE121FA7334 /* GTMSessionFetcher.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B2846F8C8EEB75BF6E4BCE173933460B /* FIRInstanceIDTokenDeleteOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = D9BB6D0D6107EB6AA9292CBA994F58BD /* FIRInstanceIDTokenDeleteOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; - B38F70804F3D61BBBA93329CA7ED0FC8 /* pb_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = CC33E734D1611BA6A191D8246CEFF204 /* pb_decode.c */; settings = {COMPILER_FLAGS = "-fno-objc-arc -fno-objc-arc"; }; }; - B52B5E4267D0030974343307EFCDE2F2 /* FIRInstanceIDCheckinPreferences_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = D9107B74D49E38BCF7B3F2ED77E71F21 /* FIRInstanceIDCheckinPreferences_Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; - B60CEC5F4A4DE230EA3EA08A13DDE360 /* FIRInstanceIDCheckinService.m in Sources */ = {isa = PBXBuildFile; fileRef = 0AA2DD0AD8A2506D0FC3BBBF05067226 /* FIRInstanceIDCheckinService.m */; }; - B874D22C452407668077BA2AB7F14F2A /* FirebaseCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AA8AEFC53E239B1C44121C6399BDF14 /* FirebaseCore.h */; settings = {ATTRIBUTES = (Public, ); }; }; - BAEA0165416D2478BB040F1584A157E9 /* GTLRBatchResult.m in Sources */ = {isa = PBXBuildFile; fileRef = ED28B4447BE06C582F74CF53046DEFA2 /* GTLRBatchResult.m */; }; - BB7CA1C508167B9F8FD455BEA2D522E3 /* GoogleUtilities-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 84B75F5A2DD728216A8F32ED58EB0EEC /* GoogleUtilities-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C071C67F80CC4B0C3B8CF21F3F91CED0 /* FIRInstanceIDTokenInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 93FB1D3F1A434DADF7E8F2E0DCDF6CB4 /* FIRInstanceIDTokenInfo.m */; }; - C191B7AFCB86D9C55E552A9432A08AA5 /* Pods-TeachersAssistant-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 74104373A68924B948E2FD66656DDF04 /* Pods-TeachersAssistant-dummy.m */; }; - C1C8CE593A5F1669B167AB171FB02783 /* FIRInstanceIDAPNSInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 580320C3A739577369ED81033BFCE123 /* FIRInstanceIDAPNSInfo.m */; }; - C40EB7CFC8729D308A3FC952DBEFDAC4 /* FIRConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 82BB2879569D536A6530B687161DC8B1 /* FIRConfiguration.m */; }; - C67A8DA52D8476D2E472A65E8ED2104C /* FIRInstanceIDUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C252AD090AF9844AB7721AC0D603C74 /* FIRInstanceIDUtilities.h */; settings = {ATTRIBUTES = (Project, ); }; }; - C89BB6836DEA8F2EE0B9199A7A78CDDC /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0F0A5A680330D1BBE6109D7E21EEBA20 /* SystemConfiguration.framework */; }; - CAA80C28BBEFFF683932412EFE2D52C8 /* FIRInstanceIDAuthService.h in Headers */ = {isa = PBXBuildFile; fileRef = 1911D2DEEADE2AAC254508D0D8D4DD05 /* FIRInstanceIDAuthService.h */; settings = {ATTRIBUTES = (Project, ); }; }; - CD615CD72DECC08D3F0223C7E23B3093 /* FIRComponentContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E3ADB623A71EF1040F07F4474B13C1F /* FIRComponentContainer.m */; }; - CDB71F03D6470F12E7217D87B7AC7AF0 /* FIRInstanceIDURLQueryItem.h in Headers */ = {isa = PBXBuildFile; fileRef = B5F6A2DBC7DB5FAD70AD67EE2F401420 /* FIRInstanceIDURLQueryItem.h */; settings = {ATTRIBUTES = (Project, ); }; }; - CE0AF5ABE638F0F58F8DC3D81B7E3100 /* GTMReadMonitorInputStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 547B4BA4FC4AC94B80BCCBAA38BEEB88 /* GTMReadMonitorInputStream.m */; }; - CF12D67880876BC3C2360BB7F3C792ED /* GTLRUploadParameters.m in Sources */ = {isa = PBXBuildFile; fileRef = 6004EF0F526D87CB1DB9CE9FE43FBE40 /* GTLRUploadParameters.m */; }; - D044612547CC780C57BA3DDF204F4550 /* GTMGatherInputStream.m in Sources */ = {isa = PBXBuildFile; fileRef = FCC79991521336223B763662128BB7A3 /* GTMGatherInputStream.m */; }; - D0684944EF39981421BA02602FB5B6BB /* FIRInstanceIDTokenDeleteOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F74B35ABB197CD426E4B528256BA88 /* FIRInstanceIDTokenDeleteOperation.m */; }; - D09DE4F8CF9819C7BB99A345BBA78339 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D669732E0BA0105016B0BFAF2C9EEE1 /* Security.framework */; }; - D0D85A8ED3641D03ECCFFD79CC11D9FF /* FIRInstanceIDStringEncoding.h in Headers */ = {isa = PBXBuildFile; fileRef = 3AA55CFA88ACE2B99420F368974ED9E7 /* FIRInstanceIDStringEncoding.h */; settings = {ATTRIBUTES = (Project, ); }; }; - D0FE30F9B8D24715714954E61B6B5F36 /* GULLoggerCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 33E015D9CF73817DBAE5EE02250E5DED /* GULLoggerCodes.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D2B0DFDD0967BE00F5CB9E1941A6D6C4 /* FIRInstanceID.m in Sources */ = {isa = PBXBuildFile; fileRef = 49C0CD9206E359DF82CB5D71E5B5097F /* FIRInstanceID.m */; }; - D316314973075DB32C8953B79BF3BC75 /* FIRInstanceID+Private.m in Sources */ = {isa = PBXBuildFile; fileRef = E62986E64C2AD9319C9BE39EFAD551E2 /* FIRInstanceID+Private.m */; }; - D61867C7D901892724105F7FAC29841E /* GULLoggerLevel.h in Headers */ = {isa = PBXBuildFile; fileRef = 58AC66E22BF3126CF2AB5A768FAABD0F /* GULLoggerLevel.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D775E01ED0653D1AA554B9D50E9C276E /* GTLRRuntimeCommon.m in Sources */ = {isa = PBXBuildFile; fileRef = C9B714FB115F77DF3A9116B5D1D89C31 /* GTLRRuntimeCommon.m */; }; - D780901FD66E3D4D29C65BD48F52340A /* GULNetworkMessageCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F130B340A708E32CAEA83F0B6619B08 /* GULNetworkMessageCode.h */; settings = {ATTRIBUTES = (Private, ); }; }; - D79F7227DECCB6A36A093DC50BDEE07E /* GTLRObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D9A4276C20DF4C737ECB8CD0541D1A67 /* GTLRObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D8A219829C97AE6AF93A048E09F5680D /* FIRComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AC4E56443368A59F770E05990328FBB /* FIRComponent.m */; }; - D90D03372B914B0F17346CFA70DE4BEC /* GTLRURITemplate.h in Headers */ = {isa = PBXBuildFile; fileRef = DCEE515F01DF166DBC634C843933F6B9 /* GTLRURITemplate.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D90D2E30A9BE48C385E0B6F2A40A8924 /* GTLRRuntimeCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AF84FD306398BAAB32D5EB452C1E569 /* GTLRRuntimeCommon.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D9CAB0323F055B25038E725BDF34909A /* GTLRBatchResult.h in Headers */ = {isa = PBXBuildFile; fileRef = ADB38B25ABA9170879CD55B53412DFE6 /* GTLRBatchResult.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DE33BF21B7C31BD920D551FAAB7EA056 /* GoogleAPIClientForREST-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 8AB3ECC077B85578CA86B1AB55A7B12D /* GoogleAPIClientForREST-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DE4E29330B8FF66A9D6931E4A35D011C /* FIRInstanceIDBackupExcludedPlist.m in Sources */ = {isa = PBXBuildFile; fileRef = 516450B002D7F6CFAD2116CE501F57A3 /* FIRInstanceIDBackupExcludedPlist.m */; }; - DE84A495B46D938B298901309B53C60A /* GTMSessionFetcher-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = F000C09E14723D2EBBD391E19D9D5FBF /* GTMSessionFetcher-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DF87CF5ECCAE4379FB2B17ACD054F1F2 /* GTLRURITemplate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6FFA90600425E042D0DB9FE2BCF44F /* GTLRURITemplate.m */; }; - E16C9C03AFF3F2637540647FB777E3A0 /* GTLRService.h in Headers */ = {isa = PBXBuildFile; fileRef = 2F3C1179BBE0B2F619AB8D842242DF54 /* GTLRService.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E32F693371E7272421A8F5ABE4C7D05B /* GTLRBatchQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = 73DEB6CDF7421F78C01F7474A67404F3 /* GTLRBatchQuery.m */; }; - E36F4E96A7B06203207C264C5ABDFD2E /* FIRInstanceIDAuthService.m in Sources */ = {isa = PBXBuildFile; fileRef = A36649E2942CA43CF746CB8BB3356A9D /* FIRInstanceIDAuthService.m */; }; - E6E306527999E035678E03FCFB44F5E6 /* FIROptions.m in Sources */ = {isa = PBXBuildFile; fileRef = DA86BE4F12D473D435458BB4FB158BCD /* FIROptions.m */; }; - E6F14D70F8F878C0D7D8894FBA1D919D /* FIRInstanceIDVersionUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 3693350ACB41663D2E80F539D7E5C50E /* FIRInstanceIDVersionUtilities.h */; settings = {ATTRIBUTES = (Project, ); }; }; - E8C0A0E2222FF021FE0174A246F9AD21 /* FIRAppAssociationRegistration.m in Sources */ = {isa = PBXBuildFile; fileRef = B6FBF86619741BAE53E3D255FBF0ABB1 /* FIRAppAssociationRegistration.m */; }; - E9D3144ECE2DB2BCCA436A874DE7EC89 /* GTLRSheetsObjects.m in Sources */ = {isa = PBXBuildFile; fileRef = B17C169B2ADA959DE38DAE86D07B7379 /* GTLRSheetsObjects.m */; }; - EA0876B4F2B40E37E01E0D9F96BA34B3 /* GTMReadMonitorInputStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 8795560D80511CF84F3EF6325D2A8F51 /* GTMReadMonitorInputStream.h */; settings = {ATTRIBUTES = (Public, ); }; }; - EAAC31E35767E4527322215E77F500CB /* GULAppDelegateSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = 64A59B0655E40448F960D448BFE2B4D4 /* GULAppDelegateSwizzler.m */; }; - EBB9A6443A2A88303F5D58BC929E7832 /* FIRInstanceID+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 52C6C4BA62B48087FCEC1011C608BDBA /* FIRInstanceID+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; - ED4EAD8B9899E20BCA8955C010D69F81 /* FIRInstanceIDLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = A737C343B6C79B154315978701F29A04 /* FIRInstanceIDLogger.m */; }; - F03936351B8D3C6B5E7D5E58703FF5BE /* GTMSessionFetcher.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B0CAE77A1601E438C553BCD88A71A50 /* GTMSessionFetcher.framework */; }; - F0DD6165CFF72F6AC7EB24BB0F81F59A /* FIRBundleUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = E150DF4221857596EE237D4604C64D39 /* FIRBundleUtil.h */; settings = {ATTRIBUTES = (Private, ); }; }; - F0F798FAF8F64C21D8A06294F9CCF82B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1DBB860A02D6C05F0481A5858569152 /* Foundation.framework */; }; - F1D4FF2068E4D0B9395A2B253CF7098C /* GTMSessionFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CB4C2370A78826FB61E74033B2F9BFF /* GTMSessionFetcher.m */; }; - F4E0A3D1D35780BFF837007FA581A4F0 /* GTLRSheetsQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = C635ED3519BFC49EB2C63A4252200FF2 /* GTLRSheetsQuery.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F9F2828D09A41F9367A8E4D678439DFD /* FIRComponentType.m in Sources */ = {isa = PBXBuildFile; fileRef = 7CC67CCBC2D46F79CC57C3F798122C7E /* FIRComponentType.m */; }; - FA4879EE891E4376D1CB122873A0D774 /* FIROptionsInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A3A538DA0C18DD8A698010361D27A8A /* FIROptionsInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; - FAFCFEADC58CB5BC49874CFEB7AB6508 /* FIRAnalyticsConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D74E330C10A59ECB0E3A651183B5902 /* FIRAnalyticsConfiguration.m */; }; - FB0C39A32EFA1192032C872DF986F94B /* FIRInstanceIDTokenManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F38AE2C8EE17A7657996595BFC9ABE11 /* FIRInstanceIDTokenManager.m */; }; - FBB36F8F7338268B4BCFD63D6CDDBE99 /* GULNSData+zlib.h in Headers */ = {isa = PBXBuildFile; fileRef = F0D1F45EB0BE7940F2B0A3B152F0BAF0 /* GULNSData+zlib.h */; settings = {ATTRIBUTES = (Public, ); }; }; - FEA8B7A05B7B352EE64E0FD4C79D720D /* FIRInstanceIDTokenFetchOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = CFF309BE82E37F7CBFD6B6D48621D286 /* FIRInstanceIDTokenFetchOperation.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0A84CCA22F1C8173E6B37F2069950093 /* Pods-TeachersAssistantTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 68969D6928EE46B31780E10AD93CFD89 /* Pods-TeachersAssistantTests-dummy.m */; }; + 49FBC1A9555F33BAD525509484C1A93D /* Pods-TeachersAssistant-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 72BBFEE5BC80C0DE9A031A654D125E71 /* Pods-TeachersAssistant-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6C571A236A1EBAA0111698DE1FC4D0A4 /* Pods-TeachersAssistantTests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = ECFFEA04571CCE4256E9CF44018F34FD /* Pods-TeachersAssistantTests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 80BEC0BE835BADF40A2CF22C4836BD3F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB4607EFCA7C5F75397649E792E2AFCB /* Foundation.framework */; }; + 94899B81237225BF746A450254A31A2A /* Pods-TeachersAssistant-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 53B1664AEDBB405D89BDC1830E4B2F0F /* Pods-TeachersAssistant-dummy.m */; }; + F0F798FAF8F64C21D8A06294F9CCF82B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB4607EFCA7C5F75397649E792E2AFCB /* Foundation.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 0ECB4C54EED84F5258E41AFD4657F11F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 01B53B6A43CBD6D4022A361BBFCCE665; - remoteInfo = FirebaseCore; - }; - 0F60F822741F17E09A70AC758014F400 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 799B29F9D6DCE28B98CC259440382F20; - remoteInfo = Firebase; - }; - 1978C06F97680C1C8CFE2AC9F848F053 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 01B53B6A43CBD6D4022A361BBFCCE665; - remoteInfo = FirebaseCore; - }; - 449060759393A041D614674D0E5B2085 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 232D00D8ED7797390FB38004DE01723B; - remoteInfo = FirebaseAnalytics; - }; - 455009ED9ED8F59E3D7880EA52A66B11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 01B53B6A43CBD6D4022A361BBFCCE665; - remoteInfo = FirebaseCore; - }; - 46123FA0B5C451A00D38BB12B40AD23A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D9A2B7F6350AE8AB9AAFF5A9395AD63C; - remoteInfo = GoogleUtilities; - }; - 475E73100BA3CA8F024336F74263C678 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 57B9E0A892EAB5C13D4AE7D4B1DE0C16; - remoteInfo = GoogleAppMeasurement; - }; - 53E2A1BD19729C2293AB46582C686251 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D9A2B7F6350AE8AB9AAFF5A9395AD63C; - remoteInfo = GoogleUtilities; - }; - 54A7BA384E80D5DB0269C827877FE175 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D9A2B7F6350AE8AB9AAFF5A9395AD63C; - remoteInfo = GoogleUtilities; - }; - 54C6A825F7C3057AC5EB47B5EDA879F3 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D9A2B7F6350AE8AB9AAFF5A9395AD63C; - remoteInfo = GoogleUtilities; - }; - 5BE488B88EB1D7B8BFE4A63D278D4B18 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D9A2B7F6350AE8AB9AAFF5A9395AD63C; - remoteInfo = GoogleUtilities; - }; - 63982F044D1394A02009890DC4D11191 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = E93C48A48FB03EA19C4F756B97B5F1D3; - remoteInfo = nanopb; - }; - 7AEA5761B26CAEF1A0C0E82599059DA8 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 232D00D8ED7797390FB38004DE01723B; - remoteInfo = FirebaseAnalytics; - }; - 94497EC05AB24679A89D934FDF900750 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3C6A9BF574C3488966C92C6A9B93CA8C; - remoteInfo = FirebaseInstanceID; - }; - 98553A26A4F1509909FEE91EA0162432 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D811FCD6F8EBFE221BF9D923CEFB5CE8; - remoteInfo = GTMSessionFetcher; - }; - B82C96A38C8E60FE2CEB597BB1AC15D7 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 772340DB04E857CA1ABBDB7EC1CA7079; - remoteInfo = GoogleAPIClientForREST; - }; - BBDC7C661CA5567D3925BC0747CAAEC5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 57B9E0A892EAB5C13D4AE7D4B1DE0C16; - remoteInfo = GoogleAppMeasurement; - }; - C6318E60C9E68C5F678F7ADDF357AED8 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = E93C48A48FB03EA19C4F756B97B5F1D3; - remoteInfo = nanopb; - }; - C6C35C61164D4136265E61ECEB28D38A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 3C6A9BF574C3488966C92C6A9B93CA8C; - remoteInfo = FirebaseInstanceID; - }; CBA0C327941F96015A5D0C2A0F65E1D9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = C1DBAA447353B7E3A4A495D068C464D8; + remoteGlobalIDString = DC3A57A44D7A30108A57480929F8FDFE; remoteInfo = "Pods-TeachersAssistant"; }; - DF12C5D7BB68C2724D2F39A531F2A52A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = E93C48A48FB03EA19C4F756B97B5F1D3; - remoteInfo = nanopb; - }; - F57E55D97C9AF0B37D53F628359ABA5F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D811FCD6F8EBFE221BF9D923CEFB5CE8; - remoteInfo = GTMSessionFetcher; - }; - F6A14184DE3C02C257A7298719E4FD9B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 01B53B6A43CBD6D4022A361BBFCCE665; - remoteInfo = FirebaseCore; - }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 00061B4668B2781E6A386D5E815509C2 /* GULNetworkLoggerProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkLoggerProtocol.h; path = GoogleUtilities/Network/Private/GULNetworkLoggerProtocol.h; sourceTree = "<group>"; }; - 017F9C2BF8786F97CC75BB1728EC1B83 /* FirebaseCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = FirebaseCore.framework; path = FirebaseCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 029A66B7819D4FD2C4DD1328C5488419 /* Pods-TeachersAssistantTests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-TeachersAssistantTests-umbrella.h"; sourceTree = "<group>"; }; - 03CAC1CE04C75824406C3CB91E3A6CB2 /* FIRInstanceIDURLQueryItem.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDURLQueryItem.m; path = Firebase/InstanceID/FIRInstanceIDURLQueryItem.m; sourceTree = "<group>"; }; - 042BE6629EC9A2E9F87D17CED7AACB6A /* FIRAppInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAppInternal.h; path = Firebase/Core/Private/FIRAppInternal.h; sourceTree = "<group>"; }; - 0508F9F459470F87AE900EE671A33683 /* FIRDependency.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRDependency.m; path = Firebase/Core/FIRDependency.m; sourceTree = "<group>"; }; - 069518B8B1116A7286048E10777CE4B1 /* Firebase.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Firebase.xcconfig; sourceTree = "<group>"; }; - 07C940E5390B103F4CE2892BFFBC987A /* FIRConfiguration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRConfiguration.h; path = Firebase/Core/Public/FIRConfiguration.h; sourceTree = "<group>"; }; - 0810102125B8C9E4FBBF7EF7D58409CC /* GTLRDateTime.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTLRDateTime.h; path = Source/Objects/GTLRDateTime.h; sourceTree = "<group>"; }; - 09B65EA9CD18054C3731D78BF06AFBBC /* GULNSData+zlib.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "GULNSData+zlib.m"; path = "GoogleUtilities/NSData+zlib/GULNSData+zlib.m"; sourceTree = "<group>"; }; - 09CF74BB4F08D9BA981B0FCB07128326 /* GTMSessionFetcher-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "GTMSessionFetcher-dummy.m"; sourceTree = "<group>"; }; - 0A22E7D0390892ECB350FFF998A271D0 /* GTMSessionFetcher.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GTMSessionFetcher.xcconfig; sourceTree = "<group>"; }; - 0AA2DD0AD8A2506D0FC3BBBF05067226 /* FIRInstanceIDCheckinService.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDCheckinService.m; path = Firebase/InstanceID/FIRInstanceIDCheckinService.m; sourceTree = "<group>"; }; - 0AEFDB9DD19C098BAA39381962D72398 /* GULUserDefaults.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULUserDefaults.m; path = GoogleUtilities/UserDefaults/GULUserDefaults.m; sourceTree = "<group>"; }; - 0B5032812C848FA7747EE94B157813B2 /* GULSwizzler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULSwizzler.h; path = GoogleUtilities/MethodSwizzler/Private/GULSwizzler.h; sourceTree = "<group>"; }; - 0BBF3A739B0E8360360E868AA65D007D /* FIRInstanceIDCheckinStore.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDCheckinStore.h; path = Firebase/InstanceID/FIRInstanceIDCheckinStore.h; sourceTree = "<group>"; }; - 0CA616F95FA0F7EB03F1582C09FCD657 /* GTMSessionFetcherLogging.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTMSessionFetcherLogging.m; path = Source/GTMSessionFetcherLogging.m; sourceTree = "<group>"; }; - 0E9773C37D034C604399ABF8364696FC /* GTLRSheets.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTLRSheets.h; path = Source/GeneratedServices/Sheets/GTLRSheets.h; sourceTree = "<group>"; }; - 0F0A5A680330D1BBE6109D7E21EEBA20 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/SystemConfiguration.framework; sourceTree = DEVELOPER_DIR; }; - 108C5CDFDC3BEA327489B1E055ED7470 /* FIRInstanceIDBackupExcludedPlist.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDBackupExcludedPlist.h; path = Firebase/InstanceID/FIRInstanceIDBackupExcludedPlist.h; sourceTree = "<group>"; }; - 115AA047B525A10FCEE3748D755468AF /* GoogleAPIClientForREST.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = GoogleAPIClientForREST.framework; path = GoogleAPIClientForREST.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 118B269F032567135C30C461CA7A23AD /* Pods-TeachersAssistant.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-TeachersAssistant.modulemap"; sourceTree = "<group>"; }; - 1201678D8F7875046192E6EF9294A1C4 /* GULMutableDictionary.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULMutableDictionary.m; path = GoogleUtilities/Network/GULMutableDictionary.m; sourceTree = "<group>"; }; - 123565447F11349B461EAA44530EFD01 /* Pods-TeachersAssistantTests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-TeachersAssistantTests-acknowledgements.plist"; sourceTree = "<group>"; }; - 123604314885A641B32BDF8B0F9DA302 /* FirebaseAnalytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseAnalytics.framework; path = Frameworks/FirebaseAnalytics.framework; sourceTree = "<group>"; }; - 1331D13DD4DE386BCEDBC001F6B10B28 /* FIRInstanceIDAPNSInfo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDAPNSInfo.h; path = Firebase/InstanceID/FIRInstanceIDAPNSInfo.h; sourceTree = "<group>"; }; - 15D8C40F17E82EDAAA2FD2FEE97387AD /* FirebaseInstanceID.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseInstanceID.h; path = Firebase/InstanceID/Public/FirebaseInstanceID.h; sourceTree = "<group>"; }; - 176E21E234D1EF72C0869C40836ECBCC /* Pods-TeachersAssistantTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-TeachersAssistantTests-dummy.m"; sourceTree = "<group>"; }; - 17CCF5036BBF759B3851A291325A58DD /* FIRInstanceIDCheckinPreferences.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDCheckinPreferences.h; path = Firebase/InstanceID/FIRInstanceIDCheckinPreferences.h; sourceTree = "<group>"; }; - 1911D2DEEADE2AAC254508D0D8D4DD05 /* FIRInstanceIDAuthService.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDAuthService.h; path = Firebase/InstanceID/FIRInstanceIDAuthService.h; sourceTree = "<group>"; }; - 1A3A538DA0C18DD8A698010361D27A8A /* FIROptionsInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIROptionsInternal.h; path = Firebase/Core/Private/FIROptionsInternal.h; sourceTree = "<group>"; }; - 1DEDD6F11A6592A96F72E6E90EC1FD73 /* GTLRSheetsService.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTLRSheetsService.m; path = Source/GeneratedServices/Sheets/GTLRSheetsService.m; sourceTree = "<group>"; }; - 2060C1F4AD9CA43E0B2EA2B28F55A284 /* GULNetworkConstants.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkConstants.h; path = GoogleUtilities/Network/Private/GULNetworkConstants.h; sourceTree = "<group>"; }; - 20BB64A0D3C190E922B42A7DABDF4351 /* FIRLoggerLevel.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLoggerLevel.h; path = Firebase/Core/Public/FIRLoggerLevel.h; sourceTree = "<group>"; }; - 20CB19971EEB7403662B8D6D969AAA1B /* GTLRSheetsQuery.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTLRSheetsQuery.m; path = Source/GeneratedServices/Sheets/GTLRSheetsQuery.m; sourceTree = "<group>"; }; - 217305076F6C446D80ECEE650D6FF336 /* GTLRFramework.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTLRFramework.h; path = Source/Utilities/GTLRFramework.h; sourceTree = "<group>"; }; - 21E1BF177C744299F7CB68726168AE6D /* GULLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULLogger.m; path = GoogleUtilities/Logger/GULLogger.m; sourceTree = "<group>"; }; - 2554DC9B3976244F8B3433B862DD019F /* nanopb-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "nanopb-prefix.pch"; sourceTree = "<group>"; }; - 26B79195C4C8B553F57B3D3535D34328 /* pb.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = pb.h; sourceTree = "<group>"; }; - 26B7B16A2741E588921CA76370A6E0C6 /* FIRComponentType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentType.h; path = Firebase/Core/Private/FIRComponentType.h; sourceTree = "<group>"; }; - 26EEA6C6A294786C4626A5D90B0CC7A8 /* FirebaseInstanceID.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseInstanceID.xcconfig; sourceTree = "<group>"; }; - 2702574391D7BC669EE01BBCB336A64C /* FIRDependency.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDependency.h; path = Firebase/Core/Private/FIRDependency.h; sourceTree = "<group>"; }; - 271F6CEBA30B3B7191840DEDD47F81FC /* FIRApp.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRApp.m; path = Firebase/Core/FIRApp.m; sourceTree = "<group>"; }; - 2897AC5168624488338884B7C36B5865 /* FIRInstanceIDConstants.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDConstants.m; path = Firebase/InstanceID/FIRInstanceIDConstants.m; sourceTree = "<group>"; }; - 290A38F9B7BEF687F3DBB3C3255CC233 /* FIRInstanceIDKeyPairStore.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDKeyPairStore.h; path = Firebase/InstanceID/FIRInstanceIDKeyPairStore.h; sourceTree = "<group>"; }; - 294D8D5384102F5EC8F36C99BD40B553 /* GULAppEnvironmentUtil.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULAppEnvironmentUtil.m; path = GoogleUtilities/Environment/third_party/GULAppEnvironmentUtil.m; sourceTree = "<group>"; }; - 29BA6B4B3A27AAF40CE91D7F460B4C09 /* FIRInstanceIDTokenOperation+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FIRInstanceIDTokenOperation+Private.h"; path = "Firebase/InstanceID/FIRInstanceIDTokenOperation+Private.h"; sourceTree = "<group>"; }; - 2B6E82FA3B095C371861788955184AAA /* GULOriginalIMPConvenienceMacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULOriginalIMPConvenienceMacros.h; path = GoogleUtilities/MethodSwizzler/Private/GULOriginalIMPConvenienceMacros.h; sourceTree = "<group>"; }; - 2CA56DE4B76F14F33BDA8853272D8366 /* GTLRDuration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTLRDuration.h; path = Source/Objects/GTLRDuration.h; sourceTree = "<group>"; }; - 2CB4C2370A78826FB61E74033B2F9BFF /* GTMSessionFetcher.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTMSessionFetcher.m; path = Source/GTMSessionFetcher.m; sourceTree = "<group>"; }; - 2EDD142F7B8EDBDDDDB5BF548CD9DED8 /* FirebaseInstanceID-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FirebaseInstanceID-dummy.m"; sourceTree = "<group>"; }; - 2F3C1179BBE0B2F619AB8D842242DF54 /* GTLRService.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTLRService.h; path = Source/Objects/GTLRService.h; sourceTree = "<group>"; }; - 2F783D0C9291771FE7CD74A47090BDE4 /* pb_encode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = pb_encode.h; sourceTree = "<group>"; }; - 30630E98C2C2879DE2C1248CA2C52F19 /* FIRInstanceID.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceID.h; path = Firebase/InstanceID/Public/FIRInstanceID.h; sourceTree = "<group>"; }; - 312A54AECBD7450DEF1199ACE70B112A /* FirebaseCore-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FirebaseCore-dummy.m"; sourceTree = "<group>"; }; - 321D5E4C31CED38A5BE1C3397595E7F5 /* FIRVersion.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRVersion.m; path = Firebase/Core/FIRVersion.m; sourceTree = "<group>"; }; - 33E015D9CF73817DBAE5EE02250E5DED /* GULLoggerCodes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULLoggerCodes.h; path = GoogleUtilities/Common/GULLoggerCodes.h; sourceTree = "<group>"; }; - 347A040A0C9EF78AE6E2CC3305BA6394 /* FIRInstanceIDConstants.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDConstants.h; path = Firebase/InstanceID/FIRInstanceIDConstants.h; sourceTree = "<group>"; }; - 34F74B35ABB197CD426E4B528256BA88 /* FIRInstanceIDTokenDeleteOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDTokenDeleteOperation.m; path = Firebase/InstanceID/FIRInstanceIDTokenDeleteOperation.m; sourceTree = "<group>"; }; - 35039373C75F0CAA94D50D97AF90BF12 /* Pods-TeachersAssistantTests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-TeachersAssistantTests-acknowledgements.markdown"; sourceTree = "<group>"; }; - 357B0ECED3D296D4A9739C22E28FF76D /* FIRVersion.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRVersion.h; path = Firebase/Core/Private/FIRVersion.h; sourceTree = "<group>"; }; - 359D1387EF23CF339959AB5D298D182D /* GoogleAPIClientForREST-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "GoogleAPIClientForREST-dummy.m"; sourceTree = "<group>"; }; - 368ACD55DE3CCC50F08A01196D3AAF5D /* Pods_TeachersAssistant.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_TeachersAssistant.framework; path = "Pods-TeachersAssistant.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; - 3693350ACB41663D2E80F539D7E5C50E /* FIRInstanceIDVersionUtilities.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDVersionUtilities.h; path = Firebase/InstanceID/FIRInstanceIDVersionUtilities.h; sourceTree = "<group>"; }; - 374883FE51263B2BD861B86677BF5ECA /* FIRLibrary.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLibrary.h; path = Firebase/Core/Private/FIRLibrary.h; sourceTree = "<group>"; }; - 385F92547477A014104A69ADC304BCAD /* GoogleAPIClientForREST-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "GoogleAPIClientForREST-prefix.pch"; sourceTree = "<group>"; }; - 3895CC74E7806861C8DB5D96CD95C007 /* FIRInstanceIDKeyPairUtilities.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDKeyPairUtilities.m; path = Firebase/InstanceID/FIRInstanceIDKeyPairUtilities.m; sourceTree = "<group>"; }; - 39DE45AADB09BA42C0F26F4A09E7BBEE /* FIRInstanceIDTokenOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDTokenOperation.h; path = Firebase/InstanceID/FIRInstanceIDTokenOperation.h; sourceTree = "<group>"; }; - 3AA55CFA88ACE2B99420F368974ED9E7 /* FIRInstanceIDStringEncoding.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDStringEncoding.h; path = Firebase/InstanceID/FIRInstanceIDStringEncoding.h; sourceTree = "<group>"; }; - 3CAC70B7C1A8906857FA3FC99C1BD4EC /* pb_common.c */ = {isa = PBXFileReference; includeInIndex = 1; path = pb_common.c; sourceTree = "<group>"; }; - 3DFABC77294AE1B3C79891E913990217 /* Pods-TeachersAssistant-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-TeachersAssistant-umbrella.h"; sourceTree = "<group>"; }; - 3E8692905552E367BFE89057E3905DB9 /* FIRInstanceIDAuthKeyChain.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDAuthKeyChain.h; path = Firebase/InstanceID/FIRInstanceIDAuthKeyChain.h; sourceTree = "<group>"; }; - 4094FA6772FCD62F992E63FD03A145DC /* FIRIMessageCode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRIMessageCode.h; path = Firebase/InstanceID/FIRIMessageCode.h; sourceTree = "<group>"; }; - 415002A8AF1CDA669462CD54B22427D1 /* GoogleUtilities-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "GoogleUtilities-Info.plist"; sourceTree = "<group>"; }; - 41F647164C5CA7901E4BFE7741255A55 /* nanopb-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "nanopb-dummy.m"; sourceTree = "<group>"; }; - 420B98A22418457646F0C81E28AEC1F8 /* GoogleUtilities-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "GoogleUtilities-prefix.pch"; sourceTree = "<group>"; }; - 4370B2DFACB00E7DEC0868A68AA87DBD /* GTMMIMEDocument.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTMMIMEDocument.m; path = Source/GTMMIMEDocument.m; sourceTree = "<group>"; }; - 43D7AEB5BE9D344529D075789E88E926 /* FIRInstanceIDLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDLogger.h; path = Firebase/InstanceID/FIRInstanceIDLogger.h; sourceTree = "<group>"; }; - 44581CF76B50941A6B5755E48A3F0B73 /* Pods-TeachersAssistantTests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-TeachersAssistantTests.modulemap"; sourceTree = "<group>"; }; - 44BEC70CEE7D3F3A73A2AAFC74050F84 /* Pods_TeachersAssistantTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_TeachersAssistantTests.framework; path = "Pods-TeachersAssistantTests.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; - 4673860D113355AAD052F21D1D4399F7 /* GTLRErrorObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTLRErrorObject.m; path = Source/Objects/GTLRErrorObject.m; sourceTree = "<group>"; }; - 499E59FADC4F9A4FD57637B40A7E0AEB /* FIRComponent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponent.h; path = Firebase/Core/Private/FIRComponent.h; sourceTree = "<group>"; }; - 49C0CD9206E359DF82CB5D71E5B5097F /* FIRInstanceID.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceID.m; path = Firebase/InstanceID/FIRInstanceID.m; sourceTree = "<group>"; }; - 4AAFBE6129D7F7EE3751814049C55310 /* FIRApp.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRApp.h; path = Firebase/Core/Public/FIRApp.h; sourceTree = "<group>"; }; - 4B6FFA90600425E042D0DB9FE2BCF44F /* GTLRURITemplate.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTLRURITemplate.m; path = Source/Utilities/GTLRURITemplate.m; sourceTree = "<group>"; }; - 4BBAFAC2A9A529CD28ED16BCF13AECE4 /* GTMSessionFetcherService.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTMSessionFetcherService.m; path = Source/GTMSessionFetcherService.m; sourceTree = "<group>"; }; - 4CF4F8A5BE53C6A071CEA011E4022665 /* FIRInstanceIDKeychain.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDKeychain.m; path = Firebase/InstanceID/FIRInstanceIDKeychain.m; sourceTree = "<group>"; }; - 4D669732E0BA0105016B0BFAF2C9EEE1 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; }; - 4DF7D23FF6ED5F29179DAA124D6139E0 /* nanopb.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = nanopb.modulemap; sourceTree = "<group>"; }; - 4E3ADB623A71EF1040F07F4474B13C1F /* FIRComponentContainer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRComponentContainer.m; path = Firebase/Core/FIRComponentContainer.m; sourceTree = "<group>"; }; - 4E8A41DFF31FE019B30BF0B9770BE14D /* GTMSessionUploadFetcher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMSessionUploadFetcher.h; path = Source/GTMSessionUploadFetcher.h; sourceTree = "<group>"; }; - 500B9CE6A2B5ECC69A261EE855D14BDC /* FIRInstanceIDKeyPairUtilities.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDKeyPairUtilities.h; path = Firebase/InstanceID/FIRInstanceIDKeyPairUtilities.h; sourceTree = "<group>"; }; - 504D2264E8585EE42A61DCE121FA7334 /* GTMSessionFetcher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMSessionFetcher.h; path = Source/GTMSessionFetcher.h; sourceTree = "<group>"; }; - 516450B002D7F6CFAD2116CE501F57A3 /* FIRInstanceIDBackupExcludedPlist.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDBackupExcludedPlist.m; path = Firebase/InstanceID/FIRInstanceIDBackupExcludedPlist.m; sourceTree = "<group>"; }; - 52C6C4BA62B48087FCEC1011C608BDBA /* FIRInstanceID+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FIRInstanceID+Private.h"; path = "Firebase/InstanceID/FIRInstanceID+Private.h"; sourceTree = "<group>"; }; - 5422968193C250477308AB011920863A /* GULReachabilityChecker.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULReachabilityChecker.m; path = GoogleUtilities/Reachability/GULReachabilityChecker.m; sourceTree = "<group>"; }; - 547B4BA4FC4AC94B80BCCBAA38BEEB88 /* GTMReadMonitorInputStream.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTMReadMonitorInputStream.m; path = Source/GTMReadMonitorInputStream.m; sourceTree = "<group>"; }; - 54C93ABAE1D2705DC66F2D99C41F09C5 /* NSError+FIRInstanceID.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSError+FIRInstanceID.h"; path = "Firebase/InstanceID/NSError+FIRInstanceID.h"; sourceTree = "<group>"; }; - 54F922D095E5B9A857BABDE9A29D2EA7 /* GTLRQuery.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTLRQuery.m; path = Source/Objects/GTLRQuery.m; sourceTree = "<group>"; }; - 559A7AF75C7825A882D221F994EDE0FE /* FIRInstanceIDStore.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDStore.h; path = Firebase/InstanceID/FIRInstanceIDStore.h; sourceTree = "<group>"; }; - 56CE98F133AB2BA1382EB2FAB97B0AF8 /* GTLRDefines.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTLRDefines.h; path = Source/GTLRDefines.h; sourceTree = "<group>"; }; - 571008D58CCCDD41BFC7992FC649BC4D /* FIRInstanceIDTokenOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDTokenOperation.m; path = Firebase/InstanceID/FIRInstanceIDTokenOperation.m; sourceTree = "<group>"; }; - 580320C3A739577369ED81033BFCE123 /* FIRInstanceIDAPNSInfo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDAPNSInfo.m; path = Firebase/InstanceID/FIRInstanceIDAPNSInfo.m; sourceTree = "<group>"; }; - 583BBC1D30E637FD9C0BB1442D90C0D2 /* FirebaseInstanceID.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = FirebaseInstanceID.framework; path = FirebaseInstanceID.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 58AC66E22BF3126CF2AB5A768FAABD0F /* GULLoggerLevel.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULLoggerLevel.h; path = GoogleUtilities/Logger/Public/GULLoggerLevel.h; sourceTree = "<group>"; }; - 5AA8AEFC53E239B1C44121C6399BDF14 /* FirebaseCore.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseCore.h; path = Firebase/Core/Public/FirebaseCore.h; sourceTree = "<group>"; }; - 5B0CAE77A1601E438C553BCD88A71A50 /* GTMSessionFetcher.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = GTMSessionFetcher.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 5BC9D2775C1E7A3C43A2D9FB68FD6140 /* GTMGatherInputStream.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMGatherInputStream.h; path = Source/GTMGatherInputStream.h; sourceTree = "<group>"; }; - 5D066DD9A210B03A0B9E0DAB7683DE7B /* nanopb.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = nanopb.framework; path = nanopb.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 5D74E330C10A59ECB0E3A651183B5902 /* FIRAnalyticsConfiguration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRAnalyticsConfiguration.m; path = Firebase/Core/FIRAnalyticsConfiguration.m; sourceTree = "<group>"; }; - 5E92A8BA31159E11D52BAF17FD3D11F2 /* GTLRUtilities.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTLRUtilities.m; path = Source/Utilities/GTLRUtilities.m; sourceTree = "<group>"; }; - 6004EF0F526D87CB1DB9CE9FE43FBE40 /* GTLRUploadParameters.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTLRUploadParameters.m; path = Source/Objects/GTLRUploadParameters.m; sourceTree = "<group>"; }; - 61C9D32696A6761D07B73E8E6A1B0603 /* FIRInstanceIDStore.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDStore.m; path = Firebase/InstanceID/FIRInstanceIDStore.m; sourceTree = "<group>"; }; - 632CEDCB8B1B6CADF8FA17EE175367B8 /* GTLRBase64.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTLRBase64.h; path = Source/Utilities/GTLRBase64.h; sourceTree = "<group>"; }; - 637245938FD074F3B9AE443C80D0A34E /* FIRErrorCode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRErrorCode.h; path = Firebase/Core/Private/FIRErrorCode.h; sourceTree = "<group>"; }; - 63CA82E29BA583AD0A52D7A37558E2F9 /* FIRInstanceIDKeyPairStore.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDKeyPairStore.m; path = Firebase/InstanceID/FIRInstanceIDKeyPairStore.m; sourceTree = "<group>"; }; - 64A59B0655E40448F960D448BFE2B4D4 /* GULAppDelegateSwizzler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULAppDelegateSwizzler.m; path = GoogleUtilities/AppDelegateSwizzler/GULAppDelegateSwizzler.m; sourceTree = "<group>"; }; - 66B1B5E0F02389648F7D7F08EE92449E /* FirebaseCore.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseCore.xcconfig; sourceTree = "<group>"; }; - 6924954BD2F30993FB8230C4F0B6A5F5 /* GULNetworkURLSession.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULNetworkURLSession.m; path = GoogleUtilities/Network/GULNetworkURLSession.m; sourceTree = "<group>"; }; - 6980A1AC965054D472E7A754E0433A29 /* FIRInstanceIDTokenFetchOperation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDTokenFetchOperation.m; path = Firebase/InstanceID/FIRInstanceIDTokenFetchOperation.m; sourceTree = "<group>"; }; - 6BC4FA64AE2079B4E811849A1860A4A6 /* FIRInstanceIDDefines.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDDefines.h; path = Firebase/InstanceID/FIRInstanceIDDefines.h; sourceTree = "<group>"; }; - 6C217B0FC3899164615FD61D788E7FBA /* pb_encode.c */ = {isa = PBXFileReference; includeInIndex = 1; path = pb_encode.c; sourceTree = "<group>"; }; - 6C7078467D0A33F3EBEFE639202A278A /* GULAppEnvironmentUtil.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULAppEnvironmentUtil.h; path = GoogleUtilities/Environment/third_party/GULAppEnvironmentUtil.h; sourceTree = "<group>"; }; - 6CBEAF0154F92F0CD942C90DCF6C7A1B /* Pods-TeachersAssistantTests-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-TeachersAssistantTests-Info.plist"; sourceTree = "<group>"; }; - 6CF6CDA458E493AD3A13C09451C84F01 /* Pods-TeachersAssistant-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-TeachersAssistant-acknowledgements.markdown"; sourceTree = "<group>"; }; - 6DE4621B5BF4A7F747C7A66937E79855 /* FIRLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLogger.h; path = Firebase/Core/Private/FIRLogger.h; sourceTree = "<group>"; }; - 6DF78EC6817986F64D37F229896D32E8 /* FIRInstanceIDTokenStore.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDTokenStore.m; path = Firebase/InstanceID/FIRInstanceIDTokenStore.m; sourceTree = "<group>"; }; - 6F130B340A708E32CAEA83F0B6619B08 /* GULNetworkMessageCode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkMessageCode.h; path = GoogleUtilities/Network/Private/GULNetworkMessageCode.h; sourceTree = "<group>"; }; - 7110D63F53E9A413E26235ED20E973C9 /* FirebaseCore-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FirebaseCore-umbrella.h"; sourceTree = "<group>"; }; - 72A68E1354B8F68044AB4DD21E274D55 /* FIRComponentContainerInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentContainerInternal.h; path = Firebase/Core/Private/FIRComponentContainerInternal.h; sourceTree = "<group>"; }; - 734E5DCCCE857FFA34745EB5C2D6C5EA /* pb_decode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = pb_decode.h; sourceTree = "<group>"; }; - 73DEB6CDF7421F78C01F7474A67404F3 /* GTLRBatchQuery.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTLRBatchQuery.m; path = Source/Objects/GTLRBatchQuery.m; sourceTree = "<group>"; }; - 74104373A68924B948E2FD66656DDF04 /* Pods-TeachersAssistant-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-TeachersAssistant-dummy.m"; sourceTree = "<group>"; }; - 745F466B0E0CFD0057D71D440A6D7D4D /* FIRLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRLogger.m; path = Firebase/Core/FIRLogger.m; sourceTree = "<group>"; }; - 74EF9C835171D35F298E15ACA4B38506 /* GTLRBatchQuery.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTLRBatchQuery.h; path = Source/Objects/GTLRBatchQuery.h; sourceTree = "<group>"; }; - 74F65B52CC04DEB89684D01BB66C6E41 /* GULNetworkConstants.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULNetworkConstants.m; path = GoogleUtilities/Network/GULNetworkConstants.m; sourceTree = "<group>"; }; - 7943A53065BB0DF789C3CDEEC1004CD9 /* FIRInstanceIDKeychain.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDKeychain.h; path = Firebase/InstanceID/FIRInstanceIDKeychain.h; sourceTree = "<group>"; }; - 7AF84FD306398BAAB32D5EB452C1E569 /* GTLRRuntimeCommon.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTLRRuntimeCommon.h; path = Source/Objects/GTLRRuntimeCommon.h; sourceTree = "<group>"; }; - 7C62C59F592BBF3BA1637FDA859BE9A6 /* FIROptions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIROptions.h; path = Firebase/Core/Public/FIROptions.h; sourceTree = "<group>"; }; - 7CC67CCBC2D46F79CC57C3F798122C7E /* FIRComponentType.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRComponentType.m; path = Firebase/Core/FIRComponentType.m; sourceTree = "<group>"; }; - 7CCAEF0B1870F052EDE7D124EE35E5F2 /* GULReachabilityChecker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULReachabilityChecker.h; path = GoogleUtilities/Reachability/Private/GULReachabilityChecker.h; sourceTree = "<group>"; }; - 7D8784AB13BF6FBDE11552EE49C12DCC /* FIRAnalyticsConnector.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FIRAnalyticsConnector.framework; path = Frameworks/FIRAnalyticsConnector.framework; sourceTree = "<group>"; }; - 7DA698D652FCFAC16C9EEFCA83C85E72 /* GULReachabilityMessageCode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULReachabilityMessageCode.h; path = GoogleUtilities/Reachability/Private/GULReachabilityMessageCode.h; sourceTree = "<group>"; }; - 7ECD67C851A9B1AAF8CB0A1D65A67194 /* GoogleAPIClientForREST-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "GoogleAPIClientForREST-Info.plist"; sourceTree = "<group>"; }; - 7FBB2D1B3717FA3F20CC83DA53908482 /* FIRInstanceIDKeyPair.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDKeyPair.m; path = Firebase/InstanceID/FIRInstanceIDKeyPair.m; sourceTree = "<group>"; }; - 80D0ABF6F63F3EF080A906F8C625412E /* Pods-TeachersAssistant.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TeachersAssistant.debug.xcconfig"; sourceTree = "<group>"; }; - 81BAD96EB0AFAC3A8B603522A2FD846D /* GoogleUtilities.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleUtilities.xcconfig; sourceTree = "<group>"; }; - 82BB2879569D536A6530B687161DC8B1 /* FIRConfiguration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRConfiguration.m; path = Firebase/Core/FIRConfiguration.m; sourceTree = "<group>"; }; - 83537337655F0E50082CD7E2603EFCCA /* GULMutableDictionary.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULMutableDictionary.h; path = GoogleUtilities/Network/Private/GULMutableDictionary.h; sourceTree = "<group>"; }; - 83DF78C7972D2E89918296EE5DA73881 /* FirebaseCoreDiagnostics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseCoreDiagnostics.framework; path = Frameworks/FirebaseCoreDiagnostics.framework; sourceTree = "<group>"; }; - 8416808131C45D6E3E6BC32C40C76A82 /* GoogleAppMeasurement.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleAppMeasurement.xcconfig; sourceTree = "<group>"; }; - 84B75F5A2DD728216A8F32ED58EB0EEC /* GoogleUtilities-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "GoogleUtilities-umbrella.h"; sourceTree = "<group>"; }; - 85599DEC750671534D9582042B8D286B /* FIRInstanceIDTokenStore.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDTokenStore.h; path = Firebase/InstanceID/FIRInstanceIDTokenStore.h; sourceTree = "<group>"; }; - 87191E9BA56B22A703AD591A7963F5E3 /* FirebaseInstanceID-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FirebaseInstanceID-umbrella.h"; sourceTree = "<group>"; }; - 8795560D80511CF84F3EF6325D2A8F51 /* GTMReadMonitorInputStream.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMReadMonitorInputStream.h; path = Source/GTMReadMonitorInputStream.h; sourceTree = "<group>"; }; - 88278CB0E802158640AF8B0E24FAD79A /* GTMMIMEDocument.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMMIMEDocument.h; path = Source/GTMMIMEDocument.h; sourceTree = "<group>"; }; - 8A9E981E17F06280BA9E8358D8FB90FD /* GTMSessionFetcherLogging.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMSessionFetcherLogging.h; path = Source/GTMSessionFetcherLogging.h; sourceTree = "<group>"; }; - 8AB3ECC077B85578CA86B1AB55A7B12D /* GoogleAPIClientForREST-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "GoogleAPIClientForREST-umbrella.h"; sourceTree = "<group>"; }; - 8AC4E56443368A59F770E05990328FBB /* FIRComponent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRComponent.m; path = Firebase/Core/FIRComponent.m; sourceTree = "<group>"; }; - 8AF638AC9C581DA7EAF1350F43C6E347 /* FIRComponentContainer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentContainer.h; path = Firebase/Core/Private/FIRComponentContainer.h; sourceTree = "<group>"; }; - 8CA5A0BB0A7F36E8F7189D91C8B29728 /* FIRErrors.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRErrors.h; path = Firebase/Core/Private/FIRErrors.h; sourceTree = "<group>"; }; - 8F06F1782AC0D2EF8E359A25024009A7 /* FIRInstanceIDAuthKeyChain.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDAuthKeyChain.m; path = Firebase/InstanceID/FIRInstanceIDAuthKeyChain.m; sourceTree = "<group>"; }; - 8F7812E7B55B6200DF820251D9207F56 /* FIRInstanceIDTokenManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDTokenManager.h; path = Firebase/InstanceID/FIRInstanceIDTokenManager.h; sourceTree = "<group>"; }; - 91FD3DD45495B59CF1AD18C2F1C5664A /* GTLRQuery.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTLRQuery.h; path = Source/Objects/GTLRQuery.h; sourceTree = "<group>"; }; - 93FB1D3F1A434DADF7E8F2E0DCDF6CB4 /* FIRInstanceIDTokenInfo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDTokenInfo.m; path = Firebase/InstanceID/FIRInstanceIDTokenInfo.m; sourceTree = "<group>"; }; - 9C00A42C8667CADDFB41282D26A16227 /* nanopb-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "nanopb-umbrella.h"; sourceTree = "<group>"; }; - 9C252AD090AF9844AB7721AC0D603C74 /* FIRInstanceIDUtilities.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDUtilities.h; path = Firebase/InstanceID/FIRInstanceIDUtilities.h; sourceTree = "<group>"; }; + 2064F876EB35354079F4B4E7C61BB78C /* Pods-TeachersAssistantTests-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-TeachersAssistantTests-Info.plist"; sourceTree = "<group>"; }; + 2593D361D3E3CF460C4BA860F7162623 /* Pods-TeachersAssistantTests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-TeachersAssistantTests.modulemap"; sourceTree = "<group>"; }; + 323EE53D0E077C0FFF05690D19B17BC0 /* Pods-TeachersAssistant-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-TeachersAssistant-acknowledgements.markdown"; sourceTree = "<group>"; }; + 487A571D8270AD9DBC4D5B4D623A17C5 /* Pods-TeachersAssistantTests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-TeachersAssistantTests-acknowledgements.plist"; sourceTree = "<group>"; }; + 53B1664AEDBB405D89BDC1830E4B2F0F /* Pods-TeachersAssistant-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-TeachersAssistant-dummy.m"; sourceTree = "<group>"; }; + 5DE088C489A470F3DBB49C659AE00CE2 /* Pods-TeachersAssistantTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TeachersAssistantTests.release.xcconfig"; sourceTree = "<group>"; }; + 5EFC6BA502D17737843A18B6594EA639 /* Pods_TeachersAssistantTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_TeachersAssistantTests.framework; path = "Pods-TeachersAssistantTests.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 68969D6928EE46B31780E10AD93CFD89 /* Pods-TeachersAssistantTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-TeachersAssistantTests-dummy.m"; sourceTree = "<group>"; }; + 712DF69EA41A4DDB46B20CF5E438D55F /* Pods-TeachersAssistant.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TeachersAssistant.release.xcconfig"; sourceTree = "<group>"; }; + 72BBFEE5BC80C0DE9A031A654D125E71 /* Pods-TeachersAssistant-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-TeachersAssistant-umbrella.h"; sourceTree = "<group>"; }; + 7FEDD941F5EF3021D18B42CC63A8B064 /* Pods-TeachersAssistant-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-TeachersAssistant-acknowledgements.plist"; sourceTree = "<group>"; }; + 8697266AF1651BBCB0E02A6818EC909A /* Pods-TeachersAssistantTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TeachersAssistantTests.debug.xcconfig"; sourceTree = "<group>"; }; + 93C669D461B393AB37F791633C7ECEEF /* Pods-TeachersAssistantTests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-TeachersAssistantTests-acknowledgements.markdown"; sourceTree = "<group>"; }; 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; - 9E00DA041CCC31B6AEC875C52444A935 /* GULReachabilityChecker+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "GULReachabilityChecker+Internal.h"; path = "GoogleUtilities/Reachability/GULReachabilityChecker+Internal.h"; sourceTree = "<group>"; }; - 9F12DC4DF7E7F8A371738879B374FFF5 /* GTLRFramework.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTLRFramework.m; path = Source/Utilities/GTLRFramework.m; sourceTree = "<group>"; }; - A12B17E00FB8FCB54E94D10975B5302C /* GTLRBase64.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTLRBase64.m; path = Source/Utilities/GTLRBase64.m; sourceTree = "<group>"; }; - A2672AB4665EB890F1F2E052DC068B0D /* GULNetwork.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetwork.h; path = GoogleUtilities/Network/Private/GULNetwork.h; sourceTree = "<group>"; }; - A36649E2942CA43CF746CB8BB3356A9D /* FIRInstanceIDAuthService.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDAuthService.m; path = Firebase/InstanceID/FIRInstanceIDAuthService.m; sourceTree = "<group>"; }; - A3EAF3AA8E5BADD73BCE0D2B8CC69B98 /* GULAppDelegateSwizzler_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULAppDelegateSwizzler_Private.h; path = GoogleUtilities/AppDelegateSwizzler/Internal/GULAppDelegateSwizzler_Private.h; sourceTree = "<group>"; }; - A40C263DBAD4C39D2E09F730467D5085 /* Pods-TeachersAssistantTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TeachersAssistantTests.debug.xcconfig"; sourceTree = "<group>"; }; - A61A5FBB4C4917E85820D47EA05A7A31 /* Pods-TeachersAssistant.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TeachersAssistant.release.xcconfig"; sourceTree = "<group>"; }; - A62C33CAAD941D27993CFB927857A476 /* FIRAppAssociationRegistration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAppAssociationRegistration.h; path = Firebase/Core/Private/FIRAppAssociationRegistration.h; sourceTree = "<group>"; }; - A6EFE17E8C1D2435651AA1CF3C3314CB /* FIRInstanceIDCheckinPreferences+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FIRInstanceIDCheckinPreferences+Internal.h"; path = "Firebase/InstanceID/FIRInstanceIDCheckinPreferences+Internal.h"; sourceTree = "<group>"; }; - A737C343B6C79B154315978701F29A04 /* FIRInstanceIDLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDLogger.m; path = Firebase/InstanceID/FIRInstanceIDLogger.m; sourceTree = "<group>"; }; - A8CEB8453EFC3EBB8CC7F816596220DD /* GULNetworkURLSession.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkURLSession.h; path = GoogleUtilities/Network/Private/GULNetworkURLSession.h; sourceTree = "<group>"; }; - AD26A272AD866767EC8863C068DAC7A9 /* FirebaseInstanceID-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "FirebaseInstanceID-Info.plist"; sourceTree = "<group>"; }; - AD9455B83D23BDB4915ED6A130D1C8C4 /* GTMSessionUploadFetcher.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTMSessionUploadFetcher.m; path = Source/GTMSessionUploadFetcher.m; sourceTree = "<group>"; }; - ADB38B25ABA9170879CD55B53412DFE6 /* GTLRBatchResult.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTLRBatchResult.h; path = Source/Objects/GTLRBatchResult.h; sourceTree = "<group>"; }; - ADDFACA311CA984C4ED942D7153C7BBC /* GoogleAppMeasurement.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GoogleAppMeasurement.framework; path = Frameworks/GoogleAppMeasurement.framework; sourceTree = "<group>"; }; - ADF1B1D4D72635AB6E8D3C36D8D89A6C /* nanopb.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = nanopb.xcconfig; sourceTree = "<group>"; }; - B17C169B2ADA959DE38DAE86D07B7379 /* GTLRSheetsObjects.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTLRSheetsObjects.m; path = Source/GeneratedServices/Sheets/GTLRSheetsObjects.m; sourceTree = "<group>"; }; - B240966BF419D8B916096F61465022D1 /* GoogleAPIClientForREST.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = GoogleAPIClientForREST.modulemap; sourceTree = "<group>"; }; - B2CE9C8D3C9509E03742DAAC7D484973 /* FIRInstanceIDCheckinPreferences.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDCheckinPreferences.m; path = Firebase/InstanceID/FIRInstanceIDCheckinPreferences.m; sourceTree = "<group>"; }; - B50337BA0606A576144D70B0E05ED8C1 /* Pods-TeachersAssistant-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-TeachersAssistant-Info.plist"; sourceTree = "<group>"; }; - B5047997309AE128643CDACF85D5C260 /* GTLRUploadParameters.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTLRUploadParameters.h; path = Source/Objects/GTLRUploadParameters.h; sourceTree = "<group>"; }; - B5F6A2DBC7DB5FAD70AD67EE2F401420 /* FIRInstanceIDURLQueryItem.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDURLQueryItem.h; path = Firebase/InstanceID/FIRInstanceIDURLQueryItem.h; sourceTree = "<group>"; }; - B6FBF86619741BAE53E3D255FBF0ABB1 /* FIRAppAssociationRegistration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRAppAssociationRegistration.m; path = Firebase/Core/FIRAppAssociationRegistration.m; sourceTree = "<group>"; }; - B999E5AD02D47AC06D46363EEC291140 /* GTLRUtilities.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTLRUtilities.h; path = Source/Utilities/GTLRUtilities.h; sourceTree = "<group>"; }; - B9EDA8960D68B07F4E048AFDDA68BCA0 /* GTLRService.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTLRService.m; path = Source/Objects/GTLRService.m; sourceTree = "<group>"; }; - BA38906194CC3F29E0F1F97D1A889161 /* GTLRSheetsObjects.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTLRSheetsObjects.h; path = Source/GeneratedServices/Sheets/GTLRSheetsObjects.h; sourceTree = "<group>"; }; - BDCD3812853BA5FE12388D33066B3CCA /* GTMSessionFetcher-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "GTMSessionFetcher-Info.plist"; sourceTree = "<group>"; }; - BF158F186A2E83AA478BC8C6ECB96907 /* GoogleUtilities-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "GoogleUtilities-dummy.m"; sourceTree = "<group>"; }; - C1DBB860A02D6C05F0481A5858569152 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; - C2BF9601E45E61A49D75F7726674EC21 /* GoogleUtilities.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = GoogleUtilities.modulemap; sourceTree = "<group>"; }; - C509EB270A3FE03A71169745013D5768 /* FIRInstanceIDCheckinService.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDCheckinService.h; path = Firebase/InstanceID/FIRInstanceIDCheckinService.h; sourceTree = "<group>"; }; - C5F3BE46AB8368379E1DDE8F51A4978E /* FirebaseCore.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = FirebaseCore.modulemap; sourceTree = "<group>"; }; - C635ED3519BFC49EB2C63A4252200FF2 /* GTLRSheetsQuery.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTLRSheetsQuery.h; path = Source/GeneratedServices/Sheets/GTLRSheetsQuery.h; sourceTree = "<group>"; }; - C6652582DEF2924B8E1639B2B90F9553 /* nanopb-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "nanopb-Info.plist"; sourceTree = "<group>"; }; - C6BA66AB7BE9C1B35D1FEEA4378F5D1C /* GoogleAPIClientForREST.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleAPIClientForREST.xcconfig; sourceTree = "<group>"; }; - C7227F8FF64B2A4BD2394FA8B9EB659B /* FirebaseCore-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "FirebaseCore-Info.plist"; sourceTree = "<group>"; }; - C99E6C3748A149B14ABA4CF063DD4F52 /* FIRBundleUtil.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRBundleUtil.m; path = Firebase/Core/FIRBundleUtil.m; sourceTree = "<group>"; }; - C9B714FB115F77DF3A9116B5D1D89C31 /* GTLRRuntimeCommon.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTLRRuntimeCommon.m; path = Source/Objects/GTLRRuntimeCommon.m; sourceTree = "<group>"; }; - C9D528AA2118222E51B39583783D3824 /* Firebase.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Firebase.h; path = CoreOnly/Sources/Firebase.h; sourceTree = "<group>"; }; - CC33E734D1611BA6A191D8246CEFF204 /* pb_decode.c */ = {isa = PBXFileReference; includeInIndex = 1; path = pb_decode.c; sourceTree = "<group>"; }; - CD7867B1787870FFF4445F7C463304EC /* GULLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULLogger.h; path = GoogleUtilities/Logger/Private/GULLogger.h; sourceTree = "<group>"; }; - CDE4C3785A6E9E16C5DD045A8C3B62CA /* GTMSessionFetcher.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = GTMSessionFetcher.modulemap; sourceTree = "<group>"; }; - CDECB42CD69FE8C441A88EB09E5E41B1 /* FIRInstanceID+Testing.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FIRInstanceID+Testing.h"; path = "Firebase/InstanceID/FIRInstanceID+Testing.h"; sourceTree = "<group>"; }; - CF8C86C20862941343D914D49B5DE74C /* GTMSessionFetcherService.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTMSessionFetcherService.h; path = Source/GTMSessionFetcherService.h; sourceTree = "<group>"; }; - CFF309BE82E37F7CBFD6B6D48621D286 /* FIRInstanceIDTokenFetchOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDTokenFetchOperation.h; path = Firebase/InstanceID/FIRInstanceIDTokenFetchOperation.h; sourceTree = "<group>"; }; - D0990D319BA2234548E2873FFC0A8BEE /* FirebaseInstanceID.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = FirebaseInstanceID.modulemap; sourceTree = "<group>"; }; - D2C38B5767FC35488427CDB72E1252BE /* Pods-TeachersAssistant-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-TeachersAssistant-acknowledgements.plist"; sourceTree = "<group>"; }; - D3389939168D7E16A07E06299C2D2CC6 /* FIRInstanceIDStringEncoding.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDStringEncoding.m; path = Firebase/InstanceID/FIRInstanceIDStringEncoding.m; sourceTree = "<group>"; }; - D9107B74D49E38BCF7B3F2ED77E71F21 /* FIRInstanceIDCheckinPreferences_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDCheckinPreferences_Private.h; path = Firebase/InstanceID/FIRInstanceIDCheckinPreferences_Private.h; sourceTree = "<group>"; }; - D96D27B23ED456F3F91185B0591AA335 /* FIRInstanceIDTokenInfo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDTokenInfo.h; path = Firebase/InstanceID/FIRInstanceIDTokenInfo.h; sourceTree = "<group>"; }; - D9A4276C20DF4C737ECB8CD0541D1A67 /* GTLRObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTLRObject.h; path = Source/Objects/GTLRObject.h; sourceTree = "<group>"; }; - D9BB6D0D6107EB6AA9292CBA994F58BD /* FIRInstanceIDTokenDeleteOperation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDTokenDeleteOperation.h; path = Firebase/InstanceID/FIRInstanceIDTokenDeleteOperation.h; sourceTree = "<group>"; }; - DA86BE4F12D473D435458BB4FB158BCD /* FIROptions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIROptions.m; path = Firebase/Core/FIROptions.m; sourceTree = "<group>"; }; - DB136240D29989E1D1B5EDBB26789605 /* GoogleUtilities.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = GoogleUtilities.framework; path = GoogleUtilities.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - DB676188CF095CD4CF367F5EBC478EA7 /* FIRInstanceIDCheckinPreferences+Internal.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FIRInstanceIDCheckinPreferences+Internal.m"; path = "Firebase/InstanceID/FIRInstanceIDCheckinPreferences+Internal.m"; sourceTree = "<group>"; }; - DCEE515F01DF166DBC634C843933F6B9 /* GTLRURITemplate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTLRURITemplate.h; path = Source/Utilities/GTLRURITemplate.h; sourceTree = "<group>"; }; - DD8C5B5B378C757D7F3D05B7BBF50F99 /* GULNetwork.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULNetwork.m; path = GoogleUtilities/Network/GULNetwork.m; sourceTree = "<group>"; }; - DEFA1AB5522EACA4F67A002CF883955E /* GTLRObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTLRObject.m; path = Source/Objects/GTLRObject.m; sourceTree = "<group>"; }; - DF5BFCC018CAF9606683F89394C3B25B /* FIRInstanceIDCheckinStore.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDCheckinStore.m; path = Firebase/InstanceID/FIRInstanceIDCheckinStore.m; sourceTree = "<group>"; }; - DFE9A713C35D87D3276D66BDED99B818 /* FIRInstanceIDUtilities.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDUtilities.m; path = Firebase/InstanceID/FIRInstanceIDUtilities.m; sourceTree = "<group>"; }; - E141DD28AFD58761041D850CDAE0C508 /* GULSwizzler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULSwizzler.m; path = GoogleUtilities/MethodSwizzler/GULSwizzler.m; sourceTree = "<group>"; }; - E150DF4221857596EE237D4604C64D39 /* FIRBundleUtil.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRBundleUtil.h; path = Firebase/Core/Private/FIRBundleUtil.h; sourceTree = "<group>"; }; - E296AF2AA89291E5567866849C26499D /* GTLRDuration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTLRDuration.m; path = Source/Objects/GTLRDuration.m; sourceTree = "<group>"; }; - E62986E64C2AD9319C9BE39EFAD551E2 /* FIRInstanceID+Private.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FIRInstanceID+Private.m"; path = "Firebase/InstanceID/FIRInstanceID+Private.m"; sourceTree = "<group>"; }; - E63ABD34201B77F662B8D9B9DA44CDC6 /* pb_common.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = pb_common.h; sourceTree = "<group>"; }; - E83DAD359A051E38E0DCAAC7824D73BE /* FIRInstanceIDVersionUtilities.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDVersionUtilities.m; path = Firebase/InstanceID/FIRInstanceIDVersionUtilities.m; sourceTree = "<group>"; }; - E8ABC734EC5D76410142B606FB284CB9 /* FirebaseAnalytics.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseAnalytics.xcconfig; sourceTree = "<group>"; }; - E9E92D24EC1A5967CA10893102360920 /* FIRInstanceIDKeyPair.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceIDKeyPair.h; path = Firebase/InstanceID/FIRInstanceIDKeyPair.h; sourceTree = "<group>"; }; - ED28B4447BE06C582F74CF53046DEFA2 /* GTLRBatchResult.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTLRBatchResult.m; path = Source/Objects/GTLRBatchResult.m; sourceTree = "<group>"; }; - ED74DCD72556A6C8618B511D2910AB18 /* FIRAnalyticsConfiguration+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FIRAnalyticsConfiguration+Internal.h"; path = "Firebase/Core/Private/FIRAnalyticsConfiguration+Internal.h"; sourceTree = "<group>"; }; - EEF2A1FD563D62873F1FE536E3F72F91 /* GTLRSheetsService.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTLRSheetsService.h; path = Source/GeneratedServices/Sheets/GTLRSheetsService.h; sourceTree = "<group>"; }; - F000C09E14723D2EBBD391E19D9D5FBF /* GTMSessionFetcher-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "GTMSessionFetcher-umbrella.h"; sourceTree = "<group>"; }; - F047222C8056B6A3AD7E289C9EE21D28 /* FIRAnalyticsConfiguration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAnalyticsConfiguration.h; path = Firebase/Core/Public/FIRAnalyticsConfiguration.h; sourceTree = "<group>"; }; - F0D1F45EB0BE7940F2B0A3B152F0BAF0 /* GULNSData+zlib.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "GULNSData+zlib.h"; path = "GoogleUtilities/NSData+zlib/GULNSData+zlib.h"; sourceTree = "<group>"; }; - F171712428FC85037E9F00703B7F2E22 /* GULAppDelegateSwizzler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULAppDelegateSwizzler.h; path = GoogleUtilities/AppDelegateSwizzler/Private/GULAppDelegateSwizzler.h; sourceTree = "<group>"; }; - F22DC88B182B57DE12E328AAEF3F023C /* GTLRDateTime.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTLRDateTime.m; path = Source/Objects/GTLRDateTime.m; sourceTree = "<group>"; }; - F38AE2C8EE17A7657996595BFC9ABE11 /* FIRInstanceIDTokenManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstanceIDTokenManager.m; path = Firebase/InstanceID/FIRInstanceIDTokenManager.m; sourceTree = "<group>"; }; - F529CA2B381C222BE9ECC27FA5F94111 /* Pods-TeachersAssistant-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-TeachersAssistant-frameworks.sh"; sourceTree = "<group>"; }; - F5CF16EA7D24BA0445B470F3104A38C2 /* GULUserDefaults.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULUserDefaults.h; path = GoogleUtilities/UserDefaults/Private/GULUserDefaults.h; sourceTree = "<group>"; }; - F6D4CCD7AF5F1B7C6D6D88509BAB7785 /* GTLRErrorObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GTLRErrorObject.h; path = Source/Objects/GTLRErrorObject.h; sourceTree = "<group>"; }; - FA3D37CB0B564BC0A5895A015279D8F4 /* GTMSessionFetcher-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "GTMSessionFetcher-prefix.pch"; sourceTree = "<group>"; }; - FB0DA168C2F41D42C624551BC2C23F9D /* FIRErrors.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRErrors.m; path = Firebase/Core/FIRErrors.m; sourceTree = "<group>"; }; - FB866184F9DB8C552543637E0980B4FA /* NSError+FIRInstanceID.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSError+FIRInstanceID.m"; path = "Firebase/InstanceID/NSError+FIRInstanceID.m"; sourceTree = "<group>"; }; - FBA87A61F13A66578C76CA164240E08E /* GTMSessionFetcher.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = GTMSessionFetcher.framework; path = GTMSessionFetcher.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - FCC79991521336223B763662128BB7A3 /* GTMGatherInputStream.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GTMGatherInputStream.m; path = Source/GTMGatherInputStream.m; sourceTree = "<group>"; }; - FE024B7689A72CA8CC54C9B407F9507C /* Pods-TeachersAssistantTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TeachersAssistantTests.release.xcconfig"; sourceTree = "<group>"; }; + A0AA143A60A8CCFF6198114B99E582AD /* Pods-TeachersAssistant.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-TeachersAssistant.modulemap"; sourceTree = "<group>"; }; + A484B3C6B804C2A2725BB106CCA79CD2 /* Pods-TeachersAssistant-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-TeachersAssistant-Info.plist"; sourceTree = "<group>"; }; + B69955D80F9E5A6D8CD476BCD08F9999 /* Pods-TeachersAssistant.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TeachersAssistant.debug.xcconfig"; sourceTree = "<group>"; }; + CB4607EFCA7C5F75397649E792E2AFCB /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + ECFFEA04571CCE4256E9CF44018F34FD /* Pods-TeachersAssistantTests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-TeachersAssistantTests-umbrella.h"; sourceTree = "<group>"; }; + F03A69F5842E504313F19AD16F34A1C2 /* Pods_TeachersAssistant.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_TeachersAssistant.framework; path = "Pods-TeachersAssistant.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 18E8B46930253C826FB953C9E92F96CF /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 319C57F799237E5E10948965A2A94843 /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 285219F57C35AF74521FE10278556E39 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 50D319FF764331FCABB481C1A7D835E5 /* Foundation.framework in Frameworks */, - 05927EA99CFB71B69E8B3851D143526B /* Security.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 2AB82CCC1FE772DB4095EA633511AF3C /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 531D80A0B9967E698C050D4621953516 /* Foundation.framework in Frameworks */, - D09DE4F8CF9819C7BB99A345BBA78339 /* Security.framework in Frameworks */, - C89BB6836DEA8F2EE0B9199A7A78CDDC /* SystemConfiguration.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 42AFFA9AC72D8A2FF83C883E890B5F2A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -717,762 +57,101 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 5D2361E98237FB7C772C750B91DB5F05 /* Frameworks */ = { + 58C4F2D938F2E1891871766DEA5000E2 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 9043BA2AD19DEE4622D0572578355D84 /* Foundation.framework in Frameworks */, - F03936351B8D3C6B5E7D5E58703FF5BE /* GTMSessionFetcher.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A38A6054F26C426AE2C0C0EDAD0008FC /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 2C992FD410CB75581BF435EA7A66C903 /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - BD6C01A9D3F5BF4D6F5F4588AD3A7E32 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 5803D830BEAB4B1992945388A716537D /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D5CE9E2102E465709E5822E849D79D5A /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - AA969B6FE2ED5EE3ACE1C2AC005701C0 /* Foundation.framework in Frameworks */, + 80BEC0BE835BADF40A2CF22C4836BD3F /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 000568507EFC75DAD4832327C87A771A /* Network */ = { - isa = PBXGroup; - children = ( - 83537337655F0E50082CD7E2603EFCCA /* GULMutableDictionary.h */, - 1201678D8F7875046192E6EF9294A1C4 /* GULMutableDictionary.m */, - A2672AB4665EB890F1F2E052DC068B0D /* GULNetwork.h */, - DD8C5B5B378C757D7F3D05B7BBF50F99 /* GULNetwork.m */, - 2060C1F4AD9CA43E0B2EA2B28F55A284 /* GULNetworkConstants.h */, - 74F65B52CC04DEB89684D01BB66C6E41 /* GULNetworkConstants.m */, - 00061B4668B2781E6A386D5E815509C2 /* GULNetworkLoggerProtocol.h */, - 6F130B340A708E32CAEA83F0B6619B08 /* GULNetworkMessageCode.h */, - A8CEB8453EFC3EBB8CC7F816596220DD /* GULNetworkURLSession.h */, - 6924954BD2F30993FB8230C4F0B6A5F5 /* GULNetworkURLSession.m */, - ); - name = Network; - sourceTree = "<group>"; - }; - 0FBF9B71E9B8C5E178D8C2E26CE101D7 /* Pods-TeachersAssistantTests */ = { - isa = PBXGroup; - children = ( - 44581CF76B50941A6B5755E48A3F0B73 /* Pods-TeachersAssistantTests.modulemap */, - 35039373C75F0CAA94D50D97AF90BF12 /* Pods-TeachersAssistantTests-acknowledgements.markdown */, - 123565447F11349B461EAA44530EFD01 /* Pods-TeachersAssistantTests-acknowledgements.plist */, - 176E21E234D1EF72C0869C40836ECBCC /* Pods-TeachersAssistantTests-dummy.m */, - 6CBEAF0154F92F0CD942C90DCF6C7A1B /* Pods-TeachersAssistantTests-Info.plist */, - 029A66B7819D4FD2C4DD1328C5488419 /* Pods-TeachersAssistantTests-umbrella.h */, - A40C263DBAD4C39D2E09F730467D5085 /* Pods-TeachersAssistantTests.debug.xcconfig */, - FE024B7689A72CA8CC54C9B407F9507C /* Pods-TeachersAssistantTests.release.xcconfig */, - ); - name = "Pods-TeachersAssistantTests"; - path = "Target Support Files/Pods-TeachersAssistantTests"; - sourceTree = "<group>"; - }; - 13A669684406EF1322D659F985E365A0 /* Core */ = { - isa = PBXGroup; - children = ( - 504D2264E8585EE42A61DCE121FA7334 /* GTMSessionFetcher.h */, - 2CB4C2370A78826FB61E74033B2F9BFF /* GTMSessionFetcher.m */, - 8A9E981E17F06280BA9E8358D8FB90FD /* GTMSessionFetcherLogging.h */, - 0CA616F95FA0F7EB03F1582C09FCD657 /* GTMSessionFetcherLogging.m */, - CF8C86C20862941343D914D49B5DE74C /* GTMSessionFetcherService.h */, - 4BBAFAC2A9A529CD28ED16BCF13AECE4 /* GTMSessionFetcherService.m */, - 4E8A41DFF31FE019B30BF0B9770BE14D /* GTMSessionUploadFetcher.h */, - AD9455B83D23BDB4915ED6A130D1C8C4 /* GTMSessionUploadFetcher.m */, - ); - name = Core; - sourceTree = "<group>"; - }; - 15F0477509C7A66A4AFAE7FA7D44C0A7 /* GoogleAPIClientForREST */ = { - isa = PBXGroup; - children = ( - 6B25E6E6E4201A40D6523F4B4571E521 /* Core */, - 5872FBE37612B627A52D1E22A5570CB8 /* Sheets */, - 5D3D996D16C2D106DEE193F4FD2DD770 /* Support Files */, - ); - name = GoogleAPIClientForREST; - path = GoogleAPIClientForREST; - sourceTree = "<group>"; - }; - 190E7D8635BB80C952FB81757F406863 /* AppDelegateSwizzler */ = { - isa = PBXGroup; - children = ( - F171712428FC85037E9F00703B7F2E22 /* GULAppDelegateSwizzler.h */, - 64A59B0655E40448F960D448BFE2B4D4 /* GULAppDelegateSwizzler.m */, - A3EAF3AA8E5BADD73BCE0D2B8CC69B98 /* GULAppDelegateSwizzler_Private.h */, - 33E015D9CF73817DBAE5EE02250E5DED /* GULLoggerCodes.h */, - ); - name = AppDelegateSwizzler; - sourceTree = "<group>"; - }; - 222412E8F246FDD561624EAC1D1D0C97 /* Support Files */ = { - isa = PBXGroup; - children = ( - 8416808131C45D6E3E6BC32C40C76A82 /* GoogleAppMeasurement.xcconfig */, - ); - name = "Support Files"; - path = "../Target Support Files/GoogleAppMeasurement"; - sourceTree = "<group>"; - }; - 3422C3C5D7F3C159B31E27335E13173F /* Support Files */ = { - isa = PBXGroup; - children = ( - 4DF7D23FF6ED5F29179DAA124D6139E0 /* nanopb.modulemap */, - ADF1B1D4D72635AB6E8D3C36D8D89A6C /* nanopb.xcconfig */, - 41F647164C5CA7901E4BFE7741255A55 /* nanopb-dummy.m */, - C6652582DEF2924B8E1639B2B90F9553 /* nanopb-Info.plist */, - 2554DC9B3976244F8B3433B862DD019F /* nanopb-prefix.pch */, - 9C00A42C8667CADDFB41282D26A16227 /* nanopb-umbrella.h */, - ); - name = "Support Files"; - path = "../Target Support Files/nanopb"; - sourceTree = "<group>"; - }; - 3F6820844C317A9C2761C9E80E7D3293 /* Logger */ = { - isa = PBXGroup; - children = ( - CD7867B1787870FFF4445F7C463304EC /* GULLogger.h */, - 21E1BF177C744299F7CB68726168AE6D /* GULLogger.m */, - 58AC66E22BF3126CF2AB5A768FAABD0F /* GULLoggerLevel.h */, - ); - name = Logger; - sourceTree = "<group>"; - }; - 46D66038EF3F974B1F79DCC4014906E2 /* UserDefaults */ = { - isa = PBXGroup; - children = ( - F5CF16EA7D24BA0445B470F3104A38C2 /* GULUserDefaults.h */, - 0AEFDB9DD19C098BAA39381962D72398 /* GULUserDefaults.m */, - ); - name = UserDefaults; - sourceTree = "<group>"; - }; - 48ADD341D1F72077B9B0D59546FC49FE /* MethodSwizzler */ = { - isa = PBXGroup; - children = ( - 2B6E82FA3B095C371861788955184AAA /* GULOriginalIMPConvenienceMacros.h */, - 0B5032812C848FA7747EE94B157813B2 /* GULSwizzler.h */, - E141DD28AFD58761041D850CDAE0C508 /* GULSwizzler.m */, - ); - name = MethodSwizzler; - sourceTree = "<group>"; - }; - 50EE0F54CBEA07DF918CEAA8C4E49506 /* Support Files */ = { - isa = PBXGroup; - children = ( - CDE4C3785A6E9E16C5DD045A8C3B62CA /* GTMSessionFetcher.modulemap */, - 0A22E7D0390892ECB350FFF998A271D0 /* GTMSessionFetcher.xcconfig */, - 09CF74BB4F08D9BA981B0FCB07128326 /* GTMSessionFetcher-dummy.m */, - BDCD3812853BA5FE12388D33066B3CCA /* GTMSessionFetcher-Info.plist */, - FA3D37CB0B564BC0A5895A015279D8F4 /* GTMSessionFetcher-prefix.pch */, - F000C09E14723D2EBBD391E19D9D5FBF /* GTMSessionFetcher-umbrella.h */, - ); - name = "Support Files"; - path = "../Target Support Files/GTMSessionFetcher"; - sourceTree = "<group>"; - }; - 5872FBE37612B627A52D1E22A5570CB8 /* Sheets */ = { - isa = PBXGroup; - children = ( - 0E9773C37D034C604399ABF8364696FC /* GTLRSheets.h */, - BA38906194CC3F29E0F1F97D1A889161 /* GTLRSheetsObjects.h */, - B17C169B2ADA959DE38DAE86D07B7379 /* GTLRSheetsObjects.m */, - C635ED3519BFC49EB2C63A4252200FF2 /* GTLRSheetsQuery.h */, - 20CB19971EEB7403662B8D6D969AAA1B /* GTLRSheetsQuery.m */, - EEF2A1FD563D62873F1FE536E3F72F91 /* GTLRSheetsService.h */, - 1DEDD6F11A6592A96F72E6E90EC1FD73 /* GTLRSheetsService.m */, - ); - name = Sheets; - sourceTree = "<group>"; - }; - 5D3D996D16C2D106DEE193F4FD2DD770 /* Support Files */ = { - isa = PBXGroup; - children = ( - B240966BF419D8B916096F61465022D1 /* GoogleAPIClientForREST.modulemap */, - C6BA66AB7BE9C1B35D1FEEA4378F5D1C /* GoogleAPIClientForREST.xcconfig */, - 359D1387EF23CF339959AB5D298D182D /* GoogleAPIClientForREST-dummy.m */, - 7ECD67C851A9B1AAF8CB0A1D65A67194 /* GoogleAPIClientForREST-Info.plist */, - 385F92547477A014104A69ADC304BCAD /* GoogleAPIClientForREST-prefix.pch */, - 8AB3ECC077B85578CA86B1AB55A7B12D /* GoogleAPIClientForREST-umbrella.h */, - ); - name = "Support Files"; - path = "../Target Support Files/GoogleAPIClientForREST"; - sourceTree = "<group>"; - }; - 5DFB3D0FCDA8985A1D96E5FDC266EAE2 /* iOS */ = { - isa = PBXGroup; - children = ( - C1DBB860A02D6C05F0481A5858569152 /* Foundation.framework */, - 4D669732E0BA0105016B0BFAF2C9EEE1 /* Security.framework */, - 0F0A5A680330D1BBE6109D7E21EEBA20 /* SystemConfiguration.framework */, - ); - name = iOS; - sourceTree = "<group>"; - }; - 61034BDB34982019CEDBE9751923C987 /* GoogleAppMeasurement */ = { - isa = PBXGroup; - children = ( - FB89EE033F8E78976FB7923B48CEB037 /* Frameworks */, - 222412E8F246FDD561624EAC1D1D0C97 /* Support Files */, - ); - name = GoogleAppMeasurement; - path = GoogleAppMeasurement; - sourceTree = "<group>"; - }; - 6B25E6E6E4201A40D6523F4B4571E521 /* Core */ = { + 55C4487E06B8A644EBB77910FD464E2D /* Pods-TeachersAssistant */ = { isa = PBXGroup; children = ( - 632CEDCB8B1B6CADF8FA17EE175367B8 /* GTLRBase64.h */, - A12B17E00FB8FCB54E94D10975B5302C /* GTLRBase64.m */, - 74EF9C835171D35F298E15ACA4B38506 /* GTLRBatchQuery.h */, - 73DEB6CDF7421F78C01F7474A67404F3 /* GTLRBatchQuery.m */, - ADB38B25ABA9170879CD55B53412DFE6 /* GTLRBatchResult.h */, - ED28B4447BE06C582F74CF53046DEFA2 /* GTLRBatchResult.m */, - 0810102125B8C9E4FBBF7EF7D58409CC /* GTLRDateTime.h */, - F22DC88B182B57DE12E328AAEF3F023C /* GTLRDateTime.m */, - 56CE98F133AB2BA1382EB2FAB97B0AF8 /* GTLRDefines.h */, - 2CA56DE4B76F14F33BDA8853272D8366 /* GTLRDuration.h */, - E296AF2AA89291E5567866849C26499D /* GTLRDuration.m */, - F6D4CCD7AF5F1B7C6D6D88509BAB7785 /* GTLRErrorObject.h */, - 4673860D113355AAD052F21D1D4399F7 /* GTLRErrorObject.m */, - 217305076F6C446D80ECEE650D6FF336 /* GTLRFramework.h */, - 9F12DC4DF7E7F8A371738879B374FFF5 /* GTLRFramework.m */, - D9A4276C20DF4C737ECB8CD0541D1A67 /* GTLRObject.h */, - DEFA1AB5522EACA4F67A002CF883955E /* GTLRObject.m */, - 91FD3DD45495B59CF1AD18C2F1C5664A /* GTLRQuery.h */, - 54F922D095E5B9A857BABDE9A29D2EA7 /* GTLRQuery.m */, - 7AF84FD306398BAAB32D5EB452C1E569 /* GTLRRuntimeCommon.h */, - C9B714FB115F77DF3A9116B5D1D89C31 /* GTLRRuntimeCommon.m */, - 2F3C1179BBE0B2F619AB8D842242DF54 /* GTLRService.h */, - B9EDA8960D68B07F4E048AFDDA68BCA0 /* GTLRService.m */, - B5047997309AE128643CDACF85D5C260 /* GTLRUploadParameters.h */, - 6004EF0F526D87CB1DB9CE9FE43FBE40 /* GTLRUploadParameters.m */, - DCEE515F01DF166DBC634C843933F6B9 /* GTLRURITemplate.h */, - 4B6FFA90600425E042D0DB9FE2BCF44F /* GTLRURITemplate.m */, - B999E5AD02D47AC06D46363EEC291140 /* GTLRUtilities.h */, - 5E92A8BA31159E11D52BAF17FD3D11F2 /* GTLRUtilities.m */, - ); - name = Core; - sourceTree = "<group>"; - }; - 6B9A9C6008E62201B938BD6DF406BD76 /* Reachability */ = { - isa = PBXGroup; - children = ( - 7CCAEF0B1870F052EDE7D124EE35E5F2 /* GULReachabilityChecker.h */, - 5422968193C250477308AB011920863A /* GULReachabilityChecker.m */, - 9E00DA041CCC31B6AEC875C52444A935 /* GULReachabilityChecker+Internal.h */, - 7DA698D652FCFAC16C9EEFCA83C85E72 /* GULReachabilityMessageCode.h */, - ); - name = Reachability; - sourceTree = "<group>"; - }; - 6D6F748954782717B496DFBC7AD91379 /* nanopb */ = { - isa = PBXGroup; - children = ( - 26B79195C4C8B553F57B3D3535D34328 /* pb.h */, - 3CAC70B7C1A8906857FA3FC99C1BD4EC /* pb_common.c */, - E63ABD34201B77F662B8D9B9DA44CDC6 /* pb_common.h */, - CC33E734D1611BA6A191D8246CEFF204 /* pb_decode.c */, - 734E5DCCCE857FFA34745EB5C2D6C5EA /* pb_decode.h */, - 6C217B0FC3899164615FD61D788E7FBA /* pb_encode.c */, - 2F783D0C9291771FE7CD74A47090BDE4 /* pb_encode.h */, - BB34A8F19260533021E56F35106A3D9E /* decode */, - ED948ECEDEC70E540465331CF6AD793B /* encode */, - 3422C3C5D7F3C159B31E27335E13173F /* Support Files */, - ); - name = nanopb; - path = nanopb; - sourceTree = "<group>"; - }; - 853EC0BD12F56AA7C7F2C10C782D1A2A /* Support Files */ = { - isa = PBXGroup; - children = ( - C5F3BE46AB8368379E1DDE8F51A4978E /* FirebaseCore.modulemap */, - 66B1B5E0F02389648F7D7F08EE92449E /* FirebaseCore.xcconfig */, - 312A54AECBD7450DEF1199ACE70B112A /* FirebaseCore-dummy.m */, - C7227F8FF64B2A4BD2394FA8B9EB659B /* FirebaseCore-Info.plist */, - 7110D63F53E9A413E26235ED20E973C9 /* FirebaseCore-umbrella.h */, - ); - name = "Support Files"; - path = "../Target Support Files/FirebaseCore"; - sourceTree = "<group>"; - }; - 85BDCBE8335926A5DB41B3C841A3C263 /* Pods */ = { - isa = PBXGroup; - children = ( - E51C279489632B4AE3A37D169F20A5FE /* Firebase */, - 8AC2F05606201D445330DBBA99B8FCE8 /* FirebaseAnalytics */, - AD1B20E72047E995DA3A5BB3EB0B4B38 /* FirebaseCore */, - D5C309574E054758426FF93D19E5CA99 /* FirebaseInstanceID */, - 15F0477509C7A66A4AFAE7FA7D44C0A7 /* GoogleAPIClientForREST */, - 61034BDB34982019CEDBE9751923C987 /* GoogleAppMeasurement */, - C120AAFD9B8F9040B8CB01A9F341ADCC /* GoogleUtilities */, - D8E1E1B643379135870A88FE866DF9BE /* GTMSessionFetcher */, - 6D6F748954782717B496DFBC7AD91379 /* nanopb */, - ); - name = Pods; - sourceTree = "<group>"; - }; - 8AC2F05606201D445330DBBA99B8FCE8 /* FirebaseAnalytics */ = { - isa = PBXGroup; - children = ( - C72D17D0EE04F174CCC70EF0C4FACA9C /* Frameworks */, - 9DEB7A68F141922B221C5088B5293CEB /* Support Files */, - ); - name = FirebaseAnalytics; - path = FirebaseAnalytics; - sourceTree = "<group>"; - }; - 95D80BD57F09D32EBA1416C100D6161A /* Support Files */ = { - isa = PBXGroup; - children = ( - 069518B8B1116A7286048E10777CE4B1 /* Firebase.xcconfig */, - ); - name = "Support Files"; - path = "../Target Support Files/Firebase"; - sourceTree = "<group>"; - }; - 9DEB7A68F141922B221C5088B5293CEB /* Support Files */ = { - isa = PBXGroup; - children = ( - E8ABC734EC5D76410142B606FB284CB9 /* FirebaseAnalytics.xcconfig */, - ); - name = "Support Files"; - path = "../Target Support Files/FirebaseAnalytics"; - sourceTree = "<group>"; - }; - AD1B20E72047E995DA3A5BB3EB0B4B38 /* FirebaseCore */ = { - isa = PBXGroup; - children = ( - F047222C8056B6A3AD7E289C9EE21D28 /* FIRAnalyticsConfiguration.h */, - 5D74E330C10A59ECB0E3A651183B5902 /* FIRAnalyticsConfiguration.m */, - ED74DCD72556A6C8618B511D2910AB18 /* FIRAnalyticsConfiguration+Internal.h */, - 4AAFBE6129D7F7EE3751814049C55310 /* FIRApp.h */, - 271F6CEBA30B3B7191840DEDD47F81FC /* FIRApp.m */, - A62C33CAAD941D27993CFB927857A476 /* FIRAppAssociationRegistration.h */, - B6FBF86619741BAE53E3D255FBF0ABB1 /* FIRAppAssociationRegistration.m */, - 042BE6629EC9A2E9F87D17CED7AACB6A /* FIRAppInternal.h */, - E150DF4221857596EE237D4604C64D39 /* FIRBundleUtil.h */, - C99E6C3748A149B14ABA4CF063DD4F52 /* FIRBundleUtil.m */, - 499E59FADC4F9A4FD57637B40A7E0AEB /* FIRComponent.h */, - 8AC4E56443368A59F770E05990328FBB /* FIRComponent.m */, - 8AF638AC9C581DA7EAF1350F43C6E347 /* FIRComponentContainer.h */, - 4E3ADB623A71EF1040F07F4474B13C1F /* FIRComponentContainer.m */, - 72A68E1354B8F68044AB4DD21E274D55 /* FIRComponentContainerInternal.h */, - 26B7B16A2741E588921CA76370A6E0C6 /* FIRComponentType.h */, - 7CC67CCBC2D46F79CC57C3F798122C7E /* FIRComponentType.m */, - 07C940E5390B103F4CE2892BFFBC987A /* FIRConfiguration.h */, - 82BB2879569D536A6530B687161DC8B1 /* FIRConfiguration.m */, - 2702574391D7BC669EE01BBCB336A64C /* FIRDependency.h */, - 0508F9F459470F87AE900EE671A33683 /* FIRDependency.m */, - 5AA8AEFC53E239B1C44121C6399BDF14 /* FirebaseCore.h */, - 637245938FD074F3B9AE443C80D0A34E /* FIRErrorCode.h */, - 8CA5A0BB0A7F36E8F7189D91C8B29728 /* FIRErrors.h */, - FB0DA168C2F41D42C624551BC2C23F9D /* FIRErrors.m */, - 374883FE51263B2BD861B86677BF5ECA /* FIRLibrary.h */, - 6DE4621B5BF4A7F747C7A66937E79855 /* FIRLogger.h */, - 745F466B0E0CFD0057D71D440A6D7D4D /* FIRLogger.m */, - 20BB64A0D3C190E922B42A7DABDF4351 /* FIRLoggerLevel.h */, - 7C62C59F592BBF3BA1637FDA859BE9A6 /* FIROptions.h */, - DA86BE4F12D473D435458BB4FB158BCD /* FIROptions.m */, - 1A3A538DA0C18DD8A698010361D27A8A /* FIROptionsInternal.h */, - 357B0ECED3D296D4A9739C22E28FF76D /* FIRVersion.h */, - 321D5E4C31CED38A5BE1C3397595E7F5 /* FIRVersion.m */, - 853EC0BD12F56AA7C7F2C10C782D1A2A /* Support Files */, - ); - name = FirebaseCore; - path = FirebaseCore; - sourceTree = "<group>"; - }; - AEB6E5ED4592D8BEF6808CBB5ABD44EA /* Pods-TeachersAssistant */ = { - isa = PBXGroup; - children = ( - 118B269F032567135C30C461CA7A23AD /* Pods-TeachersAssistant.modulemap */, - 6CF6CDA458E493AD3A13C09451C84F01 /* Pods-TeachersAssistant-acknowledgements.markdown */, - D2C38B5767FC35488427CDB72E1252BE /* Pods-TeachersAssistant-acknowledgements.plist */, - 74104373A68924B948E2FD66656DDF04 /* Pods-TeachersAssistant-dummy.m */, - F529CA2B381C222BE9ECC27FA5F94111 /* Pods-TeachersAssistant-frameworks.sh */, - B50337BA0606A576144D70B0E05ED8C1 /* Pods-TeachersAssistant-Info.plist */, - 3DFABC77294AE1B3C79891E913990217 /* Pods-TeachersAssistant-umbrella.h */, - 80D0ABF6F63F3EF080A906F8C625412E /* Pods-TeachersAssistant.debug.xcconfig */, - A61A5FBB4C4917E85820D47EA05A7A31 /* Pods-TeachersAssistant.release.xcconfig */, + A0AA143A60A8CCFF6198114B99E582AD /* Pods-TeachersAssistant.modulemap */, + 323EE53D0E077C0FFF05690D19B17BC0 /* Pods-TeachersAssistant-acknowledgements.markdown */, + 7FEDD941F5EF3021D18B42CC63A8B064 /* Pods-TeachersAssistant-acknowledgements.plist */, + 53B1664AEDBB405D89BDC1830E4B2F0F /* Pods-TeachersAssistant-dummy.m */, + A484B3C6B804C2A2725BB106CCA79CD2 /* Pods-TeachersAssistant-Info.plist */, + 72BBFEE5BC80C0DE9A031A654D125E71 /* Pods-TeachersAssistant-umbrella.h */, + B69955D80F9E5A6D8CD476BCD08F9999 /* Pods-TeachersAssistant.debug.xcconfig */, + 712DF69EA41A4DDB46B20CF5E438D55F /* Pods-TeachersAssistant.release.xcconfig */, ); name = "Pods-TeachersAssistant"; path = "Target Support Files/Pods-TeachersAssistant"; sourceTree = "<group>"; }; - AFD5746B3322A5A7717FD58DEC1AB0C6 /* Full */ = { - isa = PBXGroup; - children = ( - 5BC9D2775C1E7A3C43A2D9FB68FD6140 /* GTMGatherInputStream.h */, - FCC79991521336223B763662128BB7A3 /* GTMGatherInputStream.m */, - 88278CB0E802158640AF8B0E24FAD79A /* GTMMIMEDocument.h */, - 4370B2DFACB00E7DEC0868A68AA87DBD /* GTMMIMEDocument.m */, - 8795560D80511CF84F3EF6325D2A8F51 /* GTMReadMonitorInputStream.h */, - 547B4BA4FC4AC94B80BCCBAA38BEEB88 /* GTMReadMonitorInputStream.m */, - ); - name = Full; - sourceTree = "<group>"; - }; - BB34A8F19260533021E56F35106A3D9E /* decode */ = { + 61DC4C579DBBE61D0ACC83D1C12321C9 /* Targets Support Files */ = { isa = PBXGroup; children = ( + 55C4487E06B8A644EBB77910FD464E2D /* Pods-TeachersAssistant */, + D6A3E3478D9653F1FED135D15CBF0957 /* Pods-TeachersAssistantTests */, ); - name = decode; - sourceTree = "<group>"; - }; - C120AAFD9B8F9040B8CB01A9F341ADCC /* GoogleUtilities */ = { - isa = PBXGroup; - children = ( - 190E7D8635BB80C952FB81757F406863 /* AppDelegateSwizzler */, - CD1D88E16DF89CB347322C5845068DED /* Environment */, - 3F6820844C317A9C2761C9E80E7D3293 /* Logger */, - 48ADD341D1F72077B9B0D59546FC49FE /* MethodSwizzler */, - 000568507EFC75DAD4832327C87A771A /* Network */, - ED5AEF75C2F9AC611441207C0681F931 /* NSData+zlib */, - 6B9A9C6008E62201B938BD6DF406BD76 /* Reachability */, - E34D4A6C379908310BCC0023B51767E5 /* Support Files */, - 46D66038EF3F974B1F79DCC4014906E2 /* UserDefaults */, - ); - name = GoogleUtilities; - path = GoogleUtilities; - sourceTree = "<group>"; - }; - C72D17D0EE04F174CCC70EF0C4FACA9C /* Frameworks */ = { - isa = PBXGroup; - children = ( - 7D8784AB13BF6FBDE11552EE49C12DCC /* FIRAnalyticsConnector.framework */, - 123604314885A641B32BDF8B0F9DA302 /* FirebaseAnalytics.framework */, - 83DF78C7972D2E89918296EE5DA73881 /* FirebaseCoreDiagnostics.framework */, - ); - name = Frameworks; + name = "Targets Support Files"; sourceTree = "<group>"; }; - C867A118C912B19773323DA8F4417A47 /* Support Files */ = { + 9B055D0CFEA43187E72B03DED11F5662 /* iOS */ = { isa = PBXGroup; children = ( - D0990D319BA2234548E2873FFC0A8BEE /* FirebaseInstanceID.modulemap */, - 26EEA6C6A294786C4626A5D90B0CC7A8 /* FirebaseInstanceID.xcconfig */, - 2EDD142F7B8EDBDDDDB5BF548CD9DED8 /* FirebaseInstanceID-dummy.m */, - AD26A272AD866767EC8863C068DAC7A9 /* FirebaseInstanceID-Info.plist */, - 87191E9BA56B22A703AD591A7963F5E3 /* FirebaseInstanceID-umbrella.h */, + CB4607EFCA7C5F75397649E792E2AFCB /* Foundation.framework */, ); - name = "Support Files"; - path = "../Target Support Files/FirebaseInstanceID"; + name = iOS; sourceTree = "<group>"; }; - CD1D88E16DF89CB347322C5845068DED /* Environment */ = { + CD293B6EBFE3AE45C72CAC803ABB0B8C /* Products */ = { isa = PBXGroup; children = ( - 6C7078467D0A33F3EBEFE639202A278A /* GULAppEnvironmentUtil.h */, - 294D8D5384102F5EC8F36C99BD40B553 /* GULAppEnvironmentUtil.m */, + F03A69F5842E504313F19AD16F34A1C2 /* Pods_TeachersAssistant.framework */, + 5EFC6BA502D17737843A18B6594EA639 /* Pods_TeachersAssistantTests.framework */, ); - name = Environment; + name = Products; sourceTree = "<group>"; }; CF1408CF629C7361332E53B88F7BD30C = { isa = PBXGroup; children = ( 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, - DB6645AFD4BCB1190B7697DA96230830 /* Frameworks */, - 85BDCBE8335926A5DB41B3C841A3C263 /* Pods */, - F2A8EA43702E1C27A51E54A819C55FE7 /* Products */, - E201F6F1A7795FB7DB590924C510BDB4 /* Targets Support Files */, - ); - sourceTree = "<group>"; - }; - D5C309574E054758426FF93D19E5CA99 /* FirebaseInstanceID */ = { - isa = PBXGroup; - children = ( - 15D8C40F17E82EDAAA2FD2FEE97387AD /* FirebaseInstanceID.h */, - 4094FA6772FCD62F992E63FD03A145DC /* FIRIMessageCode.h */, - 30630E98C2C2879DE2C1248CA2C52F19 /* FIRInstanceID.h */, - 49C0CD9206E359DF82CB5D71E5B5097F /* FIRInstanceID.m */, - 52C6C4BA62B48087FCEC1011C608BDBA /* FIRInstanceID+Private.h */, - E62986E64C2AD9319C9BE39EFAD551E2 /* FIRInstanceID+Private.m */, - CDECB42CD69FE8C441A88EB09E5E41B1 /* FIRInstanceID+Testing.h */, - 1331D13DD4DE386BCEDBC001F6B10B28 /* FIRInstanceIDAPNSInfo.h */, - 580320C3A739577369ED81033BFCE123 /* FIRInstanceIDAPNSInfo.m */, - 3E8692905552E367BFE89057E3905DB9 /* FIRInstanceIDAuthKeyChain.h */, - 8F06F1782AC0D2EF8E359A25024009A7 /* FIRInstanceIDAuthKeyChain.m */, - 1911D2DEEADE2AAC254508D0D8D4DD05 /* FIRInstanceIDAuthService.h */, - A36649E2942CA43CF746CB8BB3356A9D /* FIRInstanceIDAuthService.m */, - 108C5CDFDC3BEA327489B1E055ED7470 /* FIRInstanceIDBackupExcludedPlist.h */, - 516450B002D7F6CFAD2116CE501F57A3 /* FIRInstanceIDBackupExcludedPlist.m */, - 17CCF5036BBF759B3851A291325A58DD /* FIRInstanceIDCheckinPreferences.h */, - B2CE9C8D3C9509E03742DAAC7D484973 /* FIRInstanceIDCheckinPreferences.m */, - A6EFE17E8C1D2435651AA1CF3C3314CB /* FIRInstanceIDCheckinPreferences+Internal.h */, - DB676188CF095CD4CF367F5EBC478EA7 /* FIRInstanceIDCheckinPreferences+Internal.m */, - D9107B74D49E38BCF7B3F2ED77E71F21 /* FIRInstanceIDCheckinPreferences_Private.h */, - C509EB270A3FE03A71169745013D5768 /* FIRInstanceIDCheckinService.h */, - 0AA2DD0AD8A2506D0FC3BBBF05067226 /* FIRInstanceIDCheckinService.m */, - 0BBF3A739B0E8360360E868AA65D007D /* FIRInstanceIDCheckinStore.h */, - DF5BFCC018CAF9606683F89394C3B25B /* FIRInstanceIDCheckinStore.m */, - 347A040A0C9EF78AE6E2CC3305BA6394 /* FIRInstanceIDConstants.h */, - 2897AC5168624488338884B7C36B5865 /* FIRInstanceIDConstants.m */, - 6BC4FA64AE2079B4E811849A1860A4A6 /* FIRInstanceIDDefines.h */, - 7943A53065BB0DF789C3CDEEC1004CD9 /* FIRInstanceIDKeychain.h */, - 4CF4F8A5BE53C6A071CEA011E4022665 /* FIRInstanceIDKeychain.m */, - E9E92D24EC1A5967CA10893102360920 /* FIRInstanceIDKeyPair.h */, - 7FBB2D1B3717FA3F20CC83DA53908482 /* FIRInstanceIDKeyPair.m */, - 290A38F9B7BEF687F3DBB3C3255CC233 /* FIRInstanceIDKeyPairStore.h */, - 63CA82E29BA583AD0A52D7A37558E2F9 /* FIRInstanceIDKeyPairStore.m */, - 500B9CE6A2B5ECC69A261EE855D14BDC /* FIRInstanceIDKeyPairUtilities.h */, - 3895CC74E7806861C8DB5D96CD95C007 /* FIRInstanceIDKeyPairUtilities.m */, - 43D7AEB5BE9D344529D075789E88E926 /* FIRInstanceIDLogger.h */, - A737C343B6C79B154315978701F29A04 /* FIRInstanceIDLogger.m */, - 559A7AF75C7825A882D221F994EDE0FE /* FIRInstanceIDStore.h */, - 61C9D32696A6761D07B73E8E6A1B0603 /* FIRInstanceIDStore.m */, - 3AA55CFA88ACE2B99420F368974ED9E7 /* FIRInstanceIDStringEncoding.h */, - D3389939168D7E16A07E06299C2D2CC6 /* FIRInstanceIDStringEncoding.m */, - D9BB6D0D6107EB6AA9292CBA994F58BD /* FIRInstanceIDTokenDeleteOperation.h */, - 34F74B35ABB197CD426E4B528256BA88 /* FIRInstanceIDTokenDeleteOperation.m */, - CFF309BE82E37F7CBFD6B6D48621D286 /* FIRInstanceIDTokenFetchOperation.h */, - 6980A1AC965054D472E7A754E0433A29 /* FIRInstanceIDTokenFetchOperation.m */, - D96D27B23ED456F3F91185B0591AA335 /* FIRInstanceIDTokenInfo.h */, - 93FB1D3F1A434DADF7E8F2E0DCDF6CB4 /* FIRInstanceIDTokenInfo.m */, - 8F7812E7B55B6200DF820251D9207F56 /* FIRInstanceIDTokenManager.h */, - F38AE2C8EE17A7657996595BFC9ABE11 /* FIRInstanceIDTokenManager.m */, - 39DE45AADB09BA42C0F26F4A09E7BBEE /* FIRInstanceIDTokenOperation.h */, - 571008D58CCCDD41BFC7992FC649BC4D /* FIRInstanceIDTokenOperation.m */, - 29BA6B4B3A27AAF40CE91D7F460B4C09 /* FIRInstanceIDTokenOperation+Private.h */, - 85599DEC750671534D9582042B8D286B /* FIRInstanceIDTokenStore.h */, - 6DF78EC6817986F64D37F229896D32E8 /* FIRInstanceIDTokenStore.m */, - B5F6A2DBC7DB5FAD70AD67EE2F401420 /* FIRInstanceIDURLQueryItem.h */, - 03CAC1CE04C75824406C3CB91E3A6CB2 /* FIRInstanceIDURLQueryItem.m */, - 9C252AD090AF9844AB7721AC0D603C74 /* FIRInstanceIDUtilities.h */, - DFE9A713C35D87D3276D66BDED99B818 /* FIRInstanceIDUtilities.m */, - 3693350ACB41663D2E80F539D7E5C50E /* FIRInstanceIDVersionUtilities.h */, - E83DAD359A051E38E0DCAAC7824D73BE /* FIRInstanceIDVersionUtilities.m */, - 54C93ABAE1D2705DC66F2D99C41F09C5 /* NSError+FIRInstanceID.h */, - FB866184F9DB8C552543637E0980B4FA /* NSError+FIRInstanceID.m */, - C867A118C912B19773323DA8F4417A47 /* Support Files */, - ); - name = FirebaseInstanceID; - path = FirebaseInstanceID; - sourceTree = "<group>"; - }; - D8E1E1B643379135870A88FE866DF9BE /* GTMSessionFetcher */ = { - isa = PBXGroup; - children = ( - 13A669684406EF1322D659F985E365A0 /* Core */, - AFD5746B3322A5A7717FD58DEC1AB0C6 /* Full */, - 50EE0F54CBEA07DF918CEAA8C4E49506 /* Support Files */, + D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */, + CD293B6EBFE3AE45C72CAC803ABB0B8C /* Products */, + 61DC4C579DBBE61D0ACC83D1C12321C9 /* Targets Support Files */, ); - name = GTMSessionFetcher; - path = GTMSessionFetcher; sourceTree = "<group>"; }; - DB6645AFD4BCB1190B7697DA96230830 /* Frameworks */ = { + D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */ = { isa = PBXGroup; children = ( - 5B0CAE77A1601E438C553BCD88A71A50 /* GTMSessionFetcher.framework */, - 5DFB3D0FCDA8985A1D96E5FDC266EAE2 /* iOS */, + 9B055D0CFEA43187E72B03DED11F5662 /* iOS */, ); name = Frameworks; sourceTree = "<group>"; }; - E201F6F1A7795FB7DB590924C510BDB4 /* Targets Support Files */ = { - isa = PBXGroup; - children = ( - AEB6E5ED4592D8BEF6808CBB5ABD44EA /* Pods-TeachersAssistant */, - 0FBF9B71E9B8C5E178D8C2E26CE101D7 /* Pods-TeachersAssistantTests */, - ); - name = "Targets Support Files"; - sourceTree = "<group>"; - }; - E34D4A6C379908310BCC0023B51767E5 /* Support Files */ = { - isa = PBXGroup; - children = ( - C2BF9601E45E61A49D75F7726674EC21 /* GoogleUtilities.modulemap */, - 81BAD96EB0AFAC3A8B603522A2FD846D /* GoogleUtilities.xcconfig */, - BF158F186A2E83AA478BC8C6ECB96907 /* GoogleUtilities-dummy.m */, - 415002A8AF1CDA669462CD54B22427D1 /* GoogleUtilities-Info.plist */, - 420B98A22418457646F0C81E28AEC1F8 /* GoogleUtilities-prefix.pch */, - 84B75F5A2DD728216A8F32ED58EB0EEC /* GoogleUtilities-umbrella.h */, - ); - name = "Support Files"; - path = "../Target Support Files/GoogleUtilities"; - sourceTree = "<group>"; - }; - E51C279489632B4AE3A37D169F20A5FE /* Firebase */ = { - isa = PBXGroup; - children = ( - EE77EDCD35852D3D8DAA905696217D4F /* CoreOnly */, - 95D80BD57F09D32EBA1416C100D6161A /* Support Files */, - ); - name = Firebase; - path = Firebase; - sourceTree = "<group>"; - }; - ED5AEF75C2F9AC611441207C0681F931 /* NSData+zlib */ = { - isa = PBXGroup; - children = ( - F0D1F45EB0BE7940F2B0A3B152F0BAF0 /* GULNSData+zlib.h */, - 09B65EA9CD18054C3731D78BF06AFBBC /* GULNSData+zlib.m */, - ); - name = "NSData+zlib"; - sourceTree = "<group>"; - }; - ED948ECEDEC70E540465331CF6AD793B /* encode */ = { - isa = PBXGroup; - children = ( - ); - name = encode; - sourceTree = "<group>"; - }; - EE77EDCD35852D3D8DAA905696217D4F /* CoreOnly */ = { - isa = PBXGroup; - children = ( - C9D528AA2118222E51B39583783D3824 /* Firebase.h */, - ); - name = CoreOnly; - sourceTree = "<group>"; - }; - F2A8EA43702E1C27A51E54A819C55FE7 /* Products */ = { + D6A3E3478D9653F1FED135D15CBF0957 /* Pods-TeachersAssistantTests */ = { isa = PBXGroup; children = ( - 017F9C2BF8786F97CC75BB1728EC1B83 /* FirebaseCore.framework */, - 583BBC1D30E637FD9C0BB1442D90C0D2 /* FirebaseInstanceID.framework */, - 115AA047B525A10FCEE3748D755468AF /* GoogleAPIClientForREST.framework */, - DB136240D29989E1D1B5EDBB26789605 /* GoogleUtilities.framework */, - FBA87A61F13A66578C76CA164240E08E /* GTMSessionFetcher.framework */, - 5D066DD9A210B03A0B9E0DAB7683DE7B /* nanopb.framework */, - 368ACD55DE3CCC50F08A01196D3AAF5D /* Pods_TeachersAssistant.framework */, - 44BEC70CEE7D3F3A73A2AAFC74050F84 /* Pods_TeachersAssistantTests.framework */, + 2593D361D3E3CF460C4BA860F7162623 /* Pods-TeachersAssistantTests.modulemap */, + 93C669D461B393AB37F791633C7ECEEF /* Pods-TeachersAssistantTests-acknowledgements.markdown */, + 487A571D8270AD9DBC4D5B4D623A17C5 /* Pods-TeachersAssistantTests-acknowledgements.plist */, + 68969D6928EE46B31780E10AD93CFD89 /* Pods-TeachersAssistantTests-dummy.m */, + 2064F876EB35354079F4B4E7C61BB78C /* Pods-TeachersAssistantTests-Info.plist */, + ECFFEA04571CCE4256E9CF44018F34FD /* Pods-TeachersAssistantTests-umbrella.h */, + 8697266AF1651BBCB0E02A6818EC909A /* Pods-TeachersAssistantTests.debug.xcconfig */, + 5DE088C489A470F3DBB49C659AE00CE2 /* Pods-TeachersAssistantTests.release.xcconfig */, ); - name = Products; - sourceTree = "<group>"; - }; - FB89EE033F8E78976FB7923B48CEB037 /* Frameworks */ = { - isa = PBXGroup; - children = ( - ADDFACA311CA984C4ED942D7153C7BBC /* GoogleAppMeasurement.framework */, - ); - name = Frameworks; + name = "Pods-TeachersAssistantTests"; + path = "Target Support Files/Pods-TeachersAssistantTests"; sourceTree = "<group>"; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - 7651B2F44918358BF29B9101BF7FC04A /* Headers */ = { + 641A9EF906BCCB12A3C8F931DA8AC79F /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - DE33BF21B7C31BD920D551FAAB7EA056 /* GoogleAPIClientForREST-umbrella.h in Headers */, - ABA437DFA30B41D0B77E0592682739FE /* GTLRBase64.h in Headers */, - 69F46ADB15D518B3F0323377AFEE974E /* GTLRBatchQuery.h in Headers */, - D9CAB0323F055B25038E725BDF34909A /* GTLRBatchResult.h in Headers */, - 8E0A60B68DDAD2843111B1C139A1C29E /* GTLRDateTime.h in Headers */, - 730879B4705522202D09520FBDEE11A5 /* GTLRDefines.h in Headers */, - 63CBC280596E3A453DF91743EBBC898A /* GTLRDuration.h in Headers */, - 7D1EE73692570398E3148C707E474265 /* GTLRErrorObject.h in Headers */, - 3C650CC5DFF8B2369B0326CF9EFA3B74 /* GTLRFramework.h in Headers */, - D79F7227DECCB6A36A093DC50BDEE07E /* GTLRObject.h in Headers */, - 8F07CBB8F46A54B2AE38082096AAC033 /* GTLRQuery.h in Headers */, - D90D2E30A9BE48C385E0B6F2A40A8924 /* GTLRRuntimeCommon.h in Headers */, - E16C9C03AFF3F2637540647FB777E3A0 /* GTLRService.h in Headers */, - 689CA019D0B329049875601AD99A0C04 /* GTLRSheets.h in Headers */, - 57C2471A37561E07AE381E7E346F77B3 /* GTLRSheetsObjects.h in Headers */, - F4E0A3D1D35780BFF837007FA581A4F0 /* GTLRSheetsQuery.h in Headers */, - 529E198E8565F59B3BE1364522AAEC87 /* GTLRSheetsService.h in Headers */, - 0DC5A104F5C14D11C8CA9F2EBEB41725 /* GTLRUploadParameters.h in Headers */, - D90D03372B914B0F17346CFA70DE4BEC /* GTLRURITemplate.h in Headers */, - 4F6EF06D616D2AEDAEAC81ECDE2C488E /* GTLRUtilities.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 87C026EB9FF5BAE426AB2D038DE18A0C /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - BB7CA1C508167B9F8FD455BEA2D522E3 /* GoogleUtilities-umbrella.h in Headers */, - A4077CB32B233FA9A612685884A231A5 /* GULAppDelegateSwizzler.h in Headers */, - A8F30A21B9C02C553EDA86290D8C896F /* GULAppDelegateSwizzler_Private.h in Headers */, - 250394D1E8BA232672EDB0720E269F26 /* GULAppEnvironmentUtil.h in Headers */, - 90BA3209CD339006E7B46A3410F4CD47 /* GULLogger.h in Headers */, - D0FE30F9B8D24715714954E61B6B5F36 /* GULLoggerCodes.h in Headers */, - D61867C7D901892724105F7FAC29841E /* GULLoggerLevel.h in Headers */, - 3F5F0473B00C277797303FA939E6DBAB /* GULMutableDictionary.h in Headers */, - 1B76EA90F9022A327F46E8E13D367B81 /* GULNetwork.h in Headers */, - 35D665B3D90C6BE89DEC067A5ED94F57 /* GULNetworkConstants.h in Headers */, - 6C8C3F762C321C7FCF5D7A91E0CBD4B1 /* GULNetworkLoggerProtocol.h in Headers */, - D780901FD66E3D4D29C65BD48F52340A /* GULNetworkMessageCode.h in Headers */, - 49EA6B4459F2B9C1CE0E1DCAE261FDEF /* GULNetworkURLSession.h in Headers */, - FBB36F8F7338268B4BCFD63D6CDDBE99 /* GULNSData+zlib.h in Headers */, - 3186A8F692C6DCA34411EBCED965DA5C /* GULOriginalIMPConvenienceMacros.h in Headers */, - A8EB0C6CA4D63005360D86AA889A518A /* GULReachabilityChecker+Internal.h in Headers */, - 4BA3FA7832147EC2B3EE59FD01CC2CAE /* GULReachabilityChecker.h in Headers */, - 7E169F6567DADEB4C0269E64A51E6DA4 /* GULReachabilityMessageCode.h in Headers */, - 7FE7DA15DFBB03C6F320F4137F0284ED /* GULSwizzler.h in Headers */, - 06DE8D644B4500C4F25871F5817E9B30 /* GULUserDefaults.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 975138D412B64947404A4BBBEC1120B8 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 350A5A886E6A58D8CDCDD4253BC38BDC /* nanopb-umbrella.h in Headers */, - 0AA1516C53AF76061CBAB2646F3AFFE8 /* pb.h in Headers */, - 2F4F0E5F03828E47ACDB08F50C32750A /* pb_common.h in Headers */, - 20A087E51101B8CB92AD91F7248A5AF3 /* pb_decode.h in Headers */, - 98E8C4DA7467C8A63B31CA042446E2E6 /* pb_encode.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 9EE6B9D2BCE26D1D034F17B647CE0CE4 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 57C854E399EE2DDEA121CD54EE49CB07 /* Pods-TeachersAssistant-umbrella.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B0C6AA217B2F7C5F9FB7BB5807636FE9 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 8343914CF540F43454F0A80F319961E8 /* FIRAnalyticsConfiguration+Internal.h in Headers */, - 3114C26A42681313B7F292DEFEA4AB23 /* FIRAnalyticsConfiguration.h in Headers */, - 90FF5AE27672B3705B540430627AAE1A /* FIRApp.h in Headers */, - 20A5A8E9A67B9FF611833437B7C5EA4B /* FIRAppAssociationRegistration.h in Headers */, - 5A84786CE0B0F1A1F8090E765B046C4D /* FIRAppInternal.h in Headers */, - F0DD6165CFF72F6AC7EB24BB0F81F59A /* FIRBundleUtil.h in Headers */, - 854834B0636DAEB384EAC5BBFA00993A /* FIRComponent.h in Headers */, - 98C8F3CD30D7FC179619C4297EDFA954 /* FIRComponentContainer.h in Headers */, - 01D879EED839FAE13BE060638310A23E /* FIRComponentContainerInternal.h in Headers */, - 1DBEB4345285DDD0576C9205C1607F45 /* FIRComponentType.h in Headers */, - 17C8EF1758E18D4BC2CDC094579C17AC /* FIRConfiguration.h in Headers */, - 29D6BF1387573FF76079F4370615F42F /* FIRDependency.h in Headers */, - 9CB382D049F3DBBFEB176BEF0543DA34 /* FirebaseCore-umbrella.h in Headers */, - B874D22C452407668077BA2AB7F14F2A /* FirebaseCore.h in Headers */, - 4DB3785D5FF90EE291AD9E6888678568 /* FIRErrorCode.h in Headers */, - 3B68F1157F767E0A567E3342BE503D66 /* FIRErrors.h in Headers */, - 131C584CC42207AE38C9B02CCA93BC20 /* FIRLibrary.h in Headers */, - 167EC0D6E6CA8F0A13B6CB28FCDFB2D3 /* FIRLogger.h in Headers */, - 2120FC11F12792CCF30112ABF6AECDC2 /* FIRLoggerLevel.h in Headers */, - 5B469132FE6F3D6BD781A223B88A5F41 /* FIROptions.h in Headers */, - FA4879EE891E4376D1CB122873A0D774 /* FIROptionsInternal.h in Headers */, - 1C13102930FBAE48D3508BE1166A7254 /* FIRVersion.h in Headers */, + 49FBC1A9555F33BAD525509484C1A93D /* Pods-TeachersAssistant-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1484,124 +163,9 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - E3726D77485F7144BB47EFF1791796A5 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 033BDE177CE4158DBD1D93B86E0DA68C /* FirebaseInstanceID-umbrella.h in Headers */, - 40F36D2E46BA807F50F3E49F1A3F14A0 /* FirebaseInstanceID.h in Headers */, - 876F2110FD88F97EDECF6652D7193836 /* FIRIMessageCode.h in Headers */, - EBB9A6443A2A88303F5D58BC929E7832 /* FIRInstanceID+Private.h in Headers */, - 3C7B678AE30C0CFDF2F6230C4182405B /* FIRInstanceID+Testing.h in Headers */, - A0779DD555A5A31F2302853261F22548 /* FIRInstanceID.h in Headers */, - 3358337525AF2964298F3C2457BAA271 /* FIRInstanceIDAPNSInfo.h in Headers */, - 28FD68E488D4EB3F967E24EB321A3D8C /* FIRInstanceIDAuthKeyChain.h in Headers */, - CAA80C28BBEFFF683932412EFE2D52C8 /* FIRInstanceIDAuthService.h in Headers */, - 6FD0FBAB532F0C93B7B8909FC99BFE97 /* FIRInstanceIDBackupExcludedPlist.h in Headers */, - 7FB4AACD60131CB28B62F5EDB531AAA4 /* FIRInstanceIDCheckinPreferences+Internal.h in Headers */, - 0059C3A34002842E58E7A96B79ECD15C /* FIRInstanceIDCheckinPreferences.h in Headers */, - B52B5E4267D0030974343307EFCDE2F2 /* FIRInstanceIDCheckinPreferences_Private.h in Headers */, - 22C2EC4924A727034D60B942E9FB3B76 /* FIRInstanceIDCheckinService.h in Headers */, - 06716C4D82C54A67EE2FC8558AC001D3 /* FIRInstanceIDCheckinStore.h in Headers */, - 0467A4AB857C1EA04F142878E6B5F7D7 /* FIRInstanceIDConstants.h in Headers */, - 63E86A46BDB0362808FB9BA64DE35DA5 /* FIRInstanceIDDefines.h in Headers */, - 59CEC609B2677DAC48C94403C96404CD /* FIRInstanceIDKeychain.h in Headers */, - 57600D38E2FDA193B83876BC5357B486 /* FIRInstanceIDKeyPair.h in Headers */, - 5AE38B0A395E28D92DF14A261A9EBE45 /* FIRInstanceIDKeyPairStore.h in Headers */, - 0BE43A5E3B4F77F37B8343CAFB34785F /* FIRInstanceIDKeyPairUtilities.h in Headers */, - 7F6426897180E49EE98F3A6CE8F24D58 /* FIRInstanceIDLogger.h in Headers */, - 43A96F3C7695AE0E52B91FFD50FFB008 /* FIRInstanceIDStore.h in Headers */, - D0D85A8ED3641D03ECCFFD79CC11D9FF /* FIRInstanceIDStringEncoding.h in Headers */, - B2846F8C8EEB75BF6E4BCE173933460B /* FIRInstanceIDTokenDeleteOperation.h in Headers */, - FEA8B7A05B7B352EE64E0FD4C79D720D /* FIRInstanceIDTokenFetchOperation.h in Headers */, - 225CD805988CB60469B5BF834F3D9CF2 /* FIRInstanceIDTokenInfo.h in Headers */, - 7D49364D45BC35C596753015EED2158D /* FIRInstanceIDTokenManager.h in Headers */, - 526B347701CC61AA8D42C5004F5DACDD /* FIRInstanceIDTokenOperation+Private.h in Headers */, - 5DE36E758B1620E0A005E2038548BFE8 /* FIRInstanceIDTokenOperation.h in Headers */, - 11FC0A073774C034685F68FC4DBFAD71 /* FIRInstanceIDTokenStore.h in Headers */, - CDB71F03D6470F12E7217D87B7AC7AF0 /* FIRInstanceIDURLQueryItem.h in Headers */, - C67A8DA52D8476D2E472A65E8ED2104C /* FIRInstanceIDUtilities.h in Headers */, - E6F14D70F8F878C0D7D8894FBA1D919D /* FIRInstanceIDVersionUtilities.h in Headers */, - 376B561BE4A9CF76B656848C439B8DE7 /* NSError+FIRInstanceID.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F94EBFB7D9EA26CBCA328213A9F6C50F /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 4113F1C1982CB9F61B0877D8E2A3C982 /* GTMGatherInputStream.h in Headers */, - 38AE6B968DC0DE94A749503C4FF43E51 /* GTMMIMEDocument.h in Headers */, - EA0876B4F2B40E37E01E0D9F96BA34B3 /* GTMReadMonitorInputStream.h in Headers */, - DE84A495B46D938B298901309B53C60A /* GTMSessionFetcher-umbrella.h in Headers */, - B1A5C2FE1615E297E4A245C34B7F6762 /* GTMSessionFetcher.h in Headers */, - A3A05DE0E3AEB3299F7606F0F8BD7756 /* GTMSessionFetcherLogging.h in Headers */, - 102658B33FEC7C008C1C8229F40351F9 /* GTMSessionFetcherService.h in Headers */, - 90B3B87D94A9F9F6A90C2222E7516DC9 /* GTMSessionUploadFetcher.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 01B53B6A43CBD6D4022A361BBFCCE665 /* FirebaseCore */ = { - isa = PBXNativeTarget; - buildConfigurationList = 272C318C3C138518DD0B0FB5BF575E70 /* Build configuration list for PBXNativeTarget "FirebaseCore" */; - buildPhases = ( - B0C6AA217B2F7C5F9FB7BB5807636FE9 /* Headers */, - 204045C2E2F5F5BF79FC8D5E7EE930C2 /* Sources */, - 18E8B46930253C826FB953C9E92F96CF /* Frameworks */, - BAD5E7CBF36881EC0AA5D9EF5D47B6F4 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - AE2135E39D7AC4E181788F79286CC4E9 /* PBXTargetDependency */, - ); - name = FirebaseCore; - productName = FirebaseCore; - productReference = 017F9C2BF8786F97CC75BB1728EC1B83 /* FirebaseCore.framework */; - productType = "com.apple.product-type.framework"; - }; - 3C6A9BF574C3488966C92C6A9B93CA8C /* FirebaseInstanceID */ = { - isa = PBXNativeTarget; - buildConfigurationList = 17528847ED7361712D5774B3F57F412E /* Build configuration list for PBXNativeTarget "FirebaseInstanceID" */; - buildPhases = ( - E3726D77485F7144BB47EFF1791796A5 /* Headers */, - 13BAEB279781DF730E05EA038774FB1C /* Sources */, - D5CE9E2102E465709E5822E849D79D5A /* Frameworks */, - 9CFCD3EA462E6C786A886950664C14DA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 11BB47F7EA1D94100004061A682344B8 /* PBXTargetDependency */, - B89D2CB67178C93A2DFF80F628C7A710 /* PBXTargetDependency */, - ); - name = FirebaseInstanceID; - productName = FirebaseInstanceID; - productReference = 583BBC1D30E637FD9C0BB1442D90C0D2 /* FirebaseInstanceID.framework */; - productType = "com.apple.product-type.framework"; - }; - 772340DB04E857CA1ABBDB7EC1CA7079 /* GoogleAPIClientForREST */ = { - isa = PBXNativeTarget; - buildConfigurationList = 89E0E08DEE3712E3F0EB975775425754 /* Build configuration list for PBXNativeTarget "GoogleAPIClientForREST" */; - buildPhases = ( - 7651B2F44918358BF29B9101BF7FC04A /* Headers */, - 34D7FA85EF968F82B524206A7BEFB71F /* Sources */, - 5D2361E98237FB7C772C750B91DB5F05 /* Frameworks */, - D7AA918ECAFF58E36CFFDEDDFB63C960 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 7C898B425FA4DA448FB2CF9AFF680EB3 /* PBXTargetDependency */, - ); - name = GoogleAPIClientForREST; - productName = GoogleAPIClientForREST; - productReference = 115AA047B525A10FCEE3748D755468AF /* GoogleAPIClientForREST.framework */; - productType = "com.apple.product-type.framework"; - }; 9115383C4EEFD422CC2FA6BC0AEEF0EE /* Pods-TeachersAssistantTests */ = { isa = PBXNativeTarget; buildConfigurationList = 34A3E21F8EBDF4849164D45564BF83D3 /* Build configuration list for PBXNativeTarget "Pods-TeachersAssistantTests" */; @@ -1618,88 +182,25 @@ ); name = "Pods-TeachersAssistantTests"; productName = "Pods-TeachersAssistantTests"; - productReference = 44BEC70CEE7D3F3A73A2AAFC74050F84 /* Pods_TeachersAssistantTests.framework */; + productReference = 5EFC6BA502D17737843A18B6594EA639 /* Pods_TeachersAssistantTests.framework */; productType = "com.apple.product-type.framework"; }; - C1DBAA447353B7E3A4A495D068C464D8 /* Pods-TeachersAssistant */ = { + DC3A57A44D7A30108A57480929F8FDFE /* Pods-TeachersAssistant */ = { isa = PBXNativeTarget; - buildConfigurationList = 4E2FA166349EB1570B43A20CD7C75E62 /* Build configuration list for PBXNativeTarget "Pods-TeachersAssistant" */; + buildConfigurationList = 04D114BD04630F88DEBEECF7CD6022A7 /* Build configuration list for PBXNativeTarget "Pods-TeachersAssistant" */; buildPhases = ( - 9EE6B9D2BCE26D1D034F17B647CE0CE4 /* Headers */, - 31ABA1B93F9C30E2DA6887C83DDF6EC4 /* Sources */, - A38A6054F26C426AE2C0C0EDAD0008FC /* Frameworks */, - 3D21DC586C06817D3BFE1CEABF727378 /* Resources */, + 641A9EF906BCCB12A3C8F931DA8AC79F /* Headers */, + 5616731DED8AB60414D3D1849587455E /* Sources */, + 58C4F2D938F2E1891871766DEA5000E2 /* Frameworks */, + 238B9D8341BBD85C75CBA0E8A5242F15 /* Resources */, ); buildRules = ( ); dependencies = ( - 5375E58AA18148CDB7F1E4D467ED33C7 /* PBXTargetDependency */, - FD179E7758867534E6581E867B338091 /* PBXTargetDependency */, - A5C6C41C0E1E593E24CC18D4327294F0 /* PBXTargetDependency */, - D864BA67E5C411873861098E5DF40E5B /* PBXTargetDependency */, - 1B066CE6895A68932D1E3FB0E6D60288 /* PBXTargetDependency */, - EB950109F56ACBB3F970D78AF505E00B /* PBXTargetDependency */, - CED6FBDC7E35B5A1EDAC22DF1D0066FC /* PBXTargetDependency */, - CCD4F9B43A101889457818D0E194D031 /* PBXTargetDependency */, - 5109C054A0FD609A3CF3986B9B8C9177 /* PBXTargetDependency */, ); name = "Pods-TeachersAssistant"; productName = "Pods-TeachersAssistant"; - productReference = 368ACD55DE3CCC50F08A01196D3AAF5D /* Pods_TeachersAssistant.framework */; - productType = "com.apple.product-type.framework"; - }; - D811FCD6F8EBFE221BF9D923CEFB5CE8 /* GTMSessionFetcher */ = { - isa = PBXNativeTarget; - buildConfigurationList = A0F94913EC690DC5D7F6D981D004310A /* Build configuration list for PBXNativeTarget "GTMSessionFetcher" */; - buildPhases = ( - F94EBFB7D9EA26CBCA328213A9F6C50F /* Headers */, - F8054326668F148082A04F36EA9270E4 /* Sources */, - 285219F57C35AF74521FE10278556E39 /* Frameworks */, - C559FBE113680A38D58FBC77BF6FA323 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = GTMSessionFetcher; - productName = GTMSessionFetcher; - productReference = FBA87A61F13A66578C76CA164240E08E /* GTMSessionFetcher.framework */; - productType = "com.apple.product-type.framework"; - }; - D9A2B7F6350AE8AB9AAFF5A9395AD63C /* GoogleUtilities */ = { - isa = PBXNativeTarget; - buildConfigurationList = BC00811E082341577790995EE25EA091 /* Build configuration list for PBXNativeTarget "GoogleUtilities" */; - buildPhases = ( - 87C026EB9FF5BAE426AB2D038DE18A0C /* Headers */, - 0089DDDA3A25B67F94AF09C8C8811837 /* Sources */, - 2AB82CCC1FE772DB4095EA633511AF3C /* Frameworks */, - 55761CA536EE839D1D94DFD593A64BE0 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = GoogleUtilities; - productName = GoogleUtilities; - productReference = DB136240D29989E1D1B5EDBB26789605 /* GoogleUtilities.framework */; - productType = "com.apple.product-type.framework"; - }; - E93C48A48FB03EA19C4F756B97B5F1D3 /* nanopb */ = { - isa = PBXNativeTarget; - buildConfigurationList = 7F06B8F325208699248FA6C351C472D4 /* Build configuration list for PBXNativeTarget "nanopb" */; - buildPhases = ( - 975138D412B64947404A4BBBEC1120B8 /* Headers */, - 700851C9880F6C2451244067429289CA /* Sources */, - BD6C01A9D3F5BF4D6F5F4588AD3A7E32 /* Frameworks */, - C7AA1C6CBDCA2488533EB20B524FF83F /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = nanopb; - productName = nanopb; - productReference = 5D066DD9A210B03A0B9E0DAB7683DE7B /* nanopb.framework */; + productReference = F03A69F5842E504313F19AD16F34A1C2 /* Pods_TeachersAssistant.framework */; productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ @@ -1715,80 +216,29 @@ compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = CF1408CF629C7361332E53B88F7BD30C; - productRefGroup = F2A8EA43702E1C27A51E54A819C55FE7 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 799B29F9D6DCE28B98CC259440382F20 /* Firebase */, - 232D00D8ED7797390FB38004DE01723B /* FirebaseAnalytics */, - 01B53B6A43CBD6D4022A361BBFCCE665 /* FirebaseCore */, - 3C6A9BF574C3488966C92C6A9B93CA8C /* FirebaseInstanceID */, - 772340DB04E857CA1ABBDB7EC1CA7079 /* GoogleAPIClientForREST */, - 57B9E0A892EAB5C13D4AE7D4B1DE0C16 /* GoogleAppMeasurement */, - D9A2B7F6350AE8AB9AAFF5A9395AD63C /* GoogleUtilities */, - D811FCD6F8EBFE221BF9D923CEFB5CE8 /* GTMSessionFetcher */, - E93C48A48FB03EA19C4F756B97B5F1D3 /* nanopb */, - C1DBAA447353B7E3A4A495D068C464D8 /* Pods-TeachersAssistant */, - 9115383C4EEFD422CC2FA6BC0AEEF0EE /* Pods-TeachersAssistantTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 0CFAA73F65795CED4B9F45F1FE7E9EAA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3D21DC586C06817D3BFE1CEABF727378 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 55761CA536EE839D1D94DFD593A64BE0 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 9CFCD3EA462E6C786A886950664C14DA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - BAD5E7CBF36881EC0AA5D9EF5D47B6F4 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( + knownRegions = ( + en, ); - runOnlyForDeploymentPostprocessing = 0; - }; - C559FBE113680A38D58FBC77BF6FA323 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( + mainGroup = CF1408CF629C7361332E53B88F7BD30C; + productRefGroup = CD293B6EBFE3AE45C72CAC803ABB0B8C /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + DC3A57A44D7A30108A57480929F8FDFE /* Pods-TeachersAssistant */, + 9115383C4EEFD422CC2FA6BC0AEEF0EE /* Pods-TeachersAssistantTests */, ); - runOnlyForDeploymentPostprocessing = 0; }; - C7AA1C6CBDCA2488533EB20B524FF83F /* Resources */ = { +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 0CFAA73F65795CED4B9F45F1FE7E9EAA /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - D7AA918ECAFF58E36CFFDEDDFB63C960 /* Resources */ = { + 238B9D8341BBD85C75CBA0E8A5242F15 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( @@ -1798,138 +248,11 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 0089DDDA3A25B67F94AF09C8C8811837 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 161DA7FD58D2B4BD6788ED1A1EC4D4D9 /* GoogleUtilities-dummy.m in Sources */, - EAAC31E35767E4527322215E77F500CB /* GULAppDelegateSwizzler.m in Sources */, - 3BB343D149E94DCA9736241B605534AA /* GULAppEnvironmentUtil.m in Sources */, - 723B1DEC2C8098017A02DF898B87E8D0 /* GULLogger.m in Sources */, - 6AA5596E1B32B6664794B84C8D53BB3C /* GULMutableDictionary.m in Sources */, - 62D28905E5357811247084EA63BBF4DA /* GULNetwork.m in Sources */, - 09BA2B85B4D3A18F7D1E57BB80828BD9 /* GULNetworkConstants.m in Sources */, - 05F0BE6D01F6317AB56399068AA03408 /* GULNetworkURLSession.m in Sources */, - 9E31E2EBECBBEE07EFC16DF386D6AE4E /* GULNSData+zlib.m in Sources */, - 88B58642B5770D7313961DB5AAC02C58 /* GULReachabilityChecker.m in Sources */, - 9A1C90B1E05093DDF8B89EF59A6727AE /* GULSwizzler.m in Sources */, - 2E4BF72932067C69FF51DB6AC0790798 /* GULUserDefaults.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 13BAEB279781DF730E05EA038774FB1C /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 60D21973F190744E3DC7BE8B088679C3 /* FirebaseInstanceID-dummy.m in Sources */, - D316314973075DB32C8953B79BF3BC75 /* FIRInstanceID+Private.m in Sources */, - D2B0DFDD0967BE00F5CB9E1941A6D6C4 /* FIRInstanceID.m in Sources */, - C1C8CE593A5F1669B167AB171FB02783 /* FIRInstanceIDAPNSInfo.m in Sources */, - 56BAB83EAE402801FA7BA3911CCF67D7 /* FIRInstanceIDAuthKeyChain.m in Sources */, - E36F4E96A7B06203207C264C5ABDFD2E /* FIRInstanceIDAuthService.m in Sources */, - DE4E29330B8FF66A9D6931E4A35D011C /* FIRInstanceIDBackupExcludedPlist.m in Sources */, - 5BA1BBD448693996005C28B6F23F9860 /* FIRInstanceIDCheckinPreferences+Internal.m in Sources */, - 9B06D94D480832601A64BE7F6D29532C /* FIRInstanceIDCheckinPreferences.m in Sources */, - B60CEC5F4A4DE230EA3EA08A13DDE360 /* FIRInstanceIDCheckinService.m in Sources */, - A64F4FE4D9093E1AE9EFEE5094DC0E43 /* FIRInstanceIDCheckinStore.m in Sources */, - 2C104E24C5AD39EAEA527722426513D0 /* FIRInstanceIDConstants.m in Sources */, - 61B23F7031A1C5919E7338E490C116E7 /* FIRInstanceIDKeychain.m in Sources */, - 45BF0F342DD18D393CF71EA76BCAF831 /* FIRInstanceIDKeyPair.m in Sources */, - 46FFA8D318E8298B80CFF968BD58A1DE /* FIRInstanceIDKeyPairStore.m in Sources */, - 2390AF73CF77000D9FFA4F7E71F87709 /* FIRInstanceIDKeyPairUtilities.m in Sources */, - ED4EAD8B9899E20BCA8955C010D69F81 /* FIRInstanceIDLogger.m in Sources */, - 5F2485A11C7E0A6818B2FB30C4B2146D /* FIRInstanceIDStore.m in Sources */, - 93942FEE248D34A1409BA4C09935228D /* FIRInstanceIDStringEncoding.m in Sources */, - D0684944EF39981421BA02602FB5B6BB /* FIRInstanceIDTokenDeleteOperation.m in Sources */, - 02262A3E212C0EB9ACBC055C1FB08E3D /* FIRInstanceIDTokenFetchOperation.m in Sources */, - C071C67F80CC4B0C3B8CF21F3F91CED0 /* FIRInstanceIDTokenInfo.m in Sources */, - FB0C39A32EFA1192032C872DF986F94B /* FIRInstanceIDTokenManager.m in Sources */, - 764B2AE2F2B17F964F6437AE468C0F15 /* FIRInstanceIDTokenOperation.m in Sources */, - 7B4645279AD67C809174C1B58AD6F915 /* FIRInstanceIDTokenStore.m in Sources */, - A764BBEB0892656245FE139E4F6EA311 /* FIRInstanceIDURLQueryItem.m in Sources */, - AE273C13E5C6707E77A6B4EBFA096DA1 /* FIRInstanceIDUtilities.m in Sources */, - 6EC07394A547C7982468ED9069AAB53B /* FIRInstanceIDVersionUtilities.m in Sources */, - 3E3765FEDEFB49732071DF7CCFDA4F18 /* NSError+FIRInstanceID.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 204045C2E2F5F5BF79FC8D5E7EE930C2 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - FAFCFEADC58CB5BC49874CFEB7AB6508 /* FIRAnalyticsConfiguration.m in Sources */, - ABBA4D1A08A1D18ECF18CFCEC1D683DE /* FIRApp.m in Sources */, - E8C0A0E2222FF021FE0174A246F9AD21 /* FIRAppAssociationRegistration.m in Sources */, - 4AEAF2548FD03171132E796282A5A71A /* FIRBundleUtil.m in Sources */, - D8A219829C97AE6AF93A048E09F5680D /* FIRComponent.m in Sources */, - CD615CD72DECC08D3F0223C7E23B3093 /* FIRComponentContainer.m in Sources */, - F9F2828D09A41F9367A8E4D678439DFD /* FIRComponentType.m in Sources */, - C40EB7CFC8729D308A3FC952DBEFDAC4 /* FIRConfiguration.m in Sources */, - B078F7C21362CC2EC03671646B46739F /* FIRDependency.m in Sources */, - A14D03FFE5AB2DDE88377934063BF951 /* FirebaseCore-dummy.m in Sources */, - 76478F8839B3E900D460C0DE15D21F53 /* FIRErrors.m in Sources */, - 2057D78059437EADF8E509FB3A4E3463 /* FIRLogger.m in Sources */, - E6E306527999E035678E03FCFB44F5E6 /* FIROptions.m in Sources */, - 5E638B27DC537F86FE14FD7E312A350E /* FIRVersion.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 31ABA1B93F9C30E2DA6887C83DDF6EC4 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - C191B7AFCB86D9C55E552A9432A08AA5 /* Pods-TeachersAssistant-dummy.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 34D7FA85EF968F82B524206A7BEFB71F /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 93F238A3CBF92469EAB23AA952814B9E /* GoogleAPIClientForREST-dummy.m in Sources */, - 9597B01BCD32158B7674DA270A77A05D /* GTLRBase64.m in Sources */, - E32F693371E7272421A8F5ABE4C7D05B /* GTLRBatchQuery.m in Sources */, - BAEA0165416D2478BB040F1584A157E9 /* GTLRBatchResult.m in Sources */, - 26FE54055CE40CA8B7B8556919C21149 /* GTLRDateTime.m in Sources */, - 6B80256F23FA1918E977CEDE91CE3697 /* GTLRDuration.m in Sources */, - 5D2B3289AB0C9082A36E106B6FC1A1C9 /* GTLRErrorObject.m in Sources */, - 09E4B4EBE4FBA72C30564F3E3DA2081F /* GTLRFramework.m in Sources */, - 564FB83D43683D79E3DF91EC972184D8 /* GTLRObject.m in Sources */, - 9BBC4EFFC569655FBA0A52C627D674F0 /* GTLRQuery.m in Sources */, - D775E01ED0653D1AA554B9D50E9C276E /* GTLRRuntimeCommon.m in Sources */, - 6D61C466E6E69A842B65285DE2261213 /* GTLRService.m in Sources */, - E9D3144ECE2DB2BCCA436A874DE7EC89 /* GTLRSheetsObjects.m in Sources */, - 6DEE0C82F00E41474F70E54D39C1337D /* GTLRSheetsQuery.m in Sources */, - 2ECE32250F9379832BA31C5788E02EBC /* GTLRSheetsService.m in Sources */, - CF12D67880876BC3C2360BB7F3C792ED /* GTLRUploadParameters.m in Sources */, - DF87CF5ECCAE4379FB2B17ACD054F1F2 /* GTLRURITemplate.m in Sources */, - 656F3D54ACD64C547F9594F124FA2D5E /* GTLRUtilities.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 700851C9880F6C2451244067429289CA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 20F3EC5F96CECCC418924F80B181053B /* nanopb-dummy.m in Sources */, - 4DF83A76C578938051AFFAC51A0E1471 /* pb_common.c in Sources */, - B38F70804F3D61BBBA93329CA7ED0FC8 /* pb_decode.c in Sources */, - 4CD69ED3DFC0C9AE77A59B70AF7FE036 /* pb_encode.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F8054326668F148082A04F36EA9270E4 /* Sources */ = { + 5616731DED8AB60414D3D1849587455E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - D044612547CC780C57BA3DDF204F4550 /* GTMGatherInputStream.m in Sources */, - 1752930EA1F0BD6E9408C8298F178491 /* GTMMIMEDocument.m in Sources */, - CE0AF5ABE638F0F58F8DC3D81B7E3100 /* GTMReadMonitorInputStream.m in Sources */, - 60070AAFBCB471BDF2A5903E309BF939 /* GTMSessionFetcher-dummy.m in Sources */, - F1D4FF2068E4D0B9395A2B253CF7098C /* GTMSessionFetcher.m in Sources */, - 55E0ADCA640BB3322559794AED57F451 /* GTMSessionFetcherLogging.m in Sources */, - 5992ECFCB7E99F063A2D36AE73F44D60 /* GTMSessionFetcherService.m in Sources */, - 2300C13FB133313D32DFFB0D57C25ECC /* GTMSessionUploadFetcher.m in Sources */, + 94899B81237225BF746A450254A31A2A /* Pods-TeachersAssistant-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1944,144 +267,12 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 03C5D1361123B1B19A913F4F89661FDB /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = GoogleUtilities; - target = D9A2B7F6350AE8AB9AAFF5A9395AD63C /* GoogleUtilities */; - targetProxy = 46123FA0B5C451A00D38BB12B40AD23A /* PBXContainerItemProxy */; - }; - 11BB47F7EA1D94100004061A682344B8 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = FirebaseCore; - target = 01B53B6A43CBD6D4022A361BBFCCE665 /* FirebaseCore */; - targetProxy = 0ECB4C54EED84F5258E41AFD4657F11F /* PBXContainerItemProxy */; - }; - 1B066CE6895A68932D1E3FB0E6D60288 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = GTMSessionFetcher; - target = D811FCD6F8EBFE221BF9D923CEFB5CE8 /* GTMSessionFetcher */; - targetProxy = 98553A26A4F1509909FEE91EA0162432 /* PBXContainerItemProxy */; - }; - 3BDD26DF1C76A2717767412BFEFD633E /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = nanopb; - target = E93C48A48FB03EA19C4F756B97B5F1D3 /* nanopb */; - targetProxy = C6318E60C9E68C5F678F7ADDF357AED8 /* PBXContainerItemProxy */; - }; - 5109C054A0FD609A3CF3986B9B8C9177 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = nanopb; - target = E93C48A48FB03EA19C4F756B97B5F1D3 /* nanopb */; - targetProxy = 63982F044D1394A02009890DC4D11191 /* PBXContainerItemProxy */; - }; - 5375E58AA18148CDB7F1E4D467ED33C7 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = Firebase; - target = 799B29F9D6DCE28B98CC259440382F20 /* Firebase */; - targetProxy = 0F60F822741F17E09A70AC758014F400 /* PBXContainerItemProxy */; - }; - 7AEC0D15EF11C1415A94D769184AD812 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = FirebaseAnalytics; - target = 232D00D8ED7797390FB38004DE01723B /* FirebaseAnalytics */; - targetProxy = 7AEA5761B26CAEF1A0C0E82599059DA8 /* PBXContainerItemProxy */; - }; - 7AEF416F1165E14B97A1CD16C71D4F0C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = GoogleUtilities; - target = D9A2B7F6350AE8AB9AAFF5A9395AD63C /* GoogleUtilities */; - targetProxy = 53E2A1BD19729C2293AB46582C686251 /* PBXContainerItemProxy */; - }; - 7C898B425FA4DA448FB2CF9AFF680EB3 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = GTMSessionFetcher; - target = D811FCD6F8EBFE221BF9D923CEFB5CE8 /* GTMSessionFetcher */; - targetProxy = F57E55D97C9AF0B37D53F628359ABA5F /* PBXContainerItemProxy */; - }; - 9C390500C3C568F59A8589C455BFF4D5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = FirebaseInstanceID; - target = 3C6A9BF574C3488966C92C6A9B93CA8C /* FirebaseInstanceID */; - targetProxy = C6C35C61164D4136265E61ECEB28D38A /* PBXContainerItemProxy */; - }; - A545116FEA98CB2DC602ECFE976A5146 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = nanopb; - target = E93C48A48FB03EA19C4F756B97B5F1D3 /* nanopb */; - targetProxy = DF12C5D7BB68C2724D2F39A531F2A52A /* PBXContainerItemProxy */; - }; - A5C6C41C0E1E593E24CC18D4327294F0 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = FirebaseCore; - target = 01B53B6A43CBD6D4022A361BBFCCE665 /* FirebaseCore */; - targetProxy = 1978C06F97680C1C8CFE2AC9F848F053 /* PBXContainerItemProxy */; - }; - AA9052A974DA4ECF27CC38A7633849E0 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = GoogleAppMeasurement; - target = 57B9E0A892EAB5C13D4AE7D4B1DE0C16 /* GoogleAppMeasurement */; - targetProxy = BBDC7C661CA5567D3925BC0747CAAEC5 /* PBXContainerItemProxy */; - }; - AE2135E39D7AC4E181788F79286CC4E9 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = GoogleUtilities; - target = D9A2B7F6350AE8AB9AAFF5A9395AD63C /* GoogleUtilities */; - targetProxy = 5BE488B88EB1D7B8BFE4A63D278D4B18 /* PBXContainerItemProxy */; - }; - B89D2CB67178C93A2DFF80F628C7A710 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = GoogleUtilities; - target = D9A2B7F6350AE8AB9AAFF5A9395AD63C /* GoogleUtilities */; - targetProxy = 54A7BA384E80D5DB0269C827877FE175 /* PBXContainerItemProxy */; - }; - CA20CC0CC8595F02B384BCF03BBE9452 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = FirebaseCore; - target = 01B53B6A43CBD6D4022A361BBFCCE665 /* FirebaseCore */; - targetProxy = 455009ED9ED8F59E3D7880EA52A66B11 /* PBXContainerItemProxy */; - }; - CB67FB062DE8CAF07E20E144CB621739 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = FirebaseCore; - target = 01B53B6A43CBD6D4022A361BBFCCE665 /* FirebaseCore */; - targetProxy = F6A14184DE3C02C257A7298719E4FD9B /* PBXContainerItemProxy */; - }; - CCD4F9B43A101889457818D0E194D031 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = GoogleUtilities; - target = D9A2B7F6350AE8AB9AAFF5A9395AD63C /* GoogleUtilities */; - targetProxy = 54C6A825F7C3057AC5EB47B5EDA879F3 /* PBXContainerItemProxy */; - }; - CED6FBDC7E35B5A1EDAC22DF1D0066FC /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = GoogleAppMeasurement; - target = 57B9E0A892EAB5C13D4AE7D4B1DE0C16 /* GoogleAppMeasurement */; - targetProxy = 475E73100BA3CA8F024336F74263C678 /* PBXContainerItemProxy */; - }; - D864BA67E5C411873861098E5DF40E5B /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = FirebaseInstanceID; - target = 3C6A9BF574C3488966C92C6A9B93CA8C /* FirebaseInstanceID */; - targetProxy = 94497EC05AB24679A89D934FDF900750 /* PBXContainerItemProxy */; - }; EB4921EFA7B1ACE9CB14B01E8D6AA7B9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = "Pods-TeachersAssistant"; - target = C1DBAA447353B7E3A4A495D068C464D8 /* Pods-TeachersAssistant */; + target = DC3A57A44D7A30108A57480929F8FDFE /* Pods-TeachersAssistant */; targetProxy = CBA0C327941F96015A5D0C2A0F65E1D9 /* PBXContainerItemProxy */; }; - EB950109F56ACBB3F970D78AF505E00B /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = GoogleAPIClientForREST; - target = 772340DB04E857CA1ABBDB7EC1CA7079 /* GoogleAPIClientForREST */; - targetProxy = B82C96A38C8E60FE2CEB597BB1AC15D7 /* PBXContainerItemProxy */; - }; - FD179E7758867534E6581E867B338091 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = FirebaseAnalytics; - target = 232D00D8ED7797390FB38004DE01723B /* FirebaseAnalytics */; - targetProxy = 449060759393A041D614674D0E5B2085 /* PBXContainerItemProxy */; - }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -2128,231 +319,32 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "POD_CONFIGURATION_DEBUG=1", "DEBUG=1", - "$(inherited)", - ); - 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 = 9.0; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - STRIP_INSTALLED_PRODUCT = NO; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 4.2; - SYMROOT = "${SRCROOT}/../build"; - }; - name = Debug; - }; - 16393E98E7D33B078F35DAD0BF562519 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = E8ABC734EC5D76410142B606FB284CB9 /* FirebaseAnalytics.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "iPhone Developer"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 1AF9C8CAFEB4999C4459A2A076CB87EA /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 81BAD96EB0AFAC3A8B603522A2FD846D /* GoogleUtilities.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/GoogleUtilities/GoogleUtilities-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/GoogleUtilities/GoogleUtilities-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/GoogleUtilities/GoogleUtilities.modulemap"; - PRODUCT_MODULE_NAME = GoogleUtilities; - PRODUCT_NAME = GoogleUtilities; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 4.0; - TARGETED_DEVICE_FAMILY = "1,2"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 20A9A4E87D934379BD3E45E876B82100 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = C6BA66AB7BE9C1B35D1FEEA4378F5D1C /* GoogleAPIClientForREST.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST.modulemap"; - PRODUCT_MODULE_NAME = GoogleAPIClientForREST; - PRODUCT_NAME = GoogleAPIClientForREST; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 4.0; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - 310A7C2D9EB41AC5A1EA77050797C1CF /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = C6BA66AB7BE9C1B35D1FEEA4378F5D1C /* GoogleAPIClientForREST.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST.modulemap"; - PRODUCT_MODULE_NAME = GoogleAPIClientForREST; - PRODUCT_NAME = GoogleAPIClientForREST; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 4.0; - TARGETED_DEVICE_FAMILY = "1,2"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 31667BB5CFC7B8D4C8E24E1A05DE6F20 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = E8ABC734EC5D76410142B606FB284CB9 /* FirebaseAnalytics.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "iPhone Developer"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 3533CB8438160A7CEA06ADAB9FF2F53C /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 66B1B5E0F02389648F7D7F08EE92449E /* FirebaseCore.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/FirebaseCore/FirebaseCore-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/FirebaseCore/FirebaseCore.modulemap"; - PRODUCT_MODULE_NAME = FirebaseCore; - PRODUCT_NAME = FirebaseCore; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 4.0; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - 3DDB11D040453637BA5D7B834E0A0DC3 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = A61A5FBB4C4917E85820D47EA05A7A31 /* Pods-TeachersAssistant.release.xcconfig */; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-TeachersAssistant/Pods-TeachersAssistant-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-TeachersAssistant/Pods-TeachersAssistant.modulemap"; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - 58C4DFAAABA5B1ADD585B075C392989E /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 069518B8B1116A7286048E10777CE4B1 /* Firebase.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "iPhone Developer"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; + "$(inherited)", + ); + 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 = 9.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRIP_INSTALLED_PRODUCT = NO; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + SYMROOT = "${SRCROOT}/../build"; }; name = Debug; }; - 7F4D756E8156ED9F30F40B92F6C0AEA4 /* Release */ = { + 5BA2225F9AE586EADCD275389B01C0DC /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 26EEA6C6A294786C4626A5D90B0CC7A8 /* FirebaseInstanceID.xcconfig */; + baseConfigurationReference = 712DF69EA41A4DDB46B20CF5E438D55F /* Pods-TeachersAssistant.release.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -2362,18 +354,19 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/FirebaseInstanceID/FirebaseInstanceID-Info.plist"; + INFOPLIST_FILE = "Target Support Files/Pods-TeachersAssistant/Pods-TeachersAssistant-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/FirebaseInstanceID/FirebaseInstanceID.modulemap"; - PRODUCT_MODULE_NAME = FirebaseInstanceID; - PRODUCT_NAME = FirebaseInstanceID; + MODULEMAP_FILE = "Target Support Files/Pods-TeachersAssistant/Pods-TeachersAssistant.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; @@ -2381,40 +374,9 @@ }; name = Release; }; - 8545458A45F896E5207861008FCC568E /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 66B1B5E0F02389648F7D7F08EE92449E /* FirebaseCore.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/FirebaseCore/FirebaseCore-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/FirebaseCore/FirebaseCore.modulemap"; - PRODUCT_MODULE_NAME = FirebaseCore; - PRODUCT_NAME = FirebaseCore; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 4.0; - TARGETED_DEVICE_FAMILY = "1,2"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 861A432984C82E905B9F26DA86C47709 /* Debug */ = { + A1899AE4F7FA8258ED4A618C851BBCFD /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 80D0ABF6F63F3EF080A906F8C625412E /* Pods-TeachersAssistant.debug.xcconfig */; + baseConfigurationReference = B69955D80F9E5A6D8CD476BCD08F9999 /* Pods-TeachersAssistant.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CODE_SIGN_IDENTITY = ""; @@ -2445,20 +407,6 @@ }; name = Debug; }; - 9D31AF365B999422C95ED9755B2E8F0F /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 069518B8B1116A7286048E10777CE4B1 /* Firebase.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "iPhone Developer"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; A1962E6FF39BBAC201A2E5DDF99557DF /* Release */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2521,7 +469,7 @@ }; A91C1089EC051EA16D3436CB75BBDD4E /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A40C263DBAD4C39D2E09F730467D5085 /* Pods-TeachersAssistantTests.debug.xcconfig */; + baseConfigurationReference = 8697266AF1651BBCB0E02A6818EC909A /* Pods-TeachersAssistantTests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CODE_SIGN_IDENTITY = ""; @@ -2552,131 +500,9 @@ }; name = Debug; }; - B152863C5CAB9435224A4B4B99FB9056 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 81BAD96EB0AFAC3A8B603522A2FD846D /* GoogleUtilities.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/GoogleUtilities/GoogleUtilities-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/GoogleUtilities/GoogleUtilities-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/GoogleUtilities/GoogleUtilities.modulemap"; - PRODUCT_MODULE_NAME = GoogleUtilities; - PRODUCT_NAME = GoogleUtilities; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 4.0; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - D39AE346BB890EE92D52B4365CF97C8E /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 8416808131C45D6E3E6BC32C40C76A82 /* GoogleAppMeasurement.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "iPhone Developer"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - D3FA7F3570E2CF3159A5CBBF6D6D03EB /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 8416808131C45D6E3E6BC32C40C76A82 /* GoogleAppMeasurement.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "iPhone Developer"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - D6EB5AEAC28EC7AAE85BD1E933FB690C /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 0A22E7D0390892ECB350FFF998A271D0 /* GTMSessionFetcher.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/GTMSessionFetcher/GTMSessionFetcher-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/GTMSessionFetcher/GTMSessionFetcher-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/GTMSessionFetcher/GTMSessionFetcher.modulemap"; - PRODUCT_MODULE_NAME = GTMSessionFetcher; - PRODUCT_NAME = GTMSessionFetcher; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 4.0; - TARGETED_DEVICE_FAMILY = "1,2"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - D882A20A5AA7EA50AAF3215480D4722C /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = ADF1B1D4D72635AB6E8D3C36D8D89A6C /* nanopb.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/nanopb/nanopb-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/nanopb/nanopb-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/nanopb/nanopb.modulemap"; - PRODUCT_MODULE_NAME = nanopb; - PRODUCT_NAME = nanopb; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 4.0; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; F045264B613674F3119ECB97E01F2E61 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = FE024B7689A72CA8CC54C9B407F9507C /* Pods-TeachersAssistantTests.release.xcconfig */; + baseConfigurationReference = 5DE088C489A470F3DBB49C659AE00CE2 /* Pods-TeachersAssistantTests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CODE_SIGN_IDENTITY = ""; @@ -2708,117 +534,14 @@ }; name = Release; }; - F587407A3C5808F95C6CB5151809FBF9 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 0A22E7D0390892ECB350FFF998A271D0 /* GTMSessionFetcher.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/GTMSessionFetcher/GTMSessionFetcher-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/GTMSessionFetcher/GTMSessionFetcher-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/GTMSessionFetcher/GTMSessionFetcher.modulemap"; - PRODUCT_MODULE_NAME = GTMSessionFetcher; - PRODUCT_NAME = GTMSessionFetcher; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 4.0; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - FB0FE76ECC42F40FB47968B8BBDE0E0B /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 26EEA6C6A294786C4626A5D90B0CC7A8 /* FirebaseInstanceID.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/FirebaseInstanceID/FirebaseInstanceID-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/FirebaseInstanceID/FirebaseInstanceID.modulemap"; - PRODUCT_MODULE_NAME = FirebaseInstanceID; - PRODUCT_NAME = FirebaseInstanceID; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 4.0; - TARGETED_DEVICE_FAMILY = "1,2"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - FFB7DBE7747FE7B036A3959B526D616C /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = ADF1B1D4D72635AB6E8D3C36D8D89A6C /* nanopb.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/nanopb/nanopb-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/nanopb/nanopb-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/nanopb/nanopb.modulemap"; - PRODUCT_MODULE_NAME = nanopb; - PRODUCT_NAME = nanopb; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 4.0; - TARGETED_DEVICE_FAMILY = "1,2"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 17528847ED7361712D5774B3F57F412E /* Build configuration list for PBXNativeTarget "FirebaseInstanceID" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - FB0FE76ECC42F40FB47968B8BBDE0E0B /* Debug */, - 7F4D756E8156ED9F30F40B92F6C0AEA4 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 272C318C3C138518DD0B0FB5BF575E70 /* Build configuration list for PBXNativeTarget "FirebaseCore" */ = { + 04D114BD04630F88DEBEECF7CD6022A7 /* Build configuration list for PBXNativeTarget "Pods-TeachersAssistant" */ = { isa = XCConfigurationList; buildConfigurations = ( - 8545458A45F896E5207861008FCC568E /* Debug */, - 3533CB8438160A7CEA06ADAB9FF2F53C /* Release */, + A1899AE4F7FA8258ED4A618C851BBCFD /* Debug */, + 5BA2225F9AE586EADCD275389B01C0DC /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -2841,78 +564,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4E2FA166349EB1570B43A20CD7C75E62 /* Build configuration list for PBXNativeTarget "Pods-TeachersAssistant" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 861A432984C82E905B9F26DA86C47709 /* Debug */, - 3DDB11D040453637BA5D7B834E0A0DC3 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 7F06B8F325208699248FA6C351C472D4 /* Build configuration list for PBXNativeTarget "nanopb" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - FFB7DBE7747FE7B036A3959B526D616C /* Debug */, - D882A20A5AA7EA50AAF3215480D4722C /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 89E0E08DEE3712E3F0EB975775425754 /* Build configuration list for PBXNativeTarget "GoogleAPIClientForREST" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 310A7C2D9EB41AC5A1EA77050797C1CF /* Debug */, - 20A9A4E87D934379BD3E45E876B82100 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - A0F94913EC690DC5D7F6D981D004310A /* Build configuration list for PBXNativeTarget "GTMSessionFetcher" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - D6EB5AEAC28EC7AAE85BD1E933FB690C /* Debug */, - F587407A3C5808F95C6CB5151809FBF9 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - BC00811E082341577790995EE25EA091 /* Build configuration list for PBXNativeTarget "GoogleUtilities" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1AF9C8CAFEB4999C4459A2A076CB87EA /* Debug */, - B152863C5CAB9435224A4B4B99FB9056 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - D5F445878D2BF274AA19BE3720E017FD /* Build configuration list for PBXAggregateTarget "Firebase" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 58C4DFAAABA5B1ADD585B075C392989E /* Debug */, - 9D31AF365B999422C95ED9755B2E8F0F /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - D714EFAF91AF42119B673C282ADF2B13 /* Build configuration list for PBXAggregateTarget "GoogleAppMeasurement" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - D3FA7F3570E2CF3159A5CBBF6D6D03EB /* Debug */, - D39AE346BB890EE92D52B4365CF97C8E /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - F7B9206E26DEB0994836EBA1FC0E2DE6 /* Build configuration list for PBXAggregateTarget "FirebaseAnalytics" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 16393E98E7D33B078F35DAD0BF562519 /* Debug */, - 31667BB5CFC7B8D4C8E24E1A05DE6F20 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; /* End XCConfigurationList section */ }; rootObject = BFDFE7DC352907FC980B868725387E98 /* Project object */; diff --git a/Pods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/Firebase.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/Firebase.xcscheme @@ -1,60 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Scheme - LastUpgradeVersion = "0930" - version = "1.3"> - <BuildAction - parallelizeBuildables = "YES" - buildImplicitDependencies = "YES"> - <BuildActionEntries> - <BuildActionEntry - buildForAnalyzing = "YES" - buildForTesting = "YES" - buildForRunning = "YES" - buildForProfiling = "YES" - buildForArchiving = "YES"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "799B29F9D6DCE28B98CC259440382F20" - BuildableName = "Firebase" - BlueprintName = "Firebase" - ReferencedContainer = "container:Pods.xcodeproj"> - </BuildableReference> - </BuildActionEntry> - </BuildActionEntries> - </BuildAction> - <TestAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES" - buildConfiguration = "Debug"> - <AdditionalOptions> - </AdditionalOptions> - </TestAction> - <LaunchAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "0" - useCustomWorkingDirectory = "NO" - ignoresPersistentStateOnLaunch = "NO" - debugDocumentVersioning = "YES" - debugServiceExtension = "internal" - buildConfiguration = "Debug" - allowLocationSimulation = "YES"> - <AdditionalOptions> - </AdditionalOptions> - </LaunchAction> - <ProfileAction - savedToolIdentifier = "" - useCustomWorkingDirectory = "NO" - debugDocumentVersioning = "YES" - buildConfiguration = "Release" - shouldUseLaunchSchemeArgsEnv = "YES"> - </ProfileAction> - <AnalyzeAction - buildConfiguration = "Debug"> - </AnalyzeAction> - <ArchiveAction - buildConfiguration = "Release" - revealArchiveInOrganizer = "YES"> - </ArchiveAction> -</Scheme> diff --git a/Pods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/FirebaseAnalytics.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/FirebaseAnalytics.xcscheme @@ -1,60 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Scheme - LastUpgradeVersion = "0930" - version = "1.3"> - <BuildAction - parallelizeBuildables = "YES" - buildImplicitDependencies = "YES"> - <BuildActionEntries> - <BuildActionEntry - buildForAnalyzing = "YES" - buildForTesting = "YES" - buildForRunning = "YES" - buildForProfiling = "YES" - buildForArchiving = "YES"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "232D00D8ED7797390FB38004DE01723B" - BuildableName = "FirebaseAnalytics" - BlueprintName = "FirebaseAnalytics" - ReferencedContainer = "container:Pods.xcodeproj"> - </BuildableReference> - </BuildActionEntry> - </BuildActionEntries> - </BuildAction> - <TestAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES" - buildConfiguration = "Debug"> - <AdditionalOptions> - </AdditionalOptions> - </TestAction> - <LaunchAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "0" - useCustomWorkingDirectory = "NO" - ignoresPersistentStateOnLaunch = "NO" - debugDocumentVersioning = "YES" - debugServiceExtension = "internal" - buildConfiguration = "Debug" - allowLocationSimulation = "YES"> - <AdditionalOptions> - </AdditionalOptions> - </LaunchAction> - <ProfileAction - savedToolIdentifier = "" - useCustomWorkingDirectory = "NO" - debugDocumentVersioning = "YES" - buildConfiguration = "Release" - shouldUseLaunchSchemeArgsEnv = "YES"> - </ProfileAction> - <AnalyzeAction - buildConfiguration = "Debug"> - </AnalyzeAction> - <ArchiveAction - buildConfiguration = "Release" - revealArchiveInOrganizer = "YES"> - </ArchiveAction> -</Scheme> diff --git a/Pods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/FirebaseCore.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/FirebaseCore.xcscheme @@ -1,60 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Scheme - LastUpgradeVersion = "0930" - version = "1.3"> - <BuildAction - parallelizeBuildables = "YES" - buildImplicitDependencies = "YES"> - <BuildActionEntries> - <BuildActionEntry - buildForAnalyzing = "YES" - buildForTesting = "YES" - buildForRunning = "YES" - buildForProfiling = "YES" - buildForArchiving = "YES"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "01B53B6A43CBD6D4022A361BBFCCE665" - BuildableName = "FirebaseCore.framework" - BlueprintName = "FirebaseCore" - ReferencedContainer = "container:Pods.xcodeproj"> - </BuildableReference> - </BuildActionEntry> - </BuildActionEntries> - </BuildAction> - <TestAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES" - buildConfiguration = "Debug"> - <AdditionalOptions> - </AdditionalOptions> - </TestAction> - <LaunchAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "0" - useCustomWorkingDirectory = "NO" - ignoresPersistentStateOnLaunch = "NO" - debugDocumentVersioning = "YES" - debugServiceExtension = "internal" - buildConfiguration = "Debug" - allowLocationSimulation = "YES"> - <AdditionalOptions> - </AdditionalOptions> - </LaunchAction> - <ProfileAction - savedToolIdentifier = "" - useCustomWorkingDirectory = "NO" - debugDocumentVersioning = "YES" - buildConfiguration = "Release" - shouldUseLaunchSchemeArgsEnv = "YES"> - </ProfileAction> - <AnalyzeAction - buildConfiguration = "Debug"> - </AnalyzeAction> - <ArchiveAction - buildConfiguration = "Release" - revealArchiveInOrganizer = "YES"> - </ArchiveAction> -</Scheme> diff --git a/Pods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/FirebaseInstanceID.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/FirebaseInstanceID.xcscheme @@ -1,60 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Scheme - LastUpgradeVersion = "0930" - version = "1.3"> - <BuildAction - parallelizeBuildables = "YES" - buildImplicitDependencies = "YES"> - <BuildActionEntries> - <BuildActionEntry - buildForAnalyzing = "YES" - buildForTesting = "YES" - buildForRunning = "YES" - buildForProfiling = "YES" - buildForArchiving = "YES"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "3C6A9BF574C3488966C92C6A9B93CA8C" - BuildableName = "FirebaseInstanceID.framework" - BlueprintName = "FirebaseInstanceID" - ReferencedContainer = "container:Pods.xcodeproj"> - </BuildableReference> - </BuildActionEntry> - </BuildActionEntries> - </BuildAction> - <TestAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES" - buildConfiguration = "Debug"> - <AdditionalOptions> - </AdditionalOptions> - </TestAction> - <LaunchAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "0" - useCustomWorkingDirectory = "NO" - ignoresPersistentStateOnLaunch = "NO" - debugDocumentVersioning = "YES" - debugServiceExtension = "internal" - buildConfiguration = "Debug" - allowLocationSimulation = "YES"> - <AdditionalOptions> - </AdditionalOptions> - </LaunchAction> - <ProfileAction - savedToolIdentifier = "" - useCustomWorkingDirectory = "NO" - debugDocumentVersioning = "YES" - buildConfiguration = "Release" - shouldUseLaunchSchemeArgsEnv = "YES"> - </ProfileAction> - <AnalyzeAction - buildConfiguration = "Debug"> - </AnalyzeAction> - <ArchiveAction - buildConfiguration = "Release" - revealArchiveInOrganizer = "YES"> - </ArchiveAction> -</Scheme> diff --git a/Pods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/GTMSessionFetcher.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/GTMSessionFetcher.xcscheme @@ -1,60 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Scheme - LastUpgradeVersion = "0930" - version = "1.3"> - <BuildAction - parallelizeBuildables = "YES" - buildImplicitDependencies = "YES"> - <BuildActionEntries> - <BuildActionEntry - buildForAnalyzing = "YES" - buildForTesting = "YES" - buildForRunning = "YES" - buildForProfiling = "YES" - buildForArchiving = "YES"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "D811FCD6F8EBFE221BF9D923CEFB5CE8" - BuildableName = "GTMSessionFetcher.framework" - BlueprintName = "GTMSessionFetcher" - ReferencedContainer = "container:Pods.xcodeproj"> - </BuildableReference> - </BuildActionEntry> - </BuildActionEntries> - </BuildAction> - <TestAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES" - buildConfiguration = "Debug"> - <AdditionalOptions> - </AdditionalOptions> - </TestAction> - <LaunchAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "0" - useCustomWorkingDirectory = "NO" - ignoresPersistentStateOnLaunch = "NO" - debugDocumentVersioning = "YES" - debugServiceExtension = "internal" - buildConfiguration = "Debug" - allowLocationSimulation = "YES"> - <AdditionalOptions> - </AdditionalOptions> - </LaunchAction> - <ProfileAction - savedToolIdentifier = "" - useCustomWorkingDirectory = "NO" - debugDocumentVersioning = "YES" - buildConfiguration = "Release" - shouldUseLaunchSchemeArgsEnv = "YES"> - </ProfileAction> - <AnalyzeAction - buildConfiguration = "Debug"> - </AnalyzeAction> - <ArchiveAction - buildConfiguration = "Release" - revealArchiveInOrganizer = "YES"> - </ArchiveAction> -</Scheme> diff --git a/Pods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/GoogleAPIClientForREST.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/GoogleAPIClientForREST.xcscheme @@ -1,60 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Scheme - LastUpgradeVersion = "0930" - version = "1.3"> - <BuildAction - parallelizeBuildables = "YES" - buildImplicitDependencies = "YES"> - <BuildActionEntries> - <BuildActionEntry - buildForAnalyzing = "YES" - buildForTesting = "YES" - buildForRunning = "YES" - buildForProfiling = "YES" - buildForArchiving = "YES"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "772340DB04E857CA1ABBDB7EC1CA7079" - BuildableName = "GoogleAPIClientForREST.framework" - BlueprintName = "GoogleAPIClientForREST" - ReferencedContainer = "container:Pods.xcodeproj"> - </BuildableReference> - </BuildActionEntry> - </BuildActionEntries> - </BuildAction> - <TestAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES" - buildConfiguration = "Debug"> - <AdditionalOptions> - </AdditionalOptions> - </TestAction> - <LaunchAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "0" - useCustomWorkingDirectory = "NO" - ignoresPersistentStateOnLaunch = "NO" - debugDocumentVersioning = "YES" - debugServiceExtension = "internal" - buildConfiguration = "Debug" - allowLocationSimulation = "YES"> - <AdditionalOptions> - </AdditionalOptions> - </LaunchAction> - <ProfileAction - savedToolIdentifier = "" - useCustomWorkingDirectory = "NO" - debugDocumentVersioning = "YES" - buildConfiguration = "Release" - shouldUseLaunchSchemeArgsEnv = "YES"> - </ProfileAction> - <AnalyzeAction - buildConfiguration = "Debug"> - </AnalyzeAction> - <ArchiveAction - buildConfiguration = "Release" - revealArchiveInOrganizer = "YES"> - </ArchiveAction> -</Scheme> diff --git a/Pods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/GoogleAppMeasurement.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/GoogleAppMeasurement.xcscheme @@ -1,60 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Scheme - LastUpgradeVersion = "0930" - version = "1.3"> - <BuildAction - parallelizeBuildables = "YES" - buildImplicitDependencies = "YES"> - <BuildActionEntries> - <BuildActionEntry - buildForAnalyzing = "YES" - buildForTesting = "YES" - buildForRunning = "YES" - buildForProfiling = "YES" - buildForArchiving = "YES"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "57B9E0A892EAB5C13D4AE7D4B1DE0C16" - BuildableName = "GoogleAppMeasurement" - BlueprintName = "GoogleAppMeasurement" - ReferencedContainer = "container:Pods.xcodeproj"> - </BuildableReference> - </BuildActionEntry> - </BuildActionEntries> - </BuildAction> - <TestAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES" - buildConfiguration = "Debug"> - <AdditionalOptions> - </AdditionalOptions> - </TestAction> - <LaunchAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "0" - useCustomWorkingDirectory = "NO" - ignoresPersistentStateOnLaunch = "NO" - debugDocumentVersioning = "YES" - debugServiceExtension = "internal" - buildConfiguration = "Debug" - allowLocationSimulation = "YES"> - <AdditionalOptions> - </AdditionalOptions> - </LaunchAction> - <ProfileAction - savedToolIdentifier = "" - useCustomWorkingDirectory = "NO" - debugDocumentVersioning = "YES" - buildConfiguration = "Release" - shouldUseLaunchSchemeArgsEnv = "YES"> - </ProfileAction> - <AnalyzeAction - buildConfiguration = "Debug"> - </AnalyzeAction> - <ArchiveAction - buildConfiguration = "Release" - revealArchiveInOrganizer = "YES"> - </ArchiveAction> -</Scheme> diff --git a/Pods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/GoogleUtilities.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/GoogleUtilities.xcscheme @@ -1,60 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Scheme - LastUpgradeVersion = "0930" - version = "1.3"> - <BuildAction - parallelizeBuildables = "YES" - buildImplicitDependencies = "YES"> - <BuildActionEntries> - <BuildActionEntry - buildForAnalyzing = "YES" - buildForTesting = "YES" - buildForRunning = "YES" - buildForProfiling = "YES" - buildForArchiving = "YES"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "D9A2B7F6350AE8AB9AAFF5A9395AD63C" - BuildableName = "GoogleUtilities.framework" - BlueprintName = "GoogleUtilities" - ReferencedContainer = "container:Pods.xcodeproj"> - </BuildableReference> - </BuildActionEntry> - </BuildActionEntries> - </BuildAction> - <TestAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES" - buildConfiguration = "Debug"> - <AdditionalOptions> - </AdditionalOptions> - </TestAction> - <LaunchAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "0" - useCustomWorkingDirectory = "NO" - ignoresPersistentStateOnLaunch = "NO" - debugDocumentVersioning = "YES" - debugServiceExtension = "internal" - buildConfiguration = "Debug" - allowLocationSimulation = "YES"> - <AdditionalOptions> - </AdditionalOptions> - </LaunchAction> - <ProfileAction - savedToolIdentifier = "" - useCustomWorkingDirectory = "NO" - debugDocumentVersioning = "YES" - buildConfiguration = "Release" - shouldUseLaunchSchemeArgsEnv = "YES"> - </ProfileAction> - <AnalyzeAction - buildConfiguration = "Debug"> - </AnalyzeAction> - <ArchiveAction - buildConfiguration = "Release" - revealArchiveInOrganizer = "YES"> - </ArchiveAction> -</Scheme> diff --git a/Pods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/Pods-TeachersAssistant.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/Pods-TeachersAssistant.xcscheme @@ -14,7 +14,7 @@ buildForAnalyzing = "YES"> <BuildableReference BuildableIdentifier = "primary" - BlueprintIdentifier = "C1DBAA447353B7E3A4A495D068C464D8" + BlueprintIdentifier = "DC3A57A44D7A30108A57480929F8FDFE" BuildableName = "Pods_TeachersAssistant.framework" BlueprintName = "Pods-TeachersAssistant" ReferencedContainer = "container:Pods.xcodeproj"> @@ -47,7 +47,7 @@ <MacroExpansion> <BuildableReference BuildableIdentifier = "primary" - BlueprintIdentifier = "C1DBAA447353B7E3A4A495D068C464D8" + BlueprintIdentifier = "DC3A57A44D7A30108A57480929F8FDFE" BuildableName = "Pods_TeachersAssistant.framework" BlueprintName = "Pods-TeachersAssistant" ReferencedContainer = "container:Pods.xcodeproj"> diff --git a/Pods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/nanopb.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/nanopb.xcscheme @@ -1,60 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Scheme - LastUpgradeVersion = "0930" - version = "1.3"> - <BuildAction - parallelizeBuildables = "YES" - buildImplicitDependencies = "YES"> - <BuildActionEntries> - <BuildActionEntry - buildForAnalyzing = "YES" - buildForTesting = "YES" - buildForRunning = "YES" - buildForProfiling = "YES" - buildForArchiving = "YES"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "E93C48A48FB03EA19C4F756B97B5F1D3" - BuildableName = "nanopb.framework" - BlueprintName = "nanopb" - ReferencedContainer = "container:Pods.xcodeproj"> - </BuildableReference> - </BuildActionEntry> - </BuildActionEntries> - </BuildAction> - <TestAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES" - buildConfiguration = "Debug"> - <AdditionalOptions> - </AdditionalOptions> - </TestAction> - <LaunchAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "0" - useCustomWorkingDirectory = "NO" - ignoresPersistentStateOnLaunch = "NO" - debugDocumentVersioning = "YES" - debugServiceExtension = "internal" - buildConfiguration = "Debug" - allowLocationSimulation = "YES"> - <AdditionalOptions> - </AdditionalOptions> - </LaunchAction> - <ProfileAction - savedToolIdentifier = "" - useCustomWorkingDirectory = "NO" - debugDocumentVersioning = "YES" - buildConfiguration = "Release" - shouldUseLaunchSchemeArgsEnv = "YES"> - </ProfileAction> - <AnalyzeAction - buildConfiguration = "Debug"> - </AnalyzeAction> - <ArchiveAction - buildConfiguration = "Release" - revealArchiveInOrganizer = "YES"> - </ArchiveAction> -</Scheme> diff --git a/Pods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/xcschememanagement.plist b/Pods/Pods.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/xcschememanagement.plist @@ -4,82 +4,19 @@ <dict> <key>SchemeUserState</key> <dict> - <key>Firebase.xcscheme</key> - <dict> - <key>isShown</key> - <false/> - <key>orderHint</key> - <integer>0</integer> - </dict> - <key>FirebaseAnalytics.xcscheme</key> - <dict> - <key>isShown</key> - <false/> - <key>orderHint</key> - <integer>1</integer> - </dict> - <key>FirebaseCore.xcscheme</key> - <dict> - <key>isShown</key> - <false/> - <key>orderHint</key> - <integer>2</integer> - </dict> - <key>FirebaseInstanceID.xcscheme</key> - <dict> - <key>isShown</key> - <false/> - <key>orderHint</key> - <integer>3</integer> - </dict> - <key>GTMSessionFetcher.xcscheme</key> - <dict> - <key>isShown</key> - <false/> - <key>orderHint</key> - <integer>7</integer> - </dict> - <key>GoogleAPIClientForREST.xcscheme</key> - <dict> - <key>isShown</key> - <false/> - <key>orderHint</key> - <integer>4</integer> - </dict> - <key>GoogleAppMeasurement.xcscheme</key> - <dict> - <key>isShown</key> - <false/> - <key>orderHint</key> - <integer>5</integer> - </dict> - <key>GoogleUtilities.xcscheme</key> - <dict> - <key>isShown</key> - <false/> - <key>orderHint</key> - <integer>6</integer> - </dict> <key>Pods-TeachersAssistant.xcscheme</key> <dict> <key>isShown</key> <false/> <key>orderHint</key> - <integer>9</integer> + <integer>0</integer> </dict> <key>Pods-TeachersAssistantTests.xcscheme</key> <dict> <key>isShown</key> <false/> <key>orderHint</key> - <integer>10</integer> - </dict> - <key>nanopb.xcscheme</key> - <dict> - <key>isShown</key> - <false/> - <key>orderHint</key> - <integer>8</integer> + <integer>1</integer> </dict> </dict> <key>SuppressBuildableAutocreation</key> diff --git a/Pods/Target Support Files/Firebase/Firebase.xcconfig b/Pods/Target Support Files/Firebase/Firebase.xcconfig @@ -1,10 +0,0 @@ -CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Firebase -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" -GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Firebase" "${PODS_ROOT}/Headers/Public" -PODS_BUILD_DIR = ${BUILD_DIR} -PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) -PODS_ROOT = ${SRCROOT} -PODS_TARGET_SRCROOT = ${PODS_ROOT}/Firebase -PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} -SKIP_INSTALL = YES diff --git a/Pods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics.xcconfig b/Pods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics.xcconfig @@ -1,10 +0,0 @@ -CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseAnalytics -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" -GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -OTHER_LDFLAGS = $(inherited) -l"c++" -l"sqlite3" -l"z" -framework "StoreKit" -PODS_BUILD_DIR = ${BUILD_DIR} -PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) -PODS_ROOT = ${SRCROOT} -PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseAnalytics -PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} -SKIP_INSTALL = YES diff --git a/Pods/Target Support Files/FirebaseCore/FirebaseCore-Info.plist b/Pods/Target Support Files/FirebaseCore/FirebaseCore-Info.plist @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>en</string> - <key>CFBundleExecutable</key> - <string>${EXECUTABLE_NAME}</string> - <key>CFBundleIdentifier</key> - <string>${PRODUCT_BUNDLE_IDENTIFIER}</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>${PRODUCT_NAME}</string> - <key>CFBundlePackageType</key> - <string>FMWK</string> - <key>CFBundleShortVersionString</key> - <string>5.3.1</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>${CURRENT_PROJECT_VERSION}</string> - <key>NSPrincipalClass</key> - <string></string> -</dict> -</plist> diff --git a/Pods/Target Support Files/FirebaseCore/FirebaseCore-dummy.m b/Pods/Target Support Files/FirebaseCore/FirebaseCore-dummy.m @@ -1,5 +0,0 @@ -#import <Foundation/Foundation.h> -@interface PodsDummy_FirebaseCore : NSObject -@end -@implementation PodsDummy_FirebaseCore -@end diff --git a/Pods/Target Support Files/FirebaseCore/FirebaseCore-umbrella.h b/Pods/Target Support Files/FirebaseCore/FirebaseCore-umbrella.h @@ -1,22 +0,0 @@ -#ifdef __OBJC__ -#import <UIKit/UIKit.h> -#else -#ifndef FOUNDATION_EXPORT -#if defined(__cplusplus) -#define FOUNDATION_EXPORT extern "C" -#else -#define FOUNDATION_EXPORT extern -#endif -#endif -#endif - -#import "FIRAnalyticsConfiguration.h" -#import "FIRApp.h" -#import "FIRConfiguration.h" -#import "FirebaseCore.h" -#import "FIRLoggerLevel.h" -#import "FIROptions.h" - -FOUNDATION_EXPORT double FirebaseCoreVersionNumber; -FOUNDATION_EXPORT const unsigned char FirebaseCoreVersionString[]; - diff --git a/Pods/Target Support Files/FirebaseCore/FirebaseCore.modulemap b/Pods/Target Support Files/FirebaseCore/FirebaseCore.modulemap @@ -1,6 +0,0 @@ -framework module FirebaseCore { - umbrella header "FirebaseCore-umbrella.h" - - export * - module * { export * } -} diff --git a/Pods/Target Support Files/FirebaseCore/FirebaseCore.xcconfig b/Pods/Target Support Files/FirebaseCore/FirebaseCore.xcconfig @@ -1,11 +0,0 @@ -CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" -GCC_C_LANGUAGE_STANDARD = c99 -GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 FIRCore_VERSION=5.3.1 Firebase_VERSION=5.18.0 -OTHER_CFLAGS = -fno-autolink -PODS_BUILD_DIR = ${BUILD_DIR} -PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) -PODS_ROOT = ${SRCROOT} -PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseCore -PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} -SKIP_INSTALL = YES diff --git a/Pods/Target Support Files/FirebaseInstanceID/FirebaseInstanceID-Info.plist b/Pods/Target Support Files/FirebaseInstanceID/FirebaseInstanceID-Info.plist @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>en</string> - <key>CFBundleExecutable</key> - <string>${EXECUTABLE_NAME}</string> - <key>CFBundleIdentifier</key> - <string>${PRODUCT_BUNDLE_IDENTIFIER}</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>${PRODUCT_NAME}</string> - <key>CFBundlePackageType</key> - <string>FMWK</string> - <key>CFBundleShortVersionString</key> - <string>3.7.0</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>${CURRENT_PROJECT_VERSION}</string> - <key>NSPrincipalClass</key> - <string></string> -</dict> -</plist> diff --git a/Pods/Target Support Files/FirebaseInstanceID/FirebaseInstanceID-dummy.m b/Pods/Target Support Files/FirebaseInstanceID/FirebaseInstanceID-dummy.m @@ -1,5 +0,0 @@ -#import <Foundation/Foundation.h> -@interface PodsDummy_FirebaseInstanceID : NSObject -@end -@implementation PodsDummy_FirebaseInstanceID -@end diff --git a/Pods/Target Support Files/FirebaseInstanceID/FirebaseInstanceID-umbrella.h b/Pods/Target Support Files/FirebaseInstanceID/FirebaseInstanceID-umbrella.h @@ -1,18 +0,0 @@ -#ifdef __OBJC__ -#import <UIKit/UIKit.h> -#else -#ifndef FOUNDATION_EXPORT -#if defined(__cplusplus) -#define FOUNDATION_EXPORT extern "C" -#else -#define FOUNDATION_EXPORT extern -#endif -#endif -#endif - -#import "FirebaseInstanceID.h" -#import "FIRInstanceID.h" - -FOUNDATION_EXPORT double FirebaseInstanceIDVersionNumber; -FOUNDATION_EXPORT const unsigned char FirebaseInstanceIDVersionString[]; - diff --git a/Pods/Target Support Files/FirebaseInstanceID/FirebaseInstanceID.modulemap b/Pods/Target Support Files/FirebaseInstanceID/FirebaseInstanceID.modulemap @@ -1,6 +0,0 @@ -framework module FirebaseInstanceID { - umbrella header "FirebaseInstanceID-umbrella.h" - - export * - module * { export * } -} diff --git a/Pods/Target Support Files/FirebaseInstanceID/FirebaseInstanceID.xcconfig b/Pods/Target Support Files/FirebaseInstanceID/FirebaseInstanceID.xcconfig @@ -1,10 +0,0 @@ -CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" -GCC_C_LANGUAGE_STANDARD = c99 -GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 FIRInstanceID_LIB_VERSION=3.7.0 -PODS_BUILD_DIR = ${BUILD_DIR} -PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) -PODS_ROOT = ${SRCROOT} -PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseInstanceID -PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} -SKIP_INSTALL = YES diff --git a/Pods/Target Support Files/GTMSessionFetcher/GTMSessionFetcher-Info.plist b/Pods/Target Support Files/GTMSessionFetcher/GTMSessionFetcher-Info.plist @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>en</string> - <key>CFBundleExecutable</key> - <string>${EXECUTABLE_NAME}</string> - <key>CFBundleIdentifier</key> - <string>${PRODUCT_BUNDLE_IDENTIFIER}</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>${PRODUCT_NAME}</string> - <key>CFBundlePackageType</key> - <string>FMWK</string> - <key>CFBundleShortVersionString</key> - <string>1.2.1</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>${CURRENT_PROJECT_VERSION}</string> - <key>NSPrincipalClass</key> - <string></string> -</dict> -</plist> diff --git a/Pods/Target Support Files/GTMSessionFetcher/GTMSessionFetcher-dummy.m b/Pods/Target Support Files/GTMSessionFetcher/GTMSessionFetcher-dummy.m @@ -1,5 +0,0 @@ -#import <Foundation/Foundation.h> -@interface PodsDummy_GTMSessionFetcher : NSObject -@end -@implementation PodsDummy_GTMSessionFetcher -@end diff --git a/Pods/Target Support Files/GTMSessionFetcher/GTMSessionFetcher-prefix.pch b/Pods/Target Support Files/GTMSessionFetcher/GTMSessionFetcher-prefix.pch @@ -1,12 +0,0 @@ -#ifdef __OBJC__ -#import <UIKit/UIKit.h> -#else -#ifndef FOUNDATION_EXPORT -#if defined(__cplusplus) -#define FOUNDATION_EXPORT extern "C" -#else -#define FOUNDATION_EXPORT extern -#endif -#endif -#endif - diff --git a/Pods/Target Support Files/GTMSessionFetcher/GTMSessionFetcher-umbrella.h b/Pods/Target Support Files/GTMSessionFetcher/GTMSessionFetcher-umbrella.h @@ -1,23 +0,0 @@ -#ifdef __OBJC__ -#import <UIKit/UIKit.h> -#else -#ifndef FOUNDATION_EXPORT -#if defined(__cplusplus) -#define FOUNDATION_EXPORT extern "C" -#else -#define FOUNDATION_EXPORT extern -#endif -#endif -#endif - -#import "GTMSessionFetcher.h" -#import "GTMSessionFetcherLogging.h" -#import "GTMSessionFetcherService.h" -#import "GTMSessionUploadFetcher.h" -#import "GTMGatherInputStream.h" -#import "GTMMIMEDocument.h" -#import "GTMReadMonitorInputStream.h" - -FOUNDATION_EXPORT double GTMSessionFetcherVersionNumber; -FOUNDATION_EXPORT const unsigned char GTMSessionFetcherVersionString[]; - diff --git a/Pods/Target Support Files/GTMSessionFetcher/GTMSessionFetcher.modulemap b/Pods/Target Support Files/GTMSessionFetcher/GTMSessionFetcher.modulemap @@ -1,6 +0,0 @@ -framework module GTMSessionFetcher { - umbrella header "GTMSessionFetcher-umbrella.h" - - export * - module * { export * } -} diff --git a/Pods/Target Support Files/GTMSessionFetcher/GTMSessionFetcher.xcconfig b/Pods/Target Support Files/GTMSessionFetcher/GTMSessionFetcher.xcconfig @@ -1,9 +0,0 @@ -CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher -GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -OTHER_LDFLAGS = $(inherited) -framework "Security" -PODS_BUILD_DIR = ${BUILD_DIR} -PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) -PODS_ROOT = ${SRCROOT} -PODS_TARGET_SRCROOT = ${PODS_ROOT}/GTMSessionFetcher -PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} -SKIP_INSTALL = YES diff --git a/Pods/Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST-Info.plist b/Pods/Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST-Info.plist @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>en</string> - <key>CFBundleExecutable</key> - <string>${EXECUTABLE_NAME}</string> - <key>CFBundleIdentifier</key> - <string>${PRODUCT_BUNDLE_IDENTIFIER}</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>${PRODUCT_NAME}</string> - <key>CFBundlePackageType</key> - <string>FMWK</string> - <key>CFBundleShortVersionString</key> - <string>1.3.8</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>${CURRENT_PROJECT_VERSION}</string> - <key>NSPrincipalClass</key> - <string></string> -</dict> -</plist> diff --git a/Pods/Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST-dummy.m b/Pods/Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST-dummy.m @@ -1,5 +0,0 @@ -#import <Foundation/Foundation.h> -@interface PodsDummy_GoogleAPIClientForREST : NSObject -@end -@implementation PodsDummy_GoogleAPIClientForREST -@end diff --git a/Pods/Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST-prefix.pch b/Pods/Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST-prefix.pch @@ -1,12 +0,0 @@ -#ifdef __OBJC__ -#import <UIKit/UIKit.h> -#else -#ifndef FOUNDATION_EXPORT -#if defined(__cplusplus) -#define FOUNDATION_EXPORT extern "C" -#else -#define FOUNDATION_EXPORT extern -#endif -#endif -#endif - diff --git a/Pods/Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST-umbrella.h b/Pods/Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST-umbrella.h @@ -1,35 +0,0 @@ -#ifdef __OBJC__ -#import <UIKit/UIKit.h> -#else -#ifndef FOUNDATION_EXPORT -#if defined(__cplusplus) -#define FOUNDATION_EXPORT extern "C" -#else -#define FOUNDATION_EXPORT extern -#endif -#endif -#endif - -#import "GTLRDefines.h" -#import "GTLRBatchQuery.h" -#import "GTLRBatchResult.h" -#import "GTLRDateTime.h" -#import "GTLRDuration.h" -#import "GTLRErrorObject.h" -#import "GTLRObject.h" -#import "GTLRQuery.h" -#import "GTLRRuntimeCommon.h" -#import "GTLRService.h" -#import "GTLRUploadParameters.h" -#import "GTLRBase64.h" -#import "GTLRFramework.h" -#import "GTLRURITemplate.h" -#import "GTLRUtilities.h" -#import "GTLRSheets.h" -#import "GTLRSheetsObjects.h" -#import "GTLRSheetsQuery.h" -#import "GTLRSheetsService.h" - -FOUNDATION_EXPORT double GoogleAPIClientForRESTVersionNumber; -FOUNDATION_EXPORT const unsigned char GoogleAPIClientForRESTVersionString[]; - diff --git a/Pods/Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST.modulemap b/Pods/Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST.modulemap @@ -1,6 +0,0 @@ -framework module GoogleAPIClientForREST { - umbrella header "GoogleAPIClientForREST-umbrella.h" - - export * - module * { export * } -} diff --git a/Pods/Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST.xcconfig b/Pods/Target Support Files/GoogleAPIClientForREST/GoogleAPIClientForREST.xcconfig @@ -1,9 +0,0 @@ -CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/GoogleAPIClientForREST -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher" -GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -PODS_BUILD_DIR = ${BUILD_DIR} -PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) -PODS_ROOT = ${SRCROOT} -PODS_TARGET_SRCROOT = ${PODS_ROOT}/GoogleAPIClientForREST -PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} -SKIP_INSTALL = YES diff --git a/Pods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement.xcconfig b/Pods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement.xcconfig @@ -1,10 +0,0 @@ -CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/GoogleAppMeasurement -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" -GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -OTHER_LDFLAGS = $(inherited) -l"c++" -l"sqlite3" -l"z" -framework "StoreKit" -PODS_BUILD_DIR = ${BUILD_DIR} -PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) -PODS_ROOT = ${SRCROOT} -PODS_TARGET_SRCROOT = ${PODS_ROOT}/GoogleAppMeasurement -PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} -SKIP_INSTALL = YES diff --git a/Pods/Target Support Files/GoogleUtilities/GoogleUtilities-Info.plist b/Pods/Target Support Files/GoogleUtilities/GoogleUtilities-Info.plist @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>en</string> - <key>CFBundleExecutable</key> - <string>${EXECUTABLE_NAME}</string> - <key>CFBundleIdentifier</key> - <string>${PRODUCT_BUNDLE_IDENTIFIER}</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>${PRODUCT_NAME}</string> - <key>CFBundlePackageType</key> - <string>FMWK</string> - <key>CFBundleShortVersionString</key> - <string>5.3.7</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>${CURRENT_PROJECT_VERSION}</string> - <key>NSPrincipalClass</key> - <string></string> -</dict> -</plist> diff --git a/Pods/Target Support Files/GoogleUtilities/GoogleUtilities-dummy.m b/Pods/Target Support Files/GoogleUtilities/GoogleUtilities-dummy.m @@ -1,5 +0,0 @@ -#import <Foundation/Foundation.h> -@interface PodsDummy_GoogleUtilities : NSObject -@end -@implementation PodsDummy_GoogleUtilities -@end diff --git a/Pods/Target Support Files/GoogleUtilities/GoogleUtilities-prefix.pch b/Pods/Target Support Files/GoogleUtilities/GoogleUtilities-prefix.pch @@ -1,12 +0,0 @@ -#ifdef __OBJC__ -#import <UIKit/UIKit.h> -#else -#ifndef FOUNDATION_EXPORT -#if defined(__cplusplus) -#define FOUNDATION_EXPORT extern "C" -#else -#define FOUNDATION_EXPORT extern -#endif -#endif -#endif - diff --git a/Pods/Target Support Files/GoogleUtilities/GoogleUtilities-umbrella.h b/Pods/Target Support Files/GoogleUtilities/GoogleUtilities-umbrella.h @@ -1,19 +0,0 @@ -#ifdef __OBJC__ -#import <UIKit/UIKit.h> -#else -#ifndef FOUNDATION_EXPORT -#if defined(__cplusplus) -#define FOUNDATION_EXPORT extern "C" -#else -#define FOUNDATION_EXPORT extern -#endif -#endif -#endif - -#import "GULLoggerLevel.h" -#import "GULLoggerCodes.h" -#import "GULNSData+zlib.h" - -FOUNDATION_EXPORT double GoogleUtilitiesVersionNumber; -FOUNDATION_EXPORT const unsigned char GoogleUtilitiesVersionString[]; - diff --git a/Pods/Target Support Files/GoogleUtilities/GoogleUtilities.modulemap b/Pods/Target Support Files/GoogleUtilities/GoogleUtilities.modulemap @@ -1,6 +0,0 @@ -framework module GoogleUtilities { - umbrella header "GoogleUtilities-umbrella.h" - - export * - module * { export * } -} diff --git a/Pods/Target Support Files/GoogleUtilities/GoogleUtilities.xcconfig b/Pods/Target Support Files/GoogleUtilities/GoogleUtilities.xcconfig @@ -1,9 +0,0 @@ -CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities -GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -OTHER_LDFLAGS = $(inherited) -l"z" -framework "Security" -framework "SystemConfiguration" -PODS_BUILD_DIR = ${BUILD_DIR} -PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) -PODS_ROOT = ${SRCROOT} -PODS_TARGET_SRCROOT = ${PODS_ROOT}/GoogleUtilities -PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} -SKIP_INSTALL = YES diff --git a/Pods/Target Support Files/Pods-TeachersAssistant/Pods-TeachersAssistant-acknowledgements.markdown b/Pods/Target Support Files/Pods-TeachersAssistant/Pods-TeachersAssistant-acknowledgements.markdown @@ -1,1069 +1,3 @@ # Acknowledgements This application makes use of the following third party libraries: - -## Firebase - -Copyright 2019 Google - -## FirebaseAnalytics - -Copyright 2019 Google - -## FirebaseCore - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - -## FirebaseInstanceID - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - -## GTMSessionFetcher - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - -## GoogleAPIClientForREST - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - -## GoogleAppMeasurement - -Copyright 2019 Google - -## GoogleUtilities - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - -## nanopb - -Copyright (c) 2011 Petteri Aimonen <jpa at nanopb.mail.kapsi.fi> - -This software is provided 'as-is', without any express or -implied warranty. In no event will the authors be held liable -for any damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you - must not claim that you wrote the original software. If you use - this software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and - must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source - distribution. - Generated by CocoaPods - https://cocoapods.org diff --git a/Pods/Target Support Files/Pods-TeachersAssistant/Pods-TeachersAssistant-acknowledgements.plist b/Pods/Target Support Files/Pods-TeachersAssistant/Pods-TeachersAssistant-acknowledgements.plist @@ -14,1126 +14,6 @@ </dict> <dict> <key>FooterText</key> - <string>Copyright 2019 Google</string> - <key>License</key> - <string>Copyright</string> - <key>Title</key> - <string>Firebase</string> - <key>Type</key> - <string>PSGroupSpecifier</string> - </dict> - <dict> - <key>FooterText</key> - <string>Copyright 2019 Google</string> - <key>License</key> - <string>Copyright</string> - <key>Title</key> - <string>FirebaseAnalytics</string> - <key>Type</key> - <string>PSGroupSpecifier</string> - </dict> - <dict> - <key>FooterText</key> - <string> - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -</string> - <key>License</key> - <string>Apache</string> - <key>Title</key> - <string>FirebaseCore</string> - <key>Type</key> - <string>PSGroupSpecifier</string> - </dict> - <dict> - <key>FooterText</key> - <string> - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -</string> - <key>License</key> - <string>Apache</string> - <key>Title</key> - <string>FirebaseInstanceID</string> - <key>Type</key> - <string>PSGroupSpecifier</string> - </dict> - <dict> - <key>FooterText</key> - <string> - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -</string> - <key>License</key> - <string>Apache</string> - <key>Title</key> - <string>GTMSessionFetcher</string> - <key>Type</key> - <string>PSGroupSpecifier</string> - </dict> - <dict> - <key>FooterText</key> - <string> - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -</string> - <key>License</key> - <string>Apache</string> - <key>Title</key> - <string>GoogleAPIClientForREST</string> - <key>Type</key> - <string>PSGroupSpecifier</string> - </dict> - <dict> - <key>FooterText</key> - <string>Copyright 2019 Google</string> - <key>License</key> - <string>Copyright</string> - <key>Title</key> - <string>GoogleAppMeasurement</string> - <key>Type</key> - <string>PSGroupSpecifier</string> - </dict> - <dict> - <key>FooterText</key> - <string> - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -</string> - <key>License</key> - <string>Apache</string> - <key>Title</key> - <string>GoogleUtilities</string> - <key>Type</key> - <string>PSGroupSpecifier</string> - </dict> - <dict> - <key>FooterText</key> - <string>Copyright (c) 2011 Petteri Aimonen &lt;jpa at nanopb.mail.kapsi.fi&gt; - -This software is provided 'as-is', without any express or -implied warranty. In no event will the authors be held liable -for any damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you - must not claim that you wrote the original software. If you use - this software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and - must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source - distribution. -</string> - <key>License</key> - <string>zlib</string> - <key>Title</key> - <string>nanopb</string> - <key>Type</key> - <string>PSGroupSpecifier</string> - </dict> - <dict> - <key>FooterText</key> <string>Generated by CocoaPods - https://cocoapods.org</string> <key>Title</key> <string></string> diff --git a/Pods/Target Support Files/Pods-TeachersAssistant/Pods-TeachersAssistant.debug.xcconfig b/Pods/Target Support Files/Pods-TeachersAssistant/Pods-TeachersAssistant.debug.xcconfig @@ -1,8 +1,5 @@ -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID" "${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleAPIClientForREST" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" -GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID/FirebaseInstanceID.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher/GTMSessionFetcher.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleAPIClientForREST/GoogleAPIClientForREST.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb/nanopb.framework/Headers" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Firebase" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' -OTHER_LDFLAGS = $(inherited) -ObjC -l"c++" -l"sqlite3" -l"z" -framework "FIRAnalyticsConnector" -framework "FirebaseAnalytics" -framework "FirebaseCore" -framework "FirebaseCoreDiagnostics" -framework "FirebaseInstanceID" -framework "Foundation" -framework "GTMSessionFetcher" -framework "GoogleAPIClientForREST" -framework "GoogleAppMeasurement" -framework "GoogleUtilities" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "nanopb" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. diff --git a/Pods/Target Support Files/Pods-TeachersAssistant/Pods-TeachersAssistant.release.xcconfig b/Pods/Target Support Files/Pods-TeachersAssistant/Pods-TeachersAssistant.release.xcconfig @@ -1,8 +1,5 @@ -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID" "${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleAPIClientForREST" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" -GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID/FirebaseInstanceID.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher/GTMSessionFetcher.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleAPIClientForREST/GoogleAPIClientForREST.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb/nanopb.framework/Headers" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Firebase" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' -OTHER_LDFLAGS = $(inherited) -ObjC -l"c++" -l"sqlite3" -l"z" -framework "FIRAnalyticsConnector" -framework "FirebaseAnalytics" -framework "FirebaseCore" -framework "FirebaseCoreDiagnostics" -framework "FirebaseInstanceID" -framework "Foundation" -framework "GTMSessionFetcher" -framework "GoogleAPIClientForREST" -framework "GoogleAppMeasurement" -framework "GoogleUtilities" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "nanopb" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. diff --git a/Pods/Target Support Files/Pods-TeachersAssistantTests/Pods-TeachersAssistantTests.debug.xcconfig b/Pods/Target Support Files/Pods-TeachersAssistantTests/Pods-TeachersAssistantTests.debug.xcconfig @@ -1,8 +1,5 @@ -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID" "${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleAPIClientForREST" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" -GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID/FirebaseInstanceID.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher/GTMSessionFetcher.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleAPIClientForREST/GoogleAPIClientForREST.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb/nanopb.framework/Headers" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Firebase" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' -OTHER_LDFLAGS = $(inherited) -l"c++" -l"sqlite3" -l"z" -framework "Foundation" -framework "GTMSessionFetcher" -framework "GoogleAPIClientForREST" -framework "GoogleUtilities" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "nanopb" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. diff --git a/Pods/Target Support Files/Pods-TeachersAssistantTests/Pods-TeachersAssistantTests.release.xcconfig b/Pods/Target Support Files/Pods-TeachersAssistantTests/Pods-TeachersAssistantTests.release.xcconfig @@ -1,8 +1,5 @@ -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID" "${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleAPIClientForREST" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" -GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstanceID/FirebaseInstanceID.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher/GTMSessionFetcher.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleAPIClientForREST/GoogleAPIClientForREST.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb/nanopb.framework/Headers" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Firebase" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' -OTHER_LDFLAGS = $(inherited) -l"c++" -l"sqlite3" -l"z" -framework "Foundation" -framework "GTMSessionFetcher" -framework "GoogleAPIClientForREST" -framework "GoogleUtilities" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "nanopb" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. diff --git a/Pods/Target Support Files/nanopb/nanopb-Info.plist b/Pods/Target Support Files/nanopb/nanopb-Info.plist @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>en</string> - <key>CFBundleExecutable</key> - <string>${EXECUTABLE_NAME}</string> - <key>CFBundleIdentifier</key> - <string>${PRODUCT_BUNDLE_IDENTIFIER}</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>${PRODUCT_NAME}</string> - <key>CFBundlePackageType</key> - <string>FMWK</string> - <key>CFBundleShortVersionString</key> - <string>0.3.901</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>${CURRENT_PROJECT_VERSION}</string> - <key>NSPrincipalClass</key> - <string></string> -</dict> -</plist> diff --git a/Pods/Target Support Files/nanopb/nanopb-dummy.m b/Pods/Target Support Files/nanopb/nanopb-dummy.m @@ -1,5 +0,0 @@ -#import <Foundation/Foundation.h> -@interface PodsDummy_nanopb : NSObject -@end -@implementation PodsDummy_nanopb -@end diff --git a/Pods/Target Support Files/nanopb/nanopb-prefix.pch b/Pods/Target Support Files/nanopb/nanopb-prefix.pch @@ -1,12 +0,0 @@ -#ifdef __OBJC__ -#import <UIKit/UIKit.h> -#else -#ifndef FOUNDATION_EXPORT -#if defined(__cplusplus) -#define FOUNDATION_EXPORT extern "C" -#else -#define FOUNDATION_EXPORT extern -#endif -#endif -#endif - diff --git a/Pods/Target Support Files/nanopb/nanopb-umbrella.h b/Pods/Target Support Files/nanopb/nanopb-umbrella.h @@ -1,26 +0,0 @@ -#ifdef __OBJC__ -#import <UIKit/UIKit.h> -#else -#ifndef FOUNDATION_EXPORT -#if defined(__cplusplus) -#define FOUNDATION_EXPORT extern "C" -#else -#define FOUNDATION_EXPORT extern -#endif -#endif -#endif - -#import "pb.h" -#import "pb_common.h" -#import "pb_decode.h" -#import "pb_encode.h" -#import "pb.h" -#import "pb_decode.h" -#import "pb_common.h" -#import "pb.h" -#import "pb_encode.h" -#import "pb_common.h" - -FOUNDATION_EXPORT double nanopbVersionNumber; -FOUNDATION_EXPORT const unsigned char nanopbVersionString[]; - diff --git a/Pods/Target Support Files/nanopb/nanopb.modulemap b/Pods/Target Support Files/nanopb/nanopb.modulemap @@ -1,6 +0,0 @@ -framework module nanopb { - umbrella header "nanopb-umbrella.h" - - export * - module * { export * } -} diff --git a/Pods/Target Support Files/nanopb/nanopb.xcconfig b/Pods/Target Support Files/nanopb/nanopb.xcconfig @@ -1,8 +0,0 @@ -CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/nanopb -GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1 -PODS_BUILD_DIR = ${BUILD_DIR} -PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) -PODS_ROOT = ${SRCROOT} -PODS_TARGET_SRCROOT = ${PODS_ROOT}/nanopb -PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} -SKIP_INSTALL = YES diff --git a/Pods/nanopb/LICENSE.txt b/Pods/nanopb/LICENSE.txt @@ -1,20 +0,0 @@ -Copyright (c) 2011 Petteri Aimonen <jpa at nanopb.mail.kapsi.fi> - -This software is provided 'as-is', without any express or -implied warranty. In no event will the authors be held liable -for any damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you - must not claim that you wrote the original software. If you use - this software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and - must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source - distribution. diff --git a/Pods/nanopb/README.md b/Pods/nanopb/README.md @@ -1,71 +0,0 @@ -Nanopb - Protocol Buffers for Embedded Systems -============================================== - -[![Build Status](https://travis-ci.org/nanopb/nanopb.svg?branch=master)](https://travis-ci.org/nanopb/nanopb) - -Nanopb is a small code-size Protocol Buffers implementation in ansi C. It is -especially suitable for use in microcontrollers, but fits any memory -restricted system. - -* **Homepage:** https://jpa.kapsi.fi/nanopb/ -* **Documentation:** https://jpa.kapsi.fi/nanopb/docs/ -* **Downloads:** https://jpa.kapsi.fi/nanopb/download/ -* **Forum:** https://groups.google.com/forum/#!forum/nanopb - - - -Using the nanopb library ------------------------- -To use the nanopb library, you need to do two things: - -1. Compile your .proto files for nanopb, using protoc. -2. Include pb_encode.c, pb_decode.c and pb_common.c in your project. - -The easiest way to get started is to study the project in "examples/simple". -It contains a Makefile, which should work directly under most Linux systems. -However, for any other kind of build system, see the manual steps in -README.txt in that folder. - - - -Using the Protocol Buffers compiler (protoc) --------------------------------------------- -The nanopb generator is implemented as a plugin for the Google's own protoc -compiler. This has the advantage that there is no need to reimplement the -basic parsing of .proto files. However, it does mean that you need the -Google's protobuf library in order to run the generator. - -If you have downloaded a binary package for nanopb (either Windows, Linux or -Mac OS X version), the 'protoc' binary is included in the 'generator-bin' -folder. In this case, you are ready to go. Simply run this command: - - generator-bin/protoc --nanopb_out=. myprotocol.proto - -However, if you are using a git checkout or a plain source distribution, you -need to provide your own version of protoc and the Google's protobuf library. -On Linux, the necessary packages are protobuf-compiler and python-protobuf. -On Windows, you can either build Google's protobuf library from source or use -one of the binary distributions of it. In either case, if you use a separate -protoc, you need to manually give the path to nanopb generator: - - protoc --plugin=protoc-gen-nanopb=nanopb/generator/protoc-gen-nanopb ... - - - -Running the tests ------------------ -If you want to perform further development of the nanopb core, or to verify -its functionality using your compiler and platform, you'll want to run the -test suite. The build rules for the test suite are implemented using Scons, -so you need to have that installed. To run the tests: - - cd tests - scons - -This will show the progress of various test cases. If the output does not -end in an error, the test cases were successful. - -Note: Mac OS X by default aliases 'clang' as 'gcc', while not actually -supporting the same command line options as gcc does. To run tests on -Mac OS X, use: "scons CC=clang CXX=clang". Same way can be used to run -tests with different compilers on any platform. diff --git a/Pods/nanopb/pb.h b/Pods/nanopb/pb.h @@ -1,593 +0,0 @@ -/* Common parts of the nanopb library. Most of these are quite low-level - * stuff. For the high-level interface, see pb_encode.h and pb_decode.h. - */ - -#ifndef PB_H_INCLUDED -#define PB_H_INCLUDED - -/***************************************************************** - * Nanopb compilation time options. You can change these here by * - * uncommenting the lines, or on the compiler command line. * - *****************************************************************/ - -/* Enable support for dynamically allocated fields */ -/* #define PB_ENABLE_MALLOC 1 */ - -/* Define this if your CPU / compiler combination does not support - * unaligned memory access to packed structures. */ -/* #define PB_NO_PACKED_STRUCTS 1 */ - -/* Increase the number of required fields that are tracked. - * A compiler warning will tell if you need this. */ -/* #define PB_MAX_REQUIRED_FIELDS 256 */ - -/* Add support for tag numbers > 255 and fields larger than 255 bytes. */ -/* #define PB_FIELD_16BIT 1 */ - -/* Add support for tag numbers > 65536 and fields larger than 65536 bytes. */ -/* #define PB_FIELD_32BIT 1 */ - -/* Disable support for error messages in order to save some code space. */ -/* #define PB_NO_ERRMSG 1 */ - -/* Disable support for custom streams (support only memory buffers). */ -/* #define PB_BUFFER_ONLY 1 */ - -/* Switch back to the old-style callback function signature. - * This was the default until nanopb-0.2.1. */ -/* #define PB_OLD_CALLBACK_STYLE */ - - -/****************************************************************** - * You usually don't need to change anything below this line. * - * Feel free to look around and use the defined macros, though. * - ******************************************************************/ - - -/* Version of the nanopb library. Just in case you want to check it in - * your own program. */ -#define NANOPB_VERSION nanopb-0.3.9.1 - -/* Include all the system headers needed by nanopb. You will need the - * definitions of the following: - * - strlen, memcpy, memset functions - * - [u]int_least8_t, uint_fast8_t, [u]int_least16_t, [u]int32_t, [u]int64_t - * - size_t - * - bool - * - * If you don't have the standard header files, you can instead provide - * a custom header that defines or includes all this. In that case, - * define PB_SYSTEM_HEADER to the path of this file. - */ -#ifdef PB_SYSTEM_HEADER -#include PB_SYSTEM_HEADER -#else -#include <stdint.h> -#include <stddef.h> -#include <stdbool.h> -#include <string.h> - -#ifdef PB_ENABLE_MALLOC -#include <stdlib.h> -#endif -#endif - -/* Macro for defining packed structures (compiler dependent). - * This just reduces memory requirements, but is not required. - */ -#if defined(PB_NO_PACKED_STRUCTS) - /* Disable struct packing */ -# define PB_PACKED_STRUCT_START -# define PB_PACKED_STRUCT_END -# define pb_packed -#elif defined(__GNUC__) || defined(__clang__) - /* For GCC and clang */ -# define PB_PACKED_STRUCT_START -# define PB_PACKED_STRUCT_END -# define pb_packed __attribute__((packed)) -#elif defined(__ICCARM__) || defined(__CC_ARM) - /* For IAR ARM and Keil MDK-ARM compilers */ -# define PB_PACKED_STRUCT_START _Pragma("pack(push, 1)") -# define PB_PACKED_STRUCT_END _Pragma("pack(pop)") -# define pb_packed -#elif defined(_MSC_VER) && (_MSC_VER >= 1500) - /* For Microsoft Visual C++ */ -# define PB_PACKED_STRUCT_START __pragma(pack(push, 1)) -# define PB_PACKED_STRUCT_END __pragma(pack(pop)) -# define pb_packed -#else - /* Unknown compiler */ -# define PB_PACKED_STRUCT_START -# define PB_PACKED_STRUCT_END -# define pb_packed -#endif - -/* Handly macro for suppressing unreferenced-parameter compiler warnings. */ -#ifndef PB_UNUSED -#define PB_UNUSED(x) (void)(x) -#endif - -/* Compile-time assertion, used for checking compatible compilation options. - * If this does not work properly on your compiler, use - * #define PB_NO_STATIC_ASSERT to disable it. - * - * But before doing that, check carefully the error message / place where it - * comes from to see if the error has a real cause. Unfortunately the error - * message is not always very clear to read, but you can see the reason better - * in the place where the PB_STATIC_ASSERT macro was called. - */ -#ifndef PB_NO_STATIC_ASSERT -#ifndef PB_STATIC_ASSERT -#define PB_STATIC_ASSERT(COND,MSG) typedef char PB_STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND)?1:-1]; -#define PB_STATIC_ASSERT_MSG(MSG, LINE, COUNTER) PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) -#define PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) pb_static_assertion_##MSG##LINE##COUNTER -#endif -#else -#define PB_STATIC_ASSERT(COND,MSG) -#endif - -/* Number of required fields to keep track of. */ -#ifndef PB_MAX_REQUIRED_FIELDS -#define PB_MAX_REQUIRED_FIELDS 64 -#endif - -#if PB_MAX_REQUIRED_FIELDS < 64 -#error You should not lower PB_MAX_REQUIRED_FIELDS from the default value (64). -#endif - -/* List of possible field types. These are used in the autogenerated code. - * Least-significant 4 bits tell the scalar type - * Most-significant 4 bits specify repeated/required/packed etc. - */ - -typedef uint_least8_t pb_type_t; - -/**** Field data types ****/ - -/* Numeric types */ -#define PB_LTYPE_VARINT 0x00 /* int32, int64, enum, bool */ -#define PB_LTYPE_UVARINT 0x01 /* uint32, uint64 */ -#define PB_LTYPE_SVARINT 0x02 /* sint32, sint64 */ -#define PB_LTYPE_FIXED32 0x03 /* fixed32, sfixed32, float */ -#define PB_LTYPE_FIXED64 0x04 /* fixed64, sfixed64, double */ - -/* Marker for last packable field type. */ -#define PB_LTYPE_LAST_PACKABLE 0x04 - -/* Byte array with pre-allocated buffer. - * data_size is the length of the allocated PB_BYTES_ARRAY structure. */ -#define PB_LTYPE_BYTES 0x05 - -/* String with pre-allocated buffer. - * data_size is the maximum length. */ -#define PB_LTYPE_STRING 0x06 - -/* Submessage - * submsg_fields is pointer to field descriptions */ -#define PB_LTYPE_SUBMESSAGE 0x07 - -/* Extension pseudo-field - * The field contains a pointer to pb_extension_t */ -#define PB_LTYPE_EXTENSION 0x08 - -/* Byte array with inline, pre-allocated byffer. - * data_size is the length of the inline, allocated buffer. - * This differs from PB_LTYPE_BYTES by defining the element as - * pb_byte_t[data_size] rather than pb_bytes_array_t. */ -#define PB_LTYPE_FIXED_LENGTH_BYTES 0x09 - -/* Number of declared LTYPES */ -#define PB_LTYPES_COUNT 0x0A -#define PB_LTYPE_MASK 0x0F - -/**** Field repetition rules ****/ - -#define PB_HTYPE_REQUIRED 0x00 -#define PB_HTYPE_OPTIONAL 0x10 -#define PB_HTYPE_REPEATED 0x20 -#define PB_HTYPE_ONEOF 0x30 -#define PB_HTYPE_MASK 0x30 - -/**** Field allocation types ****/ - -#define PB_ATYPE_STATIC 0x00 -#define PB_ATYPE_POINTER 0x80 -#define PB_ATYPE_CALLBACK 0x40 -#define PB_ATYPE_MASK 0xC0 - -#define PB_ATYPE(x) ((x) & PB_ATYPE_MASK) -#define PB_HTYPE(x) ((x) & PB_HTYPE_MASK) -#define PB_LTYPE(x) ((x) & PB_LTYPE_MASK) - -/* Data type used for storing sizes of struct fields - * and array counts. - */ -#if defined(PB_FIELD_32BIT) - typedef uint32_t pb_size_t; - typedef int32_t pb_ssize_t; -#elif defined(PB_FIELD_16BIT) - typedef uint_least16_t pb_size_t; - typedef int_least16_t pb_ssize_t; -#else - typedef uint_least8_t pb_size_t; - typedef int_least8_t pb_ssize_t; -#endif -#define PB_SIZE_MAX ((pb_size_t)-1) - -/* Data type for storing encoded data and other byte streams. - * This typedef exists to support platforms where uint8_t does not exist. - * You can regard it as equivalent on uint8_t on other platforms. - */ -typedef uint_least8_t pb_byte_t; - -/* This structure is used in auto-generated constants - * to specify struct fields. - * You can change field sizes if you need structures - * larger than 256 bytes or field tags larger than 256. - * The compiler should complain if your .proto has such - * structures. Fix that by defining PB_FIELD_16BIT or - * PB_FIELD_32BIT. - */ -PB_PACKED_STRUCT_START -typedef struct pb_field_s pb_field_t; -struct pb_field_s { - pb_size_t tag; - pb_type_t type; - pb_size_t data_offset; /* Offset of field data, relative to previous field. */ - pb_ssize_t size_offset; /* Offset of array size or has-boolean, relative to data */ - pb_size_t data_size; /* Data size in bytes for a single item */ - pb_size_t array_size; /* Maximum number of entries in array */ - - /* Field definitions for submessage - * OR default value for all other non-array, non-callback types - * If null, then field will zeroed. */ - const void *ptr; -} pb_packed; -PB_PACKED_STRUCT_END - -/* Make sure that the standard integer types are of the expected sizes. - * Otherwise fixed32/fixed64 fields can break. - * - * If you get errors here, it probably means that your stdint.h is not - * correct for your platform. - */ -#ifndef PB_WITHOUT_64BIT -PB_STATIC_ASSERT(sizeof(int64_t) == 2 * sizeof(int32_t), INT64_T_WRONG_SIZE) -PB_STATIC_ASSERT(sizeof(uint64_t) == 2 * sizeof(uint32_t), UINT64_T_WRONG_SIZE) -#endif - -/* This structure is used for 'bytes' arrays. - * It has the number of bytes in the beginning, and after that an array. - * Note that actual structs used will have a different length of bytes array. - */ -#define PB_BYTES_ARRAY_T(n) struct { pb_size_t size; pb_byte_t bytes[n]; } -#define PB_BYTES_ARRAY_T_ALLOCSIZE(n) ((size_t)n + offsetof(pb_bytes_array_t, bytes)) - -struct pb_bytes_array_s { - pb_size_t size; - pb_byte_t bytes[1]; -}; -typedef struct pb_bytes_array_s pb_bytes_array_t; - -/* This structure is used for giving the callback function. - * It is stored in the message structure and filled in by the method that - * calls pb_decode. - * - * The decoding callback will be given a limited-length stream - * If the wire type was string, the length is the length of the string. - * If the wire type was a varint/fixed32/fixed64, the length is the length - * of the actual value. - * The function may be called multiple times (especially for repeated types, - * but also otherwise if the message happens to contain the field multiple - * times.) - * - * The encoding callback will receive the actual output stream. - * It should write all the data in one call, including the field tag and - * wire type. It can write multiple fields. - * - * The callback can be null if you want to skip a field. - */ -typedef struct pb_istream_s pb_istream_t; -typedef struct pb_ostream_s pb_ostream_t; -typedef struct pb_callback_s pb_callback_t; -struct pb_callback_s { -#ifdef PB_OLD_CALLBACK_STYLE - /* Deprecated since nanopb-0.2.1 */ - union { - bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void *arg); - bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, const void *arg); - } funcs; -#else - /* New function signature, which allows modifying arg contents in callback. */ - union { - bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void **arg); - bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, void * const *arg); - } funcs; -#endif - - /* Free arg for use by callback */ - void *arg; -}; - -/* Wire types. Library user needs these only in encoder callbacks. */ -typedef enum { - PB_WT_VARINT = 0, - PB_WT_64BIT = 1, - PB_WT_STRING = 2, - PB_WT_32BIT = 5 -} pb_wire_type_t; - -/* Structure for defining the handling of unknown/extension fields. - * Usually the pb_extension_type_t structure is automatically generated, - * while the pb_extension_t structure is created by the user. However, - * if you want to catch all unknown fields, you can also create a custom - * pb_extension_type_t with your own callback. - */ -typedef struct pb_extension_type_s pb_extension_type_t; -typedef struct pb_extension_s pb_extension_t; -struct pb_extension_type_s { - /* Called for each unknown field in the message. - * If you handle the field, read off all of its data and return true. - * If you do not handle the field, do not read anything and return true. - * If you run into an error, return false. - * Set to NULL for default handler. - */ - bool (*decode)(pb_istream_t *stream, pb_extension_t *extension, - uint32_t tag, pb_wire_type_t wire_type); - - /* Called once after all regular fields have been encoded. - * If you have something to write, do so and return true. - * If you do not have anything to write, just return true. - * If you run into an error, return false. - * Set to NULL for default handler. - */ - bool (*encode)(pb_ostream_t *stream, const pb_extension_t *extension); - - /* Free field for use by the callback. */ - const void *arg; -}; - -struct pb_extension_s { - /* Type describing the extension field. Usually you'll initialize - * this to a pointer to the automatically generated structure. */ - const pb_extension_type_t *type; - - /* Destination for the decoded data. This must match the datatype - * of the extension field. */ - void *dest; - - /* Pointer to the next extension handler, or NULL. - * If this extension does not match a field, the next handler is - * automatically called. */ - pb_extension_t *next; - - /* The decoder sets this to true if the extension was found. - * Ignored for encoding. */ - bool found; -}; - -/* Memory allocation functions to use. You can define pb_realloc and - * pb_free to custom functions if you want. */ -#ifdef PB_ENABLE_MALLOC -# ifndef pb_realloc -# define pb_realloc(ptr, size) realloc(ptr, size) -# endif -# ifndef pb_free -# define pb_free(ptr) free(ptr) -# endif -#endif - -/* This is used to inform about need to regenerate .pb.h/.pb.c files. */ -#define PB_PROTO_HEADER_VERSION 30 - -/* These macros are used to declare pb_field_t's in the constant array. */ -/* Size of a structure member, in bytes. */ -#define pb_membersize(st, m) (sizeof ((st*)0)->m) -/* Number of entries in an array. */ -#define pb_arraysize(st, m) (pb_membersize(st, m) / pb_membersize(st, m[0])) -/* Delta from start of one member to the start of another member. */ -#define pb_delta(st, m1, m2) ((int)offsetof(st, m1) - (int)offsetof(st, m2)) -/* Marks the end of the field list */ -#define PB_LAST_FIELD {0,(pb_type_t) 0,0,0,0,0,0} - -/* Macros for filling in the data_offset field */ -/* data_offset for first field in a message */ -#define PB_DATAOFFSET_FIRST(st, m1, m2) (offsetof(st, m1)) -/* data_offset for subsequent fields */ -#define PB_DATAOFFSET_OTHER(st, m1, m2) (offsetof(st, m1) - offsetof(st, m2) - pb_membersize(st, m2)) -/* data offset for subsequent fields inside an union (oneof) */ -#define PB_DATAOFFSET_UNION(st, m1, m2) (PB_SIZE_MAX) -/* Choose first/other based on m1 == m2 (deprecated, remains for backwards compatibility) */ -#define PB_DATAOFFSET_CHOOSE(st, m1, m2) (int)(offsetof(st, m1) == offsetof(st, m2) \ - ? PB_DATAOFFSET_FIRST(st, m1, m2) \ - : PB_DATAOFFSET_OTHER(st, m1, m2)) - -/* Required fields are the simplest. They just have delta (padding) from - * previous field end, and the size of the field. Pointer is used for - * submessages and default values. - */ -#define PB_REQUIRED_STATIC(tag, st, m, fd, ltype, ptr) \ - {tag, PB_ATYPE_STATIC | PB_HTYPE_REQUIRED | ltype, \ - fd, 0, pb_membersize(st, m), 0, ptr} - -/* Optional fields add the delta to the has_ variable. */ -#define PB_OPTIONAL_STATIC(tag, st, m, fd, ltype, ptr) \ - {tag, PB_ATYPE_STATIC | PB_HTYPE_OPTIONAL | ltype, \ - fd, \ - pb_delta(st, has_ ## m, m), \ - pb_membersize(st, m), 0, ptr} - -#define PB_SINGULAR_STATIC(tag, st, m, fd, ltype, ptr) \ - {tag, PB_ATYPE_STATIC | PB_HTYPE_OPTIONAL | ltype, \ - fd, 0, pb_membersize(st, m), 0, ptr} - -/* Repeated fields have a _count field and also the maximum number of entries. */ -#define PB_REPEATED_STATIC(tag, st, m, fd, ltype, ptr) \ - {tag, PB_ATYPE_STATIC | PB_HTYPE_REPEATED | ltype, \ - fd, \ - pb_delta(st, m ## _count, m), \ - pb_membersize(st, m[0]), \ - pb_arraysize(st, m), ptr} - -/* Allocated fields carry the size of the actual data, not the pointer */ -#define PB_REQUIRED_POINTER(tag, st, m, fd, ltype, ptr) \ - {tag, PB_ATYPE_POINTER | PB_HTYPE_REQUIRED | ltype, \ - fd, 0, pb_membersize(st, m[0]), 0, ptr} - -/* Optional fields don't need a has_ variable, as information would be redundant */ -#define PB_OPTIONAL_POINTER(tag, st, m, fd, ltype, ptr) \ - {tag, PB_ATYPE_POINTER | PB_HTYPE_OPTIONAL | ltype, \ - fd, 0, pb_membersize(st, m[0]), 0, ptr} - -/* Same as optional fields*/ -#define PB_SINGULAR_POINTER(tag, st, m, fd, ltype, ptr) \ - {tag, PB_ATYPE_POINTER | PB_HTYPE_OPTIONAL | ltype, \ - fd, 0, pb_membersize(st, m[0]), 0, ptr} - -/* Repeated fields have a _count field and a pointer to array of pointers */ -#define PB_REPEATED_POINTER(tag, st, m, fd, ltype, ptr) \ - {tag, PB_ATYPE_POINTER | PB_HTYPE_REPEATED | ltype, \ - fd, pb_delta(st, m ## _count, m), \ - pb_membersize(st, m[0]), 0, ptr} - -/* Callbacks are much like required fields except with special datatype. */ -#define PB_REQUIRED_CALLBACK(tag, st, m, fd, ltype, ptr) \ - {tag, PB_ATYPE_CALLBACK | PB_HTYPE_REQUIRED | ltype, \ - fd, 0, pb_membersize(st, m), 0, ptr} - -#define PB_OPTIONAL_CALLBACK(tag, st, m, fd, ltype, ptr) \ - {tag, PB_ATYPE_CALLBACK | PB_HTYPE_OPTIONAL | ltype, \ - fd, 0, pb_membersize(st, m), 0, ptr} - -#define PB_SINGULAR_CALLBACK(tag, st, m, fd, ltype, ptr) \ - {tag, PB_ATYPE_CALLBACK | PB_HTYPE_OPTIONAL | ltype, \ - fd, 0, pb_membersize(st, m), 0, ptr} - -#define PB_REPEATED_CALLBACK(tag, st, m, fd, ltype, ptr) \ - {tag, PB_ATYPE_CALLBACK | PB_HTYPE_REPEATED | ltype, \ - fd, 0, pb_membersize(st, m), 0, ptr} - -/* Optional extensions don't have the has_ field, as that would be redundant. - * Furthermore, the combination of OPTIONAL without has_ field is used - * for indicating proto3 style fields. Extensions exist in proto2 mode only, - * so they should be encoded according to proto2 rules. To avoid the conflict, - * extensions are marked as REQUIRED instead. - */ -#define PB_OPTEXT_STATIC(tag, st, m, fd, ltype, ptr) \ - {tag, PB_ATYPE_STATIC | PB_HTYPE_REQUIRED | ltype, \ - 0, \ - 0, \ - pb_membersize(st, m), 0, ptr} - -#define PB_OPTEXT_POINTER(tag, st, m, fd, ltype, ptr) \ - PB_OPTIONAL_POINTER(tag, st, m, fd, ltype, ptr) - -#define PB_OPTEXT_CALLBACK(tag, st, m, fd, ltype, ptr) \ - PB_OPTIONAL_CALLBACK(tag, st, m, fd, ltype, ptr) - -/* The mapping from protobuf types to LTYPEs is done using these macros. */ -#define PB_LTYPE_MAP_BOOL PB_LTYPE_VARINT -#define PB_LTYPE_MAP_BYTES PB_LTYPE_BYTES -#define PB_LTYPE_MAP_DOUBLE PB_LTYPE_FIXED64 -#define PB_LTYPE_MAP_ENUM PB_LTYPE_VARINT -#define PB_LTYPE_MAP_UENUM PB_LTYPE_UVARINT -#define PB_LTYPE_MAP_FIXED32 PB_LTYPE_FIXED32 -#define PB_LTYPE_MAP_FIXED64 PB_LTYPE_FIXED64 -#define PB_LTYPE_MAP_FLOAT PB_LTYPE_FIXED32 -#define PB_LTYPE_MAP_INT32 PB_LTYPE_VARINT -#define PB_LTYPE_MAP_INT64 PB_LTYPE_VARINT -#define PB_LTYPE_MAP_MESSAGE PB_LTYPE_SUBMESSAGE -#define PB_LTYPE_MAP_SFIXED32 PB_LTYPE_FIXED32 -#define PB_LTYPE_MAP_SFIXED64 PB_LTYPE_FIXED64 -#define PB_LTYPE_MAP_SINT32 PB_LTYPE_SVARINT -#define PB_LTYPE_MAP_SINT64 PB_LTYPE_SVARINT -#define PB_LTYPE_MAP_STRING PB_LTYPE_STRING -#define PB_LTYPE_MAP_UINT32 PB_LTYPE_UVARINT -#define PB_LTYPE_MAP_UINT64 PB_LTYPE_UVARINT -#define PB_LTYPE_MAP_EXTENSION PB_LTYPE_EXTENSION -#define PB_LTYPE_MAP_FIXED_LENGTH_BYTES PB_LTYPE_FIXED_LENGTH_BYTES - -/* This is the actual macro used in field descriptions. - * It takes these arguments: - * - Field tag number - * - Field type: BOOL, BYTES, DOUBLE, ENUM, UENUM, FIXED32, FIXED64, - * FLOAT, INT32, INT64, MESSAGE, SFIXED32, SFIXED64 - * SINT32, SINT64, STRING, UINT32, UINT64 or EXTENSION - * - Field rules: REQUIRED, OPTIONAL or REPEATED - * - Allocation: STATIC, CALLBACK or POINTER - * - Placement: FIRST or OTHER, depending on if this is the first field in structure. - * - Message name - * - Field name - * - Previous field name (or field name again for first field) - * - Pointer to default value or submsg fields. - */ - -#define PB_FIELD(tag, type, rules, allocation, placement, message, field, prevfield, ptr) \ - PB_ ## rules ## _ ## allocation(tag, message, field, \ - PB_DATAOFFSET_ ## placement(message, field, prevfield), \ - PB_LTYPE_MAP_ ## type, ptr) - -/* Field description for repeated static fixed count fields.*/ -#define PB_REPEATED_FIXED_COUNT(tag, type, placement, message, field, prevfield, ptr) \ - {tag, PB_ATYPE_STATIC | PB_HTYPE_REPEATED | PB_LTYPE_MAP_ ## type, \ - PB_DATAOFFSET_ ## placement(message, field, prevfield), \ - 0, \ - pb_membersize(message, field[0]), \ - pb_arraysize(message, field), ptr} - -/* Field description for oneof fields. This requires taking into account the - * union name also, that's why a separate set of macros is needed. - */ -#define PB_ONEOF_STATIC(u, tag, st, m, fd, ltype, ptr) \ - {tag, PB_ATYPE_STATIC | PB_HTYPE_ONEOF | ltype, \ - fd, pb_delta(st, which_ ## u, u.m), \ - pb_membersize(st, u.m), 0, ptr} - -#define PB_ONEOF_POINTER(u, tag, st, m, fd, ltype, ptr) \ - {tag, PB_ATYPE_POINTER | PB_HTYPE_ONEOF | ltype, \ - fd, pb_delta(st, which_ ## u, u.m), \ - pb_membersize(st, u.m[0]), 0, ptr} - -#define PB_ONEOF_FIELD(union_name, tag, type, rules, allocation, placement, message, field, prevfield, ptr) \ - PB_ONEOF_ ## allocation(union_name, tag, message, field, \ - PB_DATAOFFSET_ ## placement(message, union_name.field, prevfield), \ - PB_LTYPE_MAP_ ## type, ptr) - -#define PB_ANONYMOUS_ONEOF_STATIC(u, tag, st, m, fd, ltype, ptr) \ - {tag, PB_ATYPE_STATIC | PB_HTYPE_ONEOF | ltype, \ - fd, pb_delta(st, which_ ## u, m), \ - pb_membersize(st, m), 0, ptr} - -#define PB_ANONYMOUS_ONEOF_POINTER(u, tag, st, m, fd, ltype, ptr) \ - {tag, PB_ATYPE_POINTER | PB_HTYPE_ONEOF | ltype, \ - fd, pb_delta(st, which_ ## u, m), \ - pb_membersize(st, m[0]), 0, ptr} - -#define PB_ANONYMOUS_ONEOF_FIELD(union_name, tag, type, rules, allocation, placement, message, field, prevfield, ptr) \ - PB_ANONYMOUS_ONEOF_ ## allocation(union_name, tag, message, field, \ - PB_DATAOFFSET_ ## placement(message, field, prevfield), \ - PB_LTYPE_MAP_ ## type, ptr) - -/* These macros are used for giving out error messages. - * They are mostly a debugging aid; the main error information - * is the true/false return value from functions. - * Some code space can be saved by disabling the error - * messages if not used. - * - * PB_SET_ERROR() sets the error message if none has been set yet. - * msg must be a constant string literal. - * PB_GET_ERROR() always returns a pointer to a string. - * PB_RETURN_ERROR() sets the error and returns false from current - * function. - */ -#ifdef PB_NO_ERRMSG -#define PB_SET_ERROR(stream, msg) PB_UNUSED(stream) -#define PB_GET_ERROR(stream) "(errmsg disabled)" -#else -#define PB_SET_ERROR(stream, msg) (stream->errmsg = (stream)->errmsg ? (stream)->errmsg : (msg)) -#define PB_GET_ERROR(stream) ((stream)->errmsg ? (stream)->errmsg : "(none)") -#endif - -#define PB_RETURN_ERROR(stream, msg) return PB_SET_ERROR(stream, msg), false - -#endif diff --git a/Pods/nanopb/pb_common.c b/Pods/nanopb/pb_common.c @@ -1,97 +0,0 @@ -/* pb_common.c: Common support functions for pb_encode.c and pb_decode.c. - * - * 2014 Petteri Aimonen <jpa@kapsi.fi> - */ - -#include "pb_common.h" - -bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_field_t *fields, void *dest_struct) -{ - iter->start = fields; - iter->pos = fields; - iter->required_field_index = 0; - iter->dest_struct = dest_struct; - iter->pData = (char*)dest_struct + iter->pos->data_offset; - iter->pSize = (char*)iter->pData + iter->pos->size_offset; - - return (iter->pos->tag != 0); -} - -bool pb_field_iter_next(pb_field_iter_t *iter) -{ - const pb_field_t *prev_field = iter->pos; - - if (prev_field->tag == 0) - { - /* Handle empty message types, where the first field is already the terminator. - * In other cases, the iter->pos never points to the terminator. */ - return false; - } - - iter->pos++; - - if (iter->pos->tag == 0) - { - /* Wrapped back to beginning, reinitialize */ - (void)pb_field_iter_begin(iter, iter->start, iter->dest_struct); - return false; - } - else - { - /* Increment the pointers based on previous field size */ - size_t prev_size = prev_field->data_size; - - if (PB_HTYPE(prev_field->type) == PB_HTYPE_ONEOF && - PB_HTYPE(iter->pos->type) == PB_HTYPE_ONEOF && - iter->pos->data_offset == PB_SIZE_MAX) - { - /* Don't advance pointers inside unions */ - return true; - } - else if (PB_ATYPE(prev_field->type) == PB_ATYPE_STATIC && - PB_HTYPE(prev_field->type) == PB_HTYPE_REPEATED) - { - /* In static arrays, the data_size tells the size of a single entry and - * array_size is the number of entries */ - prev_size *= prev_field->array_size; - } - else if (PB_ATYPE(prev_field->type) == PB_ATYPE_POINTER) - { - /* Pointer fields always have a constant size in the main structure. - * The data_size only applies to the dynamically allocated area. */ - prev_size = sizeof(void*); - } - - if (PB_HTYPE(prev_field->type) == PB_HTYPE_REQUIRED) - { - /* Count the required fields, in order to check their presence in the - * decoder. */ - iter->required_field_index++; - } - - iter->pData = (char*)iter->pData + prev_size + iter->pos->data_offset; - iter->pSize = (char*)iter->pData + iter->pos->size_offset; - return true; - } -} - -bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag) -{ - const pb_field_t *start = iter->pos; - - do { - if (iter->pos->tag == tag && - PB_LTYPE(iter->pos->type) != PB_LTYPE_EXTENSION) - { - /* Found the wanted field */ - return true; - } - - (void)pb_field_iter_next(iter); - } while (iter->pos != start); - - /* Searched all the way back to start, and found nothing. */ - return false; -} - - diff --git a/Pods/nanopb/pb_common.h b/Pods/nanopb/pb_common.h @@ -1,42 +0,0 @@ -/* pb_common.h: Common support functions for pb_encode.c and pb_decode.c. - * These functions are rarely needed by applications directly. - */ - -#ifndef PB_COMMON_H_INCLUDED -#define PB_COMMON_H_INCLUDED - -#include "pb.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Iterator for pb_field_t list */ -struct pb_field_iter_s { - const pb_field_t *start; /* Start of the pb_field_t array */ - const pb_field_t *pos; /* Current position of the iterator */ - unsigned required_field_index; /* Zero-based index that counts only the required fields */ - void *dest_struct; /* Pointer to start of the structure */ - void *pData; /* Pointer to current field value */ - void *pSize; /* Pointer to count/has field */ -}; -typedef struct pb_field_iter_s pb_field_iter_t; - -/* Initialize the field iterator structure to beginning. - * Returns false if the message type is empty. */ -bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_field_t *fields, void *dest_struct); - -/* Advance the iterator to the next field. - * Returns false when the iterator wraps back to the first field. */ -bool pb_field_iter_next(pb_field_iter_t *iter); - -/* Advance the iterator until it points at a field with the given tag. - * Returns false if no such field exists. */ -bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif - diff --git a/Pods/nanopb/pb_decode.c b/Pods/nanopb/pb_decode.c @@ -1,1508 +0,0 @@ -/* pb_decode.c -- decode a protobuf using minimal resources - * - * 2011 Petteri Aimonen <jpa@kapsi.fi> - */ - -/* Use the GCC warn_unused_result attribute to check that all return values - * are propagated correctly. On other compilers and gcc before 3.4.0 just - * ignore the annotation. - */ -#if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) - #define checkreturn -#else - #define checkreturn __attribute__((warn_unused_result)) -#endif - -#include "pb.h" -#include "pb_decode.h" -#include "pb_common.h" - -/************************************** - * Declarations internal to this file * - **************************************/ - -typedef bool (*pb_decoder_t)(pb_istream_t *stream, const pb_field_t *field, void *dest) checkreturn; - -static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count); -static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size); -static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter); -static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter); -static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter); -static void iter_from_extension(pb_field_iter_t *iter, pb_extension_t *extension); -static bool checkreturn default_extension_decoder(pb_istream_t *stream, pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type); -static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, pb_wire_type_t wire_type, pb_field_iter_t *iter); -static bool checkreturn find_extension_field(pb_field_iter_t *iter); -static void pb_field_set_to_default(pb_field_iter_t *iter); -static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct); -static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest); -static bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, uint32_t *dest, bool *eof); -static bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest); -static bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest); -static bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest); -static bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest); -static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest); -static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest); -static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest); -static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest); -static bool checkreturn pb_skip_varint(pb_istream_t *stream); -static bool checkreturn pb_skip_string(pb_istream_t *stream); - -#ifdef PB_ENABLE_MALLOC -static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size); -static bool checkreturn pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *iter); -static void pb_release_single_field(const pb_field_iter_t *iter); -#endif - -#ifdef PB_WITHOUT_64BIT -#define pb_int64_t int32_t -#define pb_uint64_t uint32_t -#else -#define pb_int64_t int64_t -#define pb_uint64_t uint64_t -#endif - -/* --- Function pointers to field decoders --- - * Order in the array must match pb_action_t LTYPE numbering. - */ -static const pb_decoder_t PB_DECODERS[PB_LTYPES_COUNT] = { - &pb_dec_varint, - &pb_dec_uvarint, - &pb_dec_svarint, - &pb_dec_fixed32, - &pb_dec_fixed64, - - &pb_dec_bytes, - &pb_dec_string, - &pb_dec_submessage, - NULL, /* extensions */ - &pb_dec_fixed_length_bytes -}; - -/******************************* - * pb_istream_t implementation * - *******************************/ - -static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count) -{ - size_t i; - const pb_byte_t *source = (const pb_byte_t*)stream->state; - stream->state = (pb_byte_t*)stream->state + count; - - if (buf != NULL) - { - for (i = 0; i < count; i++) - buf[i] = source[i]; - } - - return true; -} - -bool checkreturn pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count) -{ -#ifndef PB_BUFFER_ONLY - if (buf == NULL && stream->callback != buf_read) - { - /* Skip input bytes */ - pb_byte_t tmp[16]; - while (count > 16) - { - if (!pb_read(stream, tmp, 16)) - return false; - - count -= 16; - } - - return pb_read(stream, tmp, count); - } -#endif - - if (stream->bytes_left < count) - PB_RETURN_ERROR(stream, "end-of-stream"); - -#ifndef PB_BUFFER_ONLY - if (!stream->callback(stream, buf, count)) - PB_RETURN_ERROR(stream, "io error"); -#else - if (!buf_read(stream, buf, count)) - return false; -#endif - - stream->bytes_left -= count; - return true; -} - -/* Read a single byte from input stream. buf may not be NULL. - * This is an optimization for the varint decoding. */ -static bool checkreturn pb_readbyte(pb_istream_t *stream, pb_byte_t *buf) -{ - if (stream->bytes_left == 0) - PB_RETURN_ERROR(stream, "end-of-stream"); - -#ifndef PB_BUFFER_ONLY - if (!stream->callback(stream, buf, 1)) - PB_RETURN_ERROR(stream, "io error"); -#else - *buf = *(const pb_byte_t*)stream->state; - stream->state = (pb_byte_t*)stream->state + 1; -#endif - - stream->bytes_left--; - - return true; -} - -pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t bufsize) -{ - pb_istream_t stream; - /* Cast away the const from buf without a compiler error. We are - * careful to use it only in a const manner in the callbacks. - */ - union { - void *state; - const void *c_state; - } state; -#ifdef PB_BUFFER_ONLY - stream.callback = NULL; -#else - stream.callback = &buf_read; -#endif - state.c_state = buf; - stream.state = state.state; - stream.bytes_left = bufsize; -#ifndef PB_NO_ERRMSG - stream.errmsg = NULL; -#endif - return stream; -} - -/******************** - * Helper functions * - ********************/ - -static bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, uint32_t *dest, bool *eof) -{ - pb_byte_t byte; - uint32_t result; - - if (!pb_readbyte(stream, &byte)) - { - if (stream->bytes_left == 0) - { - if (eof) - { - *eof = true; - } - } - - return false; - } - - if ((byte & 0x80) == 0) - { - /* Quick case, 1 byte value */ - result = byte; - } - else - { - /* Multibyte case */ - uint_fast8_t bitpos = 7; - result = byte & 0x7F; - - do - { - if (!pb_readbyte(stream, &byte)) - return false; - - if (bitpos >= 32) - { - /* Note: The varint could have trailing 0x80 bytes, or 0xFF for negative. */ - uint8_t sign_extension = (bitpos < 63) ? 0xFF : 0x01; - - if ((byte & 0x7F) != 0x00 && ((result >> 31) == 0 || byte != sign_extension)) - { - PB_RETURN_ERROR(stream, "varint overflow"); - } - } - else - { - result |= (uint32_t)(byte & 0x7F) << bitpos; - } - bitpos = (uint_fast8_t)(bitpos + 7); - } while (byte & 0x80); - - if (bitpos == 35 && (byte & 0x70) != 0) - { - /* The last byte was at bitpos=28, so only bottom 4 bits fit. */ - PB_RETURN_ERROR(stream, "varint overflow"); - } - } - - *dest = result; - return true; -} - -bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest) -{ - return pb_decode_varint32_eof(stream, dest, NULL); -} - -#ifndef PB_WITHOUT_64BIT -bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest) -{ - pb_byte_t byte; - uint_fast8_t bitpos = 0; - uint64_t result = 0; - - do - { - if (bitpos >= 64) - PB_RETURN_ERROR(stream, "varint overflow"); - - if (!pb_readbyte(stream, &byte)) - return false; - - result |= (uint64_t)(byte & 0x7F) << bitpos; - bitpos = (uint_fast8_t)(bitpos + 7); - } while (byte & 0x80); - - *dest = result; - return true; -} -#endif - -bool checkreturn pb_skip_varint(pb_istream_t *stream) -{ - pb_byte_t byte; - do - { - if (!pb_read(stream, &byte, 1)) - return false; - } while (byte & 0x80); - return true; -} - -bool checkreturn pb_skip_string(pb_istream_t *stream) -{ - uint32_t length; - if (!pb_decode_varint32(stream, &length)) - return false; - - return pb_read(stream, NULL, length); -} - -bool checkreturn pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof) -{ - uint32_t temp; - *eof = false; - *wire_type = (pb_wire_type_t) 0; - *tag = 0; - - if (!pb_decode_varint32_eof(stream, &temp, eof)) - { - return false; - } - - if (temp == 0) - { - *eof = true; /* Special feature: allow 0-terminated messages. */ - return false; - } - - *tag = temp >> 3; - *wire_type = (pb_wire_type_t)(temp & 7); - return true; -} - -bool checkreturn pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type) -{ - switch (wire_type) - { - case PB_WT_VARINT: return pb_skip_varint(stream); - case PB_WT_64BIT: return pb_read(stream, NULL, 8); - case PB_WT_STRING: return pb_skip_string(stream); - case PB_WT_32BIT: return pb_read(stream, NULL, 4); - default: PB_RETURN_ERROR(stream, "invalid wire_type"); - } -} - -/* Read a raw value to buffer, for the purpose of passing it to callback as - * a substream. Size is maximum size on call, and actual size on return. - */ -static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size) -{ - size_t max_size = *size; - switch (wire_type) - { - case PB_WT_VARINT: - *size = 0; - do - { - (*size)++; - if (*size > max_size) return false; - if (!pb_read(stream, buf, 1)) return false; - } while (*buf++ & 0x80); - return true; - - case PB_WT_64BIT: - *size = 8; - return pb_read(stream, buf, 8); - - case PB_WT_32BIT: - *size = 4; - return pb_read(stream, buf, 4); - - case PB_WT_STRING: - /* Calling read_raw_value with a PB_WT_STRING is an error. - * Explicitly handle this case and fallthrough to default to avoid - * compiler warnings. - */ - - default: PB_RETURN_ERROR(stream, "invalid wire_type"); - } -} - -/* Decode string length from stream and return a substream with limited length. - * Remember to close the substream using pb_close_string_substream(). - */ -bool checkreturn pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream) -{ - uint32_t size; - if (!pb_decode_varint32(stream, &size)) - return false; - - *substream = *stream; - if (substream->bytes_left < size) - PB_RETURN_ERROR(stream, "parent stream too short"); - - substream->bytes_left = size; - stream->bytes_left -= size; - return true; -} - -bool checkreturn pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream) -{ - if (substream->bytes_left) { - if (!pb_read(substream, NULL, substream->bytes_left)) - return false; - } - - stream->state = substream->state; - -#ifndef PB_NO_ERRMSG - stream->errmsg = substream->errmsg; -#endif - return true; -} - -/************************* - * Decode a single field * - *************************/ - -static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) -{ - pb_type_t type; - pb_decoder_t func; - - type = iter->pos->type; - func = PB_DECODERS[PB_LTYPE(type)]; - - switch (PB_HTYPE(type)) - { - case PB_HTYPE_REQUIRED: - return func(stream, iter->pos, iter->pData); - - case PB_HTYPE_OPTIONAL: - if (iter->pSize != iter->pData) - *(bool*)iter->pSize = true; - return func(stream, iter->pos, iter->pData); - - case PB_HTYPE_REPEATED: - if (wire_type == PB_WT_STRING - && PB_LTYPE(type) <= PB_LTYPE_LAST_PACKABLE) - { - /* Packed array */ - bool status = true; - pb_size_t *size = (pb_size_t*)iter->pSize; - - pb_istream_t substream; - if (!pb_make_string_substream(stream, &substream)) - return false; - - while (substream.bytes_left > 0 && *size < iter->pos->array_size) - { - void *pItem = (char*)iter->pData + iter->pos->data_size * (*size); - if (!func(&substream, iter->pos, pItem)) - { - status = false; - break; - } - (*size)++; - } - - if (substream.bytes_left != 0) - PB_RETURN_ERROR(stream, "array overflow"); - if (!pb_close_string_substream(stream, &substream)) - return false; - - return status; - } - else - { - /* Repeated field */ - pb_size_t *size = (pb_size_t*)iter->pSize; - char *pItem = (char*)iter->pData + iter->pos->data_size * (*size); - - if ((*size)++ >= iter->pos->array_size) - PB_RETURN_ERROR(stream, "array overflow"); - - return func(stream, iter->pos, pItem); - } - - case PB_HTYPE_ONEOF: - *(pb_size_t*)iter->pSize = iter->pos->tag; - if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE) - { - /* We memset to zero so that any callbacks are set to NULL. - * Then set any default values. */ - memset(iter->pData, 0, iter->pos->data_size); - pb_message_set_to_defaults((const pb_field_t*)iter->pos->ptr, iter->pData); - } - return func(stream, iter->pos, iter->pData); - - default: - PB_RETURN_ERROR(stream, "invalid field type"); - } -} - -#ifdef PB_ENABLE_MALLOC -/* Allocate storage for the field and store the pointer at iter->pData. - * array_size is the number of entries to reserve in an array. - * Zero size is not allowed, use pb_free() for releasing. - */ -static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size) -{ - void *ptr = *(void**)pData; - - if (data_size == 0 || array_size == 0) - PB_RETURN_ERROR(stream, "invalid size"); - - /* Check for multiplication overflows. - * This code avoids the costly division if the sizes are small enough. - * Multiplication is safe as long as only half of bits are set - * in either multiplicand. - */ - { - const size_t check_limit = (size_t)1 << (sizeof(size_t) * 4); - if (data_size >= check_limit || array_size >= check_limit) - { - const size_t size_max = (size_t)-1; - if (size_max / array_size < data_size) - { - PB_RETURN_ERROR(stream, "size too large"); - } - } - } - - /* Allocate new or expand previous allocation */ - /* Note: on failure the old pointer will remain in the structure, - * the message must be freed by caller also on error return. */ - ptr = pb_realloc(ptr, array_size * data_size); - if (ptr == NULL) - PB_RETURN_ERROR(stream, "realloc failed"); - - *(void**)pData = ptr; - return true; -} - -/* Clear a newly allocated item in case it contains a pointer, or is a submessage. */ -static void initialize_pointer_field(void *pItem, pb_field_iter_t *iter) -{ - if (PB_LTYPE(iter->pos->type) == PB_LTYPE_STRING || - PB_LTYPE(iter->pos->type) == PB_LTYPE_BYTES) - { - *(void**)pItem = NULL; - } - else if (PB_LTYPE(iter->pos->type) == PB_LTYPE_SUBMESSAGE) - { - /* We memset to zero so that any callbacks are set to NULL. - * Then set any default values. */ - memset(pItem, 0, iter->pos->data_size); - pb_message_set_to_defaults((const pb_field_t *) iter->pos->ptr, pItem); - } -} -#endif - -static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) -{ -#ifndef PB_ENABLE_MALLOC - PB_UNUSED(wire_type); - PB_UNUSED(iter); - PB_RETURN_ERROR(stream, "no malloc support"); -#else - pb_type_t type; - pb_decoder_t func; - - type = iter->pos->type; - func = PB_DECODERS[PB_LTYPE(type)]; - - switch (PB_HTYPE(type)) - { - case PB_HTYPE_REQUIRED: - case PB_HTYPE_OPTIONAL: - case PB_HTYPE_ONEOF: - if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE && - *(void**)iter->pData != NULL) - { - /* Duplicate field, have to release the old allocation first. */ - pb_release_single_field(iter); - } - - if (PB_HTYPE(type) == PB_HTYPE_ONEOF) - { - *(pb_size_t*)iter->pSize = iter->pos->tag; - } - - if (PB_LTYPE(type) == PB_LTYPE_STRING || - PB_LTYPE(type) == PB_LTYPE_BYTES) - { - return func(stream, iter->pos, iter->pData); - } - else - { - if (!allocate_field(stream, iter->pData, iter->pos->data_size, 1)) - return false; - - initialize_pointer_field(*(void**)iter->pData, iter); - return func(stream, iter->pos, *(void**)iter->pData); - } - - case PB_HTYPE_REPEATED: - if (wire_type == PB_WT_STRING - && PB_LTYPE(type) <= PB_LTYPE_LAST_PACKABLE) - { - /* Packed array, multiple items come in at once. */ - bool status = true; - pb_size_t *size = (pb_size_t*)iter->pSize; - size_t allocated_size = *size; - void *pItem; - pb_istream_t substream; - - if (!pb_make_string_substream(stream, &substream)) - return false; - - while (substream.bytes_left) - { - if ((size_t)*size + 1 > allocated_size) - { - /* Allocate more storage. This tries to guess the - * number of remaining entries. Round the division - * upwards. */ - allocated_size += (substream.bytes_left - 1) / iter->pos->data_size + 1; - - if (!allocate_field(&substream, iter->pData, iter->pos->data_size, allocated_size)) - { - status = false; - break; - } - } - - /* Decode the array entry */ - pItem = *(char**)iter->pData + iter->pos->data_size * (*size); - initialize_pointer_field(pItem, iter); - if (!func(&substream, iter->pos, pItem)) - { - status = false; - break; - } - - if (*size == PB_SIZE_MAX) - { -#ifndef PB_NO_ERRMSG - stream->errmsg = "too many array entries"; -#endif - status = false; - break; - } - - (*size)++; - } - if (!pb_close_string_substream(stream, &substream)) - return false; - - return status; - } - else - { - /* Normal repeated field, i.e. only one item at a time. */ - pb_size_t *size = (pb_size_t*)iter->pSize; - void *pItem; - - if (*size == PB_SIZE_MAX) - PB_RETURN_ERROR(stream, "too many array entries"); - - (*size)++; - if (!allocate_field(stream, iter->pData, iter->pos->data_size, *size)) - return false; - - pItem = *(char**)iter->pData + iter->pos->data_size * (*size - 1); - initialize_pointer_field(pItem, iter); - return func(stream, iter->pos, pItem); - } - - default: - PB_RETURN_ERROR(stream, "invalid field type"); - } -#endif -} - -static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) -{ - pb_callback_t *pCallback = (pb_callback_t*)iter->pData; - -#ifdef PB_OLD_CALLBACK_STYLE - void *arg = pCallback->arg; -#else - void **arg = &(pCallback->arg); -#endif - - if (pCallback == NULL || pCallback->funcs.decode == NULL) - return pb_skip_field(stream, wire_type); - - if (wire_type == PB_WT_STRING) - { - pb_istream_t substream; - - if (!pb_make_string_substream(stream, &substream)) - return false; - - do - { - if (!pCallback->funcs.decode(&substream, iter->pos, arg)) - PB_RETURN_ERROR(stream, "callback failed"); - } while (substream.bytes_left); - - if (!pb_close_string_substream(stream, &substream)) - return false; - - return true; - } - else - { - /* Copy the single scalar value to stack. - * This is required so that we can limit the stream length, - * which in turn allows to use same callback for packed and - * not-packed fields. */ - pb_istream_t substream; - pb_byte_t buffer[10]; - size_t size = sizeof(buffer); - - if (!read_raw_value(stream, wire_type, buffer, &size)) - return false; - substream = pb_istream_from_buffer(buffer, size); - - return pCallback->funcs.decode(&substream, iter->pos, arg); - } -} - -static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) -{ -#ifdef PB_ENABLE_MALLOC - /* When decoding an oneof field, check if there is old data that must be - * released first. */ - if (PB_HTYPE(iter->pos->type) == PB_HTYPE_ONEOF) - { - if (!pb_release_union_field(stream, iter)) - return false; - } -#endif - - switch (PB_ATYPE(iter->pos->type)) - { - case PB_ATYPE_STATIC: - return decode_static_field(stream, wire_type, iter); - - case PB_ATYPE_POINTER: - return decode_pointer_field(stream, wire_type, iter); - - case PB_ATYPE_CALLBACK: - return decode_callback_field(stream, wire_type, iter); - - default: - PB_RETURN_ERROR(stream, "invalid field type"); - } -} - -static void iter_from_extension(pb_field_iter_t *iter, pb_extension_t *extension) -{ - /* Fake a field iterator for the extension field. - * It is not actually safe to advance this iterator, but decode_field - * will not even try to. */ - const pb_field_t *field = (const pb_field_t*)extension->type->arg; - (void)pb_field_iter_begin(iter, field, extension->dest); - iter->pData = extension->dest; - iter->pSize = &extension->found; - - if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) - { - /* For pointer extensions, the pointer is stored directly - * in the extension structure. This avoids having an extra - * indirection. */ - iter->pData = &extension->dest; - } -} - -/* Default handler for extension fields. Expects a pb_field_t structure - * in extension->type->arg. */ -static bool checkreturn default_extension_decoder(pb_istream_t *stream, - pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type) -{ - const pb_field_t *field = (const pb_field_t*)extension->type->arg; - pb_field_iter_t iter; - - if (field->tag != tag) - return true; - - iter_from_extension(&iter, extension); - extension->found = true; - return decode_field(stream, wire_type, &iter); -} - -/* Try to decode an unknown field as an extension field. Tries each extension - * decoder in turn, until one of them handles the field or loop ends. */ -static bool checkreturn decode_extension(pb_istream_t *stream, - uint32_t tag, pb_wire_type_t wire_type, pb_field_iter_t *iter) -{ - pb_extension_t *extension = *(pb_extension_t* const *)iter->pData; - size_t pos = stream->bytes_left; - - while (extension != NULL && pos == stream->bytes_left) - { - bool status; - if (extension->type->decode) - status = extension->type->decode(stream, extension, tag, wire_type); - else - status = default_extension_decoder(stream, extension, tag, wire_type); - - if (!status) - return false; - - extension = extension->next; - } - - return true; -} - -/* Step through the iterator until an extension field is found or until all - * entries have been checked. There can be only one extension field per - * message. Returns false if no extension field is found. */ -static bool checkreturn find_extension_field(pb_field_iter_t *iter) -{ - const pb_field_t *start = iter->pos; - - do { - if (PB_LTYPE(iter->pos->type) == PB_LTYPE_EXTENSION) - return true; - (void)pb_field_iter_next(iter); - } while (iter->pos != start); - - return false; -} - -/* Initialize message fields to default values, recursively */ -static void pb_field_set_to_default(pb_field_iter_t *iter) -{ - pb_type_t type; - type = iter->pos->type; - - if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) - { - pb_extension_t *ext = *(pb_extension_t* const *)iter->pData; - while (ext != NULL) - { - pb_field_iter_t ext_iter; - ext->found = false; - iter_from_extension(&ext_iter, ext); - pb_field_set_to_default(&ext_iter); - ext = ext->next; - } - } - else if (PB_ATYPE(type) == PB_ATYPE_STATIC) - { - bool init_data = true; - if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL && iter->pSize != iter->pData) - { - /* Set has_field to false. Still initialize the optional field - * itself also. */ - *(bool*)iter->pSize = false; - } - else if (PB_HTYPE(type) == PB_HTYPE_REPEATED || - PB_HTYPE(type) == PB_HTYPE_ONEOF) - { - /* REPEATED: Set array count to 0, no need to initialize contents. - ONEOF: Set which_field to 0. */ - *(pb_size_t*)iter->pSize = 0; - init_data = false; - } - - if (init_data) - { - if (PB_LTYPE(iter->pos->type) == PB_LTYPE_SUBMESSAGE) - { - /* Initialize submessage to defaults */ - pb_message_set_to_defaults((const pb_field_t *) iter->pos->ptr, iter->pData); - } - else if (iter->pos->ptr != NULL) - { - /* Initialize to default value */ - memcpy(iter->pData, iter->pos->ptr, iter->pos->data_size); - } - else - { - /* Initialize to zeros */ - memset(iter->pData, 0, iter->pos->data_size); - } - } - } - else if (PB_ATYPE(type) == PB_ATYPE_POINTER) - { - /* Initialize the pointer to NULL. */ - *(void**)iter->pData = NULL; - - /* Initialize array count to 0. */ - if (PB_HTYPE(type) == PB_HTYPE_REPEATED || - PB_HTYPE(type) == PB_HTYPE_ONEOF) - { - *(pb_size_t*)iter->pSize = 0; - } - } - else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK) - { - /* Don't overwrite callback */ - } -} - -static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct) -{ - pb_field_iter_t iter; - - if (!pb_field_iter_begin(&iter, fields, dest_struct)) - return; /* Empty message type */ - - do - { - pb_field_set_to_default(&iter); - } while (pb_field_iter_next(&iter)); -} - -/********************* - * Decode all fields * - *********************/ - -bool checkreturn pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) -{ - uint32_t fields_seen[(PB_MAX_REQUIRED_FIELDS + 31) / 32] = {0, 0}; - const uint32_t allbits = ~(uint32_t)0; - uint32_t extension_range_start = 0; - pb_field_iter_t iter; - - /* 'fixed_count_field' and 'fixed_count_size' track position of a repeated fixed - * count field. This can only handle _one_ repeated fixed count field that - * is unpacked and unordered among other (non repeated fixed count) fields. - */ - const pb_field_t *fixed_count_field = NULL; - pb_size_t fixed_count_size = 0; - - /* Return value ignored, as empty message types will be correctly handled by - * pb_field_iter_find() anyway. */ - (void)pb_field_iter_begin(&iter, fields, dest_struct); - - while (stream->bytes_left) - { - uint32_t tag; - pb_wire_type_t wire_type; - bool eof; - - if (!pb_decode_tag(stream, &wire_type, &tag, &eof)) - { - if (eof) - break; - else - return false; - } - - if (!pb_field_iter_find(&iter, tag)) - { - /* No match found, check if it matches an extension. */ - if (tag >= extension_range_start) - { - if (!find_extension_field(&iter)) - extension_range_start = (uint32_t)-1; - else - extension_range_start = iter.pos->tag; - - if (tag >= extension_range_start) - { - size_t pos = stream->bytes_left; - - if (!decode_extension(stream, tag, wire_type, &iter)) - return false; - - if (pos != stream->bytes_left) - { - /* The field was handled */ - continue; - } - } - } - - /* No match found, skip data */ - if (!pb_skip_field(stream, wire_type)) - return false; - continue; - } - - /* If a repeated fixed count field was found, get size from - * 'fixed_count_field' as there is no counter contained in the struct. - */ - if (PB_HTYPE(iter.pos->type) == PB_HTYPE_REPEATED - && iter.pSize == iter.pData) - { - if (fixed_count_field != iter.pos) { - /* If the new fixed count field does not match the previous one, - * check that the previous one is NULL or that it finished - * receiving all the expected data. - */ - if (fixed_count_field != NULL && - fixed_count_size != fixed_count_field->array_size) - { - PB_RETURN_ERROR(stream, "wrong size for fixed count field"); - } - - fixed_count_field = iter.pos; - fixed_count_size = 0; - } - - iter.pSize = &fixed_count_size; - } - - if (PB_HTYPE(iter.pos->type) == PB_HTYPE_REQUIRED - && iter.required_field_index < PB_MAX_REQUIRED_FIELDS) - { - uint32_t tmp = ((uint32_t)1 << (iter.required_field_index & 31)); - fields_seen[iter.required_field_index >> 5] |= tmp; - } - - if (!decode_field(stream, wire_type, &iter)) - return false; - } - - /* Check that all elements of the last decoded fixed count field were present. */ - if (fixed_count_field != NULL && - fixed_count_size != fixed_count_field->array_size) - { - PB_RETURN_ERROR(stream, "wrong size for fixed count field"); - } - - /* Check that all required fields were present. */ - { - /* First figure out the number of required fields by - * seeking to the end of the field array. Usually we - * are already close to end after decoding. - */ - unsigned req_field_count; - pb_type_t last_type; - unsigned i; - do { - req_field_count = iter.required_field_index; - last_type = iter.pos->type; - } while (pb_field_iter_next(&iter)); - - /* Fixup if last field was also required. */ - if (PB_HTYPE(last_type) == PB_HTYPE_REQUIRED && iter.pos->tag != 0) - req_field_count++; - - if (req_field_count > PB_MAX_REQUIRED_FIELDS) - req_field_count = PB_MAX_REQUIRED_FIELDS; - - if (req_field_count > 0) - { - /* Check the whole words */ - for (i = 0; i < (req_field_count >> 5); i++) - { - if (fields_seen[i] != allbits) - PB_RETURN_ERROR(stream, "missing required field"); - } - - /* Check the remaining bits (if any) */ - if ((req_field_count & 31) != 0) - { - if (fields_seen[req_field_count >> 5] != - (allbits >> (32 - (req_field_count & 31)))) - { - PB_RETURN_ERROR(stream, "missing required field"); - } - } - } - } - - return true; -} - -bool checkreturn pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) -{ - bool status; - pb_message_set_to_defaults(fields, dest_struct); - status = pb_decode_noinit(stream, fields, dest_struct); - -#ifdef PB_ENABLE_MALLOC - if (!status) - pb_release(fields, dest_struct); -#endif - - return status; -} - -bool pb_decode_delimited_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) -{ - pb_istream_t substream; - bool status; - - if (!pb_make_string_substream(stream, &substream)) - return false; - - status = pb_decode_noinit(&substream, fields, dest_struct); - - if (!pb_close_string_substream(stream, &substream)) - return false; - return status; -} - -bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) -{ - pb_istream_t substream; - bool status; - - if (!pb_make_string_substream(stream, &substream)) - return false; - - status = pb_decode(&substream, fields, dest_struct); - - if (!pb_close_string_substream(stream, &substream)) - return false; - return status; -} - -bool pb_decode_nullterminated(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) -{ - /* This behaviour will be separated in nanopb-0.4.0, see issue #278. */ - return pb_decode(stream, fields, dest_struct); -} - -#ifdef PB_ENABLE_MALLOC -/* Given an oneof field, if there has already been a field inside this oneof, - * release it before overwriting with a different one. */ -static bool pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *iter) -{ - pb_size_t old_tag = *(pb_size_t*)iter->pSize; /* Previous which_ value */ - pb_size_t new_tag = iter->pos->tag; /* New which_ value */ - - if (old_tag == 0) - return true; /* Ok, no old data in union */ - - if (old_tag == new_tag) - return true; /* Ok, old data is of same type => merge */ - - /* Release old data. The find can fail if the message struct contains - * invalid data. */ - if (!pb_field_iter_find(iter, old_tag)) - PB_RETURN_ERROR(stream, "invalid union tag"); - - pb_release_single_field(iter); - - /* Restore iterator to where it should be. - * This shouldn't fail unless the pb_field_t structure is corrupted. */ - if (!pb_field_iter_find(iter, new_tag)) - PB_RETURN_ERROR(stream, "iterator error"); - - return true; -} - -static void pb_release_single_field(const pb_field_iter_t *iter) -{ - pb_type_t type; - type = iter->pos->type; - - if (PB_HTYPE(type) == PB_HTYPE_ONEOF) - { - if (*(pb_size_t*)iter->pSize != iter->pos->tag) - return; /* This is not the current field in the union */ - } - - /* Release anything contained inside an extension or submsg. - * This has to be done even if the submsg itself is statically - * allocated. */ - if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) - { - /* Release fields from all extensions in the linked list */ - pb_extension_t *ext = *(pb_extension_t**)iter->pData; - while (ext != NULL) - { - pb_field_iter_t ext_iter; - iter_from_extension(&ext_iter, ext); - pb_release_single_field(&ext_iter); - ext = ext->next; - } - } - else if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE) - { - /* Release fields in submessage or submsg array */ - void *pItem = iter->pData; - pb_size_t count = 1; - - if (PB_ATYPE(type) == PB_ATYPE_POINTER) - { - pItem = *(void**)iter->pData; - } - - if (PB_HTYPE(type) == PB_HTYPE_REPEATED) - { - if (PB_ATYPE(type) == PB_ATYPE_STATIC && iter->pSize == iter->pData) { - /* No _count field so use size of the array */ - count = iter->pos->array_size; - } else { - count = *(pb_size_t*)iter->pSize; - } - - if (PB_ATYPE(type) == PB_ATYPE_STATIC && count > iter->pos->array_size) - { - /* Protect against corrupted _count fields */ - count = iter->pos->array_size; - } - } - - if (pItem) - { - while (count--) - { - pb_release((const pb_field_t*)iter->pos->ptr, pItem); - pItem = (char*)pItem + iter->pos->data_size; - } - } - } - - if (PB_ATYPE(type) == PB_ATYPE_POINTER) - { - if (PB_HTYPE(type) == PB_HTYPE_REPEATED && - (PB_LTYPE(type) == PB_LTYPE_STRING || - PB_LTYPE(type) == PB_LTYPE_BYTES)) - { - /* Release entries in repeated string or bytes array */ - void **pItem = *(void***)iter->pData; - pb_size_t count = *(pb_size_t*)iter->pSize; - while (count--) - { - pb_free(*pItem); - *pItem++ = NULL; - } - } - - if (PB_HTYPE(type) == PB_HTYPE_REPEATED) - { - /* We are going to release the array, so set the size to 0 */ - *(pb_size_t*)iter->pSize = 0; - } - - /* Release main item */ - pb_free(*(void**)iter->pData); - *(void**)iter->pData = NULL; - } -} - -void pb_release(const pb_field_t fields[], void *dest_struct) -{ - pb_field_iter_t iter; - - if (!dest_struct) - return; /* Ignore NULL pointers, similar to free() */ - - if (!pb_field_iter_begin(&iter, fields, dest_struct)) - return; /* Empty message type */ - - do - { - pb_release_single_field(&iter); - } while (pb_field_iter_next(&iter)); -} -#endif - -/* Field decoders */ - -bool pb_decode_svarint(pb_istream_t *stream, pb_int64_t *dest) -{ - pb_uint64_t value; - if (!pb_decode_varint(stream, &value)) - return false; - - if (value & 1) - *dest = (pb_int64_t)(~(value >> 1)); - else - *dest = (pb_int64_t)(value >> 1); - - return true; -} - -bool pb_decode_fixed32(pb_istream_t *stream, void *dest) -{ - pb_byte_t bytes[4]; - - if (!pb_read(stream, bytes, 4)) - return false; - - *(uint32_t*)dest = ((uint32_t)bytes[0] << 0) | - ((uint32_t)bytes[1] << 8) | - ((uint32_t)bytes[2] << 16) | - ((uint32_t)bytes[3] << 24); - return true; -} - -#ifndef PB_WITHOUT_64BIT -bool pb_decode_fixed64(pb_istream_t *stream, void *dest) -{ - pb_byte_t bytes[8]; - - if (!pb_read(stream, bytes, 8)) - return false; - - *(uint64_t*)dest = ((uint64_t)bytes[0] << 0) | - ((uint64_t)bytes[1] << 8) | - ((uint64_t)bytes[2] << 16) | - ((uint64_t)bytes[3] << 24) | - ((uint64_t)bytes[4] << 32) | - ((uint64_t)bytes[5] << 40) | - ((uint64_t)bytes[6] << 48) | - ((uint64_t)bytes[7] << 56); - - return true; -} -#endif - -static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest) -{ - pb_uint64_t value; - pb_int64_t svalue; - pb_int64_t clamped; - if (!pb_decode_varint(stream, &value)) - return false; - - /* See issue 97: Google's C++ protobuf allows negative varint values to - * be cast as int32_t, instead of the int64_t that should be used when - * encoding. Previous nanopb versions had a bug in encoding. In order to - * not break decoding of such messages, we cast <=32 bit fields to - * int32_t first to get the sign correct. - */ - if (field->data_size == sizeof(pb_int64_t)) - svalue = (pb_int64_t)value; - else - svalue = (int32_t)value; - - /* Cast to the proper field size, while checking for overflows */ - if (field->data_size == sizeof(pb_int64_t)) - clamped = *(pb_int64_t*)dest = svalue; - else if (field->data_size == sizeof(int32_t)) - clamped = *(int32_t*)dest = (int32_t)svalue; - else if (field->data_size == sizeof(int_least16_t)) - clamped = *(int_least16_t*)dest = (int_least16_t)svalue; - else if (field->data_size == sizeof(int_least8_t)) - clamped = *(int_least8_t*)dest = (int_least8_t)svalue; - else - PB_RETURN_ERROR(stream, "invalid data_size"); - - if (clamped != svalue) - PB_RETURN_ERROR(stream, "integer too large"); - - return true; -} - -static bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest) -{ - pb_uint64_t value, clamped; - if (!pb_decode_varint(stream, &value)) - return false; - - /* Cast to the proper field size, while checking for overflows */ - if (field->data_size == sizeof(pb_uint64_t)) - clamped = *(pb_uint64_t*)dest = value; - else if (field->data_size == sizeof(uint32_t)) - clamped = *(uint32_t*)dest = (uint32_t)value; - else if (field->data_size == sizeof(uint_least16_t)) - clamped = *(uint_least16_t*)dest = (uint_least16_t)value; - else if (field->data_size == sizeof(uint_least8_t)) - clamped = *(uint_least8_t*)dest = (uint_least8_t)value; - else - PB_RETURN_ERROR(stream, "invalid data_size"); - - if (clamped != value) - PB_RETURN_ERROR(stream, "integer too large"); - - return true; -} - -static bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest) -{ - pb_int64_t value, clamped; - if (!pb_decode_svarint(stream, &value)) - return false; - - /* Cast to the proper field size, while checking for overflows */ - if (field->data_size == sizeof(pb_int64_t)) - clamped = *(pb_int64_t*)dest = value; - else if (field->data_size == sizeof(int32_t)) - clamped = *(int32_t*)dest = (int32_t)value; - else if (field->data_size == sizeof(int_least16_t)) - clamped = *(int_least16_t*)dest = (int_least16_t)value; - else if (field->data_size == sizeof(int_least8_t)) - clamped = *(int_least8_t*)dest = (int_least8_t)value; - else - PB_RETURN_ERROR(stream, "invalid data_size"); - - if (clamped != value) - PB_RETURN_ERROR(stream, "integer too large"); - - return true; -} - -static bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest) -{ - PB_UNUSED(field); - return pb_decode_fixed32(stream, dest); -} - -static bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest) -{ - PB_UNUSED(field); -#ifndef PB_WITHOUT_64BIT - return pb_decode_fixed64(stream, dest); -#else - PB_UNUSED(dest); - PB_RETURN_ERROR(stream, "no 64bit support"); -#endif -} - -static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest) -{ - uint32_t size; - size_t alloc_size; - pb_bytes_array_t *bdest; - - if (!pb_decode_varint32(stream, &size)) - return false; - - if (size > PB_SIZE_MAX) - PB_RETURN_ERROR(stream, "bytes overflow"); - - alloc_size = PB_BYTES_ARRAY_T_ALLOCSIZE(size); - if (size > alloc_size) - PB_RETURN_ERROR(stream, "size too large"); - - if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) - { -#ifndef PB_ENABLE_MALLOC - PB_RETURN_ERROR(stream, "no malloc support"); -#else - if (!allocate_field(stream, dest, alloc_size, 1)) - return false; - bdest = *(pb_bytes_array_t**)dest; -#endif - } - else - { - if (alloc_size > field->data_size) - PB_RETURN_ERROR(stream, "bytes overflow"); - bdest = (pb_bytes_array_t*)dest; - } - - bdest->size = (pb_size_t)size; - return pb_read(stream, bdest->bytes, size); -} - -static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest) -{ - uint32_t size; - size_t alloc_size; - bool status; - if (!pb_decode_varint32(stream, &size)) - return false; - - /* Space for null terminator */ - alloc_size = size + 1; - - if (alloc_size < size) - PB_RETURN_ERROR(stream, "size too large"); - - if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) - { -#ifndef PB_ENABLE_MALLOC - PB_RETURN_ERROR(stream, "no malloc support"); -#else - if (!allocate_field(stream, dest, alloc_size, 1)) - return false; - dest = *(void**)dest; -#endif - } - else - { - if (alloc_size > field->data_size) - PB_RETURN_ERROR(stream, "string overflow"); - } - - status = pb_read(stream, (pb_byte_t*)dest, size); - *((pb_byte_t*)dest + size) = 0; - return status; -} - -static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest) -{ - bool status; - pb_istream_t substream; - const pb_field_t* submsg_fields = (const pb_field_t*)field->ptr; - - if (!pb_make_string_substream(stream, &substream)) - return false; - - if (field->ptr == NULL) - PB_RETURN_ERROR(stream, "invalid field descriptor"); - - /* New array entries need to be initialized, while required and optional - * submessages have already been initialized in the top-level pb_decode. */ - if (PB_HTYPE(field->type) == PB_HTYPE_REPEATED) - status = pb_decode(&substream, submsg_fields, dest); - else - status = pb_decode_noinit(&substream, submsg_fields, dest); - - if (!pb_close_string_substream(stream, &substream)) - return false; - return status; -} - -static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest) -{ - uint32_t size; - - if (!pb_decode_varint32(stream, &size)) - return false; - - if (size > PB_SIZE_MAX) - PB_RETURN_ERROR(stream, "bytes overflow"); - - if (size == 0) - { - /* As a special case, treat empty bytes string as all zeros for fixed_length_bytes. */ - memset(dest, 0, field->data_size); - return true; - } - - if (size != field->data_size) - PB_RETURN_ERROR(stream, "incorrect fixed length bytes size"); - - return pb_read(stream, (pb_byte_t*)dest, field->data_size); -} diff --git a/Pods/nanopb/pb_decode.h b/Pods/nanopb/pb_decode.h @@ -1,175 +0,0 @@ -/* pb_decode.h: Functions to decode protocol buffers. Depends on pb_decode.c. - * The main function is pb_decode. You also need an input stream, and the - * field descriptions created by nanopb_generator.py. - */ - -#ifndef PB_DECODE_H_INCLUDED -#define PB_DECODE_H_INCLUDED - -#include "pb.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Structure for defining custom input streams. You will need to provide - * a callback function to read the bytes from your storage, which can be - * for example a file or a network socket. - * - * The callback must conform to these rules: - * - * 1) Return false on IO errors. This will cause decoding to abort. - * 2) You can use state to store your own data (e.g. buffer pointer), - * and rely on pb_read to verify that no-body reads past bytes_left. - * 3) Your callback may be used with substreams, in which case bytes_left - * is different than from the main stream. Don't use bytes_left to compute - * any pointers. - */ -struct pb_istream_s -{ -#ifdef PB_BUFFER_ONLY - /* Callback pointer is not used in buffer-only configuration. - * Having an int pointer here allows binary compatibility but - * gives an error if someone tries to assign callback function. - */ - int *callback; -#else - bool (*callback)(pb_istream_t *stream, pb_byte_t *buf, size_t count); -#endif - - void *state; /* Free field for use by callback implementation */ - size_t bytes_left; - -#ifndef PB_NO_ERRMSG - const char *errmsg; -#endif -}; - -/*************************** - * Main decoding functions * - ***************************/ - -/* Decode a single protocol buffers message from input stream into a C structure. - * Returns true on success, false on any failure. - * The actual struct pointed to by dest must match the description in fields. - * Callback fields of the destination structure must be initialized by caller. - * All other fields will be initialized by this function. - * - * Example usage: - * MyMessage msg = {}; - * uint8_t buffer[64]; - * pb_istream_t stream; - * - * // ... read some data into buffer ... - * - * stream = pb_istream_from_buffer(buffer, count); - * pb_decode(&stream, MyMessage_fields, &msg); - */ -bool pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); - -/* Same as pb_decode, except does not initialize the destination structure - * to default values. This is slightly faster if you need no default values - * and just do memset(struct, 0, sizeof(struct)) yourself. - * - * This can also be used for 'merging' two messages, i.e. update only the - * fields that exist in the new message. - * - * Note: If this function returns with an error, it will not release any - * dynamically allocated fields. You will need to call pb_release() yourself. - */ -bool pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); - -/* Same as pb_decode, except expects the stream to start with the message size - * encoded as varint. Corresponds to parseDelimitedFrom() in Google's - * protobuf API. - */ -bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); - -/* Same as pb_decode_delimited, except that it does not initialize the destination structure. - * See pb_decode_noinit - */ -bool pb_decode_delimited_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); - -/* Same as pb_decode, except allows the message to be terminated with a null byte. - * NOTE: Until nanopb-0.4.0, pb_decode() also allows null-termination. This behaviour - * is not supported in most other protobuf implementations, so pb_decode_delimited() - * is a better option for compatibility. - */ -bool pb_decode_nullterminated(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); - -#ifdef PB_ENABLE_MALLOC -/* Release any allocated pointer fields. If you use dynamic allocation, you should - * call this for any successfully decoded message when you are done with it. If - * pb_decode() returns with an error, the message is already released. - */ -void pb_release(const pb_field_t fields[], void *dest_struct); -#endif - - -/************************************** - * Functions for manipulating streams * - **************************************/ - -/* Create an input stream for reading from a memory buffer. - * - * Alternatively, you can use a custom stream that reads directly from e.g. - * a file or a network socket. - */ -pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t bufsize); - -/* Function to read from a pb_istream_t. You can use this if you need to - * read some custom header data, or to read data in field callbacks. - */ -bool pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count); - - -/************************************************ - * Helper functions for writing field callbacks * - ************************************************/ - -/* Decode the tag for the next field in the stream. Gives the wire type and - * field tag. At end of the message, returns false and sets eof to true. */ -bool pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof); - -/* Skip the field payload data, given the wire type. */ -bool pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type); - -/* Decode an integer in the varint format. This works for bool, enum, int32, - * int64, uint32 and uint64 field types. */ -#ifndef PB_WITHOUT_64BIT -bool pb_decode_varint(pb_istream_t *stream, uint64_t *dest); -#else -#define pb_decode_varint pb_decode_varint32 -#endif - -/* Decode an integer in the varint format. This works for bool, enum, int32, - * and uint32 field types. */ -bool pb_decode_varint32(pb_istream_t *stream, uint32_t *dest); - -/* Decode an integer in the zig-zagged svarint format. This works for sint32 - * and sint64. */ -#ifndef PB_WITHOUT_64BIT -bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest); -#else -bool pb_decode_svarint(pb_istream_t *stream, int32_t *dest); -#endif - -/* Decode a fixed32, sfixed32 or float value. You need to pass a pointer to - * a 4-byte wide C variable. */ -bool pb_decode_fixed32(pb_istream_t *stream, void *dest); - -#ifndef PB_WITHOUT_64BIT -/* Decode a fixed64, sfixed64 or double value. You need to pass a pointer to - * a 8-byte wide C variable. */ -bool pb_decode_fixed64(pb_istream_t *stream, void *dest); -#endif - -/* Make a limited-length substream for reading a PB_WT_STRING field. */ -bool pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream); -bool pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/Pods/nanopb/pb_encode.c b/Pods/nanopb/pb_encode.c @@ -1,869 +0,0 @@ -/* pb_encode.c -- encode a protobuf using minimal resources - * - * 2011 Petteri Aimonen <jpa@kapsi.fi> - */ - -#include "pb.h" -#include "pb_encode.h" -#include "pb_common.h" - -/* Use the GCC warn_unused_result attribute to check that all return values - * are propagated correctly. On other compilers and gcc before 3.4.0 just - * ignore the annotation. - */ -#if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) - #define checkreturn -#else - #define checkreturn __attribute__((warn_unused_result)) -#endif - -/************************************** - * Declarations internal to this file * - **************************************/ -typedef bool (*pb_encoder_t)(pb_ostream_t *stream, const pb_field_t *field, const void *src) checkreturn; - -static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); -static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *field, const void *pData, size_t count, pb_encoder_t func); -static bool checkreturn encode_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData); -static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb_extension_t *extension); -static bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData); -static void *pb_const_cast(const void *p); -static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src); -static bool checkreturn pb_enc_uvarint(pb_ostream_t *stream, const pb_field_t *field, const void *src); -static bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *field, const void *src); -static bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, const void *src); -static bool checkreturn pb_enc_fixed64(pb_ostream_t *stream, const pb_field_t *field, const void *src); -static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src); -static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src); -static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src); -static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src); - -#ifdef PB_WITHOUT_64BIT -#define pb_int64_t int32_t -#define pb_uint64_t uint32_t - -static bool checkreturn pb_encode_negative_varint(pb_ostream_t *stream, pb_uint64_t value); -#else -#define pb_int64_t int64_t -#define pb_uint64_t uint64_t -#endif - -/* --- Function pointers to field encoders --- - * Order in the array must match pb_action_t LTYPE numbering. - */ -static const pb_encoder_t PB_ENCODERS[PB_LTYPES_COUNT] = { - &pb_enc_varint, - &pb_enc_uvarint, - &pb_enc_svarint, - &pb_enc_fixed32, - &pb_enc_fixed64, - - &pb_enc_bytes, - &pb_enc_string, - &pb_enc_submessage, - NULL, /* extensions */ - &pb_enc_fixed_length_bytes -}; - -/******************************* - * pb_ostream_t implementation * - *******************************/ - -static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count) -{ - size_t i; - pb_byte_t *dest = (pb_byte_t*)stream->state; - stream->state = dest + count; - - for (i = 0; i < count; i++) - dest[i] = buf[i]; - - return true; -} - -pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize) -{ - pb_ostream_t stream; -#ifdef PB_BUFFER_ONLY - stream.callback = (void*)1; /* Just a marker value */ -#else - stream.callback = &buf_write; -#endif - stream.state = buf; - stream.max_size = bufsize; - stream.bytes_written = 0; -#ifndef PB_NO_ERRMSG - stream.errmsg = NULL; -#endif - return stream; -} - -bool checkreturn pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count) -{ - if (stream->callback != NULL) - { - if (stream->bytes_written + count > stream->max_size) - PB_RETURN_ERROR(stream, "stream full"); - -#ifdef PB_BUFFER_ONLY - if (!buf_write(stream, buf, count)) - PB_RETURN_ERROR(stream, "io error"); -#else - if (!stream->callback(stream, buf, count)) - PB_RETURN_ERROR(stream, "io error"); -#endif - } - - stream->bytes_written += count; - return true; -} - -/************************* - * Encode a single field * - *************************/ - -/* Encode a static array. Handles the size calculations and possible packing. */ -static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *field, - const void *pData, size_t count, pb_encoder_t func) -{ - size_t i; - const void *p; - size_t size; - - if (count == 0) - return true; - - if (PB_ATYPE(field->type) != PB_ATYPE_POINTER && count > field->array_size) - PB_RETURN_ERROR(stream, "array max size exceeded"); - - /* We always pack arrays if the datatype allows it. */ - if (PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) - { - if (!pb_encode_tag(stream, PB_WT_STRING, field->tag)) - return false; - - /* Determine the total size of packed array. */ - if (PB_LTYPE(field->type) == PB_LTYPE_FIXED32) - { - size = 4 * count; - } - else if (PB_LTYPE(field->type) == PB_LTYPE_FIXED64) - { - size = 8 * count; - } - else - { - pb_ostream_t sizestream = PB_OSTREAM_SIZING; - p = pData; - for (i = 0; i < count; i++) - { - if (!func(&sizestream, field, p)) - return false; - p = (const char*)p + field->data_size; - } - size = sizestream.bytes_written; - } - - if (!pb_encode_varint(stream, (pb_uint64_t)size)) - return false; - - if (stream->callback == NULL) - return pb_write(stream, NULL, size); /* Just sizing.. */ - - /* Write the data */ - p = pData; - for (i = 0; i < count; i++) - { - if (!func(stream, field, p)) - return false; - p = (const char*)p + field->data_size; - } - } - else - { - p = pData; - for (i = 0; i < count; i++) - { - if (!pb_encode_tag_for_field(stream, field)) - return false; - - /* Normally the data is stored directly in the array entries, but - * for pointer-type string and bytes fields, the array entries are - * actually pointers themselves also. So we have to dereference once - * more to get to the actual data. */ - if (PB_ATYPE(field->type) == PB_ATYPE_POINTER && - (PB_LTYPE(field->type) == PB_LTYPE_STRING || - PB_LTYPE(field->type) == PB_LTYPE_BYTES)) - { - if (!func(stream, field, *(const void* const*)p)) - return false; - } - else - { - if (!func(stream, field, p)) - return false; - } - p = (const char*)p + field->data_size; - } - } - - return true; -} - -/* In proto3, all fields are optional and are only encoded if their value is "non-zero". - * This function implements the check for the zero value. */ -static bool pb_check_proto3_default_value(const pb_field_t *field, const void *pData) -{ - pb_type_t type = field->type; - const void *pSize = (const char*)pData + field->size_offset; - - if (PB_HTYPE(type) == PB_HTYPE_REQUIRED) - { - /* Required proto2 fields inside proto3 submessage, pretty rare case */ - return false; - } - else if (PB_HTYPE(type) == PB_HTYPE_REPEATED) - { - /* Repeated fields inside proto3 submessage: present if count != 0 */ - return *(const pb_size_t*)pSize == 0; - } - else if (PB_HTYPE(type) == PB_HTYPE_ONEOF) - { - /* Oneof fields */ - return *(const pb_size_t*)pSize == 0; - } - else if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL && field->size_offset) - { - /* Proto2 optional fields inside proto3 submessage */ - return *(const bool*)pSize == false; - } - - /* Rest is proto3 singular fields */ - - if (PB_ATYPE(type) == PB_ATYPE_STATIC) - { - if (PB_LTYPE(type) == PB_LTYPE_BYTES) - { - const pb_bytes_array_t *bytes = (const pb_bytes_array_t*)pData; - return bytes->size == 0; - } - else if (PB_LTYPE(type) == PB_LTYPE_STRING) - { - return *(const char*)pData == '\0'; - } - else if (PB_LTYPE(type) == PB_LTYPE_FIXED_LENGTH_BYTES) - { - /* Fixed length bytes is only empty if its length is fixed - * as 0. Which would be pretty strange, but we can check - * it anyway. */ - return field->data_size == 0; - } - else if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE) - { - /* Check all fields in the submessage to find if any of them - * are non-zero. The comparison cannot be done byte-per-byte - * because the C struct may contain padding bytes that must - * be skipped. - */ - pb_field_iter_t iter; - if (pb_field_iter_begin(&iter, (const pb_field_t*)field->ptr, pb_const_cast(pData))) - { - do - { - if (!pb_check_proto3_default_value(iter.pos, iter.pData)) - { - return false; - } - } while (pb_field_iter_next(&iter)); - } - return true; - } - } - - { - /* Catch-all branch that does byte-per-byte comparison for zero value. - * - * This is for all pointer fields, and for static PB_LTYPE_VARINT, - * UVARINT, SVARINT, FIXED32, FIXED64, EXTENSION fields, and also - * callback fields. These all have integer or pointer value which - * can be compared with 0. - */ - pb_size_t i; - const char *p = (const char*)pData; - for (i = 0; i < field->data_size; i++) - { - if (p[i] != 0) - { - return false; - } - } - - return true; - } -} - -/* Encode a field with static or pointer allocation, i.e. one whose data - * is available to the encoder directly. */ -static bool checkreturn encode_basic_field(pb_ostream_t *stream, - const pb_field_t *field, const void *pData) -{ - pb_encoder_t func; - bool implicit_has; - const void *pSize = &implicit_has; - - func = PB_ENCODERS[PB_LTYPE(field->type)]; - - if (field->size_offset) - { - /* Static optional, repeated or oneof field */ - pSize = (const char*)pData + field->size_offset; - } - else if (PB_HTYPE(field->type) == PB_HTYPE_OPTIONAL) - { - /* Proto3 style field, optional but without explicit has_ field. */ - implicit_has = !pb_check_proto3_default_value(field, pData); - } - else - { - /* Required field, always present */ - implicit_has = true; - } - - if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) - { - /* pData is a pointer to the field, which contains pointer to - * the data. If the 2nd pointer is NULL, it is interpreted as if - * the has_field was false. - */ - pData = *(const void* const*)pData; - implicit_has = (pData != NULL); - } - - switch (PB_HTYPE(field->type)) - { - case PB_HTYPE_REQUIRED: - if (!pData) - PB_RETURN_ERROR(stream, "missing required field"); - if (!pb_encode_tag_for_field(stream, field)) - return false; - if (!func(stream, field, pData)) - return false; - break; - - case PB_HTYPE_OPTIONAL: - if (*(const bool*)pSize) - { - if (!pb_encode_tag_for_field(stream, field)) - return false; - - if (!func(stream, field, pData)) - return false; - } - break; - - case PB_HTYPE_REPEATED: { - pb_size_t count; - if (field->size_offset != 0) { - count = *(const pb_size_t*)pSize; - } else { - count = field->array_size; - } - if (!encode_array(stream, field, pData, count, func)) - return false; - break; - } - - case PB_HTYPE_ONEOF: - if (*(const pb_size_t*)pSize == field->tag) - { - if (!pb_encode_tag_for_field(stream, field)) - return false; - - if (!func(stream, field, pData)) - return false; - } - break; - - default: - PB_RETURN_ERROR(stream, "invalid field type"); - } - - return true; -} - -/* Encode a field with callback semantics. This means that a user function is - * called to provide and encode the actual data. */ -static bool checkreturn encode_callback_field(pb_ostream_t *stream, - const pb_field_t *field, const void *pData) -{ - const pb_callback_t *callback = (const pb_callback_t*)pData; - -#ifdef PB_OLD_CALLBACK_STYLE - const void *arg = callback->arg; -#else - void * const *arg = &(callback->arg); -#endif - - if (callback->funcs.encode != NULL) - { - if (!callback->funcs.encode(stream, field, arg)) - PB_RETURN_ERROR(stream, "callback error"); - } - return true; -} - -/* Encode a single field of any callback or static type. */ -static bool checkreturn encode_field(pb_ostream_t *stream, - const pb_field_t *field, const void *pData) -{ - switch (PB_ATYPE(field->type)) - { - case PB_ATYPE_STATIC: - case PB_ATYPE_POINTER: - return encode_basic_field(stream, field, pData); - - case PB_ATYPE_CALLBACK: - return encode_callback_field(stream, field, pData); - - default: - PB_RETURN_ERROR(stream, "invalid field type"); - } -} - -/* Default handler for extension fields. Expects to have a pb_field_t - * pointer in the extension->type->arg field. */ -static bool checkreturn default_extension_encoder(pb_ostream_t *stream, - const pb_extension_t *extension) -{ - const pb_field_t *field = (const pb_field_t*)extension->type->arg; - - if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) - { - /* For pointer extensions, the pointer is stored directly - * in the extension structure. This avoids having an extra - * indirection. */ - return encode_field(stream, field, &extension->dest); - } - else - { - return encode_field(stream, field, extension->dest); - } -} - -/* Walk through all the registered extensions and give them a chance - * to encode themselves. */ -static bool checkreturn encode_extension_field(pb_ostream_t *stream, - const pb_field_t *field, const void *pData) -{ - const pb_extension_t *extension = *(const pb_extension_t* const *)pData; - PB_UNUSED(field); - - while (extension) - { - bool status; - if (extension->type->encode) - status = extension->type->encode(stream, extension); - else - status = default_extension_encoder(stream, extension); - - if (!status) - return false; - - extension = extension->next; - } - - return true; -} - -/********************* - * Encode all fields * - *********************/ - -static void *pb_const_cast(const void *p) -{ - /* Note: this casts away const, in order to use the common field iterator - * logic for both encoding and decoding. */ - union { - void *p1; - const void *p2; - } t; - t.p2 = p; - return t.p1; -} - -bool checkreturn pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct) -{ - pb_field_iter_t iter; - if (!pb_field_iter_begin(&iter, fields, pb_const_cast(src_struct))) - return true; /* Empty message type */ - - do { - if (PB_LTYPE(iter.pos->type) == PB_LTYPE_EXTENSION) - { - /* Special case for the extension field placeholder */ - if (!encode_extension_field(stream, iter.pos, iter.pData)) - return false; - } - else - { - /* Regular field */ - if (!encode_field(stream, iter.pos, iter.pData)) - return false; - } - } while (pb_field_iter_next(&iter)); - - return true; -} - -bool pb_encode_delimited(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct) -{ - return pb_encode_submessage(stream, fields, src_struct); -} - -bool pb_encode_nullterminated(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct) -{ - const pb_byte_t zero = 0; - - if (!pb_encode(stream, fields, src_struct)) - return false; - - return pb_write(stream, &zero, 1); -} - -bool pb_get_encoded_size(size_t *size, const pb_field_t fields[], const void *src_struct) -{ - pb_ostream_t stream = PB_OSTREAM_SIZING; - - if (!pb_encode(&stream, fields, src_struct)) - return false; - - *size = stream.bytes_written; - return true; -} - -/******************** - * Helper functions * - ********************/ - -#ifdef PB_WITHOUT_64BIT -bool checkreturn pb_encode_negative_varint(pb_ostream_t *stream, pb_uint64_t value) -{ - pb_byte_t buffer[10]; - size_t i = 0; - size_t compensation = 32;/* we need to compensate 32 bits all set to 1 */ - - while (value) - { - buffer[i] = (pb_byte_t)((value & 0x7F) | 0x80); - value >>= 7; - if (compensation) - { - /* re-set all the compensation bits we can or need */ - size_t bits = compensation > 7 ? 7 : compensation; - value ^= (pb_uint64_t)((0xFFu >> (8 - bits)) << 25); /* set the number of bits needed on the lowest of the most significant 7 bits */ - compensation -= bits; - } - i++; - } - buffer[i - 1] &= 0x7F; /* Unset top bit on last byte */ - - return pb_write(stream, buffer, i); -} -#endif - -bool checkreturn pb_encode_varint(pb_ostream_t *stream, pb_uint64_t value) -{ - pb_byte_t buffer[10]; - size_t i = 0; - - if (value <= 0x7F) - { - pb_byte_t v = (pb_byte_t)value; - return pb_write(stream, &v, 1); - } - - while (value) - { - buffer[i] = (pb_byte_t)((value & 0x7F) | 0x80); - value >>= 7; - i++; - } - buffer[i-1] &= 0x7F; /* Unset top bit on last byte */ - - return pb_write(stream, buffer, i); -} - -bool checkreturn pb_encode_svarint(pb_ostream_t *stream, pb_int64_t value) -{ - pb_uint64_t zigzagged; - if (value < 0) - zigzagged = ~((pb_uint64_t)value << 1); - else - zigzagged = (pb_uint64_t)value << 1; - - return pb_encode_varint(stream, zigzagged); -} - -bool checkreturn pb_encode_fixed32(pb_ostream_t *stream, const void *value) -{ - uint32_t val = *(const uint32_t*)value; - pb_byte_t bytes[4]; - bytes[0] = (pb_byte_t)(val & 0xFF); - bytes[1] = (pb_byte_t)((val >> 8) & 0xFF); - bytes[2] = (pb_byte_t)((val >> 16) & 0xFF); - bytes[3] = (pb_byte_t)((val >> 24) & 0xFF); - return pb_write(stream, bytes, 4); -} - -#ifndef PB_WITHOUT_64BIT -bool checkreturn pb_encode_fixed64(pb_ostream_t *stream, const void *value) -{ - uint64_t val = *(const uint64_t*)value; - pb_byte_t bytes[8]; - bytes[0] = (pb_byte_t)(val & 0xFF); - bytes[1] = (pb_byte_t)((val >> 8) & 0xFF); - bytes[2] = (pb_byte_t)((val >> 16) & 0xFF); - bytes[3] = (pb_byte_t)((val >> 24) & 0xFF); - bytes[4] = (pb_byte_t)((val >> 32) & 0xFF); - bytes[5] = (pb_byte_t)((val >> 40) & 0xFF); - bytes[6] = (pb_byte_t)((val >> 48) & 0xFF); - bytes[7] = (pb_byte_t)((val >> 56) & 0xFF); - return pb_write(stream, bytes, 8); -} -#endif - -bool checkreturn pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number) -{ - pb_uint64_t tag = ((pb_uint64_t)field_number << 3) | wiretype; - return pb_encode_varint(stream, tag); -} - -bool checkreturn pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t *field) -{ - pb_wire_type_t wiretype; - switch (PB_LTYPE(field->type)) - { - case PB_LTYPE_VARINT: - case PB_LTYPE_UVARINT: - case PB_LTYPE_SVARINT: - wiretype = PB_WT_VARINT; - break; - - case PB_LTYPE_FIXED32: - wiretype = PB_WT_32BIT; - break; - - case PB_LTYPE_FIXED64: - wiretype = PB_WT_64BIT; - break; - - case PB_LTYPE_BYTES: - case PB_LTYPE_STRING: - case PB_LTYPE_SUBMESSAGE: - case PB_LTYPE_FIXED_LENGTH_BYTES: - wiretype = PB_WT_STRING; - break; - - default: - PB_RETURN_ERROR(stream, "invalid field type"); - } - - return pb_encode_tag(stream, wiretype, field->tag); -} - -bool checkreturn pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size) -{ - if (!pb_encode_varint(stream, (pb_uint64_t)size)) - return false; - - return pb_write(stream, buffer, size); -} - -bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct) -{ - /* First calculate the message size using a non-writing substream. */ - pb_ostream_t substream = PB_OSTREAM_SIZING; - size_t size; - bool status; - - if (!pb_encode(&substream, fields, src_struct)) - { -#ifndef PB_NO_ERRMSG - stream->errmsg = substream.errmsg; -#endif - return false; - } - - size = substream.bytes_written; - - if (!pb_encode_varint(stream, (pb_uint64_t)size)) - return false; - - if (stream->callback == NULL) - return pb_write(stream, NULL, size); /* Just sizing */ - - if (stream->bytes_written + size > stream->max_size) - PB_RETURN_ERROR(stream, "stream full"); - - /* Use a substream to verify that a callback doesn't write more than - * what it did the first time. */ - substream.callback = stream->callback; - substream.state = stream->state; - substream.max_size = size; - substream.bytes_written = 0; -#ifndef PB_NO_ERRMSG - substream.errmsg = NULL; -#endif - - status = pb_encode(&substream, fields, src_struct); - - stream->bytes_written += substream.bytes_written; - stream->state = substream.state; -#ifndef PB_NO_ERRMSG - stream->errmsg = substream.errmsg; -#endif - - if (substream.bytes_written != size) - PB_RETURN_ERROR(stream, "submsg size changed"); - - return status; -} - -/* Field encoders */ - -static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src) -{ - pb_int64_t value = 0; - - if (field->data_size == sizeof(int_least8_t)) - value = *(const int_least8_t*)src; - else if (field->data_size == sizeof(int_least16_t)) - value = *(const int_least16_t*)src; - else if (field->data_size == sizeof(int32_t)) - value = *(const int32_t*)src; - else if (field->data_size == sizeof(pb_int64_t)) - value = *(const pb_int64_t*)src; - else - PB_RETURN_ERROR(stream, "invalid data_size"); - -#ifdef PB_WITHOUT_64BIT - if (value < 0) - return pb_encode_negative_varint(stream, (pb_uint64_t)value); - else -#endif - return pb_encode_varint(stream, (pb_uint64_t)value); -} - -static bool checkreturn pb_enc_uvarint(pb_ostream_t *stream, const pb_field_t *field, const void *src) -{ - pb_uint64_t value = 0; - - if (field->data_size == sizeof(uint_least8_t)) - value = *(const uint_least8_t*)src; - else if (field->data_size == sizeof(uint_least16_t)) - value = *(const uint_least16_t*)src; - else if (field->data_size == sizeof(uint32_t)) - value = *(const uint32_t*)src; - else if (field->data_size == sizeof(pb_uint64_t)) - value = *(const pb_uint64_t*)src; - else - PB_RETURN_ERROR(stream, "invalid data_size"); - - return pb_encode_varint(stream, value); -} - -static bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *field, const void *src) -{ - pb_int64_t value = 0; - - if (field->data_size == sizeof(int_least8_t)) - value = *(const int_least8_t*)src; - else if (field->data_size == sizeof(int_least16_t)) - value = *(const int_least16_t*)src; - else if (field->data_size == sizeof(int32_t)) - value = *(const int32_t*)src; - else if (field->data_size == sizeof(pb_int64_t)) - value = *(const pb_int64_t*)src; - else - PB_RETURN_ERROR(stream, "invalid data_size"); - - return pb_encode_svarint(stream, value); -} - -static bool checkreturn pb_enc_fixed64(pb_ostream_t *stream, const pb_field_t *field, const void *src) -{ - PB_UNUSED(field); -#ifndef PB_WITHOUT_64BIT - return pb_encode_fixed64(stream, src); -#else - PB_UNUSED(src); - PB_RETURN_ERROR(stream, "no 64bit support"); -#endif -} - -static bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, const void *src) -{ - PB_UNUSED(field); - return pb_encode_fixed32(stream, src); -} - -static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src) -{ - const pb_bytes_array_t *bytes = NULL; - - bytes = (const pb_bytes_array_t*)src; - - if (src == NULL) - { - /* Treat null pointer as an empty bytes field */ - return pb_encode_string(stream, NULL, 0); - } - - if (PB_ATYPE(field->type) == PB_ATYPE_STATIC && - PB_BYTES_ARRAY_T_ALLOCSIZE(bytes->size) > field->data_size) - { - PB_RETURN_ERROR(stream, "bytes size exceeded"); - } - - return pb_encode_string(stream, bytes->bytes, bytes->size); -} - -static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src) -{ - size_t size = 0; - size_t max_size = field->data_size; - const char *p = (const char*)src; - - if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) - max_size = (size_t)-1; - - if (src == NULL) - { - size = 0; /* Treat null pointer as an empty string */ - } - else - { - /* strnlen() is not always available, so just use a loop */ - while (size < max_size && *p != '\0') - { - size++; - p++; - } - } - - return pb_encode_string(stream, (const pb_byte_t*)src, size); -} - -static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src) -{ - if (field->ptr == NULL) - PB_RETURN_ERROR(stream, "invalid field descriptor"); - - return pb_encode_submessage(stream, (const pb_field_t*)field->ptr, src); -} - -static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src) -{ - return pb_encode_string(stream, (const pb_byte_t*)src, field->data_size); -} - diff --git a/Pods/nanopb/pb_encode.h b/Pods/nanopb/pb_encode.h @@ -1,170 +0,0 @@ -/* pb_encode.h: Functions to encode protocol buffers. Depends on pb_encode.c. - * The main function is pb_encode. You also need an output stream, and the - * field descriptions created by nanopb_generator.py. - */ - -#ifndef PB_ENCODE_H_INCLUDED -#define PB_ENCODE_H_INCLUDED - -#include "pb.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Structure for defining custom output streams. You will need to provide - * a callback function to write the bytes to your storage, which can be - * for example a file or a network socket. - * - * The callback must conform to these rules: - * - * 1) Return false on IO errors. This will cause encoding to abort. - * 2) You can use state to store your own data (e.g. buffer pointer). - * 3) pb_write will update bytes_written after your callback runs. - * 4) Substreams will modify max_size and bytes_written. Don't use them - * to calculate any pointers. - */ -struct pb_ostream_s -{ -#ifdef PB_BUFFER_ONLY - /* Callback pointer is not used in buffer-only configuration. - * Having an int pointer here allows binary compatibility but - * gives an error if someone tries to assign callback function. - * Also, NULL pointer marks a 'sizing stream' that does not - * write anything. - */ - int *callback; -#else - bool (*callback)(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); -#endif - void *state; /* Free field for use by callback implementation. */ - size_t max_size; /* Limit number of output bytes written (or use SIZE_MAX). */ - size_t bytes_written; /* Number of bytes written so far. */ - -#ifndef PB_NO_ERRMSG - const char *errmsg; -#endif -}; - -/*************************** - * Main encoding functions * - ***************************/ - -/* Encode a single protocol buffers message from C structure into a stream. - * Returns true on success, false on any failure. - * The actual struct pointed to by src_struct must match the description in fields. - * All required fields in the struct are assumed to have been filled in. - * - * Example usage: - * MyMessage msg = {}; - * uint8_t buffer[64]; - * pb_ostream_t stream; - * - * msg.field1 = 42; - * stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); - * pb_encode(&stream, MyMessage_fields, &msg); - */ -bool pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); - -/* Same as pb_encode, but prepends the length of the message as a varint. - * Corresponds to writeDelimitedTo() in Google's protobuf API. - */ -bool pb_encode_delimited(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); - -/* Same as pb_encode, but appends a null byte to the message for termination. - * NOTE: This behaviour is not supported in most other protobuf implementations, so pb_encode_delimited() - * is a better option for compatibility. - */ -bool pb_encode_nullterminated(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); - -/* Encode the message to get the size of the encoded data, but do not store - * the data. */ -bool pb_get_encoded_size(size_t *size, const pb_field_t fields[], const void *src_struct); - -/************************************** - * Functions for manipulating streams * - **************************************/ - -/* Create an output stream for writing into a memory buffer. - * The number of bytes written can be found in stream.bytes_written after - * encoding the message. - * - * Alternatively, you can use a custom stream that writes directly to e.g. - * a file or a network socket. - */ -pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize); - -/* Pseudo-stream for measuring the size of a message without actually storing - * the encoded data. - * - * Example usage: - * MyMessage msg = {}; - * pb_ostream_t stream = PB_OSTREAM_SIZING; - * pb_encode(&stream, MyMessage_fields, &msg); - * printf("Message size is %d\n", stream.bytes_written); - */ -#ifndef PB_NO_ERRMSG -#define PB_OSTREAM_SIZING {0,0,0,0,0} -#else -#define PB_OSTREAM_SIZING {0,0,0,0} -#endif - -/* Function to write into a pb_ostream_t stream. You can use this if you need - * to append or prepend some custom headers to the message. - */ -bool pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); - - -/************************************************ - * Helper functions for writing field callbacks * - ************************************************/ - -/* Encode field header based on type and field number defined in the field - * structure. Call this from the callback before writing out field contents. */ -bool pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t *field); - -/* Encode field header by manually specifing wire type. You need to use this - * if you want to write out packed arrays from a callback field. */ -bool pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number); - -/* Encode an integer in the varint format. - * This works for bool, enum, int32, int64, uint32 and uint64 field types. */ -#ifndef PB_WITHOUT_64BIT -bool pb_encode_varint(pb_ostream_t *stream, uint64_t value); -#else -bool pb_encode_varint(pb_ostream_t *stream, uint32_t value); -#endif - -/* Encode an integer in the zig-zagged svarint format. - * This works for sint32 and sint64. */ -#ifndef PB_WITHOUT_64BIT -bool pb_encode_svarint(pb_ostream_t *stream, int64_t value); -#else -bool pb_encode_svarint(pb_ostream_t *stream, int32_t value); -#endif - -/* Encode a string or bytes type field. For strings, pass strlen(s) as size. */ -bool pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size); - -/* Encode a fixed32, sfixed32 or float value. - * You need to pass a pointer to a 4-byte wide C variable. */ -bool pb_encode_fixed32(pb_ostream_t *stream, const void *value); - -#ifndef PB_WITHOUT_64BIT -/* Encode a fixed64, sfixed64 or double value. - * You need to pass a pointer to a 8-byte wide C variable. */ -bool pb_encode_fixed64(pb_ostream_t *stream, const void *value); -#endif - -/* Encode a submessage field. - * You need to pass the pb_field_t array and pointer to struct, just like - * with pb_encode(). This internally encodes the submessage twice, first to - * calculate message size and then to actually write it out. - */ -bool pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/Teachers' Assistant/AppDelegate.swift b/Teachers' Assistant/AppDelegate.swift @@ -8,7 +8,6 @@ import UIKit import UserNotifications -import Firebase @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate { diff --git a/Teachers' Assistant/GoogleService-Info.plist b/Teachers' Assistant/GoogleService-Info.plist @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>AD_UNIT_ID_FOR_BANNER_TEST</key> - <string>ca-app-pub-3940256099942544/2934735716</string> - <key>AD_UNIT_ID_FOR_INTERSTITIAL_TEST</key> - <string>ca-app-pub-3940256099942544/4411468910</string> - <key>CLIENT_ID</key> - <string>277304690130-tp39je6dr5d3a6enhdhumh8upc17g68i.apps.googleusercontent.com</string> - <key>REVERSED_CLIENT_ID</key> - <string>com.googleusercontent.apps.277304690130-tp39je6dr5d3a6enhdhumh8upc17g68i</string> - <key>API_KEY</key> - <string>AIzaSyCbmpeyJfs1SAbSFCA0MYR3cxVB5Qi9M9M</string> - <key>GCM_SENDER_ID</key> - <string>277304690130</string> - <key>PLIST_VERSION</key> - <string>1</string> - <key>BUNDLE_ID</key> - <string>com.figbertinc.TeachersAssistant</string> - <key>PROJECT_ID</key> - <string>teachersassistant-1f134</string> - <key>STORAGE_BUCKET</key> - <string>teachersassistant-1f134.appspot.com</string> - <key>IS_ADS_ENABLED</key> - <true/> - <key>IS_ANALYTICS_ENABLED</key> - <false/> - <key>IS_APPINVITE_ENABLED</key> - <false/> - <key>IS_GCM_ENABLED</key> - <true/> - <key>IS_SIGNIN_ENABLED</key> - <true/> - <key>GOOGLE_APP_ID</key> - <string>1:277304690130:ios:6c715d1c3aaa8d4a</string> - <key>DATABASE_URL</key> - <string>https://teachersassistant-1f134.firebaseio.com</string> -</dict> -</plist> diff --git a/TeachersAssistant.xcodeproj/project.pbxproj b/TeachersAssistant.xcodeproj/project.pbxproj @@ -38,7 +38,6 @@ B33C58C022395CE600E0E75F /* Sign-In (Dark Blue Inv).png in Resources */ = {isa = PBXBuildFile; fileRef = B33C58AE22395CE400E0E75F /* Sign-In (Dark Blue Inv).png */; }; B33C58C122395CE600E0E75F /* Sign-In (Orange Inv).png in Resources */ = {isa = PBXBuildFile; fileRef = B33C58AF22395CE500E0E75F /* Sign-In (Orange Inv).png */; }; B33C58C222395CE600E0E75F /* Sign-Out (Light Blue Inv).png in Resources */ = {isa = PBXBuildFile; fileRef = B33C58B022395CE600E0E75F /* Sign-Out (Light Blue Inv).png */; }; - B34459FD2239A0C400BF6161 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B34459FC2239A0C400BF6161 /* GoogleService-Info.plist */; }; B34CDB9F221650410031C28B /* Sign-Out (Dark Blue).png in Resources */ = {isa = PBXBuildFile; fileRef = B34CDB8C221650360031C28B /* Sign-Out (Dark Blue).png */; }; B34CDBA0221650410031C28B /* Sign-In (Light Blue).png in Resources */ = {isa = PBXBuildFile; fileRef = B34CDB8D221650360031C28B /* Sign-In (Light Blue).png */; }; B34CDBA1221650410031C28B /* LiveList (Gray).png in Resources */ = {isa = PBXBuildFile; fileRef = B34CDB8E221650370031C28B /* LiveList (Gray).png */; }; @@ -117,7 +116,6 @@ B33C58AE22395CE400E0E75F /* Sign-In (Dark Blue Inv).png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Sign-In (Dark Blue Inv).png"; sourceTree = "<group>"; }; B33C58AF22395CE500E0E75F /* Sign-In (Orange Inv).png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Sign-In (Orange Inv).png"; sourceTree = "<group>"; }; B33C58B022395CE600E0E75F /* Sign-Out (Light Blue Inv).png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Sign-Out (Light Blue Inv).png"; sourceTree = "<group>"; }; - B34459FC2239A0C400BF6161 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; }; B34CDB8C221650360031C28B /* Sign-Out (Dark Blue).png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Sign-Out (Dark Blue).png"; sourceTree = "<group>"; }; B34CDB8D221650360031C28B /* Sign-In (Light Blue).png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Sign-In (Light Blue).png"; sourceTree = "<group>"; }; B34CDB8E221650370031C28B /* LiveList (Gray).png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "LiveList (Gray).png"; sourceTree = "<group>"; }; @@ -269,7 +267,6 @@ B3D8E1DB220F7847007CAD3A /* Assets.xcassets */, B3D8E1DD220F7847007CAD3A /* LaunchScreen.storyboard */, B3D8E1E0220F7847007CAD3A /* Info.plist */, - B34459FC2239A0C400BF6161 /* GoogleService-Info.plist */, B34CDBB2221650480031C28B /* Images */, ); path = "Teachers' Assistant"; @@ -306,7 +303,6 @@ B3D8E1CD220F7847007CAD3A /* Sources */, B3D8E1CE220F7847007CAD3A /* Frameworks */, B3D8E1CF220F7847007CAD3A /* Resources */, - 2C19049363D5198A000753EA /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -392,7 +388,6 @@ B32BA0B22238D6DF0000E747 /* Brandeis_Web_HiRes_Pink_Inv.png in Resources */, B34CDBA7221650410031C28B /* Sign-In (Orange).png in Resources */, B34CDBAA221650410031C28B /* Sign-Out (Light Blue).png in Resources */, - B34459FD2239A0C400BF6161 /* GoogleService-Info.plist in Resources */, B32BA0AF2238D6DF0000E747 /* Brandeis_Web_HiRes_LightBlue_Inv.png in Resources */, B34CDBA4221650410031C28B /* LiveList (Dark Blue).png in Resources */, B34CDBAB221650410031C28B /* Sign-Out (Orange).png in Resources */, @@ -448,30 +443,6 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 2C19049363D5198A000753EA /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-TeachersAssistant/Pods-TeachersAssistant-frameworks.sh", - "${BUILT_PRODUCTS_DIR}/GTMSessionFetcher/GTMSessionFetcher.framework", - "${BUILT_PRODUCTS_DIR}/GoogleAPIClientForREST/GoogleAPIClientForREST.framework", - "${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework", - "${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework", - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GTMSessionFetcher.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleAPIClientForREST.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-TeachersAssistant/Pods-TeachersAssistant-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; 6EEFF9FA53B027D9BA085CE8 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; diff --git a/TeachersAssistant.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/xcschememanagement.plist b/TeachersAssistant.xcodeproj/xcuserdata/naomi.xcuserdatad/xcschemes/xcschememanagement.plist @@ -12,7 +12,7 @@ <key>TeachersAssistant.xcscheme</key> <dict> <key>orderHint</key> - <integer>11</integer> + <integer>2</integer> </dict> </dict> </dict> diff --git a/TeachersAssistant.xcworkspace/xcuserdata/naomi.xcuserdatad/UserInterfaceState.xcuserstate b/TeachersAssistant.xcworkspace/xcuserdata/naomi.xcuserdatad/UserInterfaceState.xcuserstate Binary files differ.