@aparajita/capacitor-biometric-auth 1.0.7 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AparajitaCapacitorBiometricAuth.podspec +2 -2
- package/README.md +76 -62
- package/android/src/main/java/com/aparajita/capacitor/biometricauth/AuthActivity.java +123 -95
- package/android/src/main/java/com/aparajita/capacitor/biometricauth/BiometricAuth.java +262 -0
- package/android/src/main/java/com/aparajita/capacitor/biometricauth/BiometryResultType.java +3 -3
- package/dist/esm/definitions.d.ts +26 -33
- package/dist/esm/definitions.js +2 -2
- package/dist/esm/index.d.ts +4 -1
- package/dist/esm/index.js +17 -2
- package/dist/esm/package.json +113 -0
- package/dist/esm/web.d.ts +6 -6
- package/dist/esm/web.js +36 -29
- package/dist/plugin.cjs.js +172 -0
- package/dist/plugin.js +173 -0
- package/ios/Plugin/Plugin.m +3 -1
- package/ios/Plugin/Plugin.swift +6 -6
- package/package.json +76 -48
- package/CHANGELOG.md +0 -71
- package/android/gradle.properties +0 -21
- package/android/settings.gradle +0 -2
- package/android/src/main/java/com/aparajita/capacitor/biometricauth/WSBiometricAuth.java +0 -216
- package/ios/Podfile +0 -16
- package/ios/Podfile.lock +0 -22
package/CHANGELOG.md
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
|
-
|
|
5
|
-
### [1.0.7](https://github.com/aparajita/capacitor-biometric-auth/compare/v1.0.6...v1.0.7) (2021-04-02)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
### Maintenance
|
|
9
|
-
|
|
10
|
-
* eliminate unnecessary stuff in the package ([3aaa594](https://github.com/aparajita/capacitor-biometric-auth/commit/3aaa594541ec6ece3d2c1b3e184014c0741b0070))
|
|
11
|
-
|
|
12
|
-
### [1.0.6](https://github.com/aparajita/capacitor-biometric-auth/compare/v1.0.5...v1.0.6) (2021-04-01)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
### Maintenance
|
|
16
|
-
|
|
17
|
-
* fix license ([9852042](https://github.com/aparajita/capacitor-biometric-auth/commit/9852042678248de14adeab9ad4da7ef9ffa1310c))
|
|
18
|
-
|
|
19
|
-
### [1.0.5](https://github.com/aparajita/capacitor-biometric-auth/compare/v1.0.4...v1.0.5) (2021-04-01)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
### Maintenance
|
|
23
|
-
|
|
24
|
-
* fix link ([4609b1d](https://github.com/aparajita/capacitor-biometric-auth/commit/4609b1d977b2507f833d0da0fb8b35615408357c))
|
|
25
|
-
* fix urls ([19954c0](https://github.com/aparajita/capacitor-biometric-auth/commit/19954c05373792bf86cbdbbb00a3f15252bde274))
|
|
26
|
-
|
|
27
|
-
### [1.0.4](https://github.com/aparajita/capacitor-biometric-auth/compare/v1.0.3...v1.0.4) (2021-03-31)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
### Maintenance
|
|
31
|
-
|
|
32
|
-
* add license ([938b24f](https://github.com/aparajita/capacitor-biometric-auth/commit/938b24f9e3e551101297acc8be96c5ab00f710e1))
|
|
33
|
-
* add push script ([6069525](https://github.com/aparajita/capacitor-biometric-auth/commit/6069525d84e319e54d0d62bc2b73c216aa7ac245))
|
|
34
|
-
|
|
35
|
-
### [1.0.3](https://github.com/aparajita/capacitor-biometric-auth/compare/v1.0.2...v1.0.3) (2021-03-31)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
### Maintenance
|
|
39
|
-
|
|
40
|
-
* fix urls ([eed2a14](https://github.com/aparajita/capacitor-biometric-auth/commit/eed2a147b76cc7718d27a3c2464584cd4c95db63))
|
|
41
|
-
|
|
42
|
-
### [1.0.2](https://github.com/willsub/ws-capacitor-biometric-auth/compare/v1.0.1...v1.0.2) (2021-03-31)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
### Bug Fixes
|
|
46
|
-
|
|
47
|
-
* change target to transform optional chaining ([f278127](https://github.com/willsub/ws-capacitor-biometric-auth/commit/f278127247bbb7881fe93dee889193b6fd641966))
|
|
48
|
-
* deps in the wrong place ([0746a21](https://github.com/willsub/ws-capacitor-biometric-auth/commit/0746a21c1a5a8a89d5e84544de13295719797171))
|
|
49
|
-
|
|
50
|
-
### [1.0.1](https://github.com/willsub/ws-capacitor-biometric-auth/compare/v1.0.0...v1.0.1) (2021-03-29)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
### Features
|
|
54
|
-
|
|
55
|
-
* add docs ([dd96a67](https://github.com/willsub/ws-capacitor-biometric-auth/commit/dd96a673edeb8d9362bdde908698e45428426919))
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
### Bug Fixes
|
|
59
|
-
|
|
60
|
-
* options might be undefined ([8e66f7e](https://github.com/willsub/ws-capacitor-biometric-auth/commit/8e66f7ea6b77916194106f8687156585504da250))
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
### Maintenance
|
|
64
|
-
|
|
65
|
-
* always use strict mode ([b8fa32a](https://github.com/willsub/ws-capacitor-biometric-auth/commit/b8fa32ac3fba8f20506e0c645acbc17a1cbb1ac8))
|
|
66
|
-
* clean up loose ends ([876561c](https://github.com/willsub/ws-capacitor-biometric-auth/commit/876561c1ac8f4b51d47307f67c5d9ecf235ac71a))
|
|
67
|
-
* lint ([1780d90](https://github.com/willsub/ws-capacitor-biometric-auth/commit/1780d9017e803a3eed5855f5e51813a6d11ec81c))
|
|
68
|
-
* rename package ([b2cf9dd](https://github.com/willsub/ws-capacitor-biometric-auth/commit/b2cf9dd21c1fa838103353a5ee780ee5ac135621))
|
|
69
|
-
* update deps ([9edbd18](https://github.com/willsub/ws-capacitor-biometric-auth/commit/9edbd18202c3e553a94561a5d05c1528cacc1464))
|
|
70
|
-
* update scripts ([2f1f5be](https://github.com/willsub/ws-capacitor-biometric-auth/commit/2f1f5bee235b5b4767622c3570cdd6a5de20f637))
|
|
71
|
-
* **deps:** updated ([c753fa3](https://github.com/willsub/ws-capacitor-biometric-auth/commit/c753fa32dbcbeb3bc601b261c675e071d7733c01))
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# Project-wide Gradle settings.
|
|
2
|
-
|
|
3
|
-
# IDE (e.g. Android Studio) users:
|
|
4
|
-
# Gradle settings configured through the IDE *will override*
|
|
5
|
-
# any settings specified in this file.
|
|
6
|
-
|
|
7
|
-
# For more details on how to configure your build environment visit
|
|
8
|
-
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
|
9
|
-
|
|
10
|
-
# Specifies the JVM arguments used for the daemon process.
|
|
11
|
-
# The setting is particularly useful for tweaking memory settings.
|
|
12
|
-
org.gradle.jvmargs=-Xmx1536m
|
|
13
|
-
|
|
14
|
-
# When configured, Gradle will run in incubating parallel mode.
|
|
15
|
-
# This option should only be used with decoupled projects. More details, visit
|
|
16
|
-
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
|
17
|
-
# org.gradle.parallel=true
|
|
18
|
-
|
|
19
|
-
# Supports AndroidX
|
|
20
|
-
android.useAndroidX=true
|
|
21
|
-
android.enableJetifier=true
|
package/android/settings.gradle
DELETED
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
package com.aparajita.capacitor.biometricauth;
|
|
2
|
-
|
|
3
|
-
import android.app.Activity;
|
|
4
|
-
import android.content.Intent;
|
|
5
|
-
import android.content.pm.PackageManager;
|
|
6
|
-
import androidx.biometric.BiometricManager;
|
|
7
|
-
import androidx.biometric.BiometricPrompt;
|
|
8
|
-
import com.getcapacitor.JSObject;
|
|
9
|
-
import com.getcapacitor.NativePlugin;
|
|
10
|
-
import com.getcapacitor.Plugin;
|
|
11
|
-
import com.getcapacitor.PluginCall;
|
|
12
|
-
import com.getcapacitor.PluginMethod;
|
|
13
|
-
import java.util.HashMap;
|
|
14
|
-
|
|
15
|
-
@NativePlugin(requestCodes = { WSBiometricAuth.REQUEST_CODE })
|
|
16
|
-
public class WSBiometricAuth extends Plugin {
|
|
17
|
-
|
|
18
|
-
public static final String RESULT_TYPE = "type";
|
|
19
|
-
public static final String RESULT_ERROR_CODE = "errorCode";
|
|
20
|
-
public static final String RESULT_ERROR_MESSAGE = "errorMessage";
|
|
21
|
-
public static final String TITLE = "androidTitle";
|
|
22
|
-
public static final String SUBTITLE = "androidSubtitle";
|
|
23
|
-
public static final String REASON = "reason";
|
|
24
|
-
public static final String CANCEL_TITLE = "cancelTitle";
|
|
25
|
-
public static final String DEVICE_CREDENTIAL = "allowDeviceCredential";
|
|
26
|
-
public static final String MAX_ATTEMPTS = "androidMaxAttempts";
|
|
27
|
-
public static final int DEFAULT_MAX_ATTEMPTS = 3;
|
|
28
|
-
// Error code when biometry is not recognized
|
|
29
|
-
public static final String BIOMETRIC_FAILURE = "authenticationFailed";
|
|
30
|
-
// Biometry prompt
|
|
31
|
-
protected static final int REQUEST_CODE = 1931;
|
|
32
|
-
// Maps biometry error numbers to string error codes
|
|
33
|
-
private static final HashMap<Integer, String> biometryErrorCodeMap;
|
|
34
|
-
private static final HashMap<BiometryType, String> biometryNameMap;
|
|
35
|
-
private static final String INVALID_CONTEXT_ERROR = "invalidContext";
|
|
36
|
-
public static String RESULT_EXTRA_PREFIX;
|
|
37
|
-
|
|
38
|
-
static {
|
|
39
|
-
biometryErrorCodeMap = new HashMap<>();
|
|
40
|
-
biometryErrorCodeMap.put(BiometricPrompt.ERROR_CANCELED, "systemCancel");
|
|
41
|
-
biometryErrorCodeMap.put(BiometricPrompt.ERROR_HW_NOT_PRESENT, "biometryNotAvailable");
|
|
42
|
-
biometryErrorCodeMap.put(BiometricPrompt.ERROR_HW_UNAVAILABLE, "biometryNotAvailable");
|
|
43
|
-
biometryErrorCodeMap.put(BiometricPrompt.ERROR_LOCKOUT, "biometryLockout");
|
|
44
|
-
biometryErrorCodeMap.put(BiometricPrompt.ERROR_LOCKOUT_PERMANENT, "biometryLockout");
|
|
45
|
-
biometryErrorCodeMap.put(BiometricPrompt.ERROR_NEGATIVE_BUTTON, "userCancel");
|
|
46
|
-
biometryErrorCodeMap.put(BiometricPrompt.ERROR_NO_BIOMETRICS, "biometryNotEnrolled");
|
|
47
|
-
biometryErrorCodeMap.put(BiometricPrompt.ERROR_NO_DEVICE_CREDENTIAL, "noDeviceCredential");
|
|
48
|
-
biometryErrorCodeMap.put(BiometricPrompt.ERROR_NO_SPACE, "systemCancel");
|
|
49
|
-
biometryErrorCodeMap.put(BiometricPrompt.ERROR_TIMEOUT, "systemCancel");
|
|
50
|
-
biometryErrorCodeMap.put(BiometricPrompt.ERROR_UNABLE_TO_PROCESS, "systemCancel");
|
|
51
|
-
biometryErrorCodeMap.put(BiometricPrompt.ERROR_USER_CANCELED, "userCancel");
|
|
52
|
-
biometryErrorCodeMap.put(BiometricPrompt.ERROR_VENDOR, "systemCancel");
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
static {
|
|
56
|
-
biometryNameMap = new HashMap<>();
|
|
57
|
-
biometryNameMap.put(BiometryType.NONE, "No Authentication");
|
|
58
|
-
biometryNameMap.put(BiometryType.FINGERPRINT, "Fingerprint Authentication");
|
|
59
|
-
biometryNameMap.put(BiometryType.FACE, "Face Authentication");
|
|
60
|
-
biometryNameMap.put(BiometryType.IRIS, "Iris Authentication");
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
private BiometryType biometryType;
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Check the device's availability and type of biometric authentication.
|
|
67
|
-
*/
|
|
68
|
-
@PluginMethod
|
|
69
|
-
public void checkBiometry(PluginCall call) {
|
|
70
|
-
BiometricManager manager = BiometricManager.from(getContext());
|
|
71
|
-
|
|
72
|
-
int result = manager.canAuthenticate();
|
|
73
|
-
|
|
74
|
-
JSObject ret = new JSObject();
|
|
75
|
-
ret.put("isAvailable", result == BiometricManager.BIOMETRIC_SUCCESS);
|
|
76
|
-
biometryType = getDeviceBiometryType();
|
|
77
|
-
ret.put("biometryType", biometryType.getType());
|
|
78
|
-
|
|
79
|
-
String reason = "";
|
|
80
|
-
|
|
81
|
-
switch (result) {
|
|
82
|
-
case BiometricManager.BIOMETRIC_SUCCESS:
|
|
83
|
-
break;
|
|
84
|
-
case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE:
|
|
85
|
-
reason = "Biometry hardware is present, but currently unavailable.";
|
|
86
|
-
break;
|
|
87
|
-
case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED:
|
|
88
|
-
reason = "The user does not have any biometrics enrolled.";
|
|
89
|
-
break;
|
|
90
|
-
case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE:
|
|
91
|
-
reason = "There is no biometric hardware on this device.";
|
|
92
|
-
break;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
ret.put("reason", reason);
|
|
96
|
-
call.resolve(ret);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
private BiometryType getDeviceBiometryType() {
|
|
100
|
-
PackageManager manager = getContext().getPackageManager();
|
|
101
|
-
|
|
102
|
-
if (manager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
|
|
103
|
-
return BiometryType.FINGERPRINT;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (manager.hasSystemFeature(PackageManager.FEATURE_FACE)) {
|
|
107
|
-
return BiometryType.FACE;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (manager.hasSystemFeature(PackageManager.FEATURE_IRIS)) {
|
|
111
|
-
return BiometryType.IRIS;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return BiometryType.NONE;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Prompt the user for biometric authentication.
|
|
119
|
-
*/
|
|
120
|
-
@PluginMethod
|
|
121
|
-
public void authenticate(final PluginCall call) {
|
|
122
|
-
// The result of an intent is supposed to have the package name as a prefix
|
|
123
|
-
RESULT_EXTRA_PREFIX = getContext().getPackageName() + ".";
|
|
124
|
-
|
|
125
|
-
Intent intent = new Intent(getContext(), AuthActivity.class);
|
|
126
|
-
|
|
127
|
-
// Pass the options to the activity
|
|
128
|
-
intent.putExtra(TITLE, call.getString(TITLE, biometryNameMap.get(biometryType)));
|
|
129
|
-
intent.putExtra(SUBTITLE, call.getString(SUBTITLE));
|
|
130
|
-
intent.putExtra(REASON, call.getString(REASON));
|
|
131
|
-
intent.putExtra(CANCEL_TITLE, call.getString(CANCEL_TITLE));
|
|
132
|
-
intent.putExtra(DEVICE_CREDENTIAL, call.getBoolean(DEVICE_CREDENTIAL, false));
|
|
133
|
-
|
|
134
|
-
// Just in case the developer does something dumb like using a number < 1...
|
|
135
|
-
int maxAttempts = Math.max(call.getInt(MAX_ATTEMPTS, DEFAULT_MAX_ATTEMPTS), 1);
|
|
136
|
-
intent.putExtra(MAX_ATTEMPTS, maxAttempts);
|
|
137
|
-
|
|
138
|
-
saveCall(call);
|
|
139
|
-
startActivityForResult(call, intent, REQUEST_CODE);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
@Override
|
|
143
|
-
protected void handleOnActivityResult(int requestCode, int resultCode, Intent data) {
|
|
144
|
-
super.handleOnActivityResult(requestCode, resultCode, data);
|
|
145
|
-
PluginCall call = getSavedCall();
|
|
146
|
-
|
|
147
|
-
// Make sure this the auth activity we started and it returned some data
|
|
148
|
-
if (requestCode != REQUEST_CODE) {
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// If the system canceled the activity, we might get RESULT_CANCELED in resultCode.
|
|
153
|
-
// In that case return that immediately, because there won't be any data.
|
|
154
|
-
if (resultCode == Activity.RESULT_CANCELED) {
|
|
155
|
-
call.reject("The system canceled authentication", biometryErrorCodeMap.get(BiometricPrompt.ERROR_CANCELED));
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Convert the string result type to an enum
|
|
160
|
-
String resultTypeName = data.getStringExtra(RESULT_EXTRA_PREFIX + WSBiometricAuth.RESULT_TYPE);
|
|
161
|
-
|
|
162
|
-
if (resultTypeName == null) {
|
|
163
|
-
call.reject("Missing data in the result of the activity", INVALID_CONTEXT_ERROR);
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
BiometryResultType resultType;
|
|
168
|
-
|
|
169
|
-
try {
|
|
170
|
-
resultType = BiometryResultType.valueOf(resultTypeName);
|
|
171
|
-
} catch (IllegalArgumentException e) {
|
|
172
|
-
call.reject("Invalid data in the result of the activity", INVALID_CONTEXT_ERROR);
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
int errorCode = data.getIntExtra(RESULT_EXTRA_PREFIX + WSBiometricAuth.RESULT_ERROR_CODE, 0);
|
|
177
|
-
String errorMessage = data.getStringExtra(RESULT_EXTRA_PREFIX + WSBiometricAuth.RESULT_ERROR_MESSAGE);
|
|
178
|
-
|
|
179
|
-
switch (resultType) {
|
|
180
|
-
case SUCCESS:
|
|
181
|
-
call.resolve();
|
|
182
|
-
break;
|
|
183
|
-
case FAILURE:
|
|
184
|
-
// Biometry was successfully presented but was not recognized
|
|
185
|
-
call.reject(errorMessage, BIOMETRIC_FAILURE);
|
|
186
|
-
break;
|
|
187
|
-
case ERROR:
|
|
188
|
-
// The user cancelled, the system cancelled, or some error occurred.
|
|
189
|
-
// If the user cancelled, errorMessage is the text of the "negative" button,
|
|
190
|
-
// which is not especially descriptive.
|
|
191
|
-
if (errorCode == BiometricPrompt.ERROR_NEGATIVE_BUTTON) {
|
|
192
|
-
errorMessage = "Cancel button was pressed";
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
call.reject(errorMessage, biometryErrorCodeMap.get(errorCode));
|
|
196
|
-
break;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
enum BiometryType {
|
|
201
|
-
NONE(0),
|
|
202
|
-
FINGERPRINT(3),
|
|
203
|
-
FACE(4),
|
|
204
|
-
IRIS(5);
|
|
205
|
-
|
|
206
|
-
private final int type;
|
|
207
|
-
|
|
208
|
-
BiometryType(int type) {
|
|
209
|
-
this.type = type;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
public int getType() {
|
|
213
|
-
return this.type;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
package/ios/Podfile
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
platform :ios, '11.0'
|
|
2
|
-
|
|
3
|
-
def capacitor_pods
|
|
4
|
-
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
|
|
5
|
-
use_frameworks!
|
|
6
|
-
pod 'Capacitor', :path => '../node_modules/@capacitor/ios'
|
|
7
|
-
pod 'CapacitorCordova', :path => '../node_modules/@capacitor/ios'
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
target 'Plugin' do
|
|
11
|
-
capacitor_pods
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
target 'PluginTests' do
|
|
15
|
-
capacitor_pods
|
|
16
|
-
end
|
package/ios/Podfile.lock
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
PODS:
|
|
2
|
-
- Capacitor (2.0.1):
|
|
3
|
-
- CapacitorCordova (= 2.0.1)
|
|
4
|
-
- CapacitorCordova (2.0.1)
|
|
5
|
-
|
|
6
|
-
DEPENDENCIES:
|
|
7
|
-
- "Capacitor (from `../node_modules/@capacitor/ios`)"
|
|
8
|
-
- "CapacitorCordova (from `../node_modules/@capacitor/ios`)"
|
|
9
|
-
|
|
10
|
-
EXTERNAL SOURCES:
|
|
11
|
-
Capacitor:
|
|
12
|
-
:path: "../node_modules/@capacitor/ios"
|
|
13
|
-
CapacitorCordova:
|
|
14
|
-
:path: "../node_modules/@capacitor/ios"
|
|
15
|
-
|
|
16
|
-
SPEC CHECKSUMS:
|
|
17
|
-
Capacitor: 893baa42b33635ddf23d29d23d2a7f33f7c08bc7
|
|
18
|
-
CapacitorCordova: 9fee2eb6780331b6ff09710d6a7d1f2e4707f1b9
|
|
19
|
-
|
|
20
|
-
PODFILE CHECKSUM: 18edf3816e869cc37578950affc00fdd78ee0dcb
|
|
21
|
-
|
|
22
|
-
COCOAPODS: 1.9.1
|