diff --git a/Provenance.xcodeproj/project.pbxproj b/Provenance.xcodeproj/project.pbxproj index f000c87d06..e05baaccff 100644 --- a/Provenance.xcodeproj/project.pbxproj +++ b/Provenance.xcodeproj/project.pbxproj @@ -161,6 +161,13 @@ B30059852C7974F5003010F5 /* PVSupport in Frameworks */ = {isa = PBXBuildFile; productRef = B30059842C7974F5003010F5 /* PVSupport */; }; B30585692C0C14EE00B91D7A /* PVWebServer in Frameworks */ = {isa = PBXBuildFile; productRef = B30585682C0C14EE00B91D7A /* PVWebServer */; }; B305856E2C0D52F200B91D7A /* PVLibrary in Frameworks */ = {isa = PBXBuildFile; productRef = B305856D2C0D52F200B91D7A /* PVLibrary */; }; + B306D7D92D3DDB6D00C71EBE /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B306D7D82D3DDB6D00C71EBE /* GoogleService-Info.plist */; }; + B306D7DD2D3DDB6D00C71EBE /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B306D7D82D3DDB6D00C71EBE /* GoogleService-Info.plist */; }; + B306D7E12D3DDB6D00C71EBE /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B306D7D82D3DDB6D00C71EBE /* GoogleService-Info.plist */; }; + B306D7E42D3DDC6B00C71EBE /* FirebaseAnalyticsWithoutAdIdSupport in Frameworks */ = {isa = PBXBuildFile; productRef = B306D7E32D3DDC6B00C71EBE /* FirebaseAnalyticsWithoutAdIdSupport */; }; + B306D7E62D3DDC6B00C71EBE /* FirebaseCore in Frameworks */ = {isa = PBXBuildFile; productRef = B306D7E52D3DDC6B00C71EBE /* FirebaseCore */; }; + B306D7E82D3DDC6B00C71EBE /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = B306D7E72D3DDC6B00C71EBE /* FirebaseCrashlytics */; }; + B306D7EA2D3DDC6B00C71EBE /* FirebasePerformance in Frameworks */ = {isa = PBXBuildFile; productRef = B306D7E92D3DDC6B00C71EBE /* FirebasePerformance */; }; B30ED0D72CFD3C4200AFCFCE /* PVCoreMednafen-Dynamic in Frameworks */ = {isa = PBXBuildFile; productRef = B30ED0D62CFD3C4200AFCFCE /* PVCoreMednafen-Dynamic */; }; B30ED0D82CFD3C4200AFCFCE /* PVCoreMednafen-Dynamic in Embed Frameworks */ = {isa = PBXBuildFile; productRef = B30ED0D62CFD3C4200AFCFCE /* PVCoreMednafen-Dynamic */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; B30ED0DA2CFD3C5200AFCFCE /* PVCoreMednafen-Dynamic in Frameworks */ = {isa = PBXBuildFile; productRef = B30ED0D92CFD3C5200AFCFCE /* PVCoreMednafen-Dynamic */; }; @@ -1772,6 +1779,7 @@ B305F103276B6BBD003AE510 /* PVCrabEmu.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = PVCrabEmu.framework; sourceTree = BUILT_PRODUCTS_DIR; }; B30623162CC81A1000B4F954 /* Provenance-UnderDevelopment-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Provenance-UnderDevelopment-Info.plist"; sourceTree = ""; }; B3062B1D2971A60D00686D31 /* libMoltenVK.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libMoltenVK.dylib; path = CoresRetro/RetroArch/RetroArch/pkg/apple/Frameworks/MoltenVK/dylib/iOS/libMoltenVK.dylib; sourceTree = ""; }; + B306D7D82D3DDB6D00C71EBE /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; B306E1412769FE65001DC52E /* PVO2EM.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = PVO2EM.framework; sourceTree = BUILT_PRODUCTS_DIR; }; B309C7A42717C49F00279529 /* PVFlycast.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = PVFlycast.framework; sourceTree = BUILT_PRODUCTS_DIR; }; B309C7A72717C4B500279529 /* PVFlycast.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = PVFlycast.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -2904,6 +2912,7 @@ files = ( B3F9049E2C1FE9D8002283B3 /* libbz2.tbd in Frameworks */, B30ED0D72CFD3C4200AFCFCE /* PVCoreMednafen-Dynamic in Frameworks */, + B306D7EA2D3DDC6B00C71EBE /* FirebasePerformance in Frameworks */, B38FB4A82CBEF6B0006786C6 /* libavcodec.xcframework in Frameworks */, B33B4F4B2C1A5B4B007371C5 /* RealmSwift in Frameworks */, B3E2AA382CB635BB00E2636D /* PVGME.framework in Frameworks */, @@ -2933,6 +2942,7 @@ B38A68C02CCF031C001C57D0 /* PVVisualBoyAdvance-Dynamic in Frameworks */, B3E0CFA52C054FC200F45074 /* PVEmulatorCore in Frameworks */, B394CD772BDEE53A006B63E8 /* Photos.framework in Frameworks */, + B306D7E82D3DDC6B00C71EBE /* FirebaseCrashlytics in Frameworks */, B3E0CFA22C054F9F00F45074 /* ZipArchive in Frameworks */, B394CD782BDEE53A006B63E8 /* GameController.framework in Frameworks */, B33BD1C82C6A6261001E933A /* PVStella-Dynamic in Frameworks */, @@ -2948,6 +2958,7 @@ B33A09342D2D0B0C00BFB6C9 /* PVJIT in Frameworks */, B32D45C72CB7310C006B76C2 /* PVGambatte in Frameworks */, B3E2AA302CB6346900E2636D /* PVOpera.framework in Frameworks */, + B306D7E62D3DDC6B00C71EBE /* FirebaseCore in Frameworks */, B394CD7C2BDEE53A006B63E8 /* CoreServices.framework in Frameworks */, B394CD872BDEE53A006B63E8 /* AVFoundation.framework in Frameworks */, B394CD892BDEE53A006B63E8 /* CFNetwork.framework in Frameworks */, @@ -2969,6 +2980,7 @@ B394CDA12BDEE53A006B63E8 /* Reachability in Frameworks */, B318E27A2CAB4C2400D0E599 /* PVO2EM.framework in Frameworks */, B38FB4AA2CBEF6B0006786C6 /* libavformat.xcframework in Frameworks */, + B306D7E42D3DDC6B00C71EBE /* FirebaseAnalyticsWithoutAdIdSupport in Frameworks */, B318E2882CAB512F00D0E599 /* PVMupen64PlusRspHLE.framework in Frameworks */, B394CDA72BDEE53A006B63E8 /* SteamController in Frameworks */, B3E2AA512CB63A6200E2636D /* PVBeetlePSX.framework in Frameworks */, @@ -3650,6 +3662,7 @@ 1A4869BB17C8CA2C0019F6D2 /* Resources */ = { isa = PBXGroup; children = ( + B306D7D82D3DDB6D00C71EBE /* GoogleService-Info.plist */, B394CDE32BDF22A2006B63E8 /* Provenance-AppStore.entitlements */, B379D0472B4FB9A80067325A /* Provenance-JB.entitlements */, B361938F221FB93B00F73875 /* Provenance-Free.entitlements */, @@ -4489,6 +4502,7 @@ B394CDB62BDEE53A006B63E8 /* Resources */, B394CDDA2BDEE53A006B63E8 /* Script: Set Build Number */, 93DB4BBC9C6D487AAA130B02 /* Upload Debug Symbols to Sentry */, + B306D7EB2D3DDD3300C71EBE /* Crashlytics */, ); buildRules = ( ); @@ -4541,6 +4555,10 @@ B33A09332D2D0B0C00BFB6C9 /* PVJIT */, B35F93E02D2F71450016E633 /* WhatsNewKit */, 54925F9AB59542258A6A5CE9 /* Sentry */, + B306D7E32D3DDC6B00C71EBE /* FirebaseAnalyticsWithoutAdIdSupport */, + B306D7E52D3DDC6B00C71EBE /* FirebaseCore */, + B306D7E72D3DDC6B00C71EBE /* FirebaseCrashlytics */, + B306D7E92D3DDC6B00C71EBE /* FirebasePerformance */, ); productName = Provenance; productReference = B394CDDF2BDEE53A006B63E8 /* Provenance.app */; @@ -4950,6 +4968,7 @@ B3E77F822D1F57E6004A3AD2 /* XCLocalSwiftPackageReference "PVFeatureFlags" */, B35F93DF2D2F71450016E633 /* XCRemoteSwiftPackageReference "WhatsNewKit" */, F8F20E7C3CB546288E1FB7F2 /* XCRemoteSwiftPackageReference "sentry-cocoa" */, + B306D7E22D3DDC6B00C71EBE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, ); productRefGroup = 1A3D409517B2DCE4004DFFFC /* Products */; projectDirPath = ""; @@ -5105,6 +5124,7 @@ files = ( B341FDDE2BE61EC100718929 /* InfoPlist.strings in Resources */, B341FDDF2BE61EC100718929 /* Strings.strings in Resources */, + B306D7D92D3DDB6D00C71EBE /* GoogleService-Info.plist in Resources */, B3DF8EDB2CC7AE1F0006F20E /* ColoredIcons.xcassets in Resources */, B341FDE42BE61EC100718929 /* Assets.xcassets in Resources */, B341FDE62BE61EC100718929 /* Settings.bundle in Resources */, @@ -5167,6 +5187,7 @@ files = ( B35EEFE32C6C6D1A00EBD1A8 /* InfoPlist.strings in Resources */, B35EEFE42C6C6D1A00EBD1A8 /* Strings.strings in Resources */, + B306D7DD2D3DDB6D00C71EBE /* GoogleService-Info.plist in Resources */, B3E17E232CCF91B000732AEA /* AppStoreAssets-Lite.xcassets in Resources */, B3DF8EE02CC7AE1F0006F20E /* ColoredIcons.xcassets in Resources */, B35EEFE92C6C6D1A00EBD1A8 /* Settings.bundle in Resources */, @@ -5188,6 +5209,7 @@ files = ( B394CDB82BDEE53A006B63E8 /* InfoPlist.strings in Resources */, B394CDB92BDEE53A006B63E8 /* Strings.strings in Resources */, + B306D7E12D3DDB6D00C71EBE /* GoogleService-Info.plist in Resources */, B3DF8EDE2CC7AE1F0006F20E /* ColoredIcons.xcassets in Resources */, B394CDBF2BDEE53A006B63E8 /* Assets.xcassets in Resources */, B394CDC12BDEE53A006B63E8 /* Settings.bundle in Resources */, @@ -5465,6 +5487,29 @@ shellPath = /bin/sh; shellScript = ./Provenance/Resources/createVersionHeader.sh; }; + B306D7EB2D3DDD3300C71EBE /* Crashlytics */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}", + "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${PRODUCT_NAME}", + "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist", + "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist", + "$(TARGET_BUILD_DIR)/$(EXECUTABLE_PATH)", + ); + name = Crashlytics; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${BUILD_DIR%/Build/*}/SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/run\"\n"; + }; B30E94842793B8BE00871E57 /* Test for CodeSigning.xcconfig */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -10981,6 +11026,14 @@ kind = branch; }; }; + B306D7E22D3DDC6B00C71EBE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/firebase/firebase-ios-sdk"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 11.7.0; + }; + }; B33B4F3E2C198F32007371C5 /* XCRemoteSwiftPackageReference "MBProgressHUD" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/jdg/MBProgressHUD.git"; @@ -11334,6 +11387,26 @@ package = B323B0072BF46D2800CEA3CF /* XCLocalSwiftPackageReference "PVLibrary" */; productName = PVLibrary; }; + B306D7E32D3DDC6B00C71EBE /* FirebaseAnalyticsWithoutAdIdSupport */ = { + isa = XCSwiftPackageProductDependency; + package = B306D7E22D3DDC6B00C71EBE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseAnalyticsWithoutAdIdSupport; + }; + B306D7E52D3DDC6B00C71EBE /* FirebaseCore */ = { + isa = XCSwiftPackageProductDependency; + package = B306D7E22D3DDC6B00C71EBE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseCore; + }; + B306D7E72D3DDC6B00C71EBE /* FirebaseCrashlytics */ = { + isa = XCSwiftPackageProductDependency; + package = B306D7E22D3DDC6B00C71EBE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseCrashlytics; + }; + B306D7E92D3DDC6B00C71EBE /* FirebasePerformance */ = { + isa = XCSwiftPackageProductDependency; + package = B306D7E22D3DDC6B00C71EBE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebasePerformance; + }; B30ED0D62CFD3C4200AFCFCE /* PVCoreMednafen-Dynamic */ = { isa = XCSwiftPackageProductDependency; package = B3B9BE542C802023005C405B /* XCLocalSwiftPackageReference "Cores/Mednafen" */; diff --git a/Provenance.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Provenance.xcworkspace/xcshareddata/swiftpm/Package.resolved index 9605c214c2..9e6e25ba95 100644 --- a/Provenance.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Provenance.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,6 +1,15 @@ { "object": { "pins": [ + { + "package": "abseil", + "repositoryURL": "https://github.com/google/abseil-cpp-binary.git", + "state": { + "branch": null, + "revision": "194a6706acbd25e4ef639bcaddea16e8758a3e27", + "version": "1.2024011602.0" + } + }, { "package": "ActivityIndicatorView", "repositoryURL": "https://github.com/exyte/ActivityIndicatorView.git", @@ -19,6 +28,15 @@ "version": "1.0.0" } }, + { + "package": "AppCheck", + "repositoryURL": "https://github.com/google/app-check.git", + "state": { + "branch": null, + "revision": "61b85103a1aeed8218f17c794687781505fbbef5", + "version": "11.2.0" + } + }, { "package": "AppCenter", "repositoryURL": "https://github.com/microsoft/appcenter-sdk-apple.git", @@ -73,6 +91,15 @@ "version": null } }, + { + "package": "Firebase", + "repositoryURL": "https://github.com/firebase/firebase-ios-sdk", + "state": { + "branch": null, + "revision": "0d885d28250fb1196b614bc9455079b75c531f72", + "version": "11.7.0" + } + }, { "package": "FloatingButton", "repositoryURL": "https://github.com/exyte/FloatingButton.git", @@ -91,6 +118,51 @@ "version": "1.16.0" } }, + { + "package": "GoogleAppMeasurement", + "repositoryURL": "https://github.com/google/GoogleAppMeasurement.git", + "state": { + "branch": null, + "revision": "be0881ff728eca210ccb628092af400c086abda3", + "version": "11.7.0" + } + }, + { + "package": "GoogleDataTransport", + "repositoryURL": "https://github.com/google/GoogleDataTransport.git", + "state": { + "branch": null, + "revision": "617af071af9aa1d6a091d59a202910ac482128f9", + "version": "10.1.0" + } + }, + { + "package": "GoogleUtilities", + "repositoryURL": "https://github.com/google/GoogleUtilities.git", + "state": { + "branch": null, + "revision": "53156c7ec267db846e6b64c9f4c4e31ba4cf75eb", + "version": "8.0.2" + } + }, + { + "package": "gRPC", + "repositoryURL": "https://github.com/google/grpc-binary.git", + "state": { + "branch": null, + "revision": "f56d8fc3162de9a498377c7b6cea43431f4f5083", + "version": "1.65.1" + } + }, + { + "package": "GTMSessionFetcher", + "repositoryURL": "https://github.com/google/gtm-session-fetcher.git", + "state": { + "branch": null, + "revision": "85b7b231882c3c472b8bda4fb495324d3f19bab6", + "version": "4.2.0" + } + }, { "package": "HexColors", "repositoryURL": "https://github.com/JoeMatt/HexColors.git", @@ -100,6 +172,24 @@ "version": null } }, + { + "package": "InteropForGoogle", + "repositoryURL": "https://github.com/google/interop-ios-for-google-sdks.git", + "state": { + "branch": null, + "revision": "2d12673670417654f08f5f90fdd62926dc3a2648", + "version": "100.0.0" + } + }, + { + "package": "leveldb", + "repositoryURL": "https://github.com/firebase/leveldb.git", + "state": { + "branch": null, + "revision": "a0bc79961d7be727d258d33d5a6b2f1023270ba1", + "version": "1.22.5" + } + }, { "package": "Lighter", "repositoryURL": "https://github.com/JoeMatt/Lighter.git", @@ -118,6 +208,15 @@ "version": "1.2.0" } }, + { + "package": "nanopb", + "repositoryURL": "https://github.com/firebase/nanopb.git", + "state": { + "branch": null, + "revision": "b7e1104502eca3a213b46303391ca4d3bc8ddec1", + "version": "2.30910.0" + } + }, { "package": "OpenDateInterval", "repositoryURL": "https://github.com/MrAsterisco/OpenDateInterval", @@ -154,6 +253,15 @@ "version": null } }, + { + "package": "Promises", + "repositoryURL": "https://github.com/google/promises.git", + "state": { + "branch": null, + "revision": "540318ecedd63d883069ae7f1ed811a2df00b6ac", + "version": "2.4.0" + } + }, { "package": "Reachability", "repositoryURL": "https://github.com/ashleymills/Reachability.swift", @@ -316,6 +424,15 @@ "version": null } }, + { + "package": "SwiftProtobuf", + "repositoryURL": "https://github.com/apple/swift-protobuf.git", + "state": { + "branch": null, + "revision": "ebc7251dd5b37f627c93698e4374084d98409633", + "version": "1.28.2" + } + }, { "package": "swift-syntax", "repositoryURL": "https://github.com/swiftlang/swift-syntax.git", diff --git a/Provenance/Main UI/PVAppDelegate.swift b/Provenance/Main UI/PVAppDelegate.swift index f421b7d4a1..bb147d3bef 100644 --- a/Provenance/Main UI/PVAppDelegate.swift +++ b/Provenance/Main UI/PVAppDelegate.swift @@ -28,6 +28,12 @@ import SwiftUI import Defaults import PVFeatureFlags +#if canImport(FirebaseCore) +import FirebaseCore +import FirebaseCrashlyticsSwift +import FirebaseAnalytics +#endif + // Conditionally import PVJIT and JITManager if available #if canImport(PVJIT) import PVJIT @@ -277,6 +283,10 @@ final class PVAppDelegate: UIResponder, GameLaunchingAppDelegate, UIApplicationD } func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { + #if canImport(FirebaseCore) + FirebaseApp.configure() + #endif + ILOG("PVAppDelegate: Application did finish launching") initializeAppComponents() diff --git a/Provenance/Main UI/ProvenanceApp.swift b/Provenance/Main UI/ProvenanceApp.swift index 79ff50e977..be95e0cafd 100644 --- a/Provenance/Main UI/ProvenanceApp.swift +++ b/Provenance/Main UI/ProvenanceApp.swift @@ -22,27 +22,27 @@ struct ProvenanceApp: App { @StateObject private var featureFlags = PVFeatureFlagsManager.shared init() { -#if canImport(Sentry) - if appState.isAppStore { - SentrySDK.start { options in - options.dsn = "https://f9976bad538343d59606a8ef312d4720@o199354.ingest.us.sentry.io/1309415" - #if DEBUG - options.debug = true // Enabled debug when first installing is always helpful - // Enable tracing to capture 100% of transactions for tracing. - // Use 'options.tracesSampleRate' to set the sampling rate. - // We recommend setting a sample rate in production. - options.tracesSampleRate = 1.0 // tracing must be enabled for profiling - options.profilesSampleRate = 1.0 // see also `profilesSampler` if you need custom sampling logic - options.enableAppLaunchProfiling = true // experimental new feature to start profiling in the pre-main launch phase - options.sessionReplay.onErrorSampleRate = 1.0 - options.sessionReplay.sessionSampleRate = 0.1 - #else - options.tracesSampleRate = 0.5 - options.sessionReplay.onErrorSampleRate = 1.0 - #endif - } - } -#endif +//#if canImport(Sentry) +// if appState.isAppStore { +// SentrySDK.start { options in +// options.dsn = "https://f9976bad538343d59606a8ef312d4720@o199354.ingest.us.sentry.io/1309415" +// #if DEBUG +// options.debug = true // Enabled debug when first installing is always helpful +// // Enable tracing to capture 100% of transactions for tracing. +// // Use 'options.tracesSampleRate' to set the sampling rate. +// // We recommend setting a sample rate in production. +// options.tracesSampleRate = 1.0 // tracing must be enabled for profiling +// options.profilesSampleRate = 1.0 // see also `profilesSampler` if you need custom sampling logic +// options.enableAppLaunchProfiling = true // experimental new feature to start profiling in the pre-main launch phase +// options.sessionReplay.onErrorSampleRate = 1.0 +// options.sessionReplay.sessionSampleRate = 0.1 +// #else +// options.tracesSampleRate = 0.5 +// options.sessionReplay.onErrorSampleRate = 1.0 +// #endif +// } +// } +//#endif } var body: some Scene { diff --git a/Provenance/Resources/GoogleService-Info.plist b/Provenance/Resources/GoogleService-Info.plist new file mode 100644 index 0000000000..07637bc4d0 --- /dev/null +++ b/Provenance/Resources/GoogleService-Info.plist @@ -0,0 +1,30 @@ + + + + + API_KEY + AIzaSyBtD2UZtnrrL3r4Y_3vRBI8zMP8SdhoXNo + GCM_SENDER_ID + 909576720402 + PLIST_VERSION + 1 + BUNDLE_ID + org.provenance-emu.provenance + PROJECT_ID + provenance-emu + STORAGE_BUCKET + provenance-emu.firebasestorage.app + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:909576720402:ios:fe4b43b5c9c8004cc488cb + + \ No newline at end of file