Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
775f219
chore: FCM 푸시 알림용 Android 네이티브 설정 추가
jeonbinggu Jul 12, 2026
4f6e83c
feat: 기기 토큰 등록/해제 API 클라이언트 추가
jeonbinggu Jul 12, 2026
6682572
feat: 푸시 알림 등록/수신/딥링크 훅 추가 및 RootLayout 연동
jeonbinggu Jul 12, 2026
04a61d4
feat: 로그아웃/탈퇴 시 기기 토큰 해제 연동
jeonbinggu Jul 12, 2026
a97bee5
chore: iOS FCM 푸시 네이티브 설정 추가
hyunseo-han Aug 1, 2026
48a1212
feat: iOS FCM 등록 토큰 브릿지 추가
hyunseo-han Aug 1, 2026
a2bb9ef
Merge branch 'develop' of https://github.com/Finders-Official/Web int…
jeonbinggu Aug 8, 2026
76a6a08
fix: iOS 포그라운드 푸시가 표시되지 않던 문제 수정
jeonbinggu Aug 8, 2026
147b67d
fix: 푸시 알림 리스너 등록 레이스 컨디션 수정
jeonbinggu Aug 8, 2026
95d793d
fix: 로그아웃·탈퇴 시 기기 토큰 해제가 401로 실패하던 문제 수정
jeonbinggu Aug 8, 2026
8d369ff
fix: 푸시 알림 아이콘·토큰 회전·딥링크 방어 보완
jeonbinggu Aug 9, 2026
bd04445
fix: 기기 토큰 등록 실패가 무음으로 사라지던 문제 수정
jeonbinggu Aug 9, 2026
7534948
fix: 세션 만료 시 로그인 화면으로 이동하지 않던 문제 수정(#345)
jeonbinggu Aug 10, 2026
a6121f3
fix: 푸시 딥링크 상대경로 이동·iOS 기기 토큰 중복 등록 수정(#345)
jeonbinggu Aug 10, 2026
4532b06
fix: 탈퇴 시 항상 401로 실패하던 기기 토큰 해제 호출 제거(#345)
jeonbinggu Aug 10, 2026
fc13136
feat: 푸시 딥링크를 route 문자열에서 action 계약으로 전환(#345)
jeonbinggu Aug 10, 2026
8c32ee4
fix: Android 헤즈업 알림 채널 추가(#345)
jeonbinggu Aug 10, 2026
beea5e3
Merge branch 'develop' of https://github.com/Finders-Official/Web int…
jeonbinggu Aug 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions android/app/capacitor.build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ dependencies {
implementation project(':capacitor-file-transfer')
implementation project(':capacitor-filesystem')
implementation project(':capacitor-geolocation')
implementation project(':capacitor-push-notifications')
implementation project(':capacitor-share')
implementation project(':capacitor-splash-screen')
implementation project(':capacitor-secure-storage-plugin')
Expand Down
16 changes: 16 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,27 @@
</provider>

<meta-data android:name="com.kakao.sdk.AppKey" android:value="@string/kakao_app_key" />

<!-- 상태바 알림 아이콘. 지정하지 않으면 런처 아이콘(배경 포함)이 쓰이는데,
Android는 알파 채널만 남겨 실루엣으로 그리므로 흰 사각형이 된다.
배경 없는 로고 레이어를 쓴다. -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@mipmap/ic_launcher_foreground" />

<!-- 서버가 channelId를 지정하지 않을 때 쓰이는 채널. 지정하지 않으면 FCM이
importance DEFAULT인 fallback 채널로 떨어뜨려 헤즈업 배너가 뜨지 않는다.
채널 자체는 usePushNotifications의 createChannel이 만든다 — id를 같이 바꿀 것. -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="finders_default" />
</application>

<!-- Permissions -->

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Android 13(API 33)+ 알림 표시를 위한 런타임 권한 (FCM 푸시) -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
</manifest>
3 changes: 3 additions & 0 deletions android/capacitor.settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ project(':capacitor-filesystem').projectDir = new File('../node_modules/@capacit
include ':capacitor-geolocation'
project(':capacitor-geolocation').projectDir = new File('../node_modules/@capacitor/geolocation/android')

include ':capacitor-push-notifications'
project(':capacitor-push-notifications').projectDir = new File('../node_modules/@capacitor/push-notifications/android')

include ':capacitor-share'
project(':capacitor-share').projectDir = new File('../node_modules/@capacitor/share/android')

Expand Down
4 changes: 4 additions & 0 deletions capacitor.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ const config: CapacitorConfig = {
CapacitorHttp: {
enabled: true,
},
// 미설정 시 iOS 네이티브가 빈 배열로 해석해 포그라운드 푸시가 아무것도 표시되지 않는다
PushNotifications: {
presentationOptions: ["badge", "sound", "alert"],
},
},
};

Expand Down
3 changes: 3 additions & 0 deletions ios/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ capacitor-cordova-ios-plugins
# Generated Config files
App/App/capacitor.config.json
App/App/config.xml

# Google Services (e.g. APIs or Firebase)
App/App/GoogleService-Info.plist
8 changes: 8 additions & 0 deletions ios/App/App.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
785C01742FF2604B006FD329 /* Products.storekit in Resources */ = {isa = PBXBuildFile; fileRef = 785C01732FF2604B006FD329 /* Products.storekit */; };
FB000000000000000000B002 /* FindersBillingPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB000000000000000000B001 /* FindersBillingPlugin.swift */; };
FB000000000000000000B004 /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB000000000000000000B003 /* MainViewController.swift */; };
FB000000000000000000C002 /* FindersFcmPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB000000000000000000C001 /* FindersFcmPlugin.swift */; };
FB000000000000000000C004 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = FB000000000000000000C003 /* GoogleService-Info.plist */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand All @@ -38,6 +40,8 @@
E47E3B12E0F564B87B144E94 /* Pods-App.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.release.xcconfig"; path = "Target Support Files/Pods-App/Pods-App.release.xcconfig"; sourceTree = "<group>"; };
FB000000000000000000B001 /* FindersBillingPlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FindersBillingPlugin.swift; sourceTree = "<group>"; };
FB000000000000000000B003 /* MainViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = "<group>"; };
FB000000000000000000C001 /* FindersFcmPlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FindersFcmPlugin.swift; sourceTree = "<group>"; };
FB000000000000000000C003 /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -92,9 +96,11 @@
isa = PBXGroup;
children = (
78EF470F2FF901EC00A0996C /* App.entitlements */,
FB000000000000000000C003 /* GoogleService-Info.plist */,
50379B222058CBB4000EE86E /* capacitor.config.json */,
504EC3071FED79650016851F /* AppDelegate.swift */,
FB000000000000000000B001 /* FindersBillingPlugin.swift */,
FB000000000000000000C001 /* FindersFcmPlugin.swift */,
FB000000000000000000B003 /* MainViewController.swift */,
504EC30B1FED79650016851F /* Main.storyboard */,
504EC30E1FED79650016851F /* Assets.xcassets */,
Expand Down Expand Up @@ -176,6 +182,7 @@
50B271D11FEDC1A000F3C39B /* public in Resources */,
504EC30F1FED79650016851F /* Assets.xcassets in Resources */,
50379B232058CBB4000EE86E /* capacitor.config.json in Resources */,
FB000000000000000000C004 /* GoogleService-Info.plist in Resources */,
504EC30D1FED79650016851F /* Main.storyboard in Resources */,
785C01742FF2604B006FD329 /* Products.storekit in Resources */,
2FAD9763203C412B000D30F8 /* config.xml in Resources */,
Expand Down Expand Up @@ -231,6 +238,7 @@
files = (
504EC3081FED79650016851F /* AppDelegate.swift in Sources */,
FB000000000000000000B002 /* FindersBillingPlugin.swift in Sources */,
FB000000000000000000C002 /* FindersFcmPlugin.swift in Sources */,
FB000000000000000000B004 /* MainViewController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
2 changes: 2 additions & 0 deletions ios/App/App/App.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,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>aps-environment</key>
<string>development</string>
<key>com.apple.developer.applesignin</key>
<array>
<string>Default</string>
Expand Down
19 changes: 19 additions & 0 deletions ios/App/App/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import UIKit
import Capacitor
import KakaoSDKCommon
import KakaoSDKAuth
import FirebaseCore
import FirebaseMessaging

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
Expand All @@ -12,6 +14,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
if let appKey = Bundle.main.object(forInfoDictionaryKey: "KakaoAppKey") as? String {
KakaoSDK.initSDK(appKey: appKey)
}
FirebaseApp.configure()
return true
}

Expand All @@ -37,6 +40,22 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

// APNs 등록 결과를 @capacitor/push-notifications 플러그인으로 전달 (플러그인이 이 알림을 구독한다)
// Firebase는 swizzling을 꺼둔 상태(Info.plist FirebaseAppDelegateProxyEnabled=false)라 apnsToken도 여기서 직접 넘긴다.
// APNs 환경은 자동 판별에 맡기지 말 것 — production으로 잘못 잡히면 개발 빌드에 푸시가 조용히 유실된다.
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
#if DEBUG
Messaging.messaging().setAPNSToken(deviceToken, type: .sandbox)
#else
Messaging.messaging().setAPNSToken(deviceToken, type: .prod)
#endif
NotificationCenter.default.post(name: .capacitorDidRegisterForRemoteNotifications, object: deviceToken)
}

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
NotificationCenter.default.post(name: .capacitorDidFailToRegisterForRemoteNotifications, object: error)
}

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
if AuthApi.isKakaoTalkLoginUrl(url) {
return AuthController.handleOpenUrl(url: url)
Expand Down
49 changes: 49 additions & 0 deletions ios/App/App/FindersFcmPlugin.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import Foundation
import Capacitor
import FirebaseMessaging

/**
* FCM 등록 토큰 브릿지 (iOS 전용)
* @capacitor/push-notifications의 registration 이벤트는 iOS에서 APNs 디바이스 토큰을 주는데,
* 서버는 FCM으로 발송하므로 그 토큰을 쓸 수 없다. 이 플러그인으로 FCM 토큰을 따로 받아온다.
* JS 계약: src/lib/notifications/finders-fcm.ts
*/
@objc(FindersFcmPlugin)
public class FindersFcmPlugin: CAPPlugin, CAPBridgedPlugin {
public let identifier = "FindersFcmPlugin"
public let jsName = "FindersFcm"
public let pluginMethods: [CAPPluginMethod] = [
CAPPluginMethod(name: "getToken", returnType: CAPPluginReturnPromise)
]

// Firebase가 토큰을 회전시킬 때(앱 재설치·장기 미사용 등) 알림을 받기 위해 델리게이트를 잡는다.
// Android는 push-notifications의 registration 이벤트가 다시 발생해 자동 갱신되지만,
// iOS는 이 경로가 없어 서버에 죽은 토큰이 남는다.
public override func load() {
Messaging.messaging().delegate = self
}

// AppDelegate가 Messaging.apnsToken을 세팅한 뒤(= registration 이벤트 이후) 호출해야 한다
@objc func getToken(_ call: CAPPluginCall) {
Messaging.messaging().token { token, error in
if let error = error {
call.reject(error.localizedDescription)
return
}

guard let token = token else {
call.reject("FCM token is nil")
return
}

call.resolve(["token": token])
}
}
}

extension FindersFcmPlugin: MessagingDelegate {
public func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
guard let token = fcmToken else { return }
notifyListeners("tokenRefresh", data: ["token": token])
}
}
6 changes: 6 additions & 0 deletions ios/App/App/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIBackgroundModes</key>
<array>
<string>remote-notification</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
Expand All @@ -47,6 +51,8 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>
<key>FirebaseAppDelegateProxyEnabled</key>
<false/>
<key>CFBundleURLTypes</key>
<array>
<dict>
Expand Down
1 change: 1 addition & 0 deletions ios/App/App/MainViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class MainViewController: CAPBridgeViewController {

override open func capacitorDidLoad() {
bridge?.registerPluginInstance(FindersBillingPlugin())
bridge?.registerPluginInstance(FindersFcmPlugin())

// 엣지 스와이프 뒤로가기 — SPA(pushState) 히스토리에도 동작
webView?.allowsBackForwardNavigationGestures = true
Expand Down
3 changes: 3 additions & 0 deletions ios/App/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def capacitor_pods
pod 'CapacitorFileTransfer', :path => '../../node_modules/@capacitor/file-transfer'
pod 'CapacitorFilesystem', :path => '../../node_modules/@capacitor/filesystem'
pod 'CapacitorGeolocation', :path => '../../node_modules/@capacitor/geolocation'
pod 'CapacitorPushNotifications', :path => '../../node_modules/@capacitor/push-notifications'
pod 'CapacitorShare', :path => '../../node_modules/@capacitor/share'
pod 'CapacitorSplashScreen', :path => '../../node_modules/@capacitor/splash-screen'
pod 'CapacitorSecureStoragePlugin', :path => '../../node_modules/capacitor-secure-storage-plugin'
Expand All @@ -24,6 +25,8 @@ end

target 'App' do
capacitor_pods
# FCM 등록 토큰 발급용. capacitor_pods 밖에 둬야 cap sync가 덮어쓰지 않는다.
pod 'FirebaseMessaging'
end

post_install do |installer|
Expand Down
78 changes: 77 additions & 1 deletion ios/App/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,62 @@ PODS:
- CapacitorGeolocation (8.2.0):
- Capacitor
- IONGeolocationLib (= 2.1.0)
- CapacitorPushNotifications (8.1.1):
- Capacitor
- CapacitorSecureStoragePlugin (0.13.0):
- Capacitor
- SwiftKeychainWrapper
- CapacitorShare (8.0.1):
- Capacitor
- CapacitorSplashScreen (8.0.1):
- Capacitor
- FirebaseCore (12.17.0):
- FirebaseCoreInternal (~> 12.17.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Logger (~> 8.1)
- FirebaseCoreInternal (12.17.0):
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- FirebaseInstallations (12.17.0):
- FirebaseCore (~> 12.17.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- PromisesObjC (~> 2.4)
- FirebaseMessaging (12.17.0):
- FirebaseCore (~> 12.17.0)
- FirebaseInstallations (~> 12.17.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Reachability (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- nanopb (~> 3.30910.0)
- GoogleDataTransport (10.1.0):
- nanopb (~> 3.30910.0)
- PromisesObjC (~> 2.4)
- GoogleUtilities/AppDelegateSwizzler (8.1.2):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
- GoogleUtilities/Network
- GoogleUtilities/Privacy
- GoogleUtilities/Environment (8.1.2):
- GoogleUtilities/Privacy
- GoogleUtilities/Logger (8.1.2):
- GoogleUtilities/Environment
- GoogleUtilities/Privacy
- GoogleUtilities/Network (8.1.2):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Privacy
- GoogleUtilities/Reachability
- "GoogleUtilities/NSData+zlib (8.1.2)":
- GoogleUtilities/Privacy
- GoogleUtilities/Privacy (8.1.2)
- GoogleUtilities/Reachability (8.1.2):
- GoogleUtilities/Logger
- GoogleUtilities/Privacy
- GoogleUtilities/UserDefaults (8.1.2):
- GoogleUtilities/Logger
- GoogleUtilities/Privacy
- IONFilesystemLib (1.1.2)
- IONFileTransferLib (1.0.3)
- IONGeolocationLib (2.1.0)
Expand All @@ -56,6 +105,12 @@ PODS:
- KakaoSDKCommon/Common (= 2.22.7)
- KakaoSDKUser (2.22.7):
- KakaoSDKAuth (= 2.22.7)
- nanopb (3.30910.0):
- nanopb/decode (= 3.30910.0)
- nanopb/encode (= 3.30910.0)
- nanopb/decode (3.30910.0)
- nanopb/encode (3.30910.0)
- PromisesObjC (2.4.1)
- SDWebImage (5.21.7):
- SDWebImage/Core (= 5.21.7)
- SDWebImage/Core (5.21.7)
Expand All @@ -71,13 +126,21 @@ DEPENDENCIES:
- "CapacitorFilesystem (from `../../node_modules/@capacitor/filesystem`)"
- "CapacitorFileTransfer (from `../../node_modules/@capacitor/file-transfer`)"
- "CapacitorGeolocation (from `../../node_modules/@capacitor/geolocation`)"
- "CapacitorPushNotifications (from `../../node_modules/@capacitor/push-notifications`)"
- CapacitorSecureStoragePlugin (from `../../node_modules/capacitor-secure-storage-plugin`)
- "CapacitorShare (from `../../node_modules/@capacitor/share`)"
- "CapacitorSplashScreen (from `../../node_modules/@capacitor/splash-screen`)"
- FirebaseMessaging

SPEC REPOS:
trunk:
- Alamofire
- FirebaseCore
- FirebaseCoreInternal
- FirebaseInstallations
- FirebaseMessaging
- GoogleDataTransport
- GoogleUtilities
- IONFilesystemLib
- IONFileTransferLib
- IONGeolocationLib
Expand All @@ -87,6 +150,8 @@ SPEC REPOS:
- KakaoSDKTalk
- KakaoSDKTemplate
- KakaoSDKUser
- nanopb
- PromisesObjC
- SDWebImage
- SwiftKeychainWrapper

Expand All @@ -109,6 +174,8 @@ EXTERNAL SOURCES:
:path: "../../node_modules/@capacitor/file-transfer"
CapacitorGeolocation:
:path: "../../node_modules/@capacitor/geolocation"
CapacitorPushNotifications:
:path: "../../node_modules/@capacitor/push-notifications"
CapacitorSecureStoragePlugin:
:path: "../../node_modules/capacitor-secure-storage-plugin"
CapacitorShare:
Expand All @@ -127,9 +194,16 @@ SPEC CHECKSUMS:
CapacitorFilesystem: 2db285a1ac6e475cc27cae2e1bea999000f9e2be
CapacitorFileTransfer: 445b9dc69ea5a5e0e708e011a4848e63c471abee
CapacitorGeolocation: b36f6287bfc9f2eefa04dc900496f2c8ae666136
CapacitorPushNotifications: ec08d589c226a2c0db7c032ec1bf5b044ec85f8e
CapacitorSecureStoragePlugin: d083ff28d9ba5bc74924b9bcf9754ea605016b63
CapacitorShare: 0c58305114538568059bfc07111f22dcb9cb2a82
CapacitorSplashScreen: 4b46c72298db552b3c57ce021ef028b6dc7f1fa7
FirebaseCore: 52d4512296984a44a8c8870c6494870fc7aeee2f
FirebaseCoreInternal: 3b310521b34a51ce3a6c605e4618b9aef8f6c112
FirebaseInstallations: bd8e80f51d4c8bdc6c872011dede0b800c5b49ea
FirebaseMessaging: 313d69fe6529c8846813d1660b65d7d38bc16954
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
GoogleUtilities: 766ace00c6b10d8148408f329d10c4f051931850
IONFilesystemLib: 21a63377696b2d8fab5632ecfb7d2ac67bddb68a
IONFileTransferLib: addbbf50405c163dcd74a7b1bd8c6f9302342be2
IONGeolocationLib: 6a7b6f76063fb1b01cfb14fae7d0f526e3c9b271
Expand All @@ -139,9 +213,11 @@ SPEC CHECKSUMS:
KakaoSDKTalk: a0c41d014cfda872ea9adae41bcaf7720a002785
KakaoSDKTemplate: b11ecf08777198ffafd184201baf93de476ddb84
KakaoSDKUser: 4c9cf1da78710d19d0b2c2dd32d1a44c544cdfa4
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
PromisesObjC: 752c3227f599e3467650e47ea36f433eeb10c273
SDWebImage: e9fc87c1aab89a8ab1bbd74eba378c6f53be8abf
SwiftKeychainWrapper: 807ba1d63c33a7d0613288512399cd1eda1e470c

PODFILE CHECKSUM: 78a963b8a3ef2797acf16ec406901ebab5375672
PODFILE CHECKSUM: b0d221686dcde6287868d6649c8ea19b1f536ca2

COCOAPODS: 1.16.2
Loading
Loading