[CHORE] Use react-native-firebase (#928)
We need to migrate from deprecated react-native-fabric to react-native-firebase. This PR enables following Firebase features: * Analytics * Crashlytics * Performance It also tracks screen view without the necessity of HOC. Future work: I won't do it in this PR because it's large enough, but we need to log more app events, like 'sent_message', 'open_admin', 'media_upload', etc.
This commit is contained in:
parent
9d79580946
commit
9e4a4d2454
|
@ -131,18 +131,6 @@ jobs:
|
||||||
|
|
||||||
echo -e "VERSIONCODE=$CIRCLE_BUILD_NUM" >> ./gradle.properties
|
echo -e "VERSIONCODE=$CIRCLE_BUILD_NUM" >> ./gradle.properties
|
||||||
|
|
||||||
if [[ $FABRIC_KEY ]]; then
|
|
||||||
echo -e "" > ./app/fabric.properties
|
|
||||||
echo -e "apiKey=$FABRIC_KEY" >> ./app/fabric.properties
|
|
||||||
echo -e "apiSecret=$FABRIC_SECRET" >> ./app/fabric.properties
|
|
||||||
fi
|
|
||||||
|
|
||||||
# - run:
|
|
||||||
# name: Install Android Depedencies
|
|
||||||
# command: |
|
|
||||||
# cd android
|
|
||||||
# ./gradlew androidDependencies
|
|
||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Build Android App
|
name: Build Android App
|
||||||
command: |
|
command: |
|
||||||
|
@ -201,25 +189,12 @@ jobs:
|
||||||
command: |
|
command: |
|
||||||
yarn
|
yarn
|
||||||
|
|
||||||
# - run:
|
|
||||||
# name: Fix known build error
|
|
||||||
# command: |
|
|
||||||
# # Fix error https://github.com/facebook/react-native/issues/14382
|
|
||||||
# cd node_modules/react-native/scripts/
|
|
||||||
# curl https://raw.githubusercontent.com/facebook/react-native/5c53f89dd86160301feee024bce4ce0c89e8c187/scripts/ios-configure-glog.sh > ios-configure-glog.sh
|
|
||||||
# chmod +x ios-configure-glog.sh
|
|
||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Fastlane Build
|
name: Fastlane Build
|
||||||
no_output_timeout: 1200
|
no_output_timeout: 1200
|
||||||
command: |
|
command: |
|
||||||
cd ios
|
cd ios
|
||||||
agvtool new-version -all $CIRCLE_BUILD_NUM
|
agvtool new-version -all $CIRCLE_BUILD_NUM
|
||||||
/usr/libexec/PlistBuddy -c "Set Fabric:APIKey $FABRIC_KEY" ./RocketChatRN/Info.plist
|
|
||||||
|
|
||||||
if [[ $FABRIC_KEY ]]; then
|
|
||||||
echo -e > "./Fabric.framework/run $FABRIC_KEY $FABRIC_SECRET" > ./RocketChatRN/Fabric.sh
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $MATCH_KEYCHAIN_NAME ]]; then
|
if [[ $MATCH_KEYCHAIN_NAME ]]; then
|
||||||
fastlane ios release
|
fastlane ios release
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
apply plugin: "com.android.application"
|
apply plugin: "com.android.application"
|
||||||
|
apply plugin: "io.fabric"
|
||||||
|
apply plugin: "com.google.firebase.firebase-perf"
|
||||||
|
|
||||||
import com.android.build.OutputFile
|
import com.android.build.OutputFile
|
||||||
|
|
||||||
|
@ -163,47 +165,8 @@ android {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buildscript {
|
|
||||||
repositories {
|
|
||||||
maven { url 'https://maven.fabric.io/public' }
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
// These docs use an open ended version so that our plugin
|
|
||||||
// can be updated quickly in response to Android tooling updates
|
|
||||||
|
|
||||||
// We recommend changing it to the latest version from our changelog:
|
|
||||||
// https://docs.fabric.io/android/changelog.html#fabric-gradle-plugin
|
|
||||||
classpath 'io.fabric.tools:gradle:1.+'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
apply plugin: 'io.fabric'
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
maven { url 'https://maven.fabric.io/public' }
|
|
||||||
}
|
|
||||||
|
|
||||||
configurations.all {
|
|
||||||
resolutionStrategy {
|
|
||||||
eachDependency { DependencyResolveDetails details ->
|
|
||||||
if (details.requested.name == 'play-services-base') {
|
|
||||||
details.useTarget group: details.requested.group, name: details.requested.name, version: '15.0.1'
|
|
||||||
}
|
|
||||||
if (details.requested.name == 'play-services-tasks') {
|
|
||||||
details.useTarget group: details.requested.group, name: details.requested.name, version: '15.0.1'
|
|
||||||
}
|
|
||||||
if (details.requested.name == 'play-services-stats') {
|
|
||||||
details.useTarget group: details.requested.group, name: details.requested.name, version: '15.0.1'
|
|
||||||
}
|
|
||||||
if (details.requested.name == 'play-services-basement') {
|
|
||||||
details.useTarget group: details.requested.group, name: details.requested.name, version: '15.0.1'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation project(':react-native-firebase')
|
||||||
implementation project(':react-native-webview')
|
implementation project(':react-native-webview')
|
||||||
implementation project(':react-native-orientation-locker')
|
implementation project(':react-native-orientation-locker')
|
||||||
implementation project(':react-native-splash-screen')
|
implementation project(':react-native-splash-screen')
|
||||||
|
@ -213,7 +176,6 @@ dependencies {
|
||||||
implementation project(':react-native-gesture-handler')
|
implementation project(':react-native-gesture-handler')
|
||||||
implementation project(':react-native-image-crop-picker')
|
implementation project(':react-native-image-crop-picker')
|
||||||
implementation project(':react-native-i18n')
|
implementation project(':react-native-i18n')
|
||||||
implementation project(':react-native-fabric')
|
|
||||||
implementation project(':react-native-audio')
|
implementation project(':react-native-audio')
|
||||||
implementation project(":reactnativekeyboardinput")
|
implementation project(":reactnativekeyboardinput")
|
||||||
implementation project(':react-native-video')
|
implementation project(':react-native-video')
|
||||||
|
@ -232,10 +194,12 @@ dependencies {
|
||||||
implementation 'com.facebook.fresco:animated-gif:1.10.0'
|
implementation 'com.facebook.fresco:animated-gif:1.10.0'
|
||||||
implementation 'com.facebook.fresco:animated-webp:1.10.0'
|
implementation 'com.facebook.fresco:animated-webp:1.10.0'
|
||||||
implementation 'com.facebook.fresco:webpsupport:1.10.0'
|
implementation 'com.facebook.fresco:webpsupport:1.10.0'
|
||||||
implementation "com.google.firebase:firebase-core:16.0.1"
|
implementation "com.google.android.gms:play-services-base:16.1.0"
|
||||||
implementation "com.google.firebase:firebase-messaging:17.3.4"
|
implementation "com.google.firebase:firebase-messaging:18.0.0"
|
||||||
|
implementation "com.google.firebase:firebase-core:16.0.9"
|
||||||
|
implementation "com.google.firebase:firebase-perf:16.2.5"
|
||||||
implementation('com.crashlytics.sdk.android:crashlytics:2.9.5@aar') {
|
implementation('com.crashlytics.sdk.android:crashlytics:2.9.5@aar') {
|
||||||
transitive = true;
|
transitive = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,4 +211,3 @@ task copyDownloadableDepsToLibs(type: Copy) {
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'com.google.gms.google-services'
|
apply plugin: 'com.google.gms.google-services'
|
||||||
com.google.gms.googleservices.GoogleServicesPlugin.config.disableVersionCheck = true
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
apiKey=ef3f46fdf18479fd3e1b9b78d0ec73751a255e14
|
|
||||||
apiSecret=e8e3d04c28bc04acd009484da5bb9d1440c4f53851564e9f95c3225ec8b0bc76
|
|
|
@ -25,15 +25,20 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"services": {
|
"services": {
|
||||||
"analytics_service": {
|
|
||||||
"status": 1
|
|
||||||
},
|
|
||||||
"appinvite_service": {
|
"appinvite_service": {
|
||||||
"status": 1,
|
"other_platform_oauth_client": [
|
||||||
"other_platform_oauth_client": []
|
{
|
||||||
|
"client_id": "673693445664-97s9t777ful7mn2510vuhb48958qd9tb.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
},
|
},
|
||||||
"ads_service": {
|
{
|
||||||
"status": 2
|
"client_id": "673693445664-jbf9m30ta163gobjfp0v7j1v7kpo7kmv.apps.googleusercontent.com",
|
||||||
|
"client_type": 2,
|
||||||
|
"ios_info": {
|
||||||
|
"bundle_id": "chat.rocket.reactnative"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -45,14 +50,6 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"oauth_client": [
|
"oauth_client": [
|
||||||
{
|
|
||||||
"client_id": "673693445664-hrjftksij02vqtd467ln2cubvu48ft5j.apps.googleusercontent.com",
|
|
||||||
"client_type": 1,
|
|
||||||
"android_info": {
|
|
||||||
"package_name": "chat.rocket.android",
|
|
||||||
"certificate_hash": "41cf750df786a6d9da712a98a629d0c8391876d6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"client_id": "673693445664-k0mvosdjoe5dbvqce3b377ckabb5dgu8.apps.googleusercontent.com",
|
"client_id": "673693445664-k0mvosdjoe5dbvqce3b377ckabb5dgu8.apps.googleusercontent.com",
|
||||||
"client_type": 1,
|
"client_type": 1,
|
||||||
|
@ -61,6 +58,14 @@
|
||||||
"certificate_hash": "33fa8582794176014a59054192e261bfad0e5273"
|
"certificate_hash": "33fa8582794176014a59054192e261bfad0e5273"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"client_id": "673693445664-hrjftksij02vqtd467ln2cubvu48ft5j.apps.googleusercontent.com",
|
||||||
|
"client_type": 1,
|
||||||
|
"android_info": {
|
||||||
|
"package_name": "chat.rocket.android",
|
||||||
|
"certificate_hash": "41cf750df786a6d9da712a98a629d0c8391876d6"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"client_id": "673693445664-97s9t777ful7mn2510vuhb48958qd9tb.apps.googleusercontent.com",
|
"client_id": "673693445664-97s9t777ful7mn2510vuhb48958qd9tb.apps.googleusercontent.com",
|
||||||
"client_type": 3
|
"client_type": 3
|
||||||
|
@ -72,28 +77,20 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"services": {
|
"services": {
|
||||||
"analytics_service": {
|
|
||||||
"status": 1
|
|
||||||
},
|
|
||||||
"appinvite_service": {
|
"appinvite_service": {
|
||||||
"status": 2,
|
|
||||||
"other_platform_oauth_client": [
|
"other_platform_oauth_client": [
|
||||||
{
|
{
|
||||||
"client_id": "673693445664-97s9t777ful7mn2510vuhb48958qd9tb.apps.googleusercontent.com",
|
"client_id": "673693445664-97s9t777ful7mn2510vuhb48958qd9tb.apps.googleusercontent.com",
|
||||||
"client_type": 3
|
"client_type": 3
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"client_id": "673693445664-dumairnsk1sbkca5nmsq2b5kdglqpc0a.apps.googleusercontent.com",
|
"client_id": "673693445664-jbf9m30ta163gobjfp0v7j1v7kpo7kmv.apps.googleusercontent.com",
|
||||||
"client_type": 2,
|
"client_type": 2,
|
||||||
"ios_info": {
|
"ios_info": {
|
||||||
"bundle_id": "chat.rocket.ios",
|
"bundle_id": "chat.rocket.reactnative"
|
||||||
"app_store_id": "1148741252"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
|
||||||
"ads_service": {
|
|
||||||
"status": 2
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -132,28 +129,20 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"services": {
|
"services": {
|
||||||
"analytics_service": {
|
|
||||||
"status": 1
|
|
||||||
},
|
|
||||||
"appinvite_service": {
|
"appinvite_service": {
|
||||||
"status": 2,
|
|
||||||
"other_platform_oauth_client": [
|
"other_platform_oauth_client": [
|
||||||
{
|
{
|
||||||
"client_id": "673693445664-97s9t777ful7mn2510vuhb48958qd9tb.apps.googleusercontent.com",
|
"client_id": "673693445664-97s9t777ful7mn2510vuhb48958qd9tb.apps.googleusercontent.com",
|
||||||
"client_type": 3
|
"client_type": 3
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"client_id": "673693445664-dumairnsk1sbkca5nmsq2b5kdglqpc0a.apps.googleusercontent.com",
|
"client_id": "673693445664-jbf9m30ta163gobjfp0v7j1v7kpo7kmv.apps.googleusercontent.com",
|
||||||
"client_type": 2,
|
"client_type": 2,
|
||||||
"ios_info": {
|
"ios_info": {
|
||||||
"bundle_id": "chat.rocket.ios",
|
"bundle_id": "chat.rocket.reactnative"
|
||||||
"app_store_id": "1148741252"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
|
||||||
"ads_service": {
|
|
||||||
"status": 2
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -176,15 +165,20 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"services": {
|
"services": {
|
||||||
"analytics_service": {
|
|
||||||
"status": 1
|
|
||||||
},
|
|
||||||
"appinvite_service": {
|
"appinvite_service": {
|
||||||
"status": 1,
|
"other_platform_oauth_client": [
|
||||||
"other_platform_oauth_client": []
|
{
|
||||||
|
"client_id": "673693445664-97s9t777ful7mn2510vuhb48958qd9tb.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
},
|
},
|
||||||
"ads_service": {
|
{
|
||||||
"status": 2
|
"client_id": "673693445664-jbf9m30ta163gobjfp0v7j1v7kpo7kmv.apps.googleusercontent.com",
|
||||||
|
"client_type": 2,
|
||||||
|
"ios_info": {
|
||||||
|
"bundle_id": "chat.rocket.reactnative"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -215,28 +209,20 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"services": {
|
"services": {
|
||||||
"analytics_service": {
|
|
||||||
"status": 1
|
|
||||||
},
|
|
||||||
"appinvite_service": {
|
"appinvite_service": {
|
||||||
"status": 2,
|
|
||||||
"other_platform_oauth_client": [
|
"other_platform_oauth_client": [
|
||||||
{
|
{
|
||||||
"client_id": "673693445664-97s9t777ful7mn2510vuhb48958qd9tb.apps.googleusercontent.com",
|
"client_id": "673693445664-97s9t777ful7mn2510vuhb48958qd9tb.apps.googleusercontent.com",
|
||||||
"client_type": 3
|
"client_type": 3
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"client_id": "673693445664-dumairnsk1sbkca5nmsq2b5kdglqpc0a.apps.googleusercontent.com",
|
"client_id": "673693445664-jbf9m30ta163gobjfp0v7j1v7kpo7kmv.apps.googleusercontent.com",
|
||||||
"client_type": 2,
|
"client_type": 2,
|
||||||
"ios_info": {
|
"ios_info": {
|
||||||
"bundle_id": "chat.rocket.ios",
|
"bundle_id": "chat.rocket.reactnative"
|
||||||
"app_store_id": "1148741252"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
|
||||||
"ads_service": {
|
|
||||||
"status": 2
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,10 @@ package chat.rocket.reactnative;
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
|
|
||||||
import com.facebook.react.ReactApplication;
|
import com.facebook.react.ReactApplication;
|
||||||
|
import io.invertase.firebase.RNFirebasePackage;
|
||||||
|
import io.invertase.firebase.fabric.crashlytics.RNFirebaseCrashlyticsPackage;
|
||||||
|
import io.invertase.firebase.analytics.RNFirebaseAnalyticsPackage;
|
||||||
|
import io.invertase.firebase.perf.RNFirebasePerformancePackage;
|
||||||
import com.reactnativecommunity.webview.RNCWebViewPackage;
|
import com.reactnativecommunity.webview.RNCWebViewPackage;
|
||||||
import org.wonday.orientation.OrientationPackage;
|
import org.wonday.orientation.OrientationPackage;
|
||||||
import org.devio.rn.splashscreen.SplashScreenReactPackage;
|
import org.devio.rn.splashscreen.SplashScreenReactPackage;
|
||||||
|
@ -15,11 +19,9 @@ import com.AlexanderZaytsev.RNI18n.RNI18nPackage;
|
||||||
import com.reactnative.ivpusic.imagepicker.PickerPackage;
|
import com.reactnative.ivpusic.imagepicker.PickerPackage;
|
||||||
import com.RNFetchBlob.RNFetchBlobPackage;
|
import com.RNFetchBlob.RNFetchBlobPackage;
|
||||||
import com.brentvatne.react.ReactVideoPackage;
|
import com.brentvatne.react.ReactVideoPackage;
|
||||||
import com.crashlytics.android.Crashlytics;
|
|
||||||
import com.dylanvann.fastimage.FastImageViewPackage;
|
import com.dylanvann.fastimage.FastImageViewPackage;
|
||||||
import com.oblador.vectoricons.VectorIconsPackage;
|
import com.oblador.vectoricons.VectorIconsPackage;
|
||||||
import com.rnim.rn.audio.ReactNativeAudioPackage;
|
import com.rnim.rn.audio.ReactNativeAudioPackage;
|
||||||
import com.smixx.fabric.FabricPackage;
|
|
||||||
import com.wix.reactnativekeyboardinput.KeyboardInputPackage;
|
import com.wix.reactnativekeyboardinput.KeyboardInputPackage;
|
||||||
import com.wix.reactnativenotifications.RNNotificationsPackage;
|
import com.wix.reactnativenotifications.RNNotificationsPackage;
|
||||||
import com.wix.reactnativenotifications.core.AppLaunchHelper;
|
import com.wix.reactnativenotifications.core.AppLaunchHelper;
|
||||||
|
@ -30,7 +32,6 @@ import com.wix.reactnativenotifications.core.notification.IPushNotification;
|
||||||
import com.swmansion.gesturehandler.react.RNGestureHandlerPackage;
|
import com.swmansion.gesturehandler.react.RNGestureHandlerPackage;
|
||||||
import com.learnium.RNDeviceInfo.RNDeviceInfo;
|
import com.learnium.RNDeviceInfo.RNDeviceInfo;
|
||||||
import com.actionsheet.ActionSheetPackage;
|
import com.actionsheet.ActionSheetPackage;
|
||||||
import io.fabric.sdk.android.Fabric;
|
|
||||||
import io.realm.react.RealmReactPackage;
|
import io.realm.react.RealmReactPackage;
|
||||||
import com.swmansion.rnscreens.RNScreensPackage;
|
import com.swmansion.rnscreens.RNScreensPackage;
|
||||||
|
|
||||||
|
@ -52,6 +53,10 @@ public class MainApplication extends Application implements ReactApplication, IN
|
||||||
protected List<ReactPackage> getPackages() {
|
protected List<ReactPackage> getPackages() {
|
||||||
return Arrays.<ReactPackage>asList(
|
return Arrays.<ReactPackage>asList(
|
||||||
new MainReactPackage(),
|
new MainReactPackage(),
|
||||||
|
new RNFirebasePackage(),
|
||||||
|
new RNFirebaseCrashlyticsPackage(),
|
||||||
|
new RNFirebaseAnalyticsPackage(),
|
||||||
|
new RNFirebasePerformancePackage(),
|
||||||
new RNCWebViewPackage(),
|
new RNCWebViewPackage(),
|
||||||
new OrientationPackage(),
|
new OrientationPackage(),
|
||||||
new SplashScreenReactPackage(),
|
new SplashScreenReactPackage(),
|
||||||
|
@ -67,7 +72,6 @@ public class MainApplication extends Application implements ReactApplication, IN
|
||||||
new ReactNativeAudioPackage(),
|
new ReactNativeAudioPackage(),
|
||||||
new KeyboardInputPackage(MainApplication.this),
|
new KeyboardInputPackage(MainApplication.this),
|
||||||
new RocketChatNativePackage(),
|
new RocketChatNativePackage(),
|
||||||
new FabricPackage(),
|
|
||||||
new FastImageViewPackage(),
|
new FastImageViewPackage(),
|
||||||
new RNI18nPackage(),
|
new RNI18nPackage(),
|
||||||
new RNNotificationsPackage(MainApplication.this)
|
new RNNotificationsPackage(MainApplication.this)
|
||||||
|
@ -88,7 +92,6 @@ public class MainApplication extends Application implements ReactApplication, IN
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
Fabric.with(this, new Crashlytics());
|
|
||||||
SoLoader.init(this, /* native exopackage */ false);
|
SoLoader.init(this, /* native exopackage */ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,15 @@ buildscript {
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
google()
|
google()
|
||||||
jcenter()
|
jcenter()
|
||||||
|
maven {
|
||||||
|
url 'https://maven.fabric.io/public'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.3.1'
|
classpath 'com.android.tools.build:gradle:3.3.1'
|
||||||
classpath 'com.google.gms:google-services:4.0.1'
|
classpath 'com.google.gms:google-services:4.2.0'
|
||||||
|
classpath 'io.fabric.tools:gradle:1.25.4'
|
||||||
|
classpath 'com.google.firebase:firebase-plugins:1.1.5'
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
rootProject.name = 'RocketChatRN'
|
rootProject.name = 'RocketChatRN'
|
||||||
|
include ':react-native-firebase'
|
||||||
|
project(':react-native-firebase').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-firebase/android')
|
||||||
include ':react-native-webview'
|
include ':react-native-webview'
|
||||||
project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android')
|
project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android')
|
||||||
include ':react-native-orientation-locker'
|
include ':react-native-orientation-locker'
|
||||||
|
@ -21,8 +23,6 @@ include ':react-native-i18n'
|
||||||
project(':react-native-i18n').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-i18n/android')
|
project(':react-native-i18n').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-i18n/android')
|
||||||
include ':react-native-fast-image'
|
include ':react-native-fast-image'
|
||||||
project(':react-native-fast-image').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fast-image/android')
|
project(':react-native-fast-image').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fast-image/android')
|
||||||
include ':react-native-fabric'
|
|
||||||
project(':react-native-fabric').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fabric/android')
|
|
||||||
include ':react-native-audio'
|
include ':react-native-audio'
|
||||||
project(':react-native-audio').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-audio/android')
|
project(':react-native-audio').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-audio/android')
|
||||||
include ':reactnativekeyboardinput'
|
include ':reactnativekeyboardinput'
|
||||||
|
|
24
app/index.js
24
app/index.js
|
@ -5,6 +5,7 @@ import {
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
import { useScreens } from 'react-native-screens'; // eslint-disable-line import/no-unresolved
|
import { useScreens } from 'react-native-screens'; // eslint-disable-line import/no-unresolved
|
||||||
import { Linking } from 'react-native';
|
import { Linking } from 'react-native';
|
||||||
|
import firebase from 'react-native-firebase';
|
||||||
|
|
||||||
import { appInit } from './actions';
|
import { appInit } from './actions';
|
||||||
import { deepLinkingOpen } from './actions/deepLinking';
|
import { deepLinkingOpen } from './actions/deepLinking';
|
||||||
|
@ -204,6 +205,28 @@ const App = createAppContainer(createSwitchNavigator(
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|
||||||
|
// gets the current screen from navigation state
|
||||||
|
const getActiveRouteName = (navigationState) => {
|
||||||
|
if (!navigationState) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const route = navigationState.routes[navigationState.index];
|
||||||
|
// dive into nested navigators
|
||||||
|
if (route.routes) {
|
||||||
|
return getActiveRouteName(route);
|
||||||
|
}
|
||||||
|
return route.routeName;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onNavigationStateChange = (prevState, currentState) => {
|
||||||
|
const currentScreen = getActiveRouteName(currentState);
|
||||||
|
const prevScreen = getActiveRouteName(prevState);
|
||||||
|
|
||||||
|
if (prevScreen !== currentScreen) {
|
||||||
|
firebase.analytics().setCurrentScreen(currentScreen);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export default class Root extends React.Component {
|
export default class Root extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -244,6 +267,7 @@ export default class Root extends React.Component {
|
||||||
ref={(navigatorRef) => {
|
ref={(navigatorRef) => {
|
||||||
Navigation.setTopLevelNavigator(navigatorRef);
|
Navigation.setTopLevelNavigator(navigatorRef);
|
||||||
}}
|
}}
|
||||||
|
onNavigationStateChange={onNavigationStateChange}
|
||||||
/>
|
/>
|
||||||
</Provider>
|
</Provider>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import { Answers } from 'react-native-fabric';
|
|
||||||
|
|
||||||
export default fn => (...params) => {
|
export default fn => (...params) => {
|
||||||
try {
|
try {
|
||||||
fn(...params);
|
fn(...params);
|
||||||
|
@ -8,7 +6,6 @@ export default fn => (...params) => {
|
||||||
if (typeof error !== 'object') {
|
if (typeof error !== 'object') {
|
||||||
error = { error };
|
error = { error };
|
||||||
}
|
}
|
||||||
Answers.logCustom('error', error);
|
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
alert(error);
|
alert(error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { Answers } from 'react-native-fabric';
|
import firebase from 'react-native-firebase';
|
||||||
|
|
||||||
export default (event, error) => {
|
export default (event, error) => {
|
||||||
if (typeof error !== 'object') {
|
if (typeof error !== 'object') {
|
||||||
error = { error };
|
error = { error };
|
||||||
}
|
}
|
||||||
Answers.logCustom(event);
|
firebase.analytics().logEvent(event);
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
console.warn(event, error);
|
console.warn(event, error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import { SafeAreaView } from 'react-navigation';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import LoggedView from '../View';
|
|
||||||
import StatusBar from '../../containers/StatusBar';
|
import StatusBar from '../../containers/StatusBar';
|
||||||
import { DrawerButton } from '../../containers/HeaderButton';
|
import { DrawerButton } from '../../containers/HeaderButton';
|
||||||
import styles from '../Styles';
|
import styles from '../Styles';
|
||||||
|
@ -14,8 +13,7 @@ import styles from '../Styles';
|
||||||
baseUrl: state.settings.Site_Url || state.server ? state.server.server : '',
|
baseUrl: state.settings.Site_Url || state.server ? state.server.server : '',
|
||||||
authToken: state.login.user && state.login.user.token
|
authToken: state.login.user && state.login.user.token
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
export default class AdminPanelView extends React.Component {
|
||||||
export default class AdminPanelView extends LoggedView {
|
|
||||||
static navigationOptions = ({ navigation }) => ({
|
static navigationOptions = ({ navigation }) => ({
|
||||||
headerLeft: <DrawerButton navigation={navigation} />,
|
headerLeft: <DrawerButton navigation={navigation} />,
|
||||||
title: I18n.t('Admin_Panel')
|
title: I18n.t('Admin_Panel')
|
||||||
|
@ -26,10 +24,6 @@ export default class AdminPanelView extends LoggedView {
|
||||||
authToken: PropTypes.string
|
authToken: PropTypes.string
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super('AdminPanelView', props);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { baseUrl, authToken } = this.props;
|
const { baseUrl, authToken } = this.props;
|
||||||
if (!baseUrl) {
|
if (!baseUrl) {
|
||||||
|
|
|
@ -8,7 +8,6 @@ import { SafeAreaView } from 'react-navigation';
|
||||||
import equal from 'deep-equal';
|
import equal from 'deep-equal';
|
||||||
|
|
||||||
import Loading from '../containers/Loading';
|
import Loading from '../containers/Loading';
|
||||||
import LoggedView from './View';
|
|
||||||
import { createChannelRequest as createChannelRequestAction } from '../actions/createChannel';
|
import { createChannelRequest as createChannelRequestAction } from '../actions/createChannel';
|
||||||
import { removeUser as removeUserAction } from '../actions/selectedUsers';
|
import { removeUser as removeUserAction } from '../actions/selectedUsers';
|
||||||
import sharedStyles from './Styles';
|
import sharedStyles from './Styles';
|
||||||
|
@ -93,8 +92,7 @@ const styles = StyleSheet.create({
|
||||||
create: data => dispatch(createChannelRequestAction(data)),
|
create: data => dispatch(createChannelRequestAction(data)),
|
||||||
removeUser: user => dispatch(removeUserAction(user))
|
removeUser: user => dispatch(removeUserAction(user))
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
export default class CreateChannelView extends React.Component {
|
||||||
export default class CreateChannelView extends LoggedView {
|
|
||||||
static navigationOptions = ({ navigation }) => {
|
static navigationOptions = ({ navigation }) => {
|
||||||
const submit = navigation.getParam('submit', () => {});
|
const submit = navigation.getParam('submit', () => {});
|
||||||
const showSubmit = navigation.getParam('showSubmit');
|
const showSubmit = navigation.getParam('showSubmit');
|
||||||
|
@ -128,14 +126,11 @@ export default class CreateChannelView extends LoggedView {
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props) {
|
state = {
|
||||||
super('CreateChannelView', props);
|
|
||||||
this.state = {
|
|
||||||
channelName: '',
|
channelName: '',
|
||||||
type: true,
|
type: true,
|
||||||
readOnly: false,
|
readOnly: false,
|
||||||
broadcast: false
|
broadcast: false
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { Text, ScrollView } from 'react-native';
|
||||||
import { SafeAreaView } from 'react-navigation';
|
import { SafeAreaView } from 'react-navigation';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import LoggedView from './View';
|
|
||||||
import KeyboardView from '../presentation/KeyboardView';
|
import KeyboardView from '../presentation/KeyboardView';
|
||||||
import TextInput from '../containers/TextInput';
|
import TextInput from '../containers/TextInput';
|
||||||
import Button from '../containers/Button';
|
import Button from '../containers/Button';
|
||||||
|
@ -15,8 +14,7 @@ import I18n from '../i18n';
|
||||||
import RocketChat from '../lib/rocketchat';
|
import RocketChat from '../lib/rocketchat';
|
||||||
import StatusBar from '../containers/StatusBar';
|
import StatusBar from '../containers/StatusBar';
|
||||||
|
|
||||||
/** @extends React.Component */
|
export default class ForgotPasswordView extends React.Component {
|
||||||
export default class ForgotPasswordView extends LoggedView {
|
|
||||||
static navigationOptions = ({ navigation }) => {
|
static navigationOptions = ({ navigation }) => {
|
||||||
const title = navigation.getParam('title', 'Rocket.Chat');
|
const title = navigation.getParam('title', 'Rocket.Chat');
|
||||||
return {
|
return {
|
||||||
|
@ -28,14 +26,10 @@ export default class ForgotPasswordView extends LoggedView {
|
||||||
navigation: PropTypes.object
|
navigation: PropTypes.object
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
state = {
|
||||||
super('ForgotPasswordView', props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
email: '',
|
email: '',
|
||||||
invalidEmail: true,
|
invalidEmail: true,
|
||||||
isFetching: false
|
isFetching: false
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
|
|
@ -9,7 +9,6 @@ import { connect } from 'react-redux';
|
||||||
|
|
||||||
import sharedStyles from './Styles';
|
import sharedStyles from './Styles';
|
||||||
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
||||||
import LoggedView from './View';
|
|
||||||
import I18n from '../i18n';
|
import I18n from '../i18n';
|
||||||
import DisclosureIndicator from '../containers/DisclosureIndicator';
|
import DisclosureIndicator from '../containers/DisclosureIndicator';
|
||||||
import StatusBar from '../containers/StatusBar';
|
import StatusBar from '../containers/StatusBar';
|
||||||
|
@ -56,8 +55,7 @@ const Separator = () => <View style={styles.separator} />;
|
||||||
@connect(state => ({
|
@connect(state => ({
|
||||||
server: state.server.server
|
server: state.server.server
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
export default class LegalView extends React.Component {
|
||||||
export default class LegalView extends LoggedView {
|
|
||||||
static navigationOptions = () => ({
|
static navigationOptions = () => ({
|
||||||
title: I18n.t('Legal')
|
title: I18n.t('Legal')
|
||||||
})
|
})
|
||||||
|
@ -66,10 +64,6 @@ export default class LegalView extends LoggedView {
|
||||||
server: PropTypes.string
|
server: PropTypes.string
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super('LegalView', props);
|
|
||||||
}
|
|
||||||
|
|
||||||
onPressItem = ({ route }) => {
|
onPressItem = ({ route }) => {
|
||||||
const { server } = this.props;
|
const { server } = this.props;
|
||||||
if (!server) {
|
if (!server) {
|
||||||
|
|
|
@ -9,7 +9,6 @@ import { SafeAreaView } from 'react-navigation';
|
||||||
import { RectButton, BorderlessButton } from 'react-native-gesture-handler';
|
import { RectButton, BorderlessButton } from 'react-native-gesture-handler';
|
||||||
import equal from 'deep-equal';
|
import equal from 'deep-equal';
|
||||||
|
|
||||||
import LoggedView from './View';
|
|
||||||
import sharedStyles from './Styles';
|
import sharedStyles from './Styles';
|
||||||
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
||||||
import random from '../utils/random';
|
import random from '../utils/random';
|
||||||
|
@ -94,8 +93,7 @@ const SERVICES_COLLAPSED_HEIGHT = 174;
|
||||||
Site_Name: state.settings.Site_Name,
|
Site_Name: state.settings.Site_Name,
|
||||||
services: state.login.services
|
services: state.login.services
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
export default class LoginSignupView extends React.Component {
|
||||||
export default class LoginSignupView extends LoggedView {
|
|
||||||
static navigationOptions = ({ navigation }) => {
|
static navigationOptions = ({ navigation }) => {
|
||||||
const title = navigation.getParam('title', 'Rocket.Chat');
|
const title = navigation.getParam('title', 'Rocket.Chat');
|
||||||
return {
|
return {
|
||||||
|
@ -112,7 +110,7 @@ export default class LoginSignupView extends LoggedView {
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super('LoginSignupView', props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
collapsed: true,
|
collapsed: true,
|
||||||
servicesHeight: new Animated.Value(SERVICES_COLLAPSED_HEIGHT)
|
servicesHeight: new Animated.Value(SERVICES_COLLAPSED_HEIGHT)
|
||||||
|
|
|
@ -4,16 +4,15 @@ import {
|
||||||
Keyboard, Text, ScrollView, View, StyleSheet, Alert, LayoutAnimation
|
Keyboard, Text, ScrollView, View, StyleSheet, Alert, LayoutAnimation
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { Answers } from 'react-native-fabric';
|
|
||||||
import { SafeAreaView } from 'react-navigation';
|
import { SafeAreaView } from 'react-navigation';
|
||||||
import equal from 'deep-equal';
|
import equal from 'deep-equal';
|
||||||
|
import firebase from 'react-native-firebase';
|
||||||
|
|
||||||
import KeyboardView from '../presentation/KeyboardView';
|
import KeyboardView from '../presentation/KeyboardView';
|
||||||
import TextInput from '../containers/TextInput';
|
import TextInput from '../containers/TextInput';
|
||||||
import Button from '../containers/Button';
|
import Button from '../containers/Button';
|
||||||
import sharedStyles from './Styles';
|
import sharedStyles from './Styles';
|
||||||
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
||||||
import LoggedView from './View';
|
|
||||||
import I18n from '../i18n';
|
import I18n from '../i18n';
|
||||||
import { loginRequest as loginRequestAction } from '../actions/login';
|
import { loginRequest as loginRequestAction } from '../actions/login';
|
||||||
import { LegalButton } from '../containers/HeaderButton';
|
import { LegalButton } from '../containers/HeaderButton';
|
||||||
|
@ -21,10 +20,6 @@ import StatusBar from '../containers/StatusBar';
|
||||||
import { COLOR_PRIMARY } from '../constants/colors';
|
import { COLOR_PRIMARY } from '../constants/colors';
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
buttonsContainer: {
|
|
||||||
flexDirection: 'column',
|
|
||||||
marginTop: 5
|
|
||||||
},
|
|
||||||
bottomContainer: {
|
bottomContainer: {
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
@ -56,8 +51,7 @@ const styles = StyleSheet.create({
|
||||||
}), dispatch => ({
|
}), dispatch => ({
|
||||||
loginRequest: params => dispatch(loginRequestAction(params))
|
loginRequest: params => dispatch(loginRequestAction(params))
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
export default class LoginView extends React.Component {
|
||||||
export default class LoginView extends LoggedView {
|
|
||||||
static navigationOptions = ({ navigation }) => {
|
static navigationOptions = ({ navigation }) => {
|
||||||
const title = navigation.getParam('title', 'Rocket.Chat');
|
const title = navigation.getParam('title', 'Rocket.Chat');
|
||||||
return {
|
return {
|
||||||
|
@ -78,7 +72,7 @@ export default class LoginView extends LoggedView {
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super('LoginView', props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
user: '',
|
user: '',
|
||||||
password: '',
|
password: '',
|
||||||
|
@ -184,7 +178,7 @@ export default class LoginView extends LoggedView {
|
||||||
const { loginRequest } = this.props;
|
const { loginRequest } = this.props;
|
||||||
Keyboard.dismiss();
|
Keyboard.dismiss();
|
||||||
loginRequest({ user, password, code });
|
loginRequest({ user, password, code });
|
||||||
Answers.logLogin('Email', true);
|
firebase.analytics().logEvent('login');
|
||||||
}
|
}
|
||||||
|
|
||||||
register = () => {
|
register = () => {
|
||||||
|
|
|
@ -6,7 +6,6 @@ import { SafeAreaView } from 'react-navigation';
|
||||||
import equal from 'deep-equal';
|
import equal from 'deep-equal';
|
||||||
import ActionSheet from 'react-native-action-sheet';
|
import ActionSheet from 'react-native-action-sheet';
|
||||||
|
|
||||||
import LoggedView from '../View';
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import Message from '../../containers/message/Message';
|
import Message from '../../containers/message/Message';
|
||||||
import RCActivityIndicator from '../../containers/ActivityIndicator';
|
import RCActivityIndicator from '../../containers/ActivityIndicator';
|
||||||
|
@ -27,8 +26,7 @@ const CANCEL_INDEX = 1;
|
||||||
token: state.login.user && state.login.user.token
|
token: state.login.user && state.login.user.token
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
export default class MessagesView extends React.Component {
|
||||||
export default class MessagesView extends LoggedView {
|
|
||||||
static navigationOptions = ({ navigation }) => ({
|
static navigationOptions = ({ navigation }) => ({
|
||||||
title: navigation.state.params.name
|
title: navigation.state.params.name
|
||||||
});
|
});
|
||||||
|
@ -40,7 +38,7 @@ export default class MessagesView extends LoggedView {
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super('MessagesView', props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
loading: false,
|
loading: false,
|
||||||
messages: [],
|
messages: [],
|
||||||
|
|
|
@ -11,7 +11,6 @@ import database, { safeAddListener } from '../lib/realm';
|
||||||
import RocketChat from '../lib/rocketchat';
|
import RocketChat from '../lib/rocketchat';
|
||||||
import UserItem from '../presentation/UserItem';
|
import UserItem from '../presentation/UserItem';
|
||||||
import debounce from '../utils/debounce';
|
import debounce from '../utils/debounce';
|
||||||
import LoggedView from './View';
|
|
||||||
import sharedStyles from './Styles';
|
import sharedStyles from './Styles';
|
||||||
import I18n from '../i18n';
|
import I18n from '../i18n';
|
||||||
import Touch from '../utils/touch';
|
import Touch from '../utils/touch';
|
||||||
|
@ -57,8 +56,7 @@ const styles = StyleSheet.create({
|
||||||
token: state.login.user && state.login.user.token
|
token: state.login.user && state.login.user.token
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
export default class NewMessageView extends React.Component {
|
||||||
export default class NewMessageView extends LoggedView {
|
|
||||||
static navigationOptions = ({ navigation }) => ({
|
static navigationOptions = ({ navigation }) => ({
|
||||||
headerLeft: <CloseModalButton navigation={navigation} testID='new-message-view-close' />,
|
headerLeft: <CloseModalButton navigation={navigation} testID='new-message-view-close' />,
|
||||||
title: I18n.t('New_Message')
|
title: I18n.t('New_Message')
|
||||||
|
@ -74,7 +72,7 @@ export default class NewMessageView extends LoggedView {
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super('NewMessageView', props);
|
super(props);
|
||||||
this.data = database.objects('subscriptions').filtered('t = $0', 'd').sorted('roomUpdatedAt', true);
|
this.data = database.objects('subscriptions').filtered('t = $0', 'd').sorted('roomUpdatedAt', true);
|
||||||
this.state = {
|
this.state = {
|
||||||
search: []
|
search: []
|
||||||
|
|
|
@ -11,7 +11,6 @@ import sharedStyles from './Styles';
|
||||||
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
||||||
import Button from '../containers/Button';
|
import Button from '../containers/Button';
|
||||||
import TextInput from '../containers/TextInput';
|
import TextInput from '../containers/TextInput';
|
||||||
import LoggedView from './View';
|
|
||||||
import I18n from '../i18n';
|
import I18n from '../i18n';
|
||||||
import { verticalScale, moderateScale } from '../utils/scaling';
|
import { verticalScale, moderateScale } from '../utils/scaling';
|
||||||
import KeyboardView from '../presentation/KeyboardView';
|
import KeyboardView from '../presentation/KeyboardView';
|
||||||
|
@ -38,16 +37,6 @@ const styles = StyleSheet.create({
|
||||||
marginTop: 25,
|
marginTop: 25,
|
||||||
marginBottom: 15
|
marginBottom: 15
|
||||||
},
|
},
|
||||||
input: {
|
|
||||||
...sharedStyles.textRegular,
|
|
||||||
...sharedStyles.textColorDescription,
|
|
||||||
fontSize: 17,
|
|
||||||
letterSpacing: 0,
|
|
||||||
paddingTop: 14,
|
|
||||||
paddingBottom: 14,
|
|
||||||
paddingLeft: 16,
|
|
||||||
paddingRight: 16
|
|
||||||
},
|
|
||||||
backButton: {
|
backButton: {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
paddingHorizontal: 9,
|
paddingHorizontal: 9,
|
||||||
|
@ -62,8 +51,7 @@ const defaultServer = 'https://open.rocket.chat';
|
||||||
}), dispatch => ({
|
}), dispatch => ({
|
||||||
connectServer: server => dispatch(serverRequest(server))
|
connectServer: server => dispatch(serverRequest(server))
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
export default class NewServerView extends React.Component {
|
||||||
export default class NewServerView extends LoggedView {
|
|
||||||
static navigationOptions = () => ({
|
static navigationOptions = () => ({
|
||||||
header: null
|
header: null
|
||||||
})
|
})
|
||||||
|
@ -75,11 +63,8 @@ export default class NewServerView extends LoggedView {
|
||||||
connectServer: PropTypes.func.isRequired
|
connectServer: PropTypes.func.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
state = {
|
||||||
super('NewServerView', props);
|
|
||||||
this.state = {
|
|
||||||
text: ''
|
text: ''
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
|
|
@ -13,7 +13,6 @@ import I18n from '../../i18n';
|
||||||
import openLink from '../../utils/openLink';
|
import openLink from '../../utils/openLink';
|
||||||
import Button from './Button';
|
import Button from './Button';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import LoggedView from '../View';
|
|
||||||
import { isIOS, isNotch } from '../../utils/deviceInfo';
|
import { isIOS, isNotch } from '../../utils/deviceInfo';
|
||||||
import EventEmitter from '../../utils/events';
|
import EventEmitter from '../../utils/events';
|
||||||
import { CustomIcon } from '../../lib/Icons';
|
import { CustomIcon } from '../../lib/Icons';
|
||||||
|
@ -29,8 +28,7 @@ import { COLOR_PRIMARY, COLOR_WHITE } from '../../constants/colors';
|
||||||
selectServer: server => dispatch(selectServerRequest(server)),
|
selectServer: server => dispatch(selectServerRequest(server)),
|
||||||
appStart: root => dispatch(appStartAction(root))
|
appStart: root => dispatch(appStartAction(root))
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
export default class OnboardingView extends React.Component {
|
||||||
export default class OnboardingView extends LoggedView {
|
|
||||||
static navigationOptions = () => ({
|
static navigationOptions = () => ({
|
||||||
header: null
|
header: null
|
||||||
})
|
})
|
||||||
|
@ -46,7 +44,7 @@ export default class OnboardingView extends LoggedView {
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super('OnboardingView', props);
|
super(props);
|
||||||
BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
|
BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
|
||||||
this.previousServer = props.navigation.getParam('previousServer');
|
this.previousServer = props.navigation.getParam('previousServer');
|
||||||
Orientation.lockToPortrait();
|
Orientation.lockToPortrait();
|
||||||
|
|
|
@ -9,7 +9,6 @@ import RNPickerSelect from 'react-native-picker-select';
|
||||||
import { SafeAreaView } from 'react-navigation';
|
import { SafeAreaView } from 'react-navigation';
|
||||||
import equal from 'deep-equal';
|
import equal from 'deep-equal';
|
||||||
|
|
||||||
import LoggedView from '../View';
|
|
||||||
import KeyboardView from '../../presentation/KeyboardView';
|
import KeyboardView from '../../presentation/KeyboardView';
|
||||||
import sharedStyles from '../Styles';
|
import sharedStyles from '../Styles';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
@ -42,8 +41,7 @@ import { COLOR_TEXT } from '../../constants/colors';
|
||||||
}), dispatch => ({
|
}), dispatch => ({
|
||||||
setUser: params => dispatch(setUserAction(params))
|
setUser: params => dispatch(setUserAction(params))
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
export default class ProfileView extends React.Component {
|
||||||
export default class ProfileView extends LoggedView {
|
|
||||||
static navigationOptions = ({ navigation }) => ({
|
static navigationOptions = ({ navigation }) => ({
|
||||||
headerLeft: <DrawerButton navigation={navigation} />,
|
headerLeft: <DrawerButton navigation={navigation} />,
|
||||||
title: I18n.t('Profile')
|
title: I18n.t('Profile')
|
||||||
|
@ -56,9 +54,7 @@ export default class ProfileView extends LoggedView {
|
||||||
setUser: PropTypes.func
|
setUser: PropTypes.func
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
state = {
|
||||||
super('ProfileView', props);
|
|
||||||
this.state = {
|
|
||||||
showPasswordAlert: false,
|
showPasswordAlert: false,
|
||||||
saving: false,
|
saving: false,
|
||||||
name: null,
|
name: null,
|
||||||
|
@ -70,7 +66,6 @@ export default class ProfileView extends LoggedView {
|
||||||
avatar: {},
|
avatar: {},
|
||||||
avatarSuggestions: {},
|
avatarSuggestions: {},
|
||||||
customFields: {}
|
customFields: {}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
|
|
|
@ -11,7 +11,6 @@ import Button from '../containers/Button';
|
||||||
import KeyboardView from '../presentation/KeyboardView';
|
import KeyboardView from '../presentation/KeyboardView';
|
||||||
import sharedStyles from './Styles';
|
import sharedStyles from './Styles';
|
||||||
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
||||||
import LoggedView from './View';
|
|
||||||
import I18n from '../i18n';
|
import I18n from '../i18n';
|
||||||
import RocketChat from '../lib/rocketchat';
|
import RocketChat from '../lib/rocketchat';
|
||||||
import { loginRequest as loginRequestAction } from '../actions/login';
|
import { loginRequest as loginRequestAction } from '../actions/login';
|
||||||
|
@ -24,8 +23,7 @@ const shouldUpdateState = ['name', 'email', 'password', 'username', 'saving'];
|
||||||
@connect(null, dispatch => ({
|
@connect(null, dispatch => ({
|
||||||
loginRequest: params => dispatch(loginRequestAction(params))
|
loginRequest: params => dispatch(loginRequestAction(params))
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
export default class RegisterView extends React.Component {
|
||||||
export default class RegisterView extends LoggedView {
|
|
||||||
static navigationOptions = ({ navigation }) => {
|
static navigationOptions = ({ navigation }) => {
|
||||||
const title = navigation.getParam('title', 'Rocket.Chat');
|
const title = navigation.getParam('title', 'Rocket.Chat');
|
||||||
return {
|
return {
|
||||||
|
@ -40,15 +38,12 @@ export default class RegisterView extends LoggedView {
|
||||||
Site_Name: PropTypes.string
|
Site_Name: PropTypes.string
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
state = {
|
||||||
super('RegisterView', props);
|
|
||||||
this.state = {
|
|
||||||
name: '',
|
name: '',
|
||||||
email: '',
|
email: '',
|
||||||
password: '',
|
password: '',
|
||||||
username: '',
|
username: '',
|
||||||
saving: false
|
saving: false
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
|
|
@ -8,7 +8,6 @@ import { SafeAreaView } from 'react-navigation';
|
||||||
import equal from 'deep-equal';
|
import equal from 'deep-equal';
|
||||||
|
|
||||||
import { leaveRoom as leaveRoomAction } from '../../actions/room';
|
import { leaveRoom as leaveRoomAction } from '../../actions/room';
|
||||||
import LoggedView from '../View';
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import sharedStyles from '../Styles';
|
import sharedStyles from '../Styles';
|
||||||
import Avatar from '../../containers/Avatar';
|
import Avatar from '../../containers/Avatar';
|
||||||
|
@ -36,8 +35,7 @@ const renderSeparator = () => <View style={styles.separator} />;
|
||||||
}), dispatch => ({
|
}), dispatch => ({
|
||||||
leaveRoom: (rid, t) => dispatch(leaveRoomAction(rid, t))
|
leaveRoom: (rid, t) => dispatch(leaveRoomAction(rid, t))
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
export default class RoomActionsView extends React.Component {
|
||||||
export default class RoomActionsView extends LoggedView {
|
|
||||||
static navigationOptions = {
|
static navigationOptions = {
|
||||||
title: I18n.t('Actions')
|
title: I18n.t('Actions')
|
||||||
}
|
}
|
||||||
|
@ -53,7 +51,7 @@ export default class RoomActionsView extends LoggedView {
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super('RoomActionsView', props);
|
super(props);
|
||||||
this.rid = props.navigation.getParam('rid');
|
this.rid = props.navigation.getParam('rid');
|
||||||
this.t = props.navigation.getParam('t');
|
this.t = props.navigation.getParam('t');
|
||||||
this.rooms = database.objects('subscriptions').filtered('rid = $0', this.rid);
|
this.rooms = database.objects('subscriptions').filtered('rid = $0', this.rid);
|
||||||
|
|
|
@ -8,7 +8,6 @@ import { SafeAreaView } from 'react-navigation';
|
||||||
import equal from 'deep-equal';
|
import equal from 'deep-equal';
|
||||||
|
|
||||||
import { eraseRoom as eraseRoomAction } from '../../actions/room';
|
import { eraseRoom as eraseRoomAction } from '../../actions/room';
|
||||||
import LoggedView from '../View';
|
|
||||||
import KeyboardView from '../../presentation/KeyboardView';
|
import KeyboardView from '../../presentation/KeyboardView';
|
||||||
import sharedStyles from '../Styles';
|
import sharedStyles from '../Styles';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
@ -42,8 +41,7 @@ const PERMISSIONS_ARRAY = [
|
||||||
@connect(null, dispatch => ({
|
@connect(null, dispatch => ({
|
||||||
eraseRoom: (rid, t) => dispatch(eraseRoomAction(rid, t))
|
eraseRoom: (rid, t) => dispatch(eraseRoomAction(rid, t))
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
export default class RoomInfoEditView extends React.Component {
|
||||||
export default class RoomInfoEditView extends LoggedView {
|
|
||||||
static navigationOptions = {
|
static navigationOptions = {
|
||||||
title: I18n.t('Room_Info_Edit')
|
title: I18n.t('Room_Info_Edit')
|
||||||
}
|
}
|
||||||
|
@ -54,7 +52,7 @@ export default class RoomInfoEditView extends LoggedView {
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super('RoomInfoEditView', props);
|
super(props);
|
||||||
const rid = props.navigation.getParam('rid');
|
const rid = props.navigation.getParam('rid');
|
||||||
this.rooms = database.objects('subscriptions').filtered('rid = $0', rid);
|
this.rooms = database.objects('subscriptions').filtered('rid = $0', rid);
|
||||||
this.permissions = {};
|
this.permissions = {};
|
||||||
|
|
|
@ -5,7 +5,6 @@ import { connect } from 'react-redux';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { SafeAreaView } from 'react-navigation';
|
import { SafeAreaView } from 'react-navigation';
|
||||||
|
|
||||||
import LoggedView from '../View';
|
|
||||||
import Status from '../../containers/Status';
|
import Status from '../../containers/Status';
|
||||||
import Avatar from '../../containers/Avatar';
|
import Avatar from '../../containers/Avatar';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
@ -39,8 +38,7 @@ const getRoomTitle = room => (room.t === 'd'
|
||||||
},
|
},
|
||||||
Message_TimeFormat: state.settings.Message_TimeFormat
|
Message_TimeFormat: state.settings.Message_TimeFormat
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
export default class RoomInfoView extends React.Component {
|
||||||
export default class RoomInfoView extends LoggedView {
|
|
||||||
static navigationOptions = ({ navigation }) => {
|
static navigationOptions = ({ navigation }) => {
|
||||||
const showEdit = navigation.getParam('showEdit');
|
const showEdit = navigation.getParam('showEdit');
|
||||||
const rid = navigation.getParam('rid');
|
const rid = navigation.getParam('rid');
|
||||||
|
@ -67,7 +65,7 @@ export default class RoomInfoView extends LoggedView {
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super('RoomInfoView', props);
|
super(props);
|
||||||
this.rid = props.navigation.getParam('rid');
|
this.rid = props.navigation.getParam('rid');
|
||||||
const room = props.navigation.getParam('room');
|
const room = props.navigation.getParam('room');
|
||||||
this.t = props.navigation.getParam('t');
|
this.t = props.navigation.getParam('t');
|
||||||
|
|
|
@ -6,7 +6,6 @@ import { connect } from 'react-redux';
|
||||||
import { SafeAreaView } from 'react-navigation';
|
import { SafeAreaView } from 'react-navigation';
|
||||||
import equal from 'deep-equal';
|
import equal from 'deep-equal';
|
||||||
|
|
||||||
import LoggedView from '../View';
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import UserItem from '../../presentation/UserItem';
|
import UserItem from '../../presentation/UserItem';
|
||||||
import scrollPersistTaps from '../../utils/scrollPersistTaps';
|
import scrollPersistTaps from '../../utils/scrollPersistTaps';
|
||||||
|
@ -30,8 +29,7 @@ const PAGE_SIZE = 25;
|
||||||
token: state.login.user && state.login.user.token
|
token: state.login.user && state.login.user.token
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
export default class RoomMembersView extends React.Component {
|
||||||
export default class RoomMembersView extends LoggedView {
|
|
||||||
static navigationOptions = ({ navigation }) => {
|
static navigationOptions = ({ navigation }) => {
|
||||||
const toggleStatus = navigation.getParam('toggleStatus', () => {});
|
const toggleStatus = navigation.getParam('toggleStatus', () => {});
|
||||||
const allUsers = navigation.getParam('allUsers');
|
const allUsers = navigation.getParam('allUsers');
|
||||||
|
@ -59,7 +57,7 @@ export default class RoomMembersView extends LoggedView {
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super('MentionedMessagesView', props);
|
super(props);
|
||||||
|
|
||||||
this.CANCEL_INDEX = 0;
|
this.CANCEL_INDEX = 0;
|
||||||
this.MUTE_INDEX = 1;
|
this.MUTE_INDEX = 1;
|
||||||
|
|
|
@ -18,7 +18,6 @@ import {
|
||||||
replyCancel as replyCancelAction,
|
replyCancel as replyCancelAction,
|
||||||
replyBroadcast as replyBroadcastAction
|
replyBroadcast as replyBroadcastAction
|
||||||
} from '../../actions/messages';
|
} from '../../actions/messages';
|
||||||
import LoggedView from '../View';
|
|
||||||
import { List } from './List';
|
import { List } from './List';
|
||||||
import database, { safeAddListener } from '../../lib/realm';
|
import database, { safeAddListener } from '../../lib/realm';
|
||||||
import RocketChat from '../../lib/rocketchat';
|
import RocketChat from '../../lib/rocketchat';
|
||||||
|
@ -70,8 +69,7 @@ import { Toast } from '../../utils/info';
|
||||||
actionsShow: actionMessage => dispatch(actionsShowAction(actionMessage)),
|
actionsShow: actionMessage => dispatch(actionsShowAction(actionMessage)),
|
||||||
replyBroadcast: message => dispatch(replyBroadcastAction(message))
|
replyBroadcast: message => dispatch(replyBroadcastAction(message))
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
export default class RoomView extends React.Component {
|
||||||
export default class RoomView extends LoggedView {
|
|
||||||
static navigationOptions = ({ navigation }) => {
|
static navigationOptions = ({ navigation }) => {
|
||||||
const rid = navigation.getParam('rid');
|
const rid = navigation.getParam('rid');
|
||||||
const prid = navigation.getParam('prid');
|
const prid = navigation.getParam('prid');
|
||||||
|
@ -131,7 +129,7 @@ export default class RoomView extends LoggedView {
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super('RoomView', props);
|
super(props);
|
||||||
console.time(`${ this.constructor.name } init`);
|
console.time(`${ this.constructor.name } init`);
|
||||||
console.time(`${ this.constructor.name } mount`);
|
console.time(`${ this.constructor.name } mount`);
|
||||||
this.rid = props.navigation.getParam('rid');
|
this.rid = props.navigation.getParam('rid');
|
||||||
|
|
|
@ -12,7 +12,6 @@ import database, { safeAddListener } from '../../lib/realm';
|
||||||
import RocketChat from '../../lib/rocketchat';
|
import RocketChat from '../../lib/rocketchat';
|
||||||
import RoomItem, { ROW_HEIGHT } from '../../presentation/RoomItem';
|
import RoomItem, { ROW_HEIGHT } from '../../presentation/RoomItem';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import LoggedView from '../View';
|
|
||||||
import log from '../../utils/log';
|
import log from '../../utils/log';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import SortDropdown from './SortDropdown';
|
import SortDropdown from './SortDropdown';
|
||||||
|
@ -59,8 +58,7 @@ const keyExtractor = item => item.rid;
|
||||||
appStart: () => dispatch(appStartAction())
|
appStart: () => dispatch(appStartAction())
|
||||||
// roomsRequest: () => dispatch(roomsRequestAction())
|
// roomsRequest: () => dispatch(roomsRequestAction())
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
export default class RoomsListView extends React.Component {
|
||||||
export default class RoomsListView extends LoggedView {
|
|
||||||
static navigationOptions = ({ navigation }) => {
|
static navigationOptions = ({ navigation }) => {
|
||||||
const searching = navigation.getParam('searching');
|
const searching = navigation.getParam('searching');
|
||||||
const cancelSearchingAndroid = navigation.getParam('cancelSearchingAndroid');
|
const cancelSearchingAndroid = navigation.getParam('cancelSearchingAndroid');
|
||||||
|
@ -115,7 +113,7 @@ export default class RoomsListView extends LoggedView {
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super('RoomsListView', props);
|
super(props);
|
||||||
console.time(`${ this.constructor.name } init`);
|
console.time(`${ this.constructor.name } init`);
|
||||||
console.time(`${ this.constructor.name } mount`);
|
console.time(`${ this.constructor.name } mount`);
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ import { connect } from 'react-redux';
|
||||||
import { SafeAreaView } from 'react-navigation';
|
import { SafeAreaView } from 'react-navigation';
|
||||||
import equal from 'deep-equal';
|
import equal from 'deep-equal';
|
||||||
|
|
||||||
import LoggedView from '../View';
|
|
||||||
import RCTextInput from '../../containers/TextInput';
|
import RCTextInput from '../../containers/TextInput';
|
||||||
import RCActivityIndicator from '../../containers/ActivityIndicator';
|
import RCActivityIndicator from '../../containers/ActivityIndicator';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
@ -25,8 +24,7 @@ import StatusBar from '../../containers/StatusBar';
|
||||||
token: state.login.user && state.login.user.token
|
token: state.login.user && state.login.user.token
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
export default class SearchMessagesView extends React.Component {
|
||||||
export default class SearchMessagesView extends LoggedView {
|
|
||||||
static navigationOptions = {
|
static navigationOptions = {
|
||||||
title: I18n.t('Search')
|
title: I18n.t('Search')
|
||||||
}
|
}
|
||||||
|
@ -38,7 +36,7 @@ export default class SearchMessagesView extends LoggedView {
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super('SearchMessagesView', props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
loading: false,
|
loading: false,
|
||||||
messages: [],
|
messages: [],
|
||||||
|
|
|
@ -15,7 +15,6 @@ import RocketChat from '../lib/rocketchat';
|
||||||
import UserItem from '../presentation/UserItem';
|
import UserItem from '../presentation/UserItem';
|
||||||
import Loading from '../containers/Loading';
|
import Loading from '../containers/Loading';
|
||||||
import debounce from '../utils/debounce';
|
import debounce from '../utils/debounce';
|
||||||
import LoggedView from './View';
|
|
||||||
import I18n from '../i18n';
|
import I18n from '../i18n';
|
||||||
import log from '../utils/log';
|
import log from '../utils/log';
|
||||||
import { isIOS } from '../utils/deviceInfo';
|
import { isIOS } from '../utils/deviceInfo';
|
||||||
|
@ -52,8 +51,7 @@ const styles = StyleSheet.create({
|
||||||
reset: () => dispatch(resetAction()),
|
reset: () => dispatch(resetAction()),
|
||||||
setLoadingInvite: loading => dispatch(setLoadingAction(loading))
|
setLoadingInvite: loading => dispatch(setLoadingAction(loading))
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
export default class SelectedUsersView extends React.Component {
|
||||||
export default class SelectedUsersView extends LoggedView {
|
|
||||||
static navigationOptions = ({ navigation }) => {
|
static navigationOptions = ({ navigation }) => {
|
||||||
const title = navigation.getParam('title');
|
const title = navigation.getParam('title');
|
||||||
const nextAction = navigation.getParam('nextAction', () => {});
|
const nextAction = navigation.getParam('nextAction', () => {});
|
||||||
|
@ -83,7 +81,7 @@ export default class SelectedUsersView extends LoggedView {
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super('SelectedUsersView', props);
|
super(props);
|
||||||
this.data = database.objects('subscriptions').filtered('t = $0', 'd').sorted('roomUpdatedAt', true);
|
this.data = database.objects('subscriptions').filtered('t = $0', 'd').sorted('roomUpdatedAt', true);
|
||||||
this.state = {
|
this.state = {
|
||||||
search: []
|
search: []
|
||||||
|
|
|
@ -13,7 +13,6 @@ import Button from '../containers/Button';
|
||||||
import KeyboardView from '../presentation/KeyboardView';
|
import KeyboardView from '../presentation/KeyboardView';
|
||||||
import sharedStyles from './Styles';
|
import sharedStyles from './Styles';
|
||||||
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
import scrollPersistTaps from '../utils/scrollPersistTaps';
|
||||||
import LoggedView from './View';
|
|
||||||
import I18n from '../i18n';
|
import I18n from '../i18n';
|
||||||
import RocketChat from '../lib/rocketchat';
|
import RocketChat from '../lib/rocketchat';
|
||||||
import StatusBar from '../containers/StatusBar';
|
import StatusBar from '../containers/StatusBar';
|
||||||
|
@ -31,8 +30,7 @@ const styles = StyleSheet.create({
|
||||||
}), dispatch => ({
|
}), dispatch => ({
|
||||||
loginRequest: params => dispatch(loginRequestAction(params))
|
loginRequest: params => dispatch(loginRequestAction(params))
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
export default class SetUsernameView extends React.Component {
|
||||||
export default class SetUsernameView extends LoggedView {
|
|
||||||
static navigationOptions = ({ navigation }) => {
|
static navigationOptions = ({ navigation }) => {
|
||||||
const title = navigation.getParam('title');
|
const title = navigation.getParam('title');
|
||||||
return {
|
return {
|
||||||
|
@ -49,7 +47,7 @@ export default class SetUsernameView extends LoggedView {
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super('SetUsernameView', props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
username: '',
|
username: '',
|
||||||
saving: false
|
saving: false
|
||||||
|
|
|
@ -6,9 +6,8 @@ import {
|
||||||
import RNPickerSelect from 'react-native-picker-select';
|
import RNPickerSelect from 'react-native-picker-select';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { SafeAreaView } from 'react-navigation';
|
import { SafeAreaView } from 'react-navigation';
|
||||||
import { Answers } from 'react-native-fabric';
|
import firebase from 'react-native-firebase';
|
||||||
|
|
||||||
import LoggedView from '../View';
|
|
||||||
import RocketChat, { MARKDOWN_KEY } from '../../lib/rocketchat';
|
import RocketChat, { MARKDOWN_KEY } from '../../lib/rocketchat';
|
||||||
import KeyboardView from '../../presentation/KeyboardView';
|
import KeyboardView from '../../presentation/KeyboardView';
|
||||||
import sharedStyles from '../Styles';
|
import sharedStyles from '../Styles';
|
||||||
|
@ -56,8 +55,7 @@ const styles = StyleSheet.create({
|
||||||
setUser: params => dispatch(setUserAction(params)),
|
setUser: params => dispatch(setUserAction(params)),
|
||||||
toggleMarkdown: params => dispatch(toggleMarkdownAction(params))
|
toggleMarkdown: params => dispatch(toggleMarkdownAction(params))
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
export default class SettingsView extends React.Component {
|
||||||
export default class SettingsView extends LoggedView {
|
|
||||||
static navigationOptions = ({ navigation }) => ({
|
static navigationOptions = ({ navigation }) => ({
|
||||||
headerLeft: <DrawerButton navigation={navigation} />,
|
headerLeft: <DrawerButton navigation={navigation} />,
|
||||||
title: I18n.t('Settings')
|
title: I18n.t('Settings')
|
||||||
|
@ -72,7 +70,7 @@ export default class SettingsView extends LoggedView {
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super('SettingsView', props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
placeholder: {},
|
placeholder: {},
|
||||||
language: props.userLanguage ? props.userLanguage : 'en',
|
language: props.userLanguage ? props.userLanguage : 'en',
|
||||||
|
@ -173,7 +171,7 @@ export default class SettingsView extends LoggedView {
|
||||||
AsyncStorage.setItem(MARKDOWN_KEY, JSON.stringify(value));
|
AsyncStorage.setItem(MARKDOWN_KEY, JSON.stringify(value));
|
||||||
const { toggleMarkdown } = this.props;
|
const { toggleMarkdown } = this.props;
|
||||||
toggleMarkdown(value);
|
toggleMarkdown(value);
|
||||||
Answers.logCustom('toggle_markdown', { value });
|
firebase.analytics().logEvent('toggle_markdown', { value });
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -7,7 +7,6 @@ import { connect } from 'react-redux';
|
||||||
import { SafeAreaView } from 'react-navigation';
|
import { SafeAreaView } from 'react-navigation';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
|
||||||
import LoggedView from '../View';
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import Message from '../../containers/message';
|
import Message from '../../containers/message';
|
||||||
import RCActivityIndicator from '../../containers/ActivityIndicator';
|
import RCActivityIndicator from '../../containers/ActivityIndicator';
|
||||||
|
@ -31,8 +30,7 @@ const API_FETCH_COUNT = 50;
|
||||||
},
|
},
|
||||||
useRealName: state.settings.UI_Use_Real_Name
|
useRealName: state.settings.UI_Use_Real_Name
|
||||||
}))
|
}))
|
||||||
/** @extends React.Component */
|
export default class ThreadMessagesView extends React.Component {
|
||||||
export default class ThreadMessagesView extends LoggedView {
|
|
||||||
static navigationOptions = {
|
static navigationOptions = {
|
||||||
title: I18n.t('Threads')
|
title: I18n.t('Threads')
|
||||||
}
|
}
|
||||||
|
@ -45,7 +43,7 @@ export default class ThreadMessagesView extends LoggedView {
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super('ThreadMessagesView', props);
|
super(props);
|
||||||
this.rid = props.navigation.getParam('rid');
|
this.rid = props.navigation.getParam('rid');
|
||||||
this.t = props.navigation.getParam('t');
|
this.t = props.navigation.getParam('t');
|
||||||
this.rooms = database.objects('subscriptions').filtered('rid = $0', this.rid);
|
this.rooms = database.objects('subscriptions').filtered('rid = $0', this.rid);
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { Answers } from 'react-native-fabric';
|
|
||||||
|
|
||||||
/** @extends React.Component */
|
|
||||||
export default class extends React.Component {
|
|
||||||
constructor(name, props) {
|
|
||||||
super(props);
|
|
||||||
Answers.logContentView(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidCatch = (error, info) => {
|
|
||||||
Answers.logCustom(error, info);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -34,6 +34,7 @@ describe('Forgot password screen', () => {
|
||||||
it('should reset password and navigate to login', async() => {
|
it('should reset password and navigate to login', async() => {
|
||||||
await element(by.id('forgot-password-view-email')).replaceText('diego.mello@rocket.chat');
|
await element(by.id('forgot-password-view-email')).replaceText('diego.mello@rocket.chat');
|
||||||
await element(by.id('forgot-password-view-submit')).tap();
|
await element(by.id('forgot-password-view-submit')).tap();
|
||||||
|
await element(by.text('OK')).tap();
|
||||||
await waitFor(element(by.id('login-view'))).toBeVisible().withTimeout(60000);
|
await waitFor(element(by.id('login-view'))).toBeVisible().withTimeout(60000);
|
||||||
await expect(element(by.id('login-view'))).toBeVisible();
|
await expect(element(by.id('login-view'))).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
|
@ -52,7 +52,9 @@ describe('Room screen', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have open emoji button', async() => {
|
it('should have open emoji button', async() => {
|
||||||
|
if (device.getPlatform() === 'android') {
|
||||||
await expect(element(by.id('messagebox-open-emoji'))).toBeVisible();
|
await expect(element(by.id('messagebox-open-emoji'))).toBeVisible();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have message input', async() => {
|
it('should have message input', async() => {
|
||||||
|
@ -98,6 +100,7 @@ describe('Room screen', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show/hide emoji keyboard', async () => {
|
it('should show/hide emoji keyboard', async () => {
|
||||||
|
if (device.getPlatform() === 'android') {
|
||||||
await element(by.id('messagebox-open-emoji')).tap();
|
await element(by.id('messagebox-open-emoji')).tap();
|
||||||
await waitFor(element(by.id('messagebox-keyboard-emoji'))).toBeVisible().withTimeout(10000);
|
await waitFor(element(by.id('messagebox-keyboard-emoji'))).toBeVisible().withTimeout(10000);
|
||||||
await expect(element(by.id('messagebox-keyboard-emoji'))).toBeVisible();
|
await expect(element(by.id('messagebox-keyboard-emoji'))).toBeVisible();
|
||||||
|
@ -108,6 +111,7 @@ describe('Room screen', () => {
|
||||||
await expect(element(by.id('messagebox-keyboard-emoji'))).toBeNotVisible();
|
await expect(element(by.id('messagebox-keyboard-emoji'))).toBeNotVisible();
|
||||||
await expect(element(by.id('messagebox-close-emoji'))).toBeNotVisible();
|
await expect(element(by.id('messagebox-close-emoji'))).toBeNotVisible();
|
||||||
await expect(element(by.id('messagebox-open-emoji'))).toBeVisible();
|
await expect(element(by.id('messagebox-open-emoji'))).toBeVisible();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show/hide emoji autocomplete', async() => {
|
it('should show/hide emoji autocomplete', async() => {
|
||||||
|
|
|
@ -140,6 +140,9 @@ describe('Join public room', () => {
|
||||||
describe('Usage', async() => {
|
describe('Usage', async() => {
|
||||||
it('should join room', async() => {
|
it('should join room', async() => {
|
||||||
await element(by.id('room-view-join-button')).tap();
|
await element(by.id('room-view-join-button')).tap();
|
||||||
|
await tapBack();
|
||||||
|
await element(by.id(`rooms-list-view-item-${ room }`)).tap();
|
||||||
|
await waitFor(element(by.id('room-view'))).toBeVisible().withTimeout(5000);
|
||||||
await waitFor(element(by.id('messagebox'))).toBeVisible().withTimeout(60000);
|
await waitFor(element(by.id('messagebox'))).toBeVisible().withTimeout(60000);
|
||||||
await expect(element(by.id('messagebox'))).toBeVisible();
|
await expect(element(by.id('messagebox'))).toBeVisible();
|
||||||
await expect(element(by.id('room-view-join'))).toBeNotVisible();
|
await expect(element(by.id('room-view-join'))).toBeNotVisible();
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?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>CLIENT_ID</key>
|
||||||
|
<string>673693445664-jbf9m30ta163gobjfp0v7j1v7kpo7kmv.apps.googleusercontent.com</string>
|
||||||
|
<key>REVERSED_CLIENT_ID</key>
|
||||||
|
<string>com.googleusercontent.apps.673693445664-jbf9m30ta163gobjfp0v7j1v7kpo7kmv</string>
|
||||||
|
<key>ANDROID_CLIENT_ID</key>
|
||||||
|
<string>673693445664-k0mvosdjoe5dbvqce3b377ckabb5dgu8.apps.googleusercontent.com</string>
|
||||||
|
<key>API_KEY</key>
|
||||||
|
<string>AIzaSyDL4sXxk8DeGYzacSib0GDQ3BoGACP0VDM</string>
|
||||||
|
<key>GCM_SENDER_ID</key>
|
||||||
|
<string>673693445664</string>
|
||||||
|
<key>PLIST_VERSION</key>
|
||||||
|
<string>1</string>
|
||||||
|
<key>BUNDLE_ID</key>
|
||||||
|
<string>chat.rocket.reactnative</string>
|
||||||
|
<key>PROJECT_ID</key>
|
||||||
|
<string>rocketchat-9e9be</string>
|
||||||
|
<key>STORAGE_BUCKET</key>
|
||||||
|
<string>rocketchat-9e9be.appspot.com</string>
|
||||||
|
<key>IS_ADS_ENABLED</key>
|
||||||
|
<false></false>
|
||||||
|
<key>IS_ANALYTICS_ENABLED</key>
|
||||||
|
<false></false>
|
||||||
|
<key>IS_APPINVITE_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>IS_GCM_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>IS_SIGNIN_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>GOOGLE_APP_ID</key>
|
||||||
|
<string>1:673693445664:ios:8be27b1f7c42a2ed</string>
|
||||||
|
<key>DATABASE_URL</key>
|
||||||
|
<string>https://rocketchat-9e9be.firebaseio.com</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -38,6 +38,12 @@ target 'RocketChatRN' do
|
||||||
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
|
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
|
||||||
pod 'react-native-webview', :path => '../node_modules/react-native-webview'
|
pod 'react-native-webview', :path => '../node_modules/react-native-webview'
|
||||||
|
|
||||||
|
pod 'Firebase/Core', '~> 5.20.1'
|
||||||
|
pod 'Fabric', '~> 1.9.0'
|
||||||
|
pod 'Crashlytics', '~> 3.12.0'
|
||||||
|
pod 'GoogleIDFASupport', '~> 3.14.0'
|
||||||
|
pod 'Firebase/Performance', '~> 5.20.1'
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
post_install do |installer|
|
post_install do |installer|
|
||||||
|
|
125
ios/Podfile.lock
125
ios/Podfile.lock
|
@ -1,11 +1,97 @@
|
||||||
PODS:
|
PODS:
|
||||||
- boost-for-react-native (1.63.0)
|
- boost-for-react-native (1.63.0)
|
||||||
|
- Crashlytics (3.12.0):
|
||||||
|
- Fabric (~> 1.9.0)
|
||||||
- DoubleConversion (1.1.6)
|
- DoubleConversion (1.1.6)
|
||||||
|
- Fabric (1.9.0)
|
||||||
|
- Firebase/Core (5.20.2):
|
||||||
|
- Firebase/CoreOnly
|
||||||
|
- FirebaseAnalytics (= 5.8.1)
|
||||||
|
- Firebase/CoreOnly (5.20.2):
|
||||||
|
- FirebaseCore (= 5.4.1)
|
||||||
|
- Firebase/Performance (5.20.2):
|
||||||
|
- Firebase/Core
|
||||||
|
- FirebasePerformance (= 2.2.4)
|
||||||
|
- FirebaseABTesting (2.0.0):
|
||||||
|
- FirebaseCore (~> 5.0)
|
||||||
|
- Protobuf (~> 3.5)
|
||||||
|
- FirebaseAnalytics (5.8.1):
|
||||||
|
- FirebaseCore (~> 5.4)
|
||||||
|
- FirebaseInstanceID (~> 3.8)
|
||||||
|
- GoogleAppMeasurement (= 5.8.1)
|
||||||
|
- GoogleUtilities/AppDelegateSwizzler (~> 5.2)
|
||||||
|
- GoogleUtilities/MethodSwizzler (~> 5.2)
|
||||||
|
- GoogleUtilities/Network (~> 5.2)
|
||||||
|
- "GoogleUtilities/NSData+zlib (~> 5.2)"
|
||||||
|
- nanopb (~> 0.3)
|
||||||
|
- FirebaseCore (5.4.1):
|
||||||
|
- GoogleUtilities/Environment (~> 5.2)
|
||||||
|
- GoogleUtilities/Logger (~> 5.2)
|
||||||
|
- FirebaseInstanceID (3.8.1):
|
||||||
|
- FirebaseCore (~> 5.2)
|
||||||
|
- GoogleUtilities/Environment (~> 5.2)
|
||||||
|
- GoogleUtilities/UserDefaults (~> 5.2)
|
||||||
|
- FirebasePerformance (2.2.4):
|
||||||
|
- FirebaseAnalytics (~> 5.8)
|
||||||
|
- FirebaseInstanceID (~> 3.8)
|
||||||
|
- FirebaseRemoteConfig (~> 3.1)
|
||||||
|
- GoogleToolboxForMac/Logger (~> 2.1)
|
||||||
|
- "GoogleToolboxForMac/NSData+zlib (~> 2.1)"
|
||||||
|
- GoogleUtilities/ISASwizzler (~> 5.2)
|
||||||
|
- GoogleUtilities/MethodSwizzler (~> 5.2)
|
||||||
|
- GTMSessionFetcher/Core (~> 1.1)
|
||||||
|
- Protobuf (~> 3.5)
|
||||||
|
- FirebaseRemoteConfig (3.1.0):
|
||||||
|
- FirebaseABTesting (~> 2.0)
|
||||||
|
- FirebaseAnalytics (~> 5.3)
|
||||||
|
- FirebaseCore (~> 5.1)
|
||||||
|
- FirebaseInstanceID (~> 3.3)
|
||||||
|
- GoogleUtilities/Environment (~> 5.2)
|
||||||
|
- "GoogleUtilities/NSData+zlib (~> 5.2)"
|
||||||
|
- Protobuf (~> 3.5)
|
||||||
- Folly (2018.10.22.00):
|
- Folly (2018.10.22.00):
|
||||||
- boost-for-react-native
|
- boost-for-react-native
|
||||||
- DoubleConversion
|
- DoubleConversion
|
||||||
- glog
|
- glog
|
||||||
- glog (0.3.5)
|
- glog (0.3.5)
|
||||||
|
- GoogleAppMeasurement (5.8.1):
|
||||||
|
- GoogleUtilities/AppDelegateSwizzler (~> 5.2)
|
||||||
|
- GoogleUtilities/MethodSwizzler (~> 5.2)
|
||||||
|
- GoogleUtilities/Network (~> 5.2)
|
||||||
|
- "GoogleUtilities/NSData+zlib (~> 5.2)"
|
||||||
|
- nanopb (~> 0.3)
|
||||||
|
- GoogleIDFASupport (3.14.0)
|
||||||
|
- GoogleToolboxForMac/Defines (2.2.1)
|
||||||
|
- GoogleToolboxForMac/Logger (2.2.1):
|
||||||
|
- GoogleToolboxForMac/Defines (= 2.2.1)
|
||||||
|
- "GoogleToolboxForMac/NSData+zlib (2.2.1)":
|
||||||
|
- GoogleToolboxForMac/Defines (= 2.2.1)
|
||||||
|
- GoogleUtilities/AppDelegateSwizzler (5.8.0):
|
||||||
|
- GoogleUtilities/Environment
|
||||||
|
- GoogleUtilities/Logger
|
||||||
|
- GoogleUtilities/Network
|
||||||
|
- GoogleUtilities/Environment (5.8.0)
|
||||||
|
- GoogleUtilities/ISASwizzler (5.8.0)
|
||||||
|
- GoogleUtilities/Logger (5.8.0):
|
||||||
|
- GoogleUtilities/Environment
|
||||||
|
- GoogleUtilities/MethodSwizzler (5.8.0):
|
||||||
|
- GoogleUtilities/Logger
|
||||||
|
- GoogleUtilities/Network (5.8.0):
|
||||||
|
- GoogleUtilities/Logger
|
||||||
|
- "GoogleUtilities/NSData+zlib"
|
||||||
|
- GoogleUtilities/Reachability
|
||||||
|
- "GoogleUtilities/NSData+zlib (5.8.0)"
|
||||||
|
- GoogleUtilities/Reachability (5.8.0):
|
||||||
|
- GoogleUtilities/Logger
|
||||||
|
- GoogleUtilities/UserDefaults (5.8.0):
|
||||||
|
- GoogleUtilities/Logger
|
||||||
|
- GTMSessionFetcher/Core (1.2.2)
|
||||||
|
- nanopb (0.3.901):
|
||||||
|
- nanopb/decode (= 0.3.901)
|
||||||
|
- nanopb/encode (= 0.3.901)
|
||||||
|
- nanopb/decode (0.3.901)
|
||||||
|
- nanopb/encode (0.3.901)
|
||||||
|
- Protobuf (3.7.0)
|
||||||
- QBImagePickerController (3.4.0)
|
- QBImagePickerController (3.4.0)
|
||||||
- React (0.59.8):
|
- React (0.59.8):
|
||||||
- React/Core (= 0.59.8)
|
- React/Core (= 0.59.8)
|
||||||
|
@ -53,9 +139,14 @@ PODS:
|
||||||
- yoga (0.59.8.React)
|
- yoga (0.59.8.React)
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
|
- Crashlytics (~> 3.12.0)
|
||||||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||||
|
- Fabric (~> 1.9.0)
|
||||||
|
- Firebase/Core (~> 5.20.1)
|
||||||
|
- Firebase/Performance (~> 5.20.1)
|
||||||
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
|
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
|
||||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||||
|
- GoogleIDFASupport (~> 3.14.0)
|
||||||
- react-native-orientation-locker (from `../node_modules/react-native-orientation-locker`)
|
- react-native-orientation-locker (from `../node_modules/react-native-orientation-locker`)
|
||||||
- react-native-splash-screen (from `../node_modules/react-native-splash-screen`)
|
- react-native-splash-screen (from `../node_modules/react-native-splash-screen`)
|
||||||
- react-native-webview (from `../node_modules/react-native-webview`)
|
- react-native-webview (from `../node_modules/react-native-webview`)
|
||||||
|
@ -77,6 +168,22 @@ DEPENDENCIES:
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
https://github.com/cocoapods/specs.git:
|
https://github.com/cocoapods/specs.git:
|
||||||
- boost-for-react-native
|
- boost-for-react-native
|
||||||
|
- Crashlytics
|
||||||
|
- Fabric
|
||||||
|
- Firebase
|
||||||
|
- FirebaseABTesting
|
||||||
|
- FirebaseAnalytics
|
||||||
|
- FirebaseCore
|
||||||
|
- FirebaseInstanceID
|
||||||
|
- FirebasePerformance
|
||||||
|
- FirebaseRemoteConfig
|
||||||
|
- GoogleAppMeasurement
|
||||||
|
- GoogleIDFASupport
|
||||||
|
- GoogleToolboxForMac
|
||||||
|
- GoogleUtilities
|
||||||
|
- GTMSessionFetcher
|
||||||
|
- nanopb
|
||||||
|
- Protobuf
|
||||||
- QBImagePickerController
|
- QBImagePickerController
|
||||||
- RSKImageCropper
|
- RSKImageCropper
|
||||||
|
|
||||||
|
@ -106,9 +213,25 @@ EXTERNAL SOURCES:
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
||||||
|
Crashlytics: 07fb167b1694128c1c9a5a5cc319b0e9c3ca0933
|
||||||
DoubleConversion: bb338842f62ab1d708ceb63ec3d999f0f3d98ecd
|
DoubleConversion: bb338842f62ab1d708ceb63ec3d999f0f3d98ecd
|
||||||
|
Fabric: f988e33c97f08930a413e08123064d2e5f68d655
|
||||||
|
Firebase: 0c8cf33f266410c61ab3e2265cfa412200351d9c
|
||||||
|
FirebaseABTesting: 1f50b8d50f5e3469eea54e7463a7b7fe221d1f5e
|
||||||
|
FirebaseAnalytics: ece1aa57a4f43c64d53a648b5a5e05151aae947b
|
||||||
|
FirebaseCore: f1a9a8be1aee4bf71a2fc0f4096df6788bdfda61
|
||||||
|
FirebaseInstanceID: a122b0c258720cf250551bb2bedf48c699f80d90
|
||||||
|
FirebasePerformance: 25ecee2a260bcf398d7f32d6f4804438df953100
|
||||||
|
FirebaseRemoteConfig: 7e11c65f0769c09bff6947997c209515058c5318
|
||||||
Folly: de497beb10f102453a1afa9edbf8cf8a251890de
|
Folly: de497beb10f102453a1afa9edbf8cf8a251890de
|
||||||
glog: aefd1eb5dda2ab95ba0938556f34b98e2da3a60d
|
glog: aefd1eb5dda2ab95ba0938556f34b98e2da3a60d
|
||||||
|
GoogleAppMeasurement: ffe513e90551844a739e7bcbb1d2aca1c28a4338
|
||||||
|
GoogleIDFASupport: aaf8c10bd429abb1c15349d5252244f5eda8ead1
|
||||||
|
GoogleToolboxForMac: b3553629623a3b1bff17f555e736cd5a6d95ad55
|
||||||
|
GoogleUtilities: 04fce34bcd5620c1ee76fb79172105c74a4df335
|
||||||
|
GTMSessionFetcher: 61bb0f61a4cb560030f1222021178008a5727a23
|
||||||
|
nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48
|
||||||
|
Protobuf: 7a877b7f3e5964e3fce995e2eb323dbc6831bb5a
|
||||||
QBImagePickerController: d54cf93db6decf26baf6ed3472f336ef35cae022
|
QBImagePickerController: d54cf93db6decf26baf6ed3472f336ef35cae022
|
||||||
React: 76e6aa2b87d05eb6cccb6926d72685c9a07df152
|
React: 76e6aa2b87d05eb6cccb6926d72685c9a07df152
|
||||||
react-native-orientation-locker: 132a63bab4dddd2a5709f6f7935ad9676b0af7c5
|
react-native-orientation-locker: 132a63bab4dddd2a5709f6f7935ad9676b0af7c5
|
||||||
|
@ -120,6 +243,6 @@ SPEC CHECKSUMS:
|
||||||
RSKImageCropper: 98296ad26b41753f796b6898d015509598f13d97
|
RSKImageCropper: 98296ad26b41753f796b6898d015509598f13d97
|
||||||
yoga: 92b2102c3d373d1a790db4ab761d2b0ffc634f64
|
yoga: 92b2102c3d373d1a790db4ab761d2b0ffc634f64
|
||||||
|
|
||||||
PODFILE CHECKSUM: 644d63bf56349cf8faaa9d1acf44cfc7ee647f3b
|
PODFILE CHECKSUM: f98adf896db83acfddda2f17bf015d55d15a89f2
|
||||||
|
|
||||||
COCOAPODS: 1.6.2
|
COCOAPODS: 1.6.2
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
We've now combined all our supported platforms into a single podspec. As a result, we moved our submit script to a new location for Cocoapods projects: ${PODS_ROOT}/Crashlytics/submit. To avoid breaking functionality that references the old location of the submit, we've placed this dummy script that calls to the correct location, while providing a helpful warning if it is invoked. This bridge for backwards compatibility will be removed in a future release, so please heed the warning!
|
|
@ -0,0 +1,6 @@
|
||||||
|
if [[ -z $PODS_ROOT ]]; then
|
||||||
|
echo "error: The submit binary delivered by cocoapods is in a new location, under '$"{"PODS_ROOT"}"/Crashlytics/submit'. This script was put in place for backwards compatibility, but it relies on PODS_ROOT, which does not have a value in your current setup. Please update the path to the submit binary to fix this issue."
|
||||||
|
else
|
||||||
|
echo "warning: The submit script is now located at '$"{"PODS_ROOT"}"/Crashlytics/submit'. To remove this warning, update your path to point to this new location."
|
||||||
|
sh "${PODS_ROOT}/Crashlytics/submit" "$@"
|
||||||
|
fi
|
|
@ -0,0 +1,39 @@
|
||||||
|
![Crashlytics Header](https://docs.fabric.io/ios/cocoapod-readmes/cocoapods-crashlytics-header.png)
|
||||||
|
|
||||||
|
Part of [Google Fabric](https://get.fabric.io), [Crashlytics](http://try.crashlytics.com/) offers the most powerful, yet lightest weight crash reporting solution for iOS. Crashlytics also provides real-time analytics through [Answers](https://answers.io/) and app distributions to testers using [Beta](http://try.crashlytics.com/beta/).
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
1. Visit [https://fabric.io/sign_up](https://fabric.io/sign_up) to create your Fabric account and to download Fabric.app.
|
||||||
|
|
||||||
|
1. Open Fabric.app, login and select the Crashlytics SDK.
|
||||||
|
|
||||||
|
![Fabric Plugin](https://docs.fabric.io/ios/cocoapod-readmes/cocoapods-fabric-plugin.png)
|
||||||
|
|
||||||
|
1. The Fabric app automatically detects when a project uses CocoaPods and gives you the option to install via the Podfile or Xcode.
|
||||||
|
|
||||||
|
![Fabric Installation Options](https://docs.fabric.io/ios/cocoapod-readmes/cocoapods-pod-installation-option.png)
|
||||||
|
|
||||||
|
1. Select the Podfile option and follow the installation instructions to update your Podfile. **Note:** the Crashlytics Pod includes Answers. If you have Answers included as a separate Pod it should be removed from your Podfile to avoid duplicate symbol errors.
|
||||||
|
|
||||||
|
```
|
||||||
|
pod 'Fabric'
|
||||||
|
pod 'Crashlytics'
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Run `pod install`
|
||||||
|
|
||||||
|
1. Add a Run Script Build Phase and build your app.
|
||||||
|
|
||||||
|
![Fabric Run Script Build Phase](https://docs.fabric.io/ios/cocoapod-readmes/cocoapods-rsbp.png)
|
||||||
|
|
||||||
|
1. Initialize the SDK by inserting code outlined in the Fabric.app.
|
||||||
|
|
||||||
|
1. Run your app to finish the installation.
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
* [Documentation](https://docs.fabric.io/apple/crashlytics/overview.html)
|
||||||
|
* [Forums](https://stackoverflow.com/questions/tagged/google-fabric)
|
||||||
|
* [Website](http://try.crashlytics.com/)
|
||||||
|
* Follow us on Twitter: [@fabric](https://twitter.com/fabric) and [@crashlytics](https://twitter.com/crashlytics)
|
Binary file not shown.
31
ios/Pods/Crashlytics/iOS/Crashlytics.framework/Headers/ANSCompatibility.h
generated
vendored
Normal file
31
ios/Pods/Crashlytics/iOS/Crashlytics.framework/Headers/ANSCompatibility.h
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
//
|
||||||
|
// ANSCompatibility.h
|
||||||
|
// AnswersKit
|
||||||
|
//
|
||||||
|
// Copyright (c) 2015 Crashlytics, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !__has_feature(nullability)
|
||||||
|
#define nonnull
|
||||||
|
#define nullable
|
||||||
|
#define _Nullable
|
||||||
|
#define _Nonnull
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NS_ASSUME_NONNULL_BEGIN
|
||||||
|
#define NS_ASSUME_NONNULL_BEGIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NS_ASSUME_NONNULL_END
|
||||||
|
#define NS_ASSUME_NONNULL_END
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_feature(objc_generics)
|
||||||
|
#define ANS_GENERIC_NSARRAY(type) NSArray<type>
|
||||||
|
#define ANS_GENERIC_NSDICTIONARY(key_type,object_key) NSDictionary<key_type, object_key>
|
||||||
|
#else
|
||||||
|
#define ANS_GENERIC_NSARRAY(type) NSArray
|
||||||
|
#define ANS_GENERIC_NSDICTIONARY(key_type,object_key) NSDictionary
|
||||||
|
#endif
|
|
@ -0,0 +1,210 @@
|
||||||
|
//
|
||||||
|
// Answers.h
|
||||||
|
// Crashlytics
|
||||||
|
//
|
||||||
|
// Copyright (c) 2015 Crashlytics, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "ANSCompatibility.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class exposes the Answers Events API, allowing you to track key
|
||||||
|
* user user actions and metrics in your app.
|
||||||
|
*/
|
||||||
|
@interface Answers : NSObject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a Sign Up event to see users signing up for your app in real-time, understand how
|
||||||
|
* many users are signing up with different methods and their success rate signing up.
|
||||||
|
*
|
||||||
|
* @param signUpMethodOrNil The method by which a user logged in, e.g. Twitter or Digits.
|
||||||
|
* @param signUpSucceededOrNil The ultimate success or failure of the login
|
||||||
|
* @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
|
||||||
|
*/
|
||||||
|
+ (void)logSignUpWithMethod:(nullable NSString *)signUpMethodOrNil
|
||||||
|
success:(nullable NSNumber *)signUpSucceededOrNil
|
||||||
|
customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log an Log In event to see users logging into your app in real-time, understand how many
|
||||||
|
* users are logging in with different methods and their success rate logging into your app.
|
||||||
|
*
|
||||||
|
* @param loginMethodOrNil The method by which a user logged in, e.g. email, Twitter or Digits.
|
||||||
|
* @param loginSucceededOrNil The ultimate success or failure of the login
|
||||||
|
* @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
|
||||||
|
*/
|
||||||
|
+ (void)logLoginWithMethod:(nullable NSString *)loginMethodOrNil
|
||||||
|
success:(nullable NSNumber *)loginSucceededOrNil
|
||||||
|
customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a Share event to see users sharing from your app in real-time, letting you
|
||||||
|
* understand what content they're sharing from the type or genre down to the specific id.
|
||||||
|
*
|
||||||
|
* @param shareMethodOrNil The method by which a user shared, e.g. email, Twitter, SMS.
|
||||||
|
* @param contentNameOrNil The human readable name for this piece of content.
|
||||||
|
* @param contentTypeOrNil The type of content shared.
|
||||||
|
* @param contentIdOrNil The unique identifier for this piece of content. Useful for finding the top shared item.
|
||||||
|
* @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
|
||||||
|
*/
|
||||||
|
+ (void)logShareWithMethod:(nullable NSString *)shareMethodOrNil
|
||||||
|
contentName:(nullable NSString *)contentNameOrNil
|
||||||
|
contentType:(nullable NSString *)contentTypeOrNil
|
||||||
|
contentId:(nullable NSString *)contentIdOrNil
|
||||||
|
customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log an Invite Event to track how users are inviting other users into
|
||||||
|
* your application.
|
||||||
|
*
|
||||||
|
* @param inviteMethodOrNil The method of invitation, e.g. GameCenter, Twitter, email.
|
||||||
|
* @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
|
||||||
|
*/
|
||||||
|
+ (void)logInviteWithMethod:(nullable NSString *)inviteMethodOrNil
|
||||||
|
customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a Purchase event to see your revenue in real-time, understand how many users are making purchases, see which
|
||||||
|
* items are most popular, and track plenty of other important purchase-related metrics.
|
||||||
|
*
|
||||||
|
* @param itemPriceOrNil The purchased item's price.
|
||||||
|
* @param currencyOrNil The ISO4217 currency code. Example: USD
|
||||||
|
* @param purchaseSucceededOrNil Was the purchase successful or unsuccessful
|
||||||
|
* @param itemNameOrNil The human-readable form of the item's name. Example:
|
||||||
|
* @param itemTypeOrNil The type, or genre of the item. Example: Song
|
||||||
|
* @param itemIdOrNil The machine-readable, unique item identifier Example: SKU
|
||||||
|
* @param customAttributesOrNil A dictionary of custom attributes to associate with this purchase.
|
||||||
|
*/
|
||||||
|
+ (void)logPurchaseWithPrice:(nullable NSDecimalNumber *)itemPriceOrNil
|
||||||
|
currency:(nullable NSString *)currencyOrNil
|
||||||
|
success:(nullable NSNumber *)purchaseSucceededOrNil
|
||||||
|
itemName:(nullable NSString *)itemNameOrNil
|
||||||
|
itemType:(nullable NSString *)itemTypeOrNil
|
||||||
|
itemId:(nullable NSString *)itemIdOrNil
|
||||||
|
customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a Level Start Event to track where users are in your game.
|
||||||
|
*
|
||||||
|
* @param levelNameOrNil The level name
|
||||||
|
* @param customAttributesOrNil A dictionary of custom attributes to associate with this level start event.
|
||||||
|
*/
|
||||||
|
+ (void)logLevelStart:(nullable NSString *)levelNameOrNil
|
||||||
|
customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a Level End event to track how users are completing levels in your game.
|
||||||
|
*
|
||||||
|
* @param levelNameOrNil The name of the level completed, E.G. "1" or "Training"
|
||||||
|
* @param scoreOrNil The score the user completed the level with.
|
||||||
|
* @param levelCompletedSuccesfullyOrNil A boolean representing whether or not the level was completed successfully.
|
||||||
|
* @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
|
||||||
|
*/
|
||||||
|
+ (void)logLevelEnd:(nullable NSString *)levelNameOrNil
|
||||||
|
score:(nullable NSNumber *)scoreOrNil
|
||||||
|
success:(nullable NSNumber *)levelCompletedSuccesfullyOrNil
|
||||||
|
customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log an Add to Cart event to see users adding items to a shopping cart in real-time, understand how
|
||||||
|
* many users start the purchase flow, see which items are most popular, and track plenty of other important
|
||||||
|
* purchase-related metrics.
|
||||||
|
*
|
||||||
|
* @param itemPriceOrNil The purchased item's price.
|
||||||
|
* @param currencyOrNil The ISO4217 currency code. Example: USD
|
||||||
|
* @param itemNameOrNil The human-readable form of the item's name. Example:
|
||||||
|
* @param itemTypeOrNil The type, or genre of the item. Example: Song
|
||||||
|
* @param itemIdOrNil The machine-readable, unique item identifier Example: SKU
|
||||||
|
* @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
|
||||||
|
*/
|
||||||
|
+ (void)logAddToCartWithPrice:(nullable NSDecimalNumber *)itemPriceOrNil
|
||||||
|
currency:(nullable NSString *)currencyOrNil
|
||||||
|
itemName:(nullable NSString *)itemNameOrNil
|
||||||
|
itemType:(nullable NSString *)itemTypeOrNil
|
||||||
|
itemId:(nullable NSString *)itemIdOrNil
|
||||||
|
customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a Start Checkout event to see users moving through the purchase funnel in real-time, understand how many
|
||||||
|
* users are doing this and how much they're spending per checkout, and see how it related to other important
|
||||||
|
* purchase-related metrics.
|
||||||
|
*
|
||||||
|
* @param totalPriceOrNil The total price of the cart.
|
||||||
|
* @param currencyOrNil The ISO4217 currency code. Example: USD
|
||||||
|
* @param itemCountOrNil The number of items in the cart.
|
||||||
|
* @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
|
||||||
|
*/
|
||||||
|
+ (void)logStartCheckoutWithPrice:(nullable NSDecimalNumber *)totalPriceOrNil
|
||||||
|
currency:(nullable NSString *)currencyOrNil
|
||||||
|
itemCount:(nullable NSNumber *)itemCountOrNil
|
||||||
|
customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a Rating event to see users rating content within your app in real-time and understand what
|
||||||
|
* content is most engaging, from the type or genre down to the specific id.
|
||||||
|
*
|
||||||
|
* @param ratingOrNil The integer rating given by the user.
|
||||||
|
* @param contentNameOrNil The human readable name for this piece of content.
|
||||||
|
* @param contentTypeOrNil The type of content shared.
|
||||||
|
* @param contentIdOrNil The unique identifier for this piece of content. Useful for finding the top shared item.
|
||||||
|
* @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
|
||||||
|
*/
|
||||||
|
+ (void)logRating:(nullable NSNumber *)ratingOrNil
|
||||||
|
contentName:(nullable NSString *)contentNameOrNil
|
||||||
|
contentType:(nullable NSString *)contentTypeOrNil
|
||||||
|
contentId:(nullable NSString *)contentIdOrNil
|
||||||
|
customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a Content View event to see users viewing content within your app in real-time and
|
||||||
|
* understand what content is most engaging, from the type or genre down to the specific id.
|
||||||
|
*
|
||||||
|
* @param contentNameOrNil The human readable name for this piece of content.
|
||||||
|
* @param contentTypeOrNil The type of content shared.
|
||||||
|
* @param contentIdOrNil The unique identifier for this piece of content. Useful for finding the top shared item.
|
||||||
|
* @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
|
||||||
|
*/
|
||||||
|
+ (void)logContentViewWithName:(nullable NSString *)contentNameOrNil
|
||||||
|
contentType:(nullable NSString *)contentTypeOrNil
|
||||||
|
contentId:(nullable NSString *)contentIdOrNil
|
||||||
|
customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a Search event allows you to see users searching within your app in real-time and understand
|
||||||
|
* exactly what they're searching for.
|
||||||
|
*
|
||||||
|
* @param queryOrNil The user's query.
|
||||||
|
* @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
|
||||||
|
*/
|
||||||
|
+ (void)logSearchWithQuery:(nullable NSString *)queryOrNil
|
||||||
|
customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a Custom Event to see user actions that are uniquely important for your app in real-time, to see how often
|
||||||
|
* they're performing these actions with breakdowns by different categories you add. Use a human-readable name for
|
||||||
|
* the name of the event, since this is how the event will appear in Answers.
|
||||||
|
*
|
||||||
|
* @param eventName The human-readable name for the event.
|
||||||
|
* @param customAttributesOrNil A dictionary of custom attributes to associate with this event. Attribute keys
|
||||||
|
* must be <code>NSString</code> and values must be <code>NSNumber</code> or <code>NSString</code>.
|
||||||
|
* @discussion How we treat <code>NSNumbers</code>:
|
||||||
|
* We will provide information about the distribution of values over time.
|
||||||
|
*
|
||||||
|
* How we treat <code>NSStrings</code>:
|
||||||
|
* NSStrings are used as categorical data, allowing comparison across different category values.
|
||||||
|
* Strings are limited to a maximum length of 100 characters, attributes over this length will be
|
||||||
|
* truncated.
|
||||||
|
*
|
||||||
|
* When tracking the Tweet views to better understand user engagement, sending the tweet's length
|
||||||
|
* and the type of media present in the tweet allows you to track how tweet length and the type of media influence
|
||||||
|
* engagement.
|
||||||
|
*/
|
||||||
|
+ (void)logCustomEventWithName:(NSString *)eventName
|
||||||
|
customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
33
ios/Pods/Crashlytics/iOS/Crashlytics.framework/Headers/CLSAttributes.h
generated
vendored
Normal file
33
ios/Pods/Crashlytics/iOS/Crashlytics.framework/Headers/CLSAttributes.h
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
//
|
||||||
|
// CLSAttributes.h
|
||||||
|
// Crashlytics
|
||||||
|
//
|
||||||
|
// Copyright (c) 2015 Crashlytics, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define CLS_DEPRECATED(x) __attribute__ ((deprecated(x)))
|
||||||
|
|
||||||
|
#if !__has_feature(nullability)
|
||||||
|
#define nonnull
|
||||||
|
#define nullable
|
||||||
|
#define _Nullable
|
||||||
|
#define _Nonnull
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NS_ASSUME_NONNULL_BEGIN
|
||||||
|
#define NS_ASSUME_NONNULL_BEGIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NS_ASSUME_NONNULL_END
|
||||||
|
#define NS_ASSUME_NONNULL_END
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_feature(objc_generics)
|
||||||
|
#define CLS_GENERIC_NSARRAY(type) NSArray<type>
|
||||||
|
#define CLS_GENERIC_NSDICTIONARY(key_type,object_key) NSDictionary<key_type, object_key>
|
||||||
|
#else
|
||||||
|
#define CLS_GENERIC_NSARRAY(type) NSArray
|
||||||
|
#define CLS_GENERIC_NSDICTIONARY(key_type,object_key) NSDictionary
|
||||||
|
#endif
|
64
ios/Pods/Crashlytics/iOS/Crashlytics.framework/Headers/CLSLogging.h
generated
vendored
Normal file
64
ios/Pods/Crashlytics/iOS/Crashlytics.framework/Headers/CLSLogging.h
generated
vendored
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
//
|
||||||
|
// CLSLogging.h
|
||||||
|
// Crashlytics
|
||||||
|
//
|
||||||
|
// Copyright (c) 2015 Crashlytics, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
#ifdef __OBJC__
|
||||||
|
#import "CLSAttributes.h"
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* The CLS_LOG macro provides as easy way to gather more information in your log messages that are
|
||||||
|
* sent with your crash data. CLS_LOG prepends your custom log message with the function name and
|
||||||
|
* line number where the macro was used. If your app was built with the DEBUG preprocessor macro
|
||||||
|
* defined CLS_LOG uses the CLSNSLog function which forwards your log message to NSLog and CLSLog.
|
||||||
|
* If the DEBUG preprocessor macro is not defined CLS_LOG uses CLSLog only.
|
||||||
|
*
|
||||||
|
* Example output:
|
||||||
|
* -[AppDelegate login:] line 134 $ login start
|
||||||
|
*
|
||||||
|
* If you would like to change this macro, create a new header file, unset our define and then define
|
||||||
|
* your own version. Make sure this new header file is imported after the Crashlytics header file.
|
||||||
|
*
|
||||||
|
* #undef CLS_LOG
|
||||||
|
* #define CLS_LOG(__FORMAT__, ...) CLSNSLog...
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
#ifdef __OBJC__
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define CLS_LOG(__FORMAT__, ...) CLSNSLog((@"%s line %d $ " __FORMAT__), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define CLS_LOG(__FORMAT__, ...) CLSLog((@"%s line %d $ " __FORMAT__), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Add logging that will be sent with your crash data. This logging will not show up in the system.log
|
||||||
|
* and will only be visible in your Crashlytics dashboard.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifdef __OBJC__
|
||||||
|
OBJC_EXTERN void CLSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);
|
||||||
|
OBJC_EXTERN void CLSLogv(NSString *format, va_list ap) NS_FORMAT_FUNCTION(1,0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Add logging that will be sent with your crash data. This logging will show up in the system.log
|
||||||
|
* and your Crashlytics dashboard. It is not recommended for Release builds.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
OBJC_EXTERN void CLSNSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);
|
||||||
|
OBJC_EXTERN void CLSNSLogv(NSString *format, va_list ap) NS_FORMAT_FUNCTION(1,0);
|
||||||
|
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
#endif
|
103
ios/Pods/Crashlytics/iOS/Crashlytics.framework/Headers/CLSReport.h
generated
vendored
Normal file
103
ios/Pods/Crashlytics/iOS/Crashlytics.framework/Headers/CLSReport.h
generated
vendored
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
//
|
||||||
|
// CLSReport.h
|
||||||
|
// Crashlytics
|
||||||
|
//
|
||||||
|
// Copyright (c) 2015 Crashlytics, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "CLSAttributes.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The CLSCrashReport protocol is deprecated. See the CLSReport class and the CrashyticsDelegate changes for details.
|
||||||
|
**/
|
||||||
|
@protocol CLSCrashReport <NSObject>
|
||||||
|
|
||||||
|
@property (nonatomic, copy, readonly) NSString *identifier;
|
||||||
|
@property (nonatomic, copy, readonly) NSDictionary *customKeys;
|
||||||
|
@property (nonatomic, copy, readonly) NSString *bundleVersion;
|
||||||
|
@property (nonatomic, copy, readonly) NSString *bundleShortVersionString;
|
||||||
|
@property (nonatomic, readonly, nullable) NSDate *crashedOnDate;
|
||||||
|
@property (nonatomic, copy, readonly) NSString *OSVersion;
|
||||||
|
@property (nonatomic, copy, readonly) NSString *OSBuildVersion;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The CLSReport exposes an interface to the phsyical report that Crashlytics has created. You can
|
||||||
|
* use this class to get information about the event, and can also set some values after the
|
||||||
|
* event has occurred.
|
||||||
|
**/
|
||||||
|
@interface CLSReport : NSObject <CLSCrashReport>
|
||||||
|
|
||||||
|
- (instancetype)init NS_UNAVAILABLE;
|
||||||
|
+ (instancetype)new NS_UNAVAILABLE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the session identifier for the report.
|
||||||
|
**/
|
||||||
|
@property (nonatomic, copy, readonly) NSString *identifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the custom key value data for the report.
|
||||||
|
**/
|
||||||
|
@property (nonatomic, copy, readonly) NSDictionary *customKeys;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the CFBundleVersion of the application that generated the report.
|
||||||
|
**/
|
||||||
|
@property (nonatomic, copy, readonly) NSString *bundleVersion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the CFBundleShortVersionString of the application that generated the report.
|
||||||
|
**/
|
||||||
|
@property (nonatomic, copy, readonly) NSString *bundleShortVersionString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the date that the report was created.
|
||||||
|
**/
|
||||||
|
@property (nonatomic, copy, readonly) NSDate *dateCreated;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the os version that the application crashed on.
|
||||||
|
**/
|
||||||
|
@property (nonatomic, copy, readonly) NSString *OSVersion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the os build version that the application crashed on.
|
||||||
|
**/
|
||||||
|
@property (nonatomic, copy, readonly) NSString *OSBuildVersion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns YES if the report contains any crash information, otherwise returns NO.
|
||||||
|
**/
|
||||||
|
@property (nonatomic, assign, readonly) BOOL isCrash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* You can use this method to set, after the event, additional custom keys. The rules
|
||||||
|
* and semantics for this method are the same as those documented in Crashlytics.h. Be aware
|
||||||
|
* that the maximum size and count of custom keys is still enforced, and you can overwrite keys
|
||||||
|
* and/or cause excess keys to be deleted by using this method.
|
||||||
|
**/
|
||||||
|
- (void)setObjectValue:(nullable id)value forKey:(NSString *)key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record an application-specific user identifier. See Crashlytics.h for details.
|
||||||
|
**/
|
||||||
|
@property (nonatomic, copy, nullable) NSString * userIdentifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record a user name. See Crashlytics.h for details.
|
||||||
|
**/
|
||||||
|
@property (nonatomic, copy, nullable) NSString * userName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record a user email. See Crashlytics.h for details.
|
||||||
|
**/
|
||||||
|
@property (nonatomic, copy, nullable) NSString * userEmail;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
38
ios/Pods/Crashlytics/iOS/Crashlytics.framework/Headers/CLSStackFrame.h
generated
vendored
Normal file
38
ios/Pods/Crashlytics/iOS/Crashlytics.framework/Headers/CLSStackFrame.h
generated
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
//
|
||||||
|
// CLSStackFrame.h
|
||||||
|
// Crashlytics
|
||||||
|
//
|
||||||
|
// Copyright 2015 Crashlytics, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "CLSAttributes.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This class is used in conjunction with -[Crashlytics recordCustomExceptionName:reason:frameArray:] to
|
||||||
|
* record information about non-ObjC/C++ exceptions. All information included here will be displayed
|
||||||
|
* in the Crashlytics UI, and can influence crash grouping. Be particularly careful with the use of the
|
||||||
|
* address property. If set, Crashlytics will attempt symbolication and could overwrite other properities
|
||||||
|
* in the process.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
@interface CLSStackFrame : NSObject
|
||||||
|
|
||||||
|
+ (instancetype)stackFrame;
|
||||||
|
+ (instancetype)stackFrameWithAddress:(NSUInteger)address;
|
||||||
|
+ (instancetype)stackFrameWithSymbol:(NSString *)symbol;
|
||||||
|
|
||||||
|
@property (nonatomic, copy, nullable) NSString *symbol;
|
||||||
|
@property (nonatomic, copy, nullable) NSString *rawSymbol;
|
||||||
|
@property (nonatomic, copy, nullable) NSString *library;
|
||||||
|
@property (nonatomic, copy, nullable) NSString *fileName;
|
||||||
|
@property (nonatomic, assign) uint32_t lineNumber;
|
||||||
|
@property (nonatomic, assign) uint64_t offset;
|
||||||
|
@property (nonatomic, assign) uint64_t address;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
288
ios/Pods/Crashlytics/iOS/Crashlytics.framework/Headers/Crashlytics.h
generated
vendored
Normal file
288
ios/Pods/Crashlytics/iOS/Crashlytics.framework/Headers/Crashlytics.h
generated
vendored
Normal file
|
@ -0,0 +1,288 @@
|
||||||
|
//
|
||||||
|
// Crashlytics.h
|
||||||
|
// Crashlytics
|
||||||
|
//
|
||||||
|
// Copyright (c) 2015 Crashlytics, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import "CLSAttributes.h"
|
||||||
|
#import "CLSLogging.h"
|
||||||
|
#import "CLSReport.h"
|
||||||
|
#import "CLSStackFrame.h"
|
||||||
|
#import "Answers.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@protocol CrashlyticsDelegate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crashlytics. Handles configuration and initialization of Crashlytics.
|
||||||
|
*
|
||||||
|
* Note: The Crashlytics class cannot be subclassed. If this is causing you pain for
|
||||||
|
* testing, we suggest using either a wrapper class or a protocol extension.
|
||||||
|
*/
|
||||||
|
@interface Crashlytics : NSObject
|
||||||
|
|
||||||
|
@property (nonatomic, readonly, copy) NSString *APIKey;
|
||||||
|
@property (nonatomic, readonly, copy) NSString *version;
|
||||||
|
@property (nonatomic, assign) BOOL debugMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* The delegate can be used to influence decisions on reporting and behavior, as well as reacting
|
||||||
|
* to previous crashes.
|
||||||
|
*
|
||||||
|
* Make certain that the delegate is setup before starting Crashlytics with startWithAPIKey:... or
|
||||||
|
* via +[Fabric with:...]. Failure to do will result in missing any delegate callbacks that occur
|
||||||
|
* synchronously during start.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
@property (nonatomic, assign, nullable) id <CrashlyticsDelegate> delegate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The recommended way to install Crashlytics into your application is to place a call to +startWithAPIKey:
|
||||||
|
* in your -application:didFinishLaunchingWithOptions: or -applicationDidFinishLaunching:
|
||||||
|
* method.
|
||||||
|
*
|
||||||
|
* Note: Starting with 3.0, the submission process has been significantly improved. The delay parameter
|
||||||
|
* is no longer required to throttle submissions on launch, performance will be great without it.
|
||||||
|
*
|
||||||
|
* @param apiKey The Crashlytics API Key for this app
|
||||||
|
*
|
||||||
|
* @return The singleton Crashlytics instance
|
||||||
|
*/
|
||||||
|
+ (Crashlytics *)startWithAPIKey:(NSString *)apiKey;
|
||||||
|
+ (Crashlytics *)startWithAPIKey:(NSString *)apiKey afterDelay:(NSTimeInterval)delay CLS_DEPRECATED("Crashlytics no longer needs or uses the delay parameter. Please use +startWithAPIKey: instead.");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If you need the functionality provided by the CrashlyticsDelegate protocol, you can use
|
||||||
|
* these convenience methods to activate the framework and set the delegate in one call.
|
||||||
|
*
|
||||||
|
* @param apiKey The Crashlytics API Key for this app
|
||||||
|
* @param delegate A delegate object which conforms to CrashlyticsDelegate.
|
||||||
|
*
|
||||||
|
* @return The singleton Crashlytics instance
|
||||||
|
*/
|
||||||
|
+ (Crashlytics *)startWithAPIKey:(NSString *)apiKey delegate:(nullable id<CrashlyticsDelegate>)delegate;
|
||||||
|
+ (Crashlytics *)startWithAPIKey:(NSString *)apiKey delegate:(nullable id<CrashlyticsDelegate>)delegate afterDelay:(NSTimeInterval)delay CLS_DEPRECATED("Crashlytics no longer needs or uses the delay parameter. Please use +startWithAPIKey:delegate: instead.");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access the singleton Crashlytics instance.
|
||||||
|
*
|
||||||
|
* @return The singleton Crashlytics instance
|
||||||
|
*/
|
||||||
|
+ (Crashlytics *)sharedInstance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The easiest way to cause a crash - great for testing!
|
||||||
|
*/
|
||||||
|
- (void)crash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The easiest way to cause a crash with an exception - great for testing.
|
||||||
|
*/
|
||||||
|
- (void)throwException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify a user identifier which will be visible in the Crashlytics UI.
|
||||||
|
*
|
||||||
|
* Many of our customers have requested the ability to tie crashes to specific end-users of their
|
||||||
|
* application in order to facilitate responses to support requests or permit the ability to reach
|
||||||
|
* out for more information. We allow you to specify up to three separate values for display within
|
||||||
|
* the Crashlytics UI - but please be mindful of your end-user's privacy.
|
||||||
|
*
|
||||||
|
* We recommend specifying a user identifier - an arbitrary string that ties an end-user to a record
|
||||||
|
* in your system. This could be a database id, hash, or other value that is meaningless to a
|
||||||
|
* third-party observer but can be indexed and queried by you.
|
||||||
|
*
|
||||||
|
* Optionally, you may also specify the end-user's name or username, as well as email address if you
|
||||||
|
* do not have a system that works well with obscured identifiers.
|
||||||
|
*
|
||||||
|
* Pursuant to our EULA, this data is transferred securely throughout our system and we will not
|
||||||
|
* disseminate end-user data unless required to by law. That said, if you choose to provide end-user
|
||||||
|
* contact information, we strongly recommend that you disclose this in your application's privacy
|
||||||
|
* policy. Data privacy is of our utmost concern.
|
||||||
|
*
|
||||||
|
* @param identifier An arbitrary user identifier string which ties an end-user to a record in your system.
|
||||||
|
*/
|
||||||
|
- (void)setUserIdentifier:(nullable NSString *)identifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify a user name which will be visible in the Crashlytics UI.
|
||||||
|
* Please be mindful of your end-user's privacy and see if setUserIdentifier: can fulfil your needs.
|
||||||
|
* @see setUserIdentifier:
|
||||||
|
*
|
||||||
|
* @param name An end user's name.
|
||||||
|
*/
|
||||||
|
- (void)setUserName:(nullable NSString *)name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify a user email which will be visible in the Crashlytics UI.
|
||||||
|
* Please be mindful of your end-user's privacy and see if setUserIdentifier: can fulfil your needs.
|
||||||
|
*
|
||||||
|
* @see setUserIdentifier:
|
||||||
|
*
|
||||||
|
* @param email An end user's email address.
|
||||||
|
*/
|
||||||
|
- (void)setUserEmail:(nullable NSString *)email;
|
||||||
|
|
||||||
|
+ (void)setUserIdentifier:(nullable NSString *)identifier CLS_DEPRECATED("Please access this method via +sharedInstance");
|
||||||
|
+ (void)setUserName:(nullable NSString *)name CLS_DEPRECATED("Please access this method via +sharedInstance");
|
||||||
|
+ (void)setUserEmail:(nullable NSString *)email CLS_DEPRECATED("Please access this method via +sharedInstance");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a value for a for a key to be associated with your crash data which will be visible in the Crashlytics UI.
|
||||||
|
* When setting an object value, the object is converted to a string. This is typically done by calling
|
||||||
|
* -[NSObject description].
|
||||||
|
*
|
||||||
|
* @param value The object to be associated with the key
|
||||||
|
* @param key The key with which to associate the value
|
||||||
|
*/
|
||||||
|
- (void)setObjectValue:(nullable id)value forKey:(NSString *)key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an int value for a key to be associated with your crash data which will be visible in the Crashlytics UI.
|
||||||
|
*
|
||||||
|
* @param value The integer value to be set
|
||||||
|
* @param key The key with which to associate the value
|
||||||
|
*/
|
||||||
|
- (void)setIntValue:(int)value forKey:(NSString *)key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an BOOL value for a key to be associated with your crash data which will be visible in the Crashlytics UI.
|
||||||
|
*
|
||||||
|
* @param value The BOOL value to be set
|
||||||
|
* @param key The key with which to associate the value
|
||||||
|
*/
|
||||||
|
- (void)setBoolValue:(BOOL)value forKey:(NSString *)key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an float value for a key to be associated with your crash data which will be visible in the Crashlytics UI.
|
||||||
|
*
|
||||||
|
* @param value The float value to be set
|
||||||
|
* @param key The key with which to associate the value
|
||||||
|
*/
|
||||||
|
- (void)setFloatValue:(float)value forKey:(NSString *)key;
|
||||||
|
|
||||||
|
+ (void)setObjectValue:(nullable id)value forKey:(NSString *)key CLS_DEPRECATED("Please access this method via +sharedInstance");
|
||||||
|
+ (void)setIntValue:(int)value forKey:(NSString *)key CLS_DEPRECATED("Please access this method via +sharedInstance");
|
||||||
|
+ (void)setBoolValue:(BOOL)value forKey:(NSString *)key CLS_DEPRECATED("Please access this method via +sharedInstance");
|
||||||
|
+ (void)setFloatValue:(float)value forKey:(NSString *)key CLS_DEPRECATED("Please access this method via +sharedInstance");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method can be used to record a single exception structure in a report. This is particularly useful
|
||||||
|
* when your code interacts with non-native languages like Lua, C#, or Javascript. This call can be
|
||||||
|
* expensive and should only be used shortly before process termination. This API is not intended be to used
|
||||||
|
* to log NSException objects. All safely-reportable NSExceptions are automatically captured by
|
||||||
|
* Crashlytics.
|
||||||
|
*
|
||||||
|
* @param name The name of the custom exception
|
||||||
|
* @param reason The reason this exception occurred
|
||||||
|
* @param frameArray An array of CLSStackFrame objects
|
||||||
|
*/
|
||||||
|
- (void)recordCustomExceptionName:(NSString *)name reason:(nullable NSString *)reason frameArray:(CLS_GENERIC_NSARRAY(CLSStackFrame *) *)frameArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This allows you to record a non-fatal event, described by an NSError object. These events will be grouped and
|
||||||
|
* displayed similarly to crashes. Keep in mind that this method can be expensive. Also, the total number of
|
||||||
|
* NSErrors that can be recorded during your app's life-cycle is limited by a fixed-size circular buffer. If the
|
||||||
|
* buffer is overrun, the oldest data is dropped. Errors are relayed to Crashlytics on a subsequent launch
|
||||||
|
* of your application.
|
||||||
|
*
|
||||||
|
* You can also use the -recordError:withAdditionalUserInfo: to include additional context not represented
|
||||||
|
* by the NSError instance itself.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
- (void)recordError:(NSError *)error;
|
||||||
|
- (void)recordError:(NSError *)error withAdditionalUserInfo:(nullable CLS_GENERIC_NSDICTIONARY(NSString *, id) *)userInfo;
|
||||||
|
|
||||||
|
- (void)logEvent:(NSString *)eventName CLS_DEPRECATED("Please refer to Answers +logCustomEventWithName:");
|
||||||
|
- (void)logEvent:(NSString *)eventName attributes:(nullable NSDictionary *) attributes CLS_DEPRECATED("Please refer to Answers +logCustomEventWithName:");
|
||||||
|
+ (void)logEvent:(NSString *)eventName CLS_DEPRECATED("Please refer to Answers +logCustomEventWithName:");
|
||||||
|
+ (void)logEvent:(NSString *)eventName attributes:(nullable NSDictionary *) attributes CLS_DEPRECATED("Please refer to Answers +logCustomEventWithName:");
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* The CrashlyticsDelegate protocol provides a mechanism for your application to take
|
||||||
|
* action on events that occur in the Crashlytics crash reporting system. You can make
|
||||||
|
* use of these calls by assigning an object to the Crashlytics' delegate property directly,
|
||||||
|
* or through the convenience +startWithAPIKey:delegate: method.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@protocol CrashlyticsDelegate <NSObject>
|
||||||
|
@optional
|
||||||
|
|
||||||
|
|
||||||
|
- (void)crashlyticsDidDetectCrashDuringPreviousExecution:(Crashlytics *)crashlytics CLS_DEPRECATED("Please refer to -crashlyticsDidDetectReportForLastExecution:");
|
||||||
|
- (void)crashlytics:(Crashlytics *)crashlytics didDetectCrashDuringPreviousExecution:(id <CLSCrashReport>)crash CLS_DEPRECATED("Please refer to -crashlyticsDidDetectReportForLastExecution:");
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Called when a Crashlytics instance has determined that the last execution of the
|
||||||
|
* application resulted in a saved report. This is called synchronously on Crashlytics
|
||||||
|
* initialization. Your delegate must invoke the completionHandler, but does not need to do so
|
||||||
|
* synchronously, or even on the main thread. Invoking completionHandler with NO will cause the
|
||||||
|
* detected report to be deleted and not submitted to Crashlytics. This is useful for
|
||||||
|
* implementing permission prompts, or other more-complex forms of logic around submitting crashes.
|
||||||
|
*
|
||||||
|
* Instead of using this method, you should try to make use of -crashlyticsDidDetectReportForLastExecution:
|
||||||
|
* if you can.
|
||||||
|
*
|
||||||
|
* @warning Failure to invoke the completionHandler will prevent submissions from being reported. Watch out.
|
||||||
|
*
|
||||||
|
* @warning Just implementing this delegate method will disable all forms of synchronous report submission. This can
|
||||||
|
* impact the reliability of reporting crashes very early in application launch.
|
||||||
|
*
|
||||||
|
* @param report The CLSReport object representing the last detected report
|
||||||
|
* @param completionHandler The completion handler to call when your logic has completed.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
- (void)crashlyticsDidDetectReportForLastExecution:(CLSReport *)report completionHandler:(void (^)(BOOL submit))completionHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Called when a Crashlytics instance has determined that the last execution of the
|
||||||
|
* application resulted in a saved report. This method differs from
|
||||||
|
* -crashlyticsDidDetectReportForLastExecution:completionHandler: in three important ways:
|
||||||
|
*
|
||||||
|
* - it is not called synchronously during initialization
|
||||||
|
* - it does not give you the ability to prevent the report from being submitted
|
||||||
|
* - the report object itself is immutable
|
||||||
|
*
|
||||||
|
* Thanks to these limitations, making use of this method does not impact reporting
|
||||||
|
* reliabilty in any way.
|
||||||
|
*
|
||||||
|
* @param report The read-only CLSReport object representing the last detected report
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
- (void)crashlyticsDidDetectReportForLastExecution:(CLSReport *)report;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If your app is running on an OS that supports it (OS X 10.9+, iOS 7.0+), Crashlytics will submit
|
||||||
|
* most reports using out-of-process background networking operations. This results in a significant
|
||||||
|
* improvement in reliability of reporting, as well as power and performance wins for your users.
|
||||||
|
* If you don't want this functionality, you can disable by returning NO from this method.
|
||||||
|
*
|
||||||
|
* @warning Background submission is not supported for extensions on iOS or OS X.
|
||||||
|
*
|
||||||
|
* @param crashlytics The Crashlytics singleton instance
|
||||||
|
*
|
||||||
|
* @return Return NO if you don't want out-of-process background network operations.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
- (BOOL)crashlyticsCanUseBackgroundSessions:(Crashlytics *)crashlytics;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `CrashlyticsKit` can be used as a parameter to `[Fabric with:@[CrashlyticsKit]];` in Objective-C. In Swift, use Crashlytics.sharedInstance()
|
||||||
|
*/
|
||||||
|
#define CrashlyticsKit [Crashlytics sharedInstance]
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
Binary file not shown.
14
ios/Pods/Crashlytics/iOS/Crashlytics.framework/Modules/module.modulemap
generated
vendored
Normal file
14
ios/Pods/Crashlytics/iOS/Crashlytics.framework/Modules/module.modulemap
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
framework module Crashlytics {
|
||||||
|
header "Crashlytics.h"
|
||||||
|
header "Answers.h"
|
||||||
|
header "ANSCompatibility.h"
|
||||||
|
header "CLSLogging.h"
|
||||||
|
header "CLSReport.h"
|
||||||
|
header "CLSStackFrame.h"
|
||||||
|
header "CLSAttributes.h"
|
||||||
|
|
||||||
|
export *
|
||||||
|
|
||||||
|
link "z"
|
||||||
|
link "c++"
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# run
|
||||||
|
#
|
||||||
|
# Copyright (c) 2015 Crashlytics. All rights reserved.
|
||||||
|
|
||||||
|
# Figure out where we're being called from
|
||||||
|
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||||
|
|
||||||
|
# Quote path in case of spaces or special chars
|
||||||
|
DIR="\"${DIR}"
|
||||||
|
|
||||||
|
PATH_SEP="/"
|
||||||
|
VALIDATE_COMMAND="uploadDSYM\" $@ validate run-script"
|
||||||
|
UPLOAD_COMMAND="uploadDSYM\" $@ run-script"
|
||||||
|
|
||||||
|
# Ensure params are as expected, run in sync mode to validate
|
||||||
|
eval $DIR$PATH_SEP$VALIDATE_COMMAND
|
||||||
|
return_code=$?
|
||||||
|
|
||||||
|
if [[ $return_code != 0 ]]; then
|
||||||
|
exit $return_code
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verification passed, upload dSYM in background to prevent Xcode from waiting
|
||||||
|
# Note: Validation is performed again before upload.
|
||||||
|
# Output can still be found in Console.app
|
||||||
|
eval $DIR$PATH_SEP$UPLOAD_COMMAND > /dev/null 2>&1 &
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
We've now combined all our supported platforms into a single podspec. As a result, we moved our run script to a new location for Cocoapods projects: ${PODS_ROOT}/Fabric/run. To avoid breaking builds that reference the old location of the run script, we've placed this dummy script that calls to the correct location, while providing a helpful warning in Xcode if it is invoked. This bridge for backwards compatibility will be removed in a future release, so please heed the warning!
|
|
@ -0,0 +1,6 @@
|
||||||
|
if [[ -z $PODS_ROOT ]]; then
|
||||||
|
echo "error: The run binary delivered by cocoapods is in a new location, under '$"{"PODS_ROOT"}"/Fabric/run'. This script was put in place for backwards compatibility, but it relies on PODS_ROOT, which does not have a value in your current setup. Please update the path to the run binary to fix this issue."
|
||||||
|
else
|
||||||
|
echo "warning: The run script is now located at '$"{"PODS_ROOT"}"/Fabric/run'. To remove this warning, update your Run Script Build Phase to point to this new location."
|
||||||
|
sh "${PODS_ROOT}/Fabric/run" "$@"
|
||||||
|
fi
|
|
@ -0,0 +1,42 @@
|
||||||
|
![Fabric Header](https://docs.fabric.io/ios/cocoapod-readmes/cocoapods-fabric-header.png)
|
||||||
|
|
||||||
|
# Fabric
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
[Fabric](https://get.fabric.io) provides developers with the tools they need to build the best apps. Developed and maintained by Google and the team that built Crashlytics, Fabric provides an easy way to manage all your SDKs so that you’ll never have to worry about tedious configurations or juggling different accounts. We let you get right into coding and building the next big app.
|
||||||
|
|
||||||
|
For a full list of SDK provided through Fabric visit [https://fabric.io/kits](https://fabric.io/kits).
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
The Fabric Pod is a dependency for all Fabric SDKs and is included when installing any Fabric related Pods. General setup instructions are shown below; however, these vary depending on the selected SDK.
|
||||||
|
|
||||||
|
1. Visit [https://fabric.io/sign_up](https://fabric.io/sign_up) to create your Fabric account and to download Fabric.app.
|
||||||
|
|
||||||
|
1. Open Fabric.app, login and select an SDK to install.
|
||||||
|
|
||||||
|
![Fabric Plugin](https://docs.fabric.io/ios/cocoapod-readmes/cocoapods-fabric-plugin.png)
|
||||||
|
|
||||||
|
1. The Fabric app automatically detects when a project uses CocoaPods and gives you the option to install via the Podfile or Xcode.
|
||||||
|
|
||||||
|
![Fabric Installation Options](https://docs.fabric.io/ios/cocoapod-readmes/cocoapods-pod-installation-option.png)
|
||||||
|
|
||||||
|
1. Select the Podfile option and follow the installation instructions to update your Podfile. Note: the example below is for the Crashlytics SDK. The instructions will vary based on the selected SDK.
|
||||||
|
|
||||||
|
![Fabric Podfile Instructions](https://docs.fabric.io/ios/cocoapod-readmes/cocoapods-podfile-instructions.png)
|
||||||
|
|
||||||
|
1. Add a Run Script Build Phase and build your app.
|
||||||
|
|
||||||
|
![Fabric Run Script Build Phase](https://docs.fabric.io/ios/cocoapod-readmes/cocoapods-rsbp.png)
|
||||||
|
|
||||||
|
1. Initialize the SDK by inserting code outlined in Fabric.app.
|
||||||
|
|
||||||
|
1. Run your app to finish the installation.
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
* [Documentation](https://docs.fabric.io/)
|
||||||
|
* [Forums](https://stackoverflow.com/questions/tagged/google-fabric)
|
||||||
|
* [Website](https://get.fabric.io)
|
||||||
|
* Follow us on Twitter: [@fabric](https://twitter.com/fabric)
|
Binary file not shown.
|
@ -0,0 +1,51 @@
|
||||||
|
//
|
||||||
|
// FABAttributes.h
|
||||||
|
// Fabric
|
||||||
|
//
|
||||||
|
// Copyright (C) 2015 Twitter, 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define FAB_UNAVAILABLE(x) __attribute__((unavailable(x)))
|
||||||
|
|
||||||
|
#if !__has_feature(nullability)
|
||||||
|
#define nonnull
|
||||||
|
#define nullable
|
||||||
|
#define _Nullable
|
||||||
|
#define _Nonnull
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NS_ASSUME_NONNULL_BEGIN
|
||||||
|
#define NS_ASSUME_NONNULL_BEGIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NS_ASSUME_NONNULL_END
|
||||||
|
#define NS_ASSUME_NONNULL_END
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The following macros are defined here to provide
|
||||||
|
* backwards compatability. If you are still using
|
||||||
|
* them you should migrate to the native nullability
|
||||||
|
* macros.
|
||||||
|
*/
|
||||||
|
#define fab_nullable nullable
|
||||||
|
#define fab_nonnull nonnull
|
||||||
|
#define FAB_NONNULL __fab_nonnull
|
||||||
|
#define FAB_NULLABLE __fab_nullable
|
||||||
|
#define FAB_START_NONNULL NS_ASSUME_NONNULL_BEGIN
|
||||||
|
#define FAB_END_NONNULL NS_ASSUME_NONNULL_END
|
|
@ -0,0 +1,82 @@
|
||||||
|
//
|
||||||
|
// Fabric.h
|
||||||
|
// Fabric
|
||||||
|
//
|
||||||
|
// Copyright (C) 2015 Twitter, 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 "FABAttributes.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
|
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
|
||||||
|
#error "Fabric's minimum iOS version is 6.0"
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if __MAC_OS_X_VERSION_MIN_REQUIRED < 1070
|
||||||
|
#error "Fabric's minimum OS X version is 10.7"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fabric Base. Coordinates configuration and starts all provided kits.
|
||||||
|
*/
|
||||||
|
@interface Fabric : NSObject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize Fabric and all provided kits. Call this method within your App Delegate's `application:didFinishLaunchingWithOptions:` and provide the kits you wish to use.
|
||||||
|
*
|
||||||
|
* For example, in Objective-C:
|
||||||
|
*
|
||||||
|
* `[Fabric with:@[[Crashlytics class], [Twitter class], [Digits class], [MoPub class]]];`
|
||||||
|
*
|
||||||
|
* Swift:
|
||||||
|
*
|
||||||
|
* `Fabric.with([Crashlytics.self(), Twitter.self(), Digits.self(), MoPub.self()])`
|
||||||
|
*
|
||||||
|
* Only the first call to this method is honored. Subsequent calls are no-ops.
|
||||||
|
*
|
||||||
|
* @param kitClasses An array of kit Class objects
|
||||||
|
*
|
||||||
|
* @return Returns the shared Fabric instance. In most cases this can be ignored.
|
||||||
|
*/
|
||||||
|
+ (instancetype)with:(NSArray *)kitClasses;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Fabric singleton object.
|
||||||
|
*/
|
||||||
|
+ (instancetype)sharedSDK;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This BOOL enables or disables debug logging, such as kit version information. The default value is NO.
|
||||||
|
*/
|
||||||
|
@property (nonatomic, assign) BOOL debug;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unavailable. Use `+sharedSDK` to retrieve the shared Fabric instance.
|
||||||
|
*/
|
||||||
|
- (id)init FAB_UNAVAILABLE("Use +sharedSDK to retrieve the shared Fabric instance.");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unavailable. Use `+sharedSDK` to retrieve the shared Fabric instance.
|
||||||
|
*/
|
||||||
|
+ (instancetype)new FAB_UNAVAILABLE("Use +sharedSDK to retrieve the shared Fabric instance.");
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,6 @@
|
||||||
|
framework module Fabric {
|
||||||
|
umbrella header "Fabric.h"
|
||||||
|
|
||||||
|
export *
|
||||||
|
module * { export * }
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# run
|
||||||
|
#
|
||||||
|
# Copyright (c) 2015 Crashlytics. All rights reserved.
|
||||||
|
|
||||||
|
# Figure out where we're being called from
|
||||||
|
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||||
|
|
||||||
|
# Quote path in case of spaces or special chars
|
||||||
|
DIR="\"${DIR}"
|
||||||
|
|
||||||
|
PATH_SEP="/"
|
||||||
|
VALIDATE_COMMAND="uploadDSYM\" $@ validate run-script"
|
||||||
|
UPLOAD_COMMAND="uploadDSYM\" $@ run-script"
|
||||||
|
|
||||||
|
# Ensure params are as expected, run in sync mode to validate
|
||||||
|
eval $DIR$PATH_SEP$VALIDATE_COMMAND
|
||||||
|
return_code=$?
|
||||||
|
|
||||||
|
if [[ $return_code != 0 ]]; then
|
||||||
|
exit $return_code
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verification passed, upload dSYM in background to prevent Xcode from waiting
|
||||||
|
# Note: Validation is performed again before upload.
|
||||||
|
# Output can still be found in Console.app
|
||||||
|
eval $DIR$PATH_SEP$UPLOAD_COMMAND > /dev/null 2>&1 &
|
Binary file not shown.
|
@ -0,0 +1,28 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# run
|
||||||
|
#
|
||||||
|
# Copyright (c) 2015 Crashlytics. All rights reserved.
|
||||||
|
|
||||||
|
# Figure out where we're being called from
|
||||||
|
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||||
|
|
||||||
|
# Quote path in case of spaces or special chars
|
||||||
|
DIR="\"${DIR}"
|
||||||
|
|
||||||
|
PATH_SEP="/"
|
||||||
|
VALIDATE_COMMAND="uploadDSYM\" $@ validate run-script"
|
||||||
|
UPLOAD_COMMAND="uploadDSYM\" $@ run-script"
|
||||||
|
|
||||||
|
# Ensure params are as expected, run in sync mode to validate
|
||||||
|
eval $DIR$PATH_SEP$VALIDATE_COMMAND
|
||||||
|
return_code=$?
|
||||||
|
|
||||||
|
if [[ $return_code != 0 ]]; then
|
||||||
|
exit $return_code
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verification passed, upload dSYM in background to prevent Xcode from waiting
|
||||||
|
# Note: Validation is performed again before upload.
|
||||||
|
# Output can still be found in Console.app
|
||||||
|
eval $DIR$PATH_SEP$UPLOAD_COMMAND > /dev/null 2>&1 &
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,117 @@
|
||||||
|
#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(<FirebaseMLNLSmartReply/FirebaseMLNLSmartReply.h>)
|
||||||
|
#import <FirebaseMLNLSmartReply/FirebaseMLNLSmartReply.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)
|
|
@ -0,0 +1,4 @@
|
||||||
|
module Firebase {
|
||||||
|
export *
|
||||||
|
header "Firebase.h"
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
# 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'
|
||||||
|
```
|
|
@ -0,0 +1,4 @@
|
||||||
|
Version 0.3.0
|
||||||
|
======================================
|
||||||
|
- Initial public beta release.
|
||||||
|
|
BIN
ios/Pods/FirebaseABTesting/Frameworks/FirebaseABTesting.framework/FirebaseABTesting
generated
Executable file
BIN
ios/Pods/FirebaseABTesting/Frameworks/FirebaseABTesting.framework/FirebaseABTesting
generated
Executable file
Binary file not shown.
48
ios/Pods/FirebaseABTesting/Frameworks/FirebaseABTesting.framework/Headers/FIRExperimentController.h
generated
Executable file
48
ios/Pods/FirebaseABTesting/Frameworks/FirebaseABTesting.framework/Headers/FIRExperimentController.h
generated
Executable file
|
@ -0,0 +1,48 @@
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import "developers/mobile/abt/proto/ExperimentPayload.pbobjc.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@class FIRLifecycleEvents;
|
||||||
|
|
||||||
|
/// The default experiment overflow policy, that is to discard the experiment with the oldest start
|
||||||
|
/// time when users start the experiment on the web console.
|
||||||
|
extern const ABTExperimentPayload_ExperimentOverflowPolicy FIRDefaultExperimentOverflowPolicy;
|
||||||
|
|
||||||
|
/// This class is for Firebase services to handle experiments updates to Firebase Analytics.
|
||||||
|
/// Experiments can be set, cleared and updated through this controller.
|
||||||
|
@interface FIRExperimentController : NSObject
|
||||||
|
|
||||||
|
/// Returns the FIRExperimentController singleton.
|
||||||
|
+ (FIRExperimentController *)sharedInstance;
|
||||||
|
|
||||||
|
/// Updates the list of experiments. Experiments already existing in payloads are not affected,
|
||||||
|
/// whose state and payload is preserved. This method compares whether the experiments have changed
|
||||||
|
/// or not by their variant ID. This runs in a background queue.
|
||||||
|
/// @param origin The originating service affected by the experiment, it is defined at
|
||||||
|
/// Firebase Analytics FIREventOrigins.h.
|
||||||
|
/// @param events A list of event names to be used for logging experiment lifecycle events,
|
||||||
|
/// if they are not defined in the payload.
|
||||||
|
/// @param policy The policy to handle new experiments when slots are full.
|
||||||
|
/// @param lastStartTime The last known experiment start timestamp for this affected service.
|
||||||
|
/// (Timestamps are specified by the number of seconds from 00:00:00 UTC on 1
|
||||||
|
/// January 1970.).
|
||||||
|
/// @param payloads List of experiment metadata.
|
||||||
|
- (void)updateExperimentsWithServiceOrigin:(NSString *)origin
|
||||||
|
events:(FIRLifecycleEvents *)events
|
||||||
|
policy:(ABTExperimentPayload_ExperimentOverflowPolicy)policy
|
||||||
|
lastStartTime:(NSTimeInterval)lastStartTime
|
||||||
|
payloads:(NSArray<NSData *> *)payloads;
|
||||||
|
|
||||||
|
/// Returns the latest experiment start timestamp given a current latest timestamp and a list of
|
||||||
|
/// experiment payloads. Timestamps are specified by the number of seconds from 00:00:00 UTC on 1
|
||||||
|
/// January 1970.
|
||||||
|
/// @param timestamp Current latest experiment start timestamp. If not known, affected service
|
||||||
|
/// should specify -1;
|
||||||
|
/// @param payloads List of experiment metadata.
|
||||||
|
- (NSTimeInterval)latestExperimentStartTimestampBetweenTimestamp:(NSTimeInterval)timestamp
|
||||||
|
andPayloads:(NSArray<NSData *> *)payloads;
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
46
ios/Pods/FirebaseABTesting/Frameworks/FirebaseABTesting.framework/Headers/FIRLifecycleEvents.h
generated
Executable file
46
ios/Pods/FirebaseABTesting/Frameworks/FirebaseABTesting.framework/Headers/FIRLifecycleEvents.h
generated
Executable file
|
@ -0,0 +1,46 @@
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
/// Default event name for when an experiment is set.
|
||||||
|
extern NSString *const FIRSetExperimentEventName;
|
||||||
|
/// Default event name for when an experiment is activated.
|
||||||
|
extern NSString *const FIRActivateExperimentEventName;
|
||||||
|
/// Default event name for when an experiment is cleared.
|
||||||
|
extern NSString *const FIRClearExperimentEventName;
|
||||||
|
/// Default event name for when an experiment times out for being activated.
|
||||||
|
extern NSString *const FIRTimeoutExperimentEventName;
|
||||||
|
/// Default event name for when an experiment is expired as it reaches the end of TTL.
|
||||||
|
extern NSString *const FIRExpireExperimentEventName;
|
||||||
|
|
||||||
|
/// An Experiment Lifecycle Event Object that specifies the name of the experiment event to be
|
||||||
|
/// logged by Firebase Analytics.
|
||||||
|
@interface FIRLifecycleEvents : NSObject
|
||||||
|
|
||||||
|
/// Event name for when an experiment is set. It is default to FIRSetExperimentEventName and can be
|
||||||
|
/// overriden. If experiment payload has a valid string of this field, always use experiment
|
||||||
|
/// payload.
|
||||||
|
@property(nonatomic, copy) NSString *setExperimentEventName;
|
||||||
|
|
||||||
|
/// Event name for when an experiment is activated. It is default to FIRActivateExperimentEventName
|
||||||
|
/// and can be overriden. If experiment payload has a valid string of this field, always use
|
||||||
|
/// experiment payload.
|
||||||
|
@property(nonatomic, copy) NSString *activateExperimentEventName;
|
||||||
|
|
||||||
|
/// Event name for when an experiment is clearred. It is default to FIRClearExperimentEventName and
|
||||||
|
/// can be overriden. If experiment payload has a valid string of this field, always use experiment
|
||||||
|
/// payload.
|
||||||
|
@property(nonatomic, copy) NSString *clearExperimentEventName;
|
||||||
|
/// Event name for when an experiment is timeout from being STANDBY. It is default to
|
||||||
|
/// FIRTimeoutExperimentEventName and can be overriden. If experiment payload has a valid string
|
||||||
|
/// of this field, always use experiment payload.
|
||||||
|
@property(nonatomic, copy) NSString *timeoutExperimentEventName;
|
||||||
|
|
||||||
|
/// Event name when an experiment is expired when it reaches the end of its TTL.
|
||||||
|
/// It is default to FIRExpireExperimentEventName and can be overriden. If experiment payload has a
|
||||||
|
/// valid string of this field, always use experiment payload.
|
||||||
|
@property(nonatomic, copy) NSString *expireExperimentEventName;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
2
ios/Pods/FirebaseABTesting/Frameworks/FirebaseABTesting.framework/Headers/FirebaseABTesting.h
generated
Executable file
2
ios/Pods/FirebaseABTesting/Frameworks/FirebaseABTesting.framework/Headers/FirebaseABTesting.h
generated
Executable file
|
@ -0,0 +1,2 @@
|
||||||
|
#import "FIRExperimentController.h"
|
||||||
|
#import "FIRLifecycleEvents.h"
|
7
ios/Pods/FirebaseABTesting/Frameworks/FirebaseABTesting.framework/Modules/module.modulemap
generated
Executable file
7
ios/Pods/FirebaseABTesting/Frameworks/FirebaseABTesting.framework/Modules/module.modulemap
generated
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
framework module FirebaseABTesting {
|
||||||
|
umbrella header "FirebaseABTesting.h"
|
||||||
|
export *
|
||||||
|
module * { export *}
|
||||||
|
link "z"
|
||||||
|
link framework "Security"
|
||||||
|
link framework "SystemConfiguration"}
|
|
@ -0,0 +1,11 @@
|
||||||
|
# Firebase ABTesting SDK for iOS
|
||||||
|
|
||||||
|
A/B testing is a Firebase service that lets you run experiments across users of
|
||||||
|
your iOS and Android apps. It lets you learn how well one or more changes to
|
||||||
|
your app work with a smaller set of users before you roll out changes to all
|
||||||
|
users. You run experiments to find the most effective ways to use the
|
||||||
|
Notifications composer and Firebase Remote Config in your app.
|
||||||
|
|
||||||
|
Please visit [our developer site]
|
||||||
|
(https://firebase.google.com/docs/ab-testing/) for integration instructions,
|
||||||
|
documentations, support information, and terms of service.
|
BIN
ios/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector
generated
Executable file
BIN
ios/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector
generated
Executable file
Binary file not shown.
10
ios/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/Modules/module.modulemap
generated
Executable file
10
ios/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/Modules/module.modulemap
generated
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
framework module FIRAnalyticsConnector {
|
||||||
|
export *
|
||||||
|
module * { export * }
|
||||||
|
link "sqlite3"
|
||||||
|
link "z"
|
||||||
|
link framework "Security"
|
||||||
|
link framework "StoreKit"
|
||||||
|
link framework "SystemConfiguration"
|
||||||
|
link framework "UIKit"
|
||||||
|
}
|
BIN
ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/FirebaseAnalytics
generated
Executable file
BIN
ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/FirebaseAnalytics
generated
Executable file
Binary file not shown.
62
ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h
generated
Executable file
62
ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h
generated
Executable file
|
@ -0,0 +1,62 @@
|
||||||
|
#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:] (on iOS 9.0 and
|
||||||
|
* above), or [UIApplicationDelegate application:openURL:sourceApplication:annotation:] (on
|
||||||
|
* iOS 8.x and below) 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
|
||||||
|
|
132
ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics.h
generated
Executable file
132
ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics.h
generated
Executable file
|
@ -0,0 +1,132 @@
|
||||||
|
#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;
|
||||||
|
|
||||||
|
/// Sets whether analytics collection is enabled for this app on this device. This setting is
|
||||||
|
/// persisted across app sessions. By default it is enabled.
|
||||||
|
///
|
||||||
|
/// @param analyticsCollectionEnabled A flag that enables or disables Analytics collection.
|
||||||
|
+ (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled;
|
||||||
|
|
||||||
|
/// Sets the interval of inactivity in seconds that terminates the current session. The default
|
||||||
|
/// value is 1800 seconds (30 minutes).
|
||||||
|
///
|
||||||
|
/// @param sessionTimeoutInterval The custom time of inactivity in seconds before the current
|
||||||
|
/// session terminates.
|
||||||
|
+ (void)setSessionTimeoutInterval:(NSTimeInterval)sessionTimeoutInterval;
|
||||||
|
|
||||||
|
/// 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
|
407
ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIREventNames.h
generated
Executable file
407
ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIREventNames.h
generated
Executable file
|
@ -0,0 +1,407 @@
|
||||||
|
/// @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";
|
532
ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRParameterNames.h
generated
Executable file
532
ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRParameterNames.h
generated
Executable file
|
@ -0,0 +1,532 @@
|
||||||
|
/// @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";
|
17
ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h
generated
Executable file
17
ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h
generated
Executable file
|
@ -0,0 +1,17 @@
|
||||||
|
/// @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";
|
5
ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h
generated
Executable file
5
ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h
generated
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
#import "FIRAnalytics+AppDelegate.h"
|
||||||
|
#import "FIRAnalytics.h"
|
||||||
|
#import "FIREventNames.h"
|
||||||
|
#import "FIRParameterNames.h"
|
||||||
|
#import "FIRUserPropertyNames.h"
|
11
ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Modules/module.modulemap
generated
Executable file
11
ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Modules/module.modulemap
generated
Executable file
|
@ -0,0 +1,11 @@
|
||||||
|
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"
|
||||||
|
}
|
BIN
ios/Pods/FirebaseAnalytics/Frameworks/FirebaseCoreDiagnostics.framework/FirebaseCoreDiagnostics
generated
Executable file
BIN
ios/Pods/FirebaseAnalytics/Frameworks/FirebaseCoreDiagnostics.framework/FirebaseCoreDiagnostics
generated
Executable file
Binary file not shown.
7
ios/Pods/FirebaseAnalytics/Frameworks/FirebaseCoreDiagnostics.framework/Modules/module.modulemap
generated
Executable file
7
ios/Pods/FirebaseAnalytics/Frameworks/FirebaseCoreDiagnostics.framework/Modules/module.modulemap
generated
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
framework module FirebaseCoreDiagnostics {
|
||||||
|
export *
|
||||||
|
module * { export * }
|
||||||
|
link "z"
|
||||||
|
link framework "Security"
|
||||||
|
link framework "SystemConfiguration"
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
// 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"
|
||||||
|
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
|
||||||
|
@implementation FIRAnalyticsConfiguration
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
|
||||||
|
+ (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
|
|
@ -0,0 +1,829 @@
|
||||||
|
// 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 can only contain alphanumeric (A-Z,a-z,0-9), "
|
||||||
|
@"hyphen (-), and underscore (_) characters"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@synchronized(self) {
|
||||||
|
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.");
|
||||||
|
}
|
||||||
|
return [sAllApps copy];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Public only for tests
|
||||||
|
+ (void)resetApps {
|
||||||
|
@synchronized(self) {
|
||||||
|
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"
|
||||||
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
[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.
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
[[FIRAnalyticsConfiguration sharedInstance]
|
||||||
|
setAnalyticsCollectionEnabled:dataCollectionDefaultEnabled
|
||||||
|
persistSetting:NO];
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
}
|
||||||
|
|
||||||
|
- (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?
|
||||||
|
@synchronized(self) {
|
||||||
|
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) {
|
||||||
|
@synchronized(self) {
|
||||||
|
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];
|
||||||
|
});
|
||||||
|
@synchronized(self) {
|
||||||
|
[sRegisteredAsConfigurable addObject:library];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[self registerLibrary:name withVersion:version];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSString *)firebaseUserAgent {
|
||||||
|
@synchronized(self) {
|
||||||
|
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 hasBundleIdentifierPrefix: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;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSScanner *stringScanner = [NSScanner scannerWithString:appID];
|
||||||
|
stringScanner.charactersToBeSkipped = nil;
|
||||||
|
|
||||||
|
NSString *appIDVersion;
|
||||||
|
if (![stringScanner scanCharactersFromSet:[NSCharacterSet decimalDigitCharacterSet]
|
||||||
|
intoString:&appIDVersion]) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (![stringScanner scanString:@":" intoString:NULL]) {
|
||||||
|
// appIDVersion must be separated by ":"
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSArray *knownVersions = @[ @"1" ];
|
||||||
|
if (![knownVersions containsObject:appIDVersion]) {
|
||||||
|
// Permit unknown yet properly formatted app ID versions.
|
||||||
|
FIRLogInfo(kFIRLoggerCore, @"I-COR000010", @"Unknown GOOGLE_APP_ID version: %@", appIDVersion);
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (![self validateAppIDFormat:appID withVersion:appIDVersion]) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (![self 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSScanner *stringScanner = [NSScanner scannerWithString:appID];
|
||||||
|
stringScanner.charactersToBeSkipped = nil;
|
||||||
|
|
||||||
|
// Skip version part
|
||||||
|
// '*<version #>*:<project number>:ios:<fingerprint of bundle id>'
|
||||||
|
if (![stringScanner scanString:version intoString:NULL]) {
|
||||||
|
// The version part is missing or mismatched
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate version part (see part between '*' symbols below)
|
||||||
|
// '<version #>*:*<project number>:ios:<fingerprint of bundle id>'
|
||||||
|
if (![stringScanner scanString:@":" intoString:NULL]) {
|
||||||
|
// appIDVersion must be separated by ":"
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate version part (see part between '*' symbols below)
|
||||||
|
// '<version #>:*<project number>*:ios:<fingerprint of bundle id>'.
|
||||||
|
NSInteger projectNumber = NSNotFound;
|
||||||
|
if (![stringScanner scanInteger:&projectNumber]) {
|
||||||
|
// NO project number found.
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate version part (see part between '*' symbols below)
|
||||||
|
// '<version #>:<project number>*:*ios:<fingerprint of bundle id>'.
|
||||||
|
if (![stringScanner scanString:@":" intoString:NULL]) {
|
||||||
|
// The project number must be separated by ":"
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate version part (see part between '*' symbols below)
|
||||||
|
// '<version #>:<project number>:*ios*:<fingerprint of bundle id>'.
|
||||||
|
NSString *platform;
|
||||||
|
if (![stringScanner scanUpToString:@":" intoString:&platform]) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (![platform isEqualToString:@"ios"]) {
|
||||||
|
// The platform must be @"ios"
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate version part (see part between '*' symbols below)
|
||||||
|
// '<version #>:<project number>:ios*:*<fingerprint of bundle id>'.
|
||||||
|
if (![stringScanner scanString:@":" intoString:NULL]) {
|
||||||
|
// The platform must be separated by ":"
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate version part (see part between '*' symbols below)
|
||||||
|
// '<version #>:<project number>:ios:*<fingerprint of bundle id>*'.
|
||||||
|
unsigned long long fingerprint = NSNotFound;
|
||||||
|
if (![stringScanner scanHexLongLong:&fingerprint]) {
|
||||||
|
// Fingerprint part is missing
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stringScanner.isAtEnd) {
|
||||||
|
// There are not allowed characters in the fingerprint part
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that the fingerprint of the app ID string is what is expected based on the supplied
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
* 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 {
|
||||||
|
// 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
|
|
@ -0,0 +1,47 @@
|
||||||
|
// 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
|
|
@ -0,0 +1,75 @@
|
||||||
|
// 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"
|
||||||
|
|
||||||
|
#import <GoogleUtilities/GULAppEnvironmentUtil.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)hasBundleIdentifierPrefix:(NSString *)bundleIdentifier inBundles:(NSArray *)bundles {
|
||||||
|
for (NSBundle *bundle in bundles) {
|
||||||
|
// This allows app extensions that have the app's bundle as their prefix to pass this test.
|
||||||
|
NSString *applicationBundleIdentifier =
|
||||||
|
[GULAppEnvironmentUtil isAppExtension]
|
||||||
|
? [self bundleIdentifierByRemovingLastPartFrom:bundleIdentifier]
|
||||||
|
: bundleIdentifier;
|
||||||
|
|
||||||
|
if ([applicationBundleIdentifier isEqualToString:bundle.bundleIdentifier]) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSString *)bundleIdentifierByRemovingLastPartFrom:(NSString *)bundleIdentifier {
|
||||||
|
NSString *bundleIDComponentsSeparator = @".";
|
||||||
|
|
||||||
|
NSMutableArray<NSString *> *bundleIDComponents =
|
||||||
|
[[bundleIdentifier componentsSeparatedByString:bundleIDComponentsSeparator] mutableCopy];
|
||||||
|
[bundleIDComponents removeLastObject];
|
||||||
|
|
||||||
|
return [bundleIDComponents componentsJoinedByString:bundleIDComponentsSeparator];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* 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
|
|
@ -0,0 +1,176 @@
|
||||||
|
/*
|
||||||
|
* 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
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* 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
|
|
@ -0,0 +1,47 @@
|
||||||
|
// 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) {
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
_analyticsConfiguration = [FIRAnalyticsConfiguration sharedInstance];
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setLoggerLevel:(FIRLoggerLevel)loggerLevel {
|
||||||
|
NSAssert(loggerLevel <= FIRLoggerLevelMax && loggerLevel >= FIRLoggerLevelMin,
|
||||||
|
@"Invalid logger level, %ld", (long)loggerLevel);
|
||||||
|
FIRSetLoggerLevel(loggerLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue