diff --git a/android/app/build.gradle b/android/app/build.gradle index c7904cac0..55f1751ac 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -1,5 +1,14 @@ apply plugin: 'com.android.application' +boolean googleServicesEnabled = project.file('google-services.json').exists() + +// Crashlytics integration is done as part of Firebase now, so it gets +// automagically activated with google-services.json +if (googleServicesEnabled) { + apply plugin: 'io.fabric' +} + + android { compileSdkVersion rootProject.ext.compileSdkVersion buildToolsVersion rootProject.ext.buildToolsVersion @@ -31,10 +40,12 @@ android { debug { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules-debug.pro' + buildConfigField "boolean", "GOOGLE_SERVICES_ENABLED", "${googleServicesEnabled}" } release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules-release.pro' + buildConfigField "boolean", "GOOGLE_SERVICES_ENABLED", "${googleServicesEnabled}" } } @@ -44,11 +55,15 @@ android { } } +repositories { + maven { url 'https://maven.fabric.io/public' } +} + dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "com.android.support:support-v4:${rootProject.ext.supportLibVersion}" implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}" - implementation 'com.google.android.gms:play-services-auth:15.0.0' + implementation 'com.google.android.gms:play-services-auth:16.0.1' implementation project(':sdk') @@ -63,6 +78,13 @@ dependencies { exclude group: "com.android.support", module: "annotations" } annotationProcessor "com.github.bumptech.glide:compiler:${rootProject.ext.glideVersion}" + + // Firebase + // - Crashlytics + // - Dynamic Links + implementation 'com.google.firebase:firebase-core:16.0.6' + implementation 'com.crashlytics.sdk.android:crashlytics:2.9.8' + implementation 'com.google.firebase:firebase-dynamic-links:16.1.5' } gradle.projectsEvaluated { @@ -117,6 +139,6 @@ gradle.projectsEvaluated { } } -if (project.file('google-services.json').exists()) { +if (googleServicesEnabled) { apply plugin: 'com.google.gms.google-services' } diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 61e8eb3d0..76abf3ade 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -16,6 +16,7 @@ android:resizeableActivity="true" android:supportsPictureInPicture="true" android:windowSoftInputMode="adjustResize"> + diff --git a/android/app/src/main/java/org/jitsi/meet/MainActivity.java b/android/app/src/main/java/org/jitsi/meet/MainActivity.java index 804167f2b..09464fad2 100644 --- a/android/app/src/main/java/org/jitsi/meet/MainActivity.java +++ b/android/app/src/main/java/org/jitsi/meet/MainActivity.java @@ -1,5 +1,6 @@ /* - * Copyright @ 2017-present Atlassian Pty Ltd + * Copyright @ 2018-present 8x8, Inc. + * Copyright @ 2017-2018 Atlassian Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +17,7 @@ package org.jitsi.meet; +import android.net.Uri; import android.os.Bundle; import android.util.Log; @@ -27,8 +29,13 @@ import org.jitsi.meet.sdk.invite.AddPeopleControllerListener; import org.jitsi.meet.sdk.invite.InviteController; import org.jitsi.meet.sdk.invite.InviteControllerListener; +import com.crashlytics.android.Crashlytics; import com.facebook.react.bridge.UiThreadUtil; +import com.google.firebase.dynamiclinks.FirebaseDynamicLinks; +import io.fabric.sdk.android.Fabric; +import java.net.MalformedURLException; +import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -182,6 +189,28 @@ public class MainActivity extends JitsiMeetActivity { setWelcomePageEnabled(true); super.onCreate(savedInstanceState); + + // Setup Crashlytics and Firebase Dynamic Links + if (BuildConfig.GOOGLE_SERVICES_ENABLED) { + Fabric.with(this, new Crashlytics()); + + FirebaseDynamicLinks.getInstance().getDynamicLink(getIntent()) + .addOnSuccessListener(this, pendingDynamicLinkData -> { + Uri dynamicLink = null; + + if (pendingDynamicLinkData != null) { + dynamicLink = pendingDynamicLinkData.getLink(); + } + + if (dynamicLink != null) { + try { + loadURL(new URL(dynamicLink.toString())); + } catch (MalformedURLException e) { + Log.d("ReactNative", "Malformed dynamic link", e); + } + } + }); + } } private void onInviteControllerBeginAddPeople( diff --git a/android/build.gradle b/android/build.gradle index dae244582..ab450bec9 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -7,10 +7,14 @@ buildscript { repositories { google() jcenter() + repositories { + maven { url 'https://maven.fabric.io/public' } + } } dependencies { classpath 'com.android.tools.build:gradle:3.2.1' - classpath 'com.google.gms:google-services:3.2.1' + classpath 'com.google.gms:google-services:4.2.0' + classpath 'io.fabric.tools:gradle:1.27.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files. diff --git a/ios/Podfile b/ios/Podfile index 0e267f598..6584c987c 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -2,6 +2,15 @@ platform :ios, '10.0' workspace 'jitsi-meet' +target 'jitsi-meet' do + project 'app/app.xcodeproj' + + pod 'Crashlytics' + pod 'Fabric' + pod 'Firebase/Core' + pod 'Firebase/DynamicLinks' +end + target 'JitsiMeet' do project 'sdk/sdk.xcodeproj' diff --git a/ios/Podfile.lock b/ios/Podfile.lock index c0c2d3662..4afba5132 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,12 +1,49 @@ PODS: - boost-for-react-native (1.63.0) + - Crashlytics (3.12.0): + - Fabric (~> 1.9.0) - DoubleConversion (1.1.6) + - Fabric (1.9.0) + - Firebase/Core (5.15.0): + - Firebase/CoreOnly + - FirebaseAnalytics (= 5.4.0) + - Firebase/CoreOnly (5.15.0): + - FirebaseCore (= 5.1.10) + - Firebase/DynamicLinks (5.15.0): + - Firebase/CoreOnly + - FirebaseDynamicLinks (= 3.3.0) + - FirebaseAnalytics (5.4.0): + - FirebaseCore (~> 5.1) + - FirebaseInstanceID (~> 3.3) + - GoogleAppMeasurement (= 5.4.0) + - GoogleUtilities/AppDelegateSwizzler (~> 5.2) + - GoogleUtilities/MethodSwizzler (~> 5.2) + - GoogleUtilities/Network (~> 5.2) + - "GoogleUtilities/NSData+zlib (~> 5.2)" + - nanopb (~> 0.3) + - FirebaseAnalyticsInterop (1.1.0) + - FirebaseCore (5.1.10): + - GoogleUtilities/Logger (~> 5.2) + - FirebaseDynamicLinks (3.3.0): + - FirebaseAnalytics (~> 5.1) + - FirebaseAnalyticsInterop (~> 1.0) + - FirebaseCore (~> 5.1) + - FirebaseInstanceID (3.3.0): + - FirebaseCore (~> 5.1) + - GoogleUtilities/Environment (~> 5.3) + - GoogleUtilities/UserDefaults (~> 5.3) - FLAnimatedImage (1.0.12) - Folly (2016.10.31.00): - boost-for-react-native - DoubleConversion - glog - glog (0.3.5) + - GoogleAppMeasurement (5.4.0): + - GoogleUtilities/AppDelegateSwizzler (~> 5.2) + - GoogleUtilities/MethodSwizzler (~> 5.2) + - GoogleUtilities/Network (~> 5.2) + - "GoogleUtilities/NSData+zlib (~> 5.2)" + - nanopb (~> 0.3) - GoogleSignIn (4.4.0): - "GoogleToolboxForMac/NSDictionary+URLArguments (~> 2.1)" - "GoogleToolboxForMac/NSString+URLArguments (~> 2.1)" @@ -19,7 +56,30 @@ PODS: - GoogleToolboxForMac/Defines (= 2.2.0) - "GoogleToolboxForMac/NSString+URLArguments (= 2.2.0)" - "GoogleToolboxForMac/NSString+URLArguments (2.2.0)" + - GoogleUtilities/AppDelegateSwizzler (5.3.6): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Environment (5.3.6) + - GoogleUtilities/Logger (5.3.6): + - GoogleUtilities/Environment + - GoogleUtilities/MethodSwizzler (5.3.6): + - GoogleUtilities/Logger + - GoogleUtilities/Network (5.3.6): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (5.3.6)" + - GoogleUtilities/Reachability (5.3.6): + - GoogleUtilities/Logger + - GoogleUtilities/UserDefaults (5.3.6): + - GoogleUtilities/Logger - 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) - ObjectiveDropboxOfficial (3.9.2) - React (0.57.8): - React/Core (= 0.57.8) @@ -92,7 +152,11 @@ PODS: - yoga (0.57.8.React) DEPENDENCIES: + - Crashlytics - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) + - Fabric + - Firebase/Core + - Firebase/DynamicLinks - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - ObjectiveDropboxOfficial @@ -119,10 +183,21 @@ DEPENDENCIES: SPEC REPOS: https://github.com/cocoapods/specs.git: - boost-for-react-native + - Crashlytics + - Fabric + - Firebase + - FirebaseAnalytics + - FirebaseAnalyticsInterop + - FirebaseCore + - FirebaseDynamicLinks + - FirebaseInstanceID - FLAnimatedImage + - GoogleAppMeasurement - GoogleSignIn - GoogleToolboxForMac + - GoogleUtilities - GTMSessionFetcher + - nanopb - ObjectiveDropboxOfficial - SDWebImage @@ -156,13 +231,24 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c + Crashlytics: 07fb167b1694128c1c9a5a5cc319b0e9c3ca0933 DoubleConversion: bb338842f62ab1d708ceb63ec3d999f0f3d98ecd + Fabric: f988e33c97f08930a413e08123064d2e5f68d655 + Firebase: 8bb9268bff82374f2cbaaabb143e725743c316ae + FirebaseAnalytics: c06f9d70577d79074214700a71fd5d39de5550fb + FirebaseAnalyticsInterop: e5f21be9af6548372e2f0815834ff909bff395a2 + FirebaseCore: 35747502d9e8c6ee217385ad04446c7c2aaf9c5c + FirebaseDynamicLinks: c713da5f75c324f38fb2d57164bbc1c461aa6739 + FirebaseInstanceID: e2fa4cb35ef5558c200f7f0ad8a53e212215f93e FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 Folly: c89ac2d5c6ab169cd7397ef27485c44f35f742c7 glog: e8acf0ebbf99759d3ff18c86c292a5898282dcde + GoogleAppMeasurement: 98b71f5e04142793729a5ef23e5b96651ff4b70f GoogleSignIn: 7ff245e1a7b26d379099d3243a562f5747e23d39 GoogleToolboxForMac: ff31605b7d66400dcec09bed5861689aebadda4d + GoogleUtilities: 95996bea7c7d9b8fb811b7507669a4a8762f80c7 GTMSessionFetcher: 32aeca0aa144acea523e1c8e053089dec2cb98ca + nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 ObjectiveDropboxOfficial: aa792e0556ceb7b72955fa29a2709072f6e35fd9 React: 1fe0eb13d90b625d94c3b117c274dcfd2e760e11 react-native-background-timer: bb7a98c8e97fc7c290de2d423dd09ddb73dcbcbb @@ -176,6 +262,6 @@ SPEC CHECKSUMS: SDWebImage: c5594f1a19c48d526d321e548902b56b479cd508 yoga: b1ce48b6cf950b98deae82838f5173ea7cf89e85 -PODFILE CHECKSUM: 2fa79bc1fe2fe42efb63895fdb0cb84d5f578884 +PODFILE CHECKSUM: b5218184626a027e8b1ca12361d46100e2fa2f1f COCOAPODS: 1.5.3 diff --git a/ios/app/GoogleService-Info.plist b/ios/app/GoogleService-Info.plist new file mode 100644 index 000000000..3f7547fb4 --- /dev/null +++ b/ios/app/GoogleService-Info.plist @@ -0,0 +1,28 @@ + + + + + API_KEY + correct_api_key + TRACKING_ID + correct_tracking_id + CLIENT_ID + correct_client_id + REVERSED_CLIENT_ID + correct_reversed_client_id + GOOGLE_APP_ID + 1:123:ios:123abc + GCM_SENDER_ID + correct_gcm_sender_id + PLIST_VERSION + 1 + BUNDLE_ID + com.google.FirebaseSDKTests + PROJECT_ID + abc-xyz-123 + DATABASE_URL + https://abc-xyz-123.firebaseio.com + STORAGE_BUCKET + project-id-123.storage.firebase.com + + diff --git a/ios/app/app.xcodeproj/project.pbxproj b/ios/app/app.xcodeproj/project.pbxproj index 131e7e31c..b73552d21 100644 --- a/ios/app/app.xcodeproj/project.pbxproj +++ b/ios/app/app.xcodeproj/project.pbxproj @@ -17,6 +17,9 @@ 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; + 695AF3ED6F686F9C5EE40F9A /* libPods-jitsi-meet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 489E8EFE2C720D10F5961AEF /* libPods-jitsi-meet.a */; }; + DE4C455E21DE1E4300EA0709 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = DE4C455D21DE1E4300EA0709 /* GoogleService-Info.plist */; }; + DE4C456121DE1E4E00EA0709 /* FIRUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = DE4C455F21DE1E4E00EA0709 /* FIRUtilities.m */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -35,6 +38,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 09AA3B93E4CC62D84B424690 /* Pods-jitsi-meet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-jitsi-meet.release.xcconfig"; path = "../Pods/Target Support Files/Pods-jitsi-meet/Pods-jitsi-meet.release.xcconfig"; sourceTree = ""; }; 0B26BE6D1EC5BC3C00EEFB41 /* JitsiMeet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = JitsiMeet.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 0B412F1D1EDEE6E800B1A0A6 /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 0B412F1E1EDEE6E800B1A0A6 /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; @@ -47,7 +51,12 @@ 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 4670A512A688E2DC34528282 /* Pods-jitsi-meet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-jitsi-meet.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-jitsi-meet/Pods-jitsi-meet.debug.xcconfig"; sourceTree = ""; }; + 489E8EFE2C720D10F5961AEF /* libPods-jitsi-meet.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-jitsi-meet.a"; sourceTree = BUILT_PRODUCTS_DIR; }; B3B083EB1D4955FF0069CEE7 /* app.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = app.entitlements; sourceTree = ""; }; + DE4C455D21DE1E4300EA0709 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = SOURCE_ROOT; }; + DE4C455F21DE1E4E00EA0709 /* FIRUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FIRUtilities.m; sourceTree = ""; }; + DE4C456021DE1E4E00EA0709 /* FIRUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIRUtilities.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -57,6 +66,7 @@ files = ( 0B26BE6E1EC5BC3C00EEFB41 /* JitsiMeet.framework in Frameworks */, 0BD6B4371EF82A6B00D1F4CD /* WebRTC.framework in Frameworks */, + 695AF3ED6F686F9C5EE40F9A /* libPods-jitsi-meet.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -68,6 +78,7 @@ children = ( 0B26BE6D1EC5BC3C00EEFB41 /* JitsiMeet.framework */, 0BD6B4361EF82A6B00D1F4CD /* WebRTC.framework */, + 489E8EFE2C720D10F5961AEF /* libPods-jitsi-meet.a */, ); name = Frameworks; sourceTree = ""; @@ -77,6 +88,9 @@ children = ( 13B07FAF1A68108700A75B9A /* AppDelegate.h */, 13B07FB01A68108700A75B9A /* AppDelegate.m */, + DE4C456021DE1E4E00EA0709 /* FIRUtilities.h */, + DE4C455F21DE1E4E00EA0709 /* FIRUtilities.m */, + DE4C455D21DE1E4300EA0709 /* GoogleService-Info.plist */, 13B07FB51A68108700A75B9A /* Images.xcassets */, 13B07FB61A68108700A75B9A /* Info.plist */, 13B07FB11A68108700A75B9A /* LaunchScreen.xib */, @@ -88,6 +102,15 @@ path = src; sourceTree = ""; }; + 5E96ADD5E49F3B3822EF9A52 /* Pods */ = { + isa = PBXGroup; + children = ( + 4670A512A688E2DC34528282 /* Pods-jitsi-meet.debug.xcconfig */, + 09AA3B93E4CC62D84B424690 /* Pods-jitsi-meet.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; 83CBB9F61A601CBA00E9B192 = { isa = PBXGroup; children = ( @@ -95,6 +118,7 @@ 0B26BE711EC5BC4D00EEFB41 /* Frameworks */, 83CBBA001A601CBA00E9B192 /* Products */, 13B07FAE1A68108700A75B9A /* src */, + 5E96ADD5E49F3B3822EF9A52 /* Pods */, ); indentWidth = 2; sourceTree = ""; @@ -115,6 +139,7 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "jitsi-meet" */; buildPhases = ( + B6607F42A5CF0C76E98929E2 /* [CP] Check Pods Manifest.lock */, 0BBA83C41EC9F7600075A103 /* Run React packager */, 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, @@ -122,6 +147,7 @@ 0B26BE701EC5BC3C00EEFB41 /* Embed Frameworks */, B35383AD1DDA0083008F406A /* Adjust embedded framework architectures */, 0BB7DA181EC9E695007AAE98 /* Adjust ATS */, + DEC2069321CBBD6900072F03 /* Setup Fabric */, ); buildRules = ( ); @@ -175,6 +201,7 @@ buildActionMask = 2147483647; files = ( 0B412F211EDEE95300B1A0A6 /* Main.storyboard in Resources */, + DE4C455E21DE1E4300EA0709 /* GoogleService-Info.plist in Resources */, 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */, ); @@ -195,7 +222,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "../scripts/fixup-ats.sh"; + shellScript = "../scripts/fixup-ats.sh\n"; }; 0BBA83C41EC9F7600075A103 /* Run React packager */ = { isa = PBXShellScriptBuildPhase; @@ -223,7 +250,47 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "../scripts/fixup-frameworks.sh"; + shellScript = "../scripts/fixup-frameworks.sh\n"; + }; + B6607F42A5CF0C76E98929E2 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-jitsi-meet-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + DEC2069321CBBD6900072F03 /* Setup Fabric */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Setup Fabric"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "${PODS_ROOT}/Fabric/run\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -234,6 +301,7 @@ files = ( 0B412F1F1EDEE6E800B1A0A6 /* ViewController.m in Sources */, 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */, + DE4C456121DE1E4E00EA0709 /* FIRUtilities.m in Sources */, 13B07FC11A68108700A75B9A /* main.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -254,6 +322,7 @@ /* Begin XCBuildConfiguration section */ 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 4670A512A688E2DC34528282 /* Pods-jitsi-meet.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIconDebug; @@ -287,6 +356,7 @@ }; 13B07F951A680F5B00A75B9A /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 09AA3B93E4CC62D84B424690 /* Pods-jitsi-meet.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIconRelease; diff --git a/ios/app/src/AppDelegate.m b/ios/app/src/AppDelegate.m index c7b0c055f..3768cf44a 100644 --- a/ios/app/src/AppDelegate.m +++ b/ios/app/src/AppDelegate.m @@ -1,5 +1,6 @@ /* - * Copyright @ 2017-present Atlassian Pty Ltd + * Copyright @ 2018-present 8x8, Inc. + * Copyright @ 2017-2018 Atlassian Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,13 +16,27 @@ */ #import "AppDelegate.h" +#import "FIRUtilities.h" #import +@import Crashlytics; +@import Fabric; +@import Firebase; + + @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + + // Initialize Crashlytics and Firebase if a valid GoogleService-Info.plist file was provided. + if ([FIRUtilities appContainsRealServiceInfoPlist]) { + NSLog(@"Enablign Crashlytics and Firebase"); + [FIRApp configure]; + [Fabric with:@[[Crashlytics class]]]; + } + return [JitsiMeetView application:application didFinishLaunchingWithOptions:launchOptions]; } @@ -31,6 +46,30 @@ - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray> *restorableObjects))restorationHandler { + + if ([FIRUtilities appContainsRealServiceInfoPlist]) { + // 1. Attempt to handle Universal Links through Firebase in order to support + // its Dynamic Links (which we utilize for the purposes of deferred deep + // linking). + BOOL handled + = [[FIRDynamicLinks dynamicLinks] + handleUniversalLink:userActivity.webpageURL + completion:^(FIRDynamicLink * _Nullable dynamicLink, NSError * _Nullable error) { + NSURL *dynamicLinkURL = dynamicLink.url; + if (dynamicLinkURL) { + userActivity.webpageURL = dynamicLinkURL; + [JitsiMeetView application:application + continueUserActivity:userActivity + restorationHandler:restorationHandler]; + } + }]; + + if (handled) { + return handled; + } + } + + // 2. Default to plain old, non-Firebase-assisted Universal Links. return [JitsiMeetView application:application continueUserActivity:userActivity restorationHandler:restorationHandler]; @@ -39,8 +78,25 @@ - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { + + NSURL *openUrl = url; + + if ([FIRUtilities appContainsRealServiceInfoPlist]) { + // Process Firebase Dynamic Links + FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url]; + if (dynamicLink != nil) { + NSURL *dynamicLinkURL = dynamicLink.url; + if (dynamicLinkURL != nil + && (dynamicLink.matchType == FIRDLMatchTypeUnique + || dynamicLink.matchType == FIRDLMatchTypeDefault)) { + // Strong match, process it. + openUrl = dynamicLinkURL; + } + } + } + return [JitsiMeetView application:app - openURL:url + openURL:openUrl options:options]; } diff --git a/ios/app/src/FIRUtilities.h b/ios/app/src/FIRUtilities.h new file mode 100644 index 000000000..8fb01b7d3 --- /dev/null +++ b/ios/app/src/FIRUtilities.h @@ -0,0 +1,23 @@ +/* + * 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 + +@interface FIRUtilities : NSObject + ++ (BOOL)appContainsRealServiceInfoPlist; + +@end diff --git a/ios/app/src/FIRUtilities.m b/ios/app/src/FIRUtilities.m new file mode 100644 index 000000000..29d754050 --- /dev/null +++ b/ios/app/src/FIRUtilities.m @@ -0,0 +1,69 @@ +/* + * 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 "FIRUtilities.h" + +// Plist file name. +NSString *const kGoogleServiceInfoFileName = @"GoogleService-Info"; +// Plist file type. +NSString *const kGoogleServiceInfoFileType = @"plist"; +NSString *const kGoogleAppIDPlistKey = @"GOOGLE_APP_ID"; +// Dummy plist GOOGLE_APP_ID +NSString *const kDummyGoogleAppID = @"1:123:ios:123abc"; + + +@implementation FIRUtilities + ++ (BOOL)appContainsRealServiceInfoPlist { + static BOOL containsRealServiceInfoPlist = NO; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSBundle *bundle = [NSBundle mainBundle]; + containsRealServiceInfoPlist = [self containsRealServiceInfoPlistInBundle:bundle]; + }); + return containsRealServiceInfoPlist; +} + ++ (BOOL)containsRealServiceInfoPlistInBundle:(NSBundle *)bundle { + NSString *bundlePath = bundle.bundlePath; + if (!bundlePath.length) { + return NO; + } + + NSString *plistFilePath = [bundle pathForResource:kGoogleServiceInfoFileName + ofType:kGoogleServiceInfoFileType]; + if (!plistFilePath.length) { + return NO; + } + + NSDictionary *plist = [NSDictionary dictionaryWithContentsOfFile:plistFilePath]; + if (!plist) { + return NO; + } + + // Perform a very naive validation by checking to see if the plist has the dummy google app id + NSString *googleAppID = plist[kGoogleAppIDPlistKey]; + if (!googleAppID.length) { + return NO; + } + if ([googleAppID isEqualToString:kDummyGoogleAppID]) { + return NO; + } + + return YES; +} + +@end diff --git a/ios/app/src/Info.plist b/ios/app/src/Info.plist index 9bea8fe55..335b12c90 100644 --- a/ios/app/src/Info.plist +++ b/ios/app/src/Info.plist @@ -93,5 +93,9 @@ UIViewControllerBasedStatusBarAppearance + FirebaseScreenReportingEnabled + + firebase_crashlytics_collection_enabled + false