mirror of
https://github.com/mosip/inji-wallet.git
synced 2026-01-09 21:48:04 -05:00
[INJIMOB-3181] - Add Deeplink support for iOS (#1907)
* [INJIMOB-3181]: add deep link support for ios Signed-off-by: adityankannan-tw <adityan.kannan@thoughtworks.com> * [INJIMOB-3181]: add deep link support for ios Signed-off-by: adityankannan-tw <adityan.kannan@thoughtworks.com> * [INJIMOB-3181]: add deep link support for ios Signed-off-by: adityankannan-tw <adityan.kannan@thoughtworks.com> * [INJIMOB-3181]: show popup for qrlogin when inital setup of app is incomplete Signed-off-by: adityankannan-tw <adityan.kannan@thoughtworks.com> * [INJIMOB-3181]: show popup for qrlogin when inital setup of app is incomplete Signed-off-by: adityankannan-tw <adityan.kannan@thoughtworks.com> * [INJIMOB-3181]: refactor deep link flow for future features Signed-off-by: adityankannan-tw <adityan.kannan@thoughtworks.com> * [INJIMOB-3181]: refactor deep link flow for future features Signed-off-by: adityankannan-tw <adityan.kannan@thoughtworks.com> * [INJIMOB-3181]: update locales for no shareable VCs Signed-off-by: adityankannan-tw <adityan.kannan@thoughtworks.com> * [INJIMOB-3181]: refactor auth selector Signed-off-by: adityankannan-tw <adityan.kannan@thoughtworks.com> * [INJIMOB-3181]: refactor deeplink native modules Signed-off-by: adityankannan-tw <adityan.kannan@thoughtworks.com> --------- Signed-off-by: adityankannan-tw <adityan.kannan@thoughtworks.com>
This commit is contained in:
@@ -13,6 +13,9 @@
|
||||
1E6875E92CA554E80086D870 /* OpenID4VP in Frameworks */ = {isa = PBXBuildFile; productRef = 1E6875E82CA554E80086D870 /* OpenID4VP */; };
|
||||
1E6875EB2CA554FD0086D870 /* RNOpenID4VPModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E6875EA2CA554FD0086D870 /* RNOpenID4VPModule.m */; };
|
||||
1E6875ED2CA5550F0086D870 /* RNOpenID4VPModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E6875EC2CA5550F0086D870 /* RNOpenID4VPModule.swift */; };
|
||||
1EED69F92DA913D30042EAFC /* IntentData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EED69F82DA913D30042EAFC /* IntentData.swift */; };
|
||||
1EED69FB2DA914130042EAFC /* RNDeepLinkIntentModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EED69FA2DA914130042EAFC /* RNDeepLinkIntentModule.swift */; };
|
||||
1EED69FD2DA914D00042EAFC /* RNDeepLinkIntentModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EED69FC2DA914D00042EAFC /* RNDeepLinkIntentModule.m */; };
|
||||
34873E472CD8DAF3004DE734 /* VCIClient in Frameworks */ = {isa = PBXBuildFile; productRef = 34873E462CD8DAF3004DE734 /* VCIClient */; };
|
||||
34873E4D2CD8DD11004DE734 /* pixelpass in Frameworks */ = {isa = PBXBuildFile; productRef = 34873E4C2CD8DD11004DE734 /* pixelpass */; };
|
||||
3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */; };
|
||||
@@ -68,6 +71,9 @@
|
||||
1D23B9CD47CFD7F3C87D202F /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = Inji/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
|
||||
1E6875EA2CA554FD0086D870 /* RNOpenID4VPModule.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNOpenID4VPModule.m; sourceTree = "<group>"; };
|
||||
1E6875EC2CA5550F0086D870 /* RNOpenID4VPModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RNOpenID4VPModule.swift; sourceTree = "<group>"; };
|
||||
1EED69F82DA913D30042EAFC /* IntentData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntentData.swift; sourceTree = "<group>"; };
|
||||
1EED69FA2DA914130042EAFC /* RNDeepLinkIntentModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RNDeepLinkIntentModule.swift; sourceTree = "<group>"; };
|
||||
1EED69FC2DA914D00042EAFC /* RNDeepLinkIntentModule.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNDeepLinkIntentModule.m; sourceTree = "<group>"; };
|
||||
58EEBF8E8E6FB1BC6CAF49B5 /* libPods-Inji.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Inji.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
6C2E3173556A471DD304B334 /* Pods-Inji.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Inji.debug.xcconfig"; path = "Target Support Files/Pods-Inji/Pods-Inji.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
7A4D352CD337FB3A3BF06240 /* Pods-Inji.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Inji.release.xcconfig"; path = "Target Support Files/Pods-Inji/Pods-Inji.release.xcconfig"; sourceTree = "<group>"; };
|
||||
@@ -155,6 +161,9 @@
|
||||
1E6875EA2CA554FD0086D870 /* RNOpenID4VPModule.m */,
|
||||
1E6875EC2CA5550F0086D870 /* RNOpenID4VPModule.swift */,
|
||||
1D23B9CD47CFD7F3C87D202F /* PrivacyInfo.xcprivacy */,
|
||||
1EED69F82DA913D30042EAFC /* IntentData.swift */,
|
||||
1EED69FA2DA914130042EAFC /* RNDeepLinkIntentModule.swift */,
|
||||
1EED69FC2DA914D00042EAFC /* RNDeepLinkIntentModule.m */,
|
||||
);
|
||||
name = Inji;
|
||||
sourceTree = "<group>";
|
||||
@@ -541,6 +550,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1EED69FD2DA914D00042EAFC /* RNDeepLinkIntentModule.m in Sources */,
|
||||
1E6875ED2CA5550F0086D870 /* RNOpenID4VPModule.swift in Sources */,
|
||||
9C48504F2C3E59B5002ECBD5 /* RNVersionModule.swift in Sources */,
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */,
|
||||
@@ -551,11 +561,13 @@
|
||||
9C4850532C3E59E2002ECBD5 /* RNEventEmitterProtocol.swift in Sources */,
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */,
|
||||
9C4850502C3E59B5002ECBD5 /* RNEventMapper.swift in Sources */,
|
||||
1EED69FB2DA914130042EAFC /* RNDeepLinkIntentModule.swift in Sources */,
|
||||
9C7CDF432C7CC13500243A9A /* RNSecureKeystoreModule.m in Sources */,
|
||||
E86208172C0335EC007C3E24 /* RNVCIClientModule.m in Sources */,
|
||||
9C48504E2C3E59B5002ECBD5 /* RNEventEmitter.swift in Sources */,
|
||||
9C7CDF3E2C7CBEDE00243A9A /* RNSecureKeystoreModule.swift in Sources */,
|
||||
9C48504B2C3E59B5002ECBD5 /* RNWalletModule.swift in Sources */,
|
||||
1EED69F92DA913D30042EAFC /* IntentData.swift in Sources */,
|
||||
9C48504D2C3E59B5002ECBD5 /* RNWalletModule.m in Sources */,
|
||||
B18059E884C0ABDD17F3DC3D /* ExpoModulesProvider.swift in Sources */,
|
||||
9C4850512C3E59B5002ECBD5 /* RNVersionModule.m in Sources */,
|
||||
|
||||
@@ -3,8 +3,17 @@
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTLinkingManager.h>
|
||||
|
||||
#import <ExpoModulesCore-Swift.h>
|
||||
#import "Inji-Swift.h"
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
typedef NS_ENUM(NSInteger, URLScheme) {
|
||||
URLSchemeInji,
|
||||
URLSchemeOpenID4VP,
|
||||
URLSchemeUnknown
|
||||
};
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
self.moduleName = @"main";
|
||||
@@ -42,9 +51,36 @@
|
||||
|
||||
// Linking API
|
||||
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
||||
[self handleIntent:url];
|
||||
return [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options];
|
||||
}
|
||||
|
||||
- (void)handleIntent:(NSURL *)url {
|
||||
|
||||
URLScheme scheme = [self schemeFromURL:url];
|
||||
IntentData *intentData = [IntentData shared];
|
||||
|
||||
switch (scheme) {
|
||||
case URLSchemeInji:
|
||||
[intentData setQrData:url.absoluteString];
|
||||
break;
|
||||
case URLSchemeOpenID4VP:
|
||||
[intentData setOvpQrData:url.absoluteString];
|
||||
break;
|
||||
case URLSchemeUnknown:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (URLScheme)schemeFromURL:(NSURL *)url {
|
||||
if ([url.scheme isEqualToString:@"io.mosip.residentapp.inji"]) {
|
||||
return URLSchemeInji;
|
||||
} else if ([url.scheme isEqualToString:@"openid4vp"]) {
|
||||
return URLSchemeOpenID4VP;
|
||||
}
|
||||
return URLSchemeUnknown;
|
||||
}
|
||||
|
||||
// Universal Links
|
||||
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
|
||||
BOOL result = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
|
||||
|
||||
@@ -28,6 +28,12 @@
|
||||
<string>io.mosip.residentapp</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>io.mosip.residentapp.inji</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
|
||||
63
ios/IntentData.swift
Normal file
63
ios/IntentData.swift
Normal file
@@ -0,0 +1,63 @@
|
||||
import Foundation
|
||||
|
||||
@objc public class IntentData: NSObject {
|
||||
@objc public static let shared = IntentData()
|
||||
private let syncQueue = DispatchQueue(label: "com.intentdata.syncQueue", attributes: .concurrent)
|
||||
private var qrData: String = ""
|
||||
private var ovpQrData: String = ""
|
||||
|
||||
private override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
@objc public func getQrData() -> String {
|
||||
var data: String = ""
|
||||
syncQueue.sync {
|
||||
data = qrData
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
@objc public func setQrData(_ newValue: String) {
|
||||
syncQueue.async(flags: .barrier) {
|
||||
self.qrData = newValue
|
||||
}
|
||||
}
|
||||
|
||||
@objc public func getOvpQrData() -> String {
|
||||
var data: String = ""
|
||||
syncQueue.sync {
|
||||
data = ovpQrData
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
@objc public func setOvpQrData(_ newValue: String) {
|
||||
syncQueue.async(flags: .barrier) {
|
||||
self.ovpQrData = newValue
|
||||
}
|
||||
}
|
||||
|
||||
func getDataByFlow(_ flowType: String?) -> String {
|
||||
switch flowType {
|
||||
case "qrLoginFlow":
|
||||
return getQrData()
|
||||
case "ovpFlow":
|
||||
return getOvpQrData()
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func resetDataByFlow(_ flowType: String) {
|
||||
switch flowType {
|
||||
case "qrLoginFlow":
|
||||
setQrData("")
|
||||
case "ovpFlow":
|
||||
setOvpQrData("")
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
9
ios/RNDeepLinkIntentModule.m
Normal file
9
ios/RNDeepLinkIntentModule.m
Normal file
@@ -0,0 +1,9 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <React/RCTBridgeModule.h>
|
||||
|
||||
@interface RCT_EXTERN_MODULE(DeepLinkIntent,NSObject)
|
||||
|
||||
RCT_EXTERN_METHOD(getDeepLinkIntentData:(NSString *)flowType resolve:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
||||
RCT_EXTERN_METHOD(resetDeepLinkIntentData:(NSString *)flowType)
|
||||
|
||||
@end
|
||||
24
ios/RNDeepLinkIntentModule.swift
Normal file
24
ios/RNDeepLinkIntentModule.swift
Normal file
@@ -0,0 +1,24 @@
|
||||
import Foundation
|
||||
import React
|
||||
|
||||
@objc(DeepLinkIntent)
|
||||
class RNDeepLinkIntentModule: NSObject, RCTBridgeModule {
|
||||
|
||||
static func moduleName() -> String {
|
||||
return "DeepLinkIntent"
|
||||
}
|
||||
|
||||
@objc func getDeepLinkIntentData(_ flowType: String, resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
||||
let intentData = IntentData.shared
|
||||
let result = intentData.getDataByFlow(flowType)
|
||||
resolve(result)
|
||||
}
|
||||
|
||||
@objc func resetDeepLinkIntentData(_ flowType: String) {
|
||||
IntentData.shared.resetDataByFlow(flowType)
|
||||
}
|
||||
|
||||
@objc static func requiresMainQueueSetup() -> Bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user