@tyrads.com/tyrads-sdk 2.0.1 → 3.1.0-beta.0
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/android/build.gradle +1 -1
- package/android/gradle.properties +1 -1
- package/android/src/main/java/com/tyradssdk/TyradsSdkModule.kt +27 -6
- package/ios/Tyrads/AcmoConfig.swift +3 -3
- package/ios/Tyrads/InitModel.swift +5 -2
- package/ios/Tyrads/Tyrads.swift +117 -186
- package/ios/Tyrads/WebViewController.swift +171 -0
- package/ios/Tyrads/helpers/aes_encryptor.swift +81 -0
- package/ios/Tyrads/helpers/device_details.swift +58 -0
- package/ios/TyradsSdk.mm +10 -2
- package/ios/TyradsSdk.swift +44 -29
- package/lib/commonjs/acmo/core/helpers/launcher.js +20 -0
- package/lib/commonjs/acmo/core/helpers/launcher.js.map +1 -0
- package/lib/commonjs/acmo/modules/dashboard/components/active_offers_button.js +76 -0
- package/lib/commonjs/acmo/modules/dashboard/components/active_offers_button.js.map +1 -0
- package/lib/commonjs/acmo/modules/dashboard/components/custom_card.js +7 -10
- package/lib/commonjs/acmo/modules/dashboard/components/custom_card.js.map +1 -1
- package/lib/commonjs/acmo/modules/dashboard/components/custom_scroller.js +141 -0
- package/lib/commonjs/acmo/modules/dashboard/components/custom_scroller.js.map +1 -0
- package/lib/commonjs/acmo/{core/marquee.js → modules/dashboard/components/custom_shimmer.js} +46 -34
- package/lib/commonjs/acmo/modules/dashboard/components/custom_shimmer.js.map +1 -0
- package/lib/commonjs/acmo/modules/dashboard/components/offer_card.js +264 -0
- package/lib/commonjs/acmo/modules/dashboard/components/offer_card.js.map +1 -0
- package/lib/commonjs/acmo/modules/dashboard/components/offer_list_item.js +197 -0
- package/lib/commonjs/acmo/modules/dashboard/components/offer_list_item.js.map +1 -0
- package/lib/commonjs/acmo/modules/dashboard/components/premium_empty_widget.js +83 -0
- package/lib/commonjs/acmo/modules/dashboard/components/premium_empty_widget.js.map +1 -0
- package/lib/commonjs/acmo/modules/dashboard/components/premium_header.js +12 -10
- package/lib/commonjs/acmo/modules/dashboard/components/premium_header.js.map +1 -1
- package/lib/commonjs/acmo/modules/dashboard/components/premium_loading.js +118 -0
- package/lib/commonjs/acmo/modules/dashboard/components/premium_loading.js.map +1 -0
- package/lib/commonjs/acmo/modules/dashboard/repository.js +108 -32
- package/lib/commonjs/acmo/modules/dashboard/repository.js.map +1 -1
- package/lib/commonjs/acmo/modules/dashboard/top_offers.js +70 -63
- package/lib/commonjs/acmo/modules/dashboard/top_offers.js.map +1 -1
- package/lib/commonjs/assets/images/angle_up.png +0 -0
- package/lib/commonjs/assets/images/diamond.png +0 -0
- package/lib/commonjs/assets/images/info.png +0 -0
- package/lib/commonjs/assets/images/info_icon.png +0 -0
- package/lib/commonjs/assets/images/premium-emptybg.jpeg +0 -0
- package/lib/commonjs/assets/images/rank_1.png +0 -0
- package/lib/commonjs/assets/images/rank_2.png +0 -0
- package/lib/commonjs/assets/images/rank_3.png +0 -0
- package/lib/commonjs/assets/images/rank_4.png +0 -0
- package/lib/commonjs/assets/images/rank_5.png +0 -0
- package/lib/commonjs/index.js +15 -16
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/acmo/core/helpers/launcher.js +15 -0
- package/lib/module/acmo/core/helpers/launcher.js.map +1 -0
- package/lib/module/acmo/modules/dashboard/components/active_offers_button.js +70 -0
- package/lib/module/acmo/modules/dashboard/components/active_offers_button.js.map +1 -0
- package/lib/module/acmo/modules/dashboard/components/custom_card.js +7 -10
- package/lib/module/acmo/modules/dashboard/components/custom_card.js.map +1 -1
- package/lib/module/acmo/modules/dashboard/components/custom_scroller.js +135 -0
- package/lib/module/acmo/modules/dashboard/components/custom_scroller.js.map +1 -0
- package/lib/module/acmo/modules/dashboard/components/custom_shimmer.js +66 -0
- package/lib/module/acmo/modules/dashboard/components/custom_shimmer.js.map +1 -0
- package/lib/module/acmo/modules/dashboard/components/offer_card.js +257 -0
- package/lib/module/acmo/modules/dashboard/components/offer_card.js.map +1 -0
- package/lib/module/acmo/modules/dashboard/components/offer_list_item.js +191 -0
- package/lib/module/acmo/modules/dashboard/components/offer_list_item.js.map +1 -0
- package/lib/module/acmo/modules/dashboard/components/premium_empty_widget.js +78 -0
- package/lib/module/acmo/modules/dashboard/components/premium_empty_widget.js.map +1 -0
- package/lib/module/acmo/modules/dashboard/components/premium_header.js +12 -10
- package/lib/module/acmo/modules/dashboard/components/premium_header.js.map +1 -1
- package/lib/module/acmo/modules/dashboard/components/premium_loading.js +113 -0
- package/lib/module/acmo/modules/dashboard/components/premium_loading.js.map +1 -0
- package/lib/module/acmo/modules/dashboard/repository.js +105 -30
- package/lib/module/acmo/modules/dashboard/repository.js.map +1 -1
- package/lib/module/acmo/modules/dashboard/top_offers.js +71 -64
- package/lib/module/acmo/modules/dashboard/top_offers.js.map +1 -1
- package/lib/module/assets/images/angle_up.png +0 -0
- package/lib/module/assets/images/diamond.png +0 -0
- package/lib/module/assets/images/info.png +0 -0
- package/lib/module/assets/images/info_icon.png +0 -0
- package/lib/module/assets/images/premium-emptybg.jpeg +0 -0
- package/lib/module/assets/images/rank_1.png +0 -0
- package/lib/module/assets/images/rank_2.png +0 -0
- package/lib/module/assets/images/rank_3.png +0 -0
- package/lib/module/assets/images/rank_4.png +0 -0
- package/lib/module/assets/images/rank_5.png +0 -0
- package/lib/module/index.js +15 -16
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/commonjs/src/acmo/core/helpers/launcher.d.ts +3 -0
- package/lib/typescript/commonjs/src/acmo/core/helpers/launcher.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/acmo/core/storage/storage.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/active_offers_button.d.ts +9 -0
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/active_offers_button.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/custom_card.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/custom_scroller.d.ts +17 -0
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/custom_scroller.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/custom_shimmer.d.ts +11 -0
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/custom_shimmer.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/offer_card.d.ts +12 -0
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/offer_card.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/offer_list_item.d.ts +15 -0
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/offer_list_item.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/premium_empty_widget.d.ts +7 -0
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/premium_empty_widget.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/premium_loading.d.ts +9 -0
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/premium_loading.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/repository.d.ts +2 -1
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/repository.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/top_offers.d.ts +8 -7
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/top_offers.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/index.d.ts +6 -8
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
- package/lib/typescript/module/src/acmo/core/helpers/launcher.d.ts +3 -0
- package/lib/typescript/module/src/acmo/core/helpers/launcher.d.ts.map +1 -0
- package/lib/typescript/module/src/acmo/core/storage/storage.d.ts.map +1 -1
- package/lib/typescript/module/src/acmo/modules/dashboard/components/active_offers_button.d.ts +9 -0
- package/lib/typescript/module/src/acmo/modules/dashboard/components/active_offers_button.d.ts.map +1 -0
- package/lib/typescript/module/src/acmo/modules/dashboard/components/custom_card.d.ts.map +1 -1
- package/lib/typescript/module/src/acmo/modules/dashboard/components/custom_scroller.d.ts +17 -0
- package/lib/typescript/module/src/acmo/modules/dashboard/components/custom_scroller.d.ts.map +1 -0
- package/lib/typescript/module/src/acmo/modules/dashboard/components/custom_shimmer.d.ts +11 -0
- package/lib/typescript/module/src/acmo/modules/dashboard/components/custom_shimmer.d.ts.map +1 -0
- package/lib/typescript/module/src/acmo/modules/dashboard/components/offer_card.d.ts +12 -0
- package/lib/typescript/module/src/acmo/modules/dashboard/components/offer_card.d.ts.map +1 -0
- package/lib/typescript/module/src/acmo/modules/dashboard/components/offer_list_item.d.ts +15 -0
- package/lib/typescript/module/src/acmo/modules/dashboard/components/offer_list_item.d.ts.map +1 -0
- package/lib/typescript/module/src/acmo/modules/dashboard/components/premium_empty_widget.d.ts +7 -0
- package/lib/typescript/module/src/acmo/modules/dashboard/components/premium_empty_widget.d.ts.map +1 -0
- package/lib/typescript/module/src/acmo/modules/dashboard/components/premium_loading.d.ts +9 -0
- package/lib/typescript/module/src/acmo/modules/dashboard/components/premium_loading.d.ts.map +1 -0
- package/lib/typescript/module/src/acmo/modules/dashboard/repository.d.ts +2 -1
- package/lib/typescript/module/src/acmo/modules/dashboard/repository.d.ts.map +1 -1
- package/lib/typescript/module/src/acmo/modules/dashboard/top_offers.d.ts +8 -7
- package/lib/typescript/module/src/acmo/modules/dashboard/top_offers.d.ts.map +1 -1
- package/lib/typescript/module/src/index.d.ts +6 -8
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/package.json +3 -2
- package/readme.md +8 -8
- package/src/acmo/core/helpers/launcher.ts +14 -0
- package/src/acmo/core/types/types.d.ts +11 -13
- package/src/acmo/modules/dashboard/components/active_offers_button.tsx +61 -0
- package/src/acmo/modules/dashboard/components/custom_card.tsx +5 -8
- package/src/acmo/modules/dashboard/components/custom_scroller.tsx +164 -0
- package/src/acmo/modules/dashboard/components/custom_shimmer.tsx +75 -0
- package/src/acmo/modules/dashboard/components/offer_card.tsx +248 -0
- package/src/acmo/modules/dashboard/components/offer_list_item.tsx +225 -0
- package/src/acmo/modules/dashboard/components/premium_empty_widget.tsx +76 -0
- package/src/acmo/modules/dashboard/components/premium_header.tsx +8 -8
- package/src/acmo/modules/dashboard/components/premium_loading.tsx +78 -0
- package/src/acmo/modules/dashboard/repository.ts +121 -46
- package/src/acmo/modules/dashboard/top_offers.tsx +89 -52
- package/src/assets/images/angle_up.png +0 -0
- package/src/assets/images/diamond.png +0 -0
- package/src/assets/images/info.png +0 -0
- package/src/assets/images/info_icon.png +0 -0
- package/src/assets/images/premium-emptybg.jpeg +0 -0
- package/src/assets/images/rank_1.png +0 -0
- package/src/assets/images/rank_2.png +0 -0
- package/src/assets/images/rank_3.png +0 -0
- package/src/assets/images/rank_4.png +0 -0
- package/src/assets/images/rank_5.png +0 -0
- package/src/index.tsx +19 -23
- package/android/src/main/java/com/tyradssdk/TyradsSdkComposeViewManager.kt +0 -112
- package/lib/commonjs/acmo/core/marquee.js.map +0 -1
- package/lib/commonjs/acmo/modules/dashboard/components/auto_scroller.js +0 -87
- package/lib/commonjs/acmo/modules/dashboard/components/auto_scroller.js.map +0 -1
- package/lib/commonjs/acmo/modules/dashboard/components/my_games_button.js +0 -48
- package/lib/commonjs/acmo/modules/dashboard/components/my_games_button.js.map +0 -1
- package/lib/commonjs/acmo/modules/dashboard/components/offer_info_section.js +0 -158
- package/lib/commonjs/acmo/modules/dashboard/components/offer_info_section.js.map +0 -1
- package/lib/commonjs/acmo/modules/dashboard/components/premium_option_1.js +0 -181
- package/lib/commonjs/acmo/modules/dashboard/components/premium_option_1.js.map +0 -1
- package/lib/commonjs/acmo/modules/dashboard/components/premium_option_2.js +0 -102
- package/lib/commonjs/acmo/modules/dashboard/components/premium_option_2.js.map +0 -1
- package/lib/commonjs/acmo/modules/dashboard/components/premium_option_3.js +0 -41
- package/lib/commonjs/acmo/modules/dashboard/components/premium_option_3.js.map +0 -1
- package/lib/commonjs/acmo/modules/dashboard/components/premium_option_4.js +0 -214
- package/lib/commonjs/acmo/modules/dashboard/components/premium_option_4.js.map +0 -1
- package/lib/module/acmo/core/marquee.js +0 -54
- package/lib/module/acmo/core/marquee.js.map +0 -1
- package/lib/module/acmo/modules/dashboard/components/auto_scroller.js +0 -81
- package/lib/module/acmo/modules/dashboard/components/auto_scroller.js.map +0 -1
- package/lib/module/acmo/modules/dashboard/components/my_games_button.js +0 -43
- package/lib/module/acmo/modules/dashboard/components/my_games_button.js.map +0 -1
- package/lib/module/acmo/modules/dashboard/components/offer_info_section.js +0 -153
- package/lib/module/acmo/modules/dashboard/components/offer_info_section.js.map +0 -1
- package/lib/module/acmo/modules/dashboard/components/premium_option_1.js +0 -176
- package/lib/module/acmo/modules/dashboard/components/premium_option_1.js.map +0 -1
- package/lib/module/acmo/modules/dashboard/components/premium_option_2.js +0 -97
- package/lib/module/acmo/modules/dashboard/components/premium_option_2.js.map +0 -1
- package/lib/module/acmo/modules/dashboard/components/premium_option_3.js +0 -36
- package/lib/module/acmo/modules/dashboard/components/premium_option_3.js.map +0 -1
- package/lib/module/acmo/modules/dashboard/components/premium_option_4.js +0 -209
- package/lib/module/acmo/modules/dashboard/components/premium_option_4.js.map +0 -1
- package/lib/typescript/commonjs/src/acmo/core/marquee.d.ts +0 -11
- package/lib/typescript/commonjs/src/acmo/core/marquee.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/auto_scroller.d.ts +0 -10
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/auto_scroller.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/my_games_button.d.ts +0 -8
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/my_games_button.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/offer_info_section.d.ts +0 -11
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/offer_info_section.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/premium_option_1.d.ts +0 -9
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/premium_option_1.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/premium_option_2.d.ts +0 -9
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/premium_option_2.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/premium_option_3.d.ts +0 -9
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/premium_option_3.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/premium_option_4.d.ts +0 -9
- package/lib/typescript/commonjs/src/acmo/modules/dashboard/components/premium_option_4.d.ts.map +0 -1
- package/lib/typescript/module/src/acmo/core/marquee.d.ts +0 -11
- package/lib/typescript/module/src/acmo/core/marquee.d.ts.map +0 -1
- package/lib/typescript/module/src/acmo/modules/dashboard/components/auto_scroller.d.ts +0 -10
- package/lib/typescript/module/src/acmo/modules/dashboard/components/auto_scroller.d.ts.map +0 -1
- package/lib/typescript/module/src/acmo/modules/dashboard/components/my_games_button.d.ts +0 -8
- package/lib/typescript/module/src/acmo/modules/dashboard/components/my_games_button.d.ts.map +0 -1
- package/lib/typescript/module/src/acmo/modules/dashboard/components/offer_info_section.d.ts +0 -11
- package/lib/typescript/module/src/acmo/modules/dashboard/components/offer_info_section.d.ts.map +0 -1
- package/lib/typescript/module/src/acmo/modules/dashboard/components/premium_option_1.d.ts +0 -9
- package/lib/typescript/module/src/acmo/modules/dashboard/components/premium_option_1.d.ts.map +0 -1
- package/lib/typescript/module/src/acmo/modules/dashboard/components/premium_option_2.d.ts +0 -9
- package/lib/typescript/module/src/acmo/modules/dashboard/components/premium_option_2.d.ts.map +0 -1
- package/lib/typescript/module/src/acmo/modules/dashboard/components/premium_option_3.d.ts +0 -9
- package/lib/typescript/module/src/acmo/modules/dashboard/components/premium_option_3.d.ts.map +0 -1
- package/lib/typescript/module/src/acmo/modules/dashboard/components/premium_option_4.d.ts +0 -9
- package/lib/typescript/module/src/acmo/modules/dashboard/components/premium_option_4.d.ts.map +0 -1
- package/src/acmo/core/marquee.tsx +0 -62
- package/src/acmo/modules/dashboard/components/auto_scroller.tsx +0 -85
- package/src/acmo/modules/dashboard/components/my_games_button.tsx +0 -40
- package/src/acmo/modules/dashboard/components/offer_info_section.tsx +0 -139
- package/src/acmo/modules/dashboard/components/premium_option_1.tsx +0 -156
- package/src/acmo/modules/dashboard/components/premium_option_2.tsx +0 -100
- package/src/acmo/modules/dashboard/components/premium_option_3.tsx +0 -42
- package/src/acmo/modules/dashboard/components/premium_option_4.tsx +0 -185
package/android/build.gradle
CHANGED
@@ -112,6 +112,6 @@ dependencies {
|
|
112
112
|
implementation "com.facebook.react:react-native:+"
|
113
113
|
implementation 'com.google.code.gson:gson:+'
|
114
114
|
|
115
|
-
implementation 'com.github.tyrads-com:tyrads-sdk-android:
|
115
|
+
implementation 'com.github.tyrads-com:tyrads-sdk-android:debd5714c1'
|
116
116
|
}
|
117
117
|
|
@@ -19,13 +19,15 @@ class TyradsSdkModule(reactContext: ReactApplicationContext) :
|
|
19
19
|
}
|
20
20
|
|
21
21
|
@ReactMethod
|
22
|
-
fun init(apiKey: String, apiSecret: String, promise: Promise) {
|
22
|
+
fun init(apiKey: String, apiSecret: String, encKey: String? = null, promise: Promise) {
|
23
|
+
Tyrads.getInstance().tyradScope.launch {
|
23
24
|
try {
|
24
|
-
|
25
|
-
|
25
|
+
Tyrads.getInstance().init(reactApplicationContext, apiKey, apiSecret, encKey)
|
26
|
+
promise.resolve(true)
|
26
27
|
} catch (e: Exception) {
|
27
|
-
|
28
|
+
promise.reject("INIT_ERROR", e.message)
|
28
29
|
}
|
30
|
+
}
|
29
31
|
}
|
30
32
|
|
31
33
|
@ReactMethod
|
@@ -46,8 +48,27 @@ class TyradsSdkModule(reactContext: ReactApplicationContext) :
|
|
46
48
|
}
|
47
49
|
}
|
48
50
|
@ReactMethod
|
49
|
-
fun showOffers(route: String? = null,
|
50
|
-
Tyrads.getInstance().
|
51
|
+
fun showOffers(route: String? = null, promise: Promise) {
|
52
|
+
Tyrads.getInstance().tyradScope.launch {
|
53
|
+
try {
|
54
|
+
Tyrads.getInstance().showOffers(route = route, campaignID = null)
|
55
|
+
promise.resolve(true)
|
56
|
+
} catch (e: Exception) {
|
57
|
+
promise.reject("SHOW_OFFERS_ERROR", e.message)
|
58
|
+
}
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
@ReactMethod
|
63
|
+
fun showOfferDetails(route: String? = null, campaignID: Int? = null, promise: Promise) {
|
64
|
+
Tyrads.getInstance().tyradScope.launch {
|
65
|
+
try {
|
66
|
+
Tyrads.getInstance().showOffers(route = route, campaignID = campaignID)
|
67
|
+
promise.resolve(true)
|
68
|
+
} catch (e: Exception) {
|
69
|
+
promise.reject("SHOW_OFFERS_ERROR", e.message)
|
70
|
+
}
|
71
|
+
}
|
51
72
|
}
|
52
73
|
|
53
74
|
companion object {
|
@@ -9,9 +9,9 @@ import Foundation
|
|
9
9
|
import UIKit
|
10
10
|
|
11
11
|
struct AcmoConfig {
|
12
|
-
static let API_VERSION = "
|
13
|
-
static let BUILD_VERSION = "
|
14
|
-
static let ACMO_VERSION = "
|
12
|
+
static let API_VERSION = "3.0"
|
13
|
+
static let BUILD_VERSION = "0"
|
14
|
+
static let ACMO_VERSION = "4"
|
15
15
|
static let SDK_VERSION = "\(API_VERSION).\(BUILD_VERSION)"
|
16
16
|
static let SDK_PLATFORM = "React Native"
|
17
17
|
static let BASE_URL = "https://api.tyrads.com/v\(API_VERSION)/"
|
@@ -8,18 +8,20 @@
|
|
8
8
|
import Foundation
|
9
9
|
|
10
10
|
struct AcmoInitModel: Codable {
|
11
|
-
let data:
|
11
|
+
let data: UserData
|
12
12
|
}
|
13
13
|
|
14
|
-
struct
|
14
|
+
struct UserData: Codable {
|
15
15
|
let newRegisteredUser: Bool
|
16
16
|
let user: User
|
17
17
|
let publisherApp: PublisherApp
|
18
|
+
let token: String
|
18
19
|
|
19
20
|
enum CodingKeys: String, CodingKey {
|
20
21
|
case newRegisteredUser = "newRegisteredUser"
|
21
22
|
case user
|
22
23
|
case publisherApp
|
24
|
+
case token
|
23
25
|
}
|
24
26
|
|
25
27
|
init(from decoder: Decoder) throws {
|
@@ -27,6 +29,7 @@ struct Data: Codable {
|
|
27
29
|
newRegisteredUser = try container.decodeIfPresent(Bool.self, forKey: .newRegisteredUser) ?? false
|
28
30
|
user = try container.decode(User.self, forKey: .user)
|
29
31
|
publisherApp = try container.decode(PublisherApp.self, forKey: .publisherApp)
|
32
|
+
token = try container.decode(String.self, forKey: .token)
|
30
33
|
}
|
31
34
|
}
|
32
35
|
|
package/ios/Tyrads/Tyrads.swift
CHANGED
@@ -13,27 +13,47 @@ public class Tyrads : NSObject {
|
|
13
13
|
|
14
14
|
private var apiKey: String = ""
|
15
15
|
private var apiSecret: String = ""
|
16
|
+
private var encKey: String?
|
16
17
|
private var publisherUserID: String = ""
|
18
|
+
private var token: String = ""
|
17
19
|
private var currentLanguage: String = "en"
|
18
20
|
private var newUser: Bool = false
|
19
21
|
private var loginData: AcmoInitModel?
|
20
22
|
var initializationWait = DispatchSemaphore(value: 0)
|
23
|
+
private var initializationContinuation: CheckedContinuation<Void, Never>?
|
21
24
|
private var debugMode: Bool = false
|
25
|
+
|
26
|
+
private var _isSecure: Bool = false
|
27
|
+
public var isSecure: Bool {
|
28
|
+
get {
|
29
|
+
return _isSecure
|
30
|
+
}
|
31
|
+
}
|
22
32
|
|
23
33
|
private func log(_ message: String) {
|
24
34
|
if debugMode {
|
25
35
|
NSLog(message)
|
26
36
|
}
|
27
37
|
}
|
38
|
+
|
39
|
+
private func ensureInitialized() async {
|
40
|
+
guard self.token.isEmpty else { return }
|
41
|
+
|
42
|
+
await withCheckedContinuation { continuation in
|
43
|
+
self.initializationContinuation = continuation
|
44
|
+
}
|
45
|
+
}
|
28
46
|
|
29
47
|
/// Configures the Tyrads SDK with the provided API key and secret key.
|
30
48
|
///
|
31
49
|
/// - Parameters:
|
32
50
|
/// - apiKey: The API key provided by Tyrads.
|
33
51
|
/// - secretKey: The secret key provided by Tyrads.
|
34
|
-
|
52
|
+
@objc public func configure( apiKey: String, secretKey: String, encKey: String? = nil, debugMode: Bool = false) {
|
35
53
|
self.apiKey = apiKey
|
36
54
|
self.apiSecret = secretKey
|
55
|
+
self.encKey = encKey
|
56
|
+
self._isSecure = (encKey != nil)
|
37
57
|
self.debugMode = debugMode
|
38
58
|
self.currentLanguage = Locale.current.languageCode ?? ""
|
39
59
|
}
|
@@ -41,129 +61,115 @@ public class Tyrads : NSObject {
|
|
41
61
|
/// Logs in the user with the provided user ID or retrieves the user ID from UserDefaults.
|
42
62
|
///
|
43
63
|
/// - Parameter userID: Optional. The user ID to log in with. If nil, the SDK will attempt to retrieve the user ID from UserDefaults.
|
44
|
-
public func loginUser(_ userID: String? = nil
|
64
|
+
public func loginUser(_ userID: String? = nil) async throws -> ApiHeaders? {
|
45
65
|
let userId = userID ?? UserDefaults.standard.string(forKey: "acmo-tyrads-sdk-user-id") ?? ""
|
46
|
-
|
47
66
|
let identifierType = "IDFA"
|
48
67
|
var advertisingId = ""
|
49
68
|
|
50
|
-
func finalizeLogin() {
|
51
|
-
let fd: [String: Any] = [
|
52
|
-
"publisherUserId": userId,
|
53
|
-
"platform": "iOS",
|
54
|
-
"identifierType": identifierType,
|
55
|
-
"identifier": advertisingId
|
56
|
-
]
|
57
|
-
|
58
|
-
self.log("Initializing with data: \(fd)")
|
59
|
-
|
60
|
-
guard let url = URL(string: AcmoConfig.BASE_URL + "initialize") else {
|
61
|
-
self.log("Failed to create URL")
|
62
|
-
completion(nil)
|
63
|
-
return
|
64
|
-
}
|
65
|
-
|
66
|
-
var request = URLRequest(url: url)
|
67
|
-
request.httpMethod = "POST"
|
68
|
-
request.setValue(AcmoConfig.SDK_PLATFORM, forHTTPHeaderField: "X-SDK-Platform")
|
69
|
-
request.setValue(AcmoConfig.SDK_VERSION, forHTTPHeaderField: "X-SDK-Version")
|
70
|
-
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
71
|
-
request.setValue(self.apiKey, forHTTPHeaderField: "X-API-Key")
|
72
|
-
request.setValue(self.apiSecret, forHTTPHeaderField: "X-API-Secret")
|
73
|
-
|
74
|
-
do {
|
75
|
-
request.httpBody = try JSONSerialization.data(withJSONObject: fd)
|
76
|
-
} catch {
|
77
|
-
self.log("Failed to serialize request body: \(error)")
|
78
|
-
completion(nil)
|
79
|
-
return
|
80
|
-
}
|
81
|
-
|
82
|
-
let task = URLSession.shared.dataTask(with: request) { data, response, error in
|
83
|
-
if let error = error {
|
84
|
-
self.log("Network request failed: \(error)")
|
85
|
-
completion(nil)
|
86
|
-
return
|
87
|
-
}
|
88
|
-
|
89
|
-
guard let data = data else {
|
90
|
-
self.log("No data received from the server")
|
91
|
-
completion(nil)
|
92
|
-
return
|
93
|
-
}
|
94
|
-
|
95
|
-
if let responseString = String(data: data, encoding: .utf8) {
|
96
|
-
self.log("Received response: \(responseString)")
|
97
|
-
|
98
|
-
guard let jsonData = responseString.data(using: .utf8),
|
99
|
-
let acmoInitModel = try? JSONDecoder().decode(AcmoInitModel.self, from: jsonData) else {
|
100
|
-
self.log("Failed to decode response")
|
101
|
-
completion(nil)
|
102
|
-
return
|
103
|
-
}
|
104
|
-
|
105
|
-
self.loginData = acmoInitModel
|
106
|
-
self.publisherUserID = acmoInitModel.data.user.publisherUserId
|
107
|
-
self.newUser = acmoInitModel.data.newRegisteredUser
|
108
|
-
self.log("Login successful. Publisher User ID: \(self.publisherUserID), New User: \(self.newUser)")
|
109
|
-
self.initializationWait.signal()
|
110
|
-
|
111
|
-
// Build ApiHeaders object
|
112
|
-
let headers = ApiHeaders(
|
113
|
-
xApiKey: self.apiKey,
|
114
|
-
xApiSecret: self.apiSecret,
|
115
|
-
xUserId: self.publisherUserID,
|
116
|
-
xSdkPlatform: AcmoConfig.SDK_PLATFORM,
|
117
|
-
xSdkVersion: AcmoConfig.SDK_VERSION,
|
118
|
-
userAgent: UIDevice.current.systemName + "/" + UIDevice.current.systemVersion,
|
119
|
-
languageCode: Locale.current.languageCode ?? "en",
|
120
|
-
premiumColor: acmoInitModel.data.publisherApp.premiumColor,
|
121
|
-
headerColor: acmoInitModel.data.publisherApp.headerColor,
|
122
|
-
mainColor: acmoInitModel.data.publisherApp.mainColor
|
123
|
-
)
|
124
|
-
|
125
|
-
completion(headers)
|
126
|
-
}
|
127
|
-
}
|
128
|
-
|
129
|
-
task.resume()
|
130
|
-
self.log("Network request started")
|
131
|
-
}
|
132
|
-
|
133
69
|
if #available(iOS 14, *) {
|
134
70
|
self.log("Requesting tracking authorization for iOS 14+")
|
135
|
-
ATTrackingManager.requestTrackingAuthorization
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
}
|
146
|
-
finalizeLogin()
|
71
|
+
let status = await ATTrackingManager.requestTrackingAuthorization()
|
72
|
+
switch status {
|
73
|
+
case .authorized:
|
74
|
+
advertisingId = ASIdentifierManager.shared().advertisingIdentifier.uuidString
|
75
|
+
self.log("Tracking authorized. Advertising ID: \(advertisingId)")
|
76
|
+
case .denied, .restricted, .notDetermined:
|
77
|
+
advertisingId = ""
|
78
|
+
self.log("Tracking not authorized or restricted")
|
79
|
+
@unknown default:
|
80
|
+
self.log("Unknown tracking status")
|
147
81
|
}
|
148
82
|
} else {
|
149
83
|
advertisingId = ASIdentifierManager.shared().advertisingIdentifier.uuidString
|
150
84
|
self.log("iOS version < 14. Advertising ID: \(advertisingId)")
|
151
|
-
finalizeLogin()
|
152
85
|
}
|
153
|
-
}
|
154
|
-
|
155
86
|
|
87
|
+
let deviceDetails = getDeviceDetails()
|
88
|
+
let fd: [String: Any] = [
|
89
|
+
"publisherUserId": userId,
|
90
|
+
"platform": "iOS",
|
91
|
+
"identifierType": identifierType,
|
92
|
+
"identifier": advertisingId,
|
93
|
+
"deviceData": deviceDetails
|
94
|
+
]
|
95
|
+
|
96
|
+
self.log("Initializing with data: \(fd)")
|
97
|
+
guard let url = URL(string: AcmoConfig.BASE_URL + "initialize") else {
|
98
|
+
self.log("Failed to create URL")
|
99
|
+
throw NSError(domain: "TyradsSdk", code: 1, userInfo: [NSLocalizedDescriptionKey: "Invalid URL"])
|
100
|
+
}
|
156
101
|
|
102
|
+
var request = URLRequest(url: url)
|
103
|
+
request.httpMethod = "POST"
|
104
|
+
request.setValue(AcmoConfig.SDK_PLATFORM, forHTTPHeaderField: "X-SDK-Platform")
|
105
|
+
request.setValue(AcmoConfig.SDK_VERSION, forHTTPHeaderField: "X-SDK-Version")
|
106
|
+
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
107
|
+
request.setValue(self.apiKey, forHTTPHeaderField: "X-API-Key")
|
108
|
+
request.setValue(self.apiSecret, forHTTPHeaderField: "X-API-Secret")
|
109
|
+
request.setValue(_isSecure ? "BASIC" : "PLAIN", forHTTPHeaderField: "X-Secure-Mode")
|
110
|
+
|
111
|
+
do {
|
112
|
+
let requestBody = _isSecure && !(encKey ?? "").isEmpty ? try AcmoEncrypt(encKey!).encryptDataAESGCM(data: fd) : fd
|
113
|
+
request.httpBody = try JSONSerialization.data(withJSONObject: requestBody)
|
114
|
+
} catch {
|
115
|
+
self.log("Failed to serialize request body: \(error)")
|
116
|
+
throw error
|
117
|
+
}
|
118
|
+
|
119
|
+
// Use the async URLSession API to get data
|
120
|
+
let (data, _) = try await URLSession.shared.data(for: request)
|
121
|
+
|
122
|
+
let responseString = String(data: data, encoding: .utf8)
|
123
|
+
self.log("Received response: \(responseString ?? "nil")")
|
157
124
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
if let campaignIDValue = campaignID {
|
162
|
-
campaignIDString = String(campaignIDValue)
|
125
|
+
guard let acmoInitModel = try? JSONDecoder().decode(AcmoInitModel.self, from: data) else {
|
126
|
+
self.log("Failed to decode response")
|
127
|
+
throw NSError(domain: "TyradsSdk", code: 2, userInfo: [NSLocalizedDescriptionKey: "Failed to decode response"])
|
163
128
|
}
|
164
|
-
let urlString =
|
165
|
-
"https://websdk.tyrads.com/?apiKey=\(Tyrads.instance.apiKey)&apiSecret=\(Tyrads.instance.apiSecret)&userID=\(Tyrads.instance.publisherUserID)&newUser=\(Tyrads.instance.newUser)&platform=\(AcmoConfig.SDK_PLATFORM)&hc=\(Tyrads.instance.loginData?.data.publisherApp.headerColor ?? "")&mc=\(Tyrads.instance.loginData?.data.publisherApp.mainColor ?? "")&launchMode=\(launchMode)&route=\(route ?? "")&campaignID=\(campaignIDString)&lang=\(Tyrads.instance.currentLanguage)&av=\(AcmoConfig.ACMO_VERSION)"
|
166
129
|
|
130
|
+
self.loginData = acmoInitModel
|
131
|
+
self.publisherUserID = acmoInitModel.data.user.publisherUserId
|
132
|
+
self.newUser = acmoInitModel.data.newRegisteredUser
|
133
|
+
self.token = acmoInitModel.data.token
|
134
|
+
self.log("Login successful. Publisher User ID: \(self.publisherUserID), New User: \(self.newUser)")
|
135
|
+
|
136
|
+
let headers = await ApiHeaders(
|
137
|
+
xApiKey: self.apiKey,
|
138
|
+
xApiSecret: self.apiSecret,
|
139
|
+
xUserId: self.publisherUserID,
|
140
|
+
xSdkPlatform: AcmoConfig.SDK_PLATFORM,
|
141
|
+
xSdkVersion: AcmoConfig.SDK_VERSION,
|
142
|
+
userAgent: UIDevice.current.systemName + "/" + UIDevice.current.systemVersion,
|
143
|
+
languageCode: Locale.current.languageCode ?? "en",
|
144
|
+
premiumColor: acmoInitModel.data.publisherApp.premiumColor,
|
145
|
+
headerColor: acmoInitModel.data.publisherApp.headerColor,
|
146
|
+
mainColor: acmoInitModel.data.publisherApp.mainColor
|
147
|
+
)
|
148
|
+
return headers
|
149
|
+
}
|
150
|
+
|
151
|
+
|
152
|
+
|
153
|
+
|
154
|
+
public func showOffers(_ launchMode: Int = 3, route: String? = nil, campaignID: Int? = nil) async {
|
155
|
+
// self.initializationWait.wait()
|
156
|
+
await ensureInitialized()
|
157
|
+
var components = URLComponents()
|
158
|
+
components.scheme = "https"
|
159
|
+
components.host = "sdk.tyrads.com"
|
160
|
+
// components.path = "/\(route ?? "")"
|
161
|
+
components.queryItems = [
|
162
|
+
URLQueryItem(name: "token", value: self.token),
|
163
|
+
URLQueryItem(name: "to", value: campaignID != nil ? "\(route ?? "")/\(campaignID!)" : route)
|
164
|
+
]
|
165
|
+
var urlString: String = ""
|
166
|
+
if let url = components.url {
|
167
|
+
urlString = url.absoluteString
|
168
|
+
print(urlString)
|
169
|
+
} else {
|
170
|
+
print("Failed to create URL with components: \(components)")
|
171
|
+
}
|
172
|
+
|
167
173
|
do {
|
168
174
|
guard let url = URL(string: urlString) else {
|
169
175
|
throw NSError(domain: "TyradsSdk", code: 1, userInfo: [NSLocalizedDescriptionKey: "Invalid URL"])
|
@@ -172,27 +178,11 @@ public class Tyrads : NSObject {
|
|
172
178
|
switch launchMode {
|
173
179
|
case 1, 2:
|
174
180
|
DispatchQueue.main.async {
|
175
|
-
let
|
176
|
-
|
177
|
-
|
178
|
-
userContentController.add(self, name: "clickHandler")
|
179
|
-
config.userContentController = userContentController
|
180
|
-
|
181
|
-
let webView = WKWebView(frame: UIScreen.main.bounds, configuration: config)
|
182
|
-
webView.navigationDelegate = self
|
183
|
-
|
184
|
-
if #available(iOS 16.4, *) {
|
185
|
-
webView.isInspectable = true
|
186
|
-
}
|
187
|
-
|
188
|
-
let viewController = UIViewController()
|
189
|
-
viewController.view = webView
|
190
|
-
viewController.modalPresentationStyle = .fullScreen
|
191
|
-
|
192
|
-
webView.load(URLRequest(url: url))
|
181
|
+
let acmoVC = AcmoWebViewController(url: url)
|
182
|
+
acmoVC.modalPresentationStyle = .fullScreen
|
193
183
|
|
194
184
|
if let rootViewController = UIApplication.shared.windows.first?.rootViewController {
|
195
|
-
rootViewController.present(
|
185
|
+
rootViewController.present(acmoVC, animated: true, completion: nil)
|
196
186
|
}
|
197
187
|
}
|
198
188
|
case 3:
|
@@ -209,62 +199,3 @@ public class Tyrads : NSObject {
|
|
209
199
|
}
|
210
200
|
}
|
211
201
|
}
|
212
|
-
|
213
|
-
|
214
|
-
extension Tyrads: WKScriptMessageHandler {
|
215
|
-
public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
216
|
-
guard message.name == "clickHandler",
|
217
|
-
let messageDict = message.body as? [String: Any] else {
|
218
|
-
return
|
219
|
-
}
|
220
|
-
print("Message data: \(messageDict)")
|
221
|
-
|
222
|
-
if let action = messageDict["action"] as? String {
|
223
|
-
switch action {
|
224
|
-
case "closeWebview":
|
225
|
-
DispatchQueue.main.async {
|
226
|
-
UIApplication.shared.windows.first?.rootViewController?.dismiss(animated: true)
|
227
|
-
}
|
228
|
-
|
229
|
-
case "changeLanguage":
|
230
|
-
if let langCode = messageDict["languageCode"] as? String {
|
231
|
-
// Handle language change
|
232
|
-
self.currentLanguage = langCode
|
233
|
-
// Notify any observers if needed
|
234
|
-
}
|
235
|
-
|
236
|
-
default:
|
237
|
-
print("Unknown command: \(action)")
|
238
|
-
}
|
239
|
-
}
|
240
|
-
}
|
241
|
-
}
|
242
|
-
|
243
|
-
extension Tyrads: WKNavigationDelegate {
|
244
|
-
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
245
|
-
let js = """
|
246
|
-
window.addEventListener('message', (event) => {
|
247
|
-
try {
|
248
|
-
const message = typeof event.data === 'string'
|
249
|
-
? JSON.parse(event.data)
|
250
|
-
: event.data;
|
251
|
-
if (message && message.command === 'webview_command') {
|
252
|
-
window.webkit.messageHandlers.clickHandler.postMessage({
|
253
|
-
command: message.command,
|
254
|
-
action: message.action,
|
255
|
-
languageCode: message.languageCode
|
256
|
-
});
|
257
|
-
}
|
258
|
-
} catch (error) {
|
259
|
-
console.log('Message handling error:', error);
|
260
|
-
}
|
261
|
-
});
|
262
|
-
"""
|
263
|
-
|
264
|
-
webView.evaluateJavaScript(js) { _, error in
|
265
|
-
if let error = error {
|
266
|
-
print("JavaScript injection failed: \(error)")
|
267
|
-
}
|
268
|
-
}
|
269
|
-
}
|
270
|
-
}
|
@@ -0,0 +1,171 @@
|
|
1
|
+
import UIKit
|
2
|
+
@preconcurrency import WebKit
|
3
|
+
|
4
|
+
class AcmoWebViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandler, WKUIDelegate {
|
5
|
+
|
6
|
+
var webView: WKWebView!
|
7
|
+
var initialURL: URL
|
8
|
+
|
9
|
+
private let internalDomains: [String] = ["sdk.tyrads.com", "acmo.in"]
|
10
|
+
|
11
|
+
private func log(_ message: String) {
|
12
|
+
NSLog("AcmoWebViewController: \(message)")
|
13
|
+
}
|
14
|
+
|
15
|
+
init(url: URL) {
|
16
|
+
self.initialURL = url
|
17
|
+
super.init(nibName: nil, bundle: nil)
|
18
|
+
}
|
19
|
+
|
20
|
+
required init?(coder: NSCoder) {
|
21
|
+
fatalError("init(coder:) has not been implemented")
|
22
|
+
}
|
23
|
+
|
24
|
+
override func viewDidLoad() {
|
25
|
+
super.viewDidLoad()
|
26
|
+
log("viewDidLoad called")
|
27
|
+
|
28
|
+
let config = WKWebViewConfiguration()
|
29
|
+
let userContentController = WKUserContentController()
|
30
|
+
|
31
|
+
userContentController.add(self, name: "clickHandler")
|
32
|
+
config.userContentController = userContentController
|
33
|
+
|
34
|
+
webView = WKWebView(frame: self.view.bounds, configuration: config)
|
35
|
+
webView.navigationDelegate = self
|
36
|
+
webView.uiDelegate = self
|
37
|
+
self.view.addSubview(webView)
|
38
|
+
|
39
|
+
webView.translatesAutoresizingMaskIntoConstraints = false
|
40
|
+
NSLayoutConstraint.activate([
|
41
|
+
webView.topAnchor.constraint(equalTo: self.view.topAnchor),
|
42
|
+
webView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
|
43
|
+
webView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
|
44
|
+
webView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor)
|
45
|
+
])
|
46
|
+
|
47
|
+
if #available(iOS 16.4, *) {
|
48
|
+
webView.isInspectable = true
|
49
|
+
}
|
50
|
+
|
51
|
+
webView.load(URLRequest(url: initialURL))
|
52
|
+
log("WebView loaded URL: \(initialURL.absoluteString)")
|
53
|
+
}
|
54
|
+
|
55
|
+
public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
56
|
+
guard message.name == "clickHandler",
|
57
|
+
let messageDict = message.body as? [String: Any] else {
|
58
|
+
log("Received unknown message or invalid format.")
|
59
|
+
return
|
60
|
+
}
|
61
|
+
|
62
|
+
log("Message data from webview: \(messageDict)")
|
63
|
+
|
64
|
+
if let action = messageDict["action"] as? String {
|
65
|
+
switch action {
|
66
|
+
case "closeWebView":
|
67
|
+
log("Action: closeWebView received. Dismissing view controller.")
|
68
|
+
DispatchQueue.main.async {
|
69
|
+
self.dismiss(animated: true) {
|
70
|
+
self.log("ViewController dismissed successfully.")
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
case "changeLanguage":
|
75
|
+
if let langCode = messageDict["languageCode"] as? String {
|
76
|
+
log("Action: changeLanguage received. Language Code: \(langCode)")
|
77
|
+
}
|
78
|
+
|
79
|
+
default:
|
80
|
+
log("Unknown command: \(action)")
|
81
|
+
}
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
86
|
+
if let url = webView.url {
|
87
|
+
print("Page loaded successfully. Final URL: \(url.absoluteString)")
|
88
|
+
}
|
89
|
+
|
90
|
+
let js = """
|
91
|
+
window.addEventListener('message', (event) => {
|
92
|
+
try {
|
93
|
+
// Safely parse JSON if event.data is a string, otherwise use directly
|
94
|
+
const message = typeof event.data === 'string'
|
95
|
+
? JSON.parse(event.data)
|
96
|
+
: event.data;
|
97
|
+
if (message) {
|
98
|
+
// Post the message to the native side using the registered handler name
|
99
|
+
window.webkit.messageHandlers.clickHandler.postMessage(message);
|
100
|
+
}
|
101
|
+
} catch (error) {
|
102
|
+
console.error('Error handling message from WebView:', error);
|
103
|
+
}
|
104
|
+
});
|
105
|
+
"""
|
106
|
+
|
107
|
+
webView.evaluateJavaScript(js) { _, error in
|
108
|
+
if let error = error {
|
109
|
+
self.log("JavaScript injection failed: \(error.localizedDescription)")
|
110
|
+
} else {
|
111
|
+
self.log("JavaScript listener injected successfully.")
|
112
|
+
}
|
113
|
+
}
|
114
|
+
}
|
115
|
+
|
116
|
+
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
|
117
|
+
|
118
|
+
guard let url = navigationAction.request.url, let host = url.host else {
|
119
|
+
decisionHandler(.cancel)
|
120
|
+
return
|
121
|
+
}
|
122
|
+
|
123
|
+
if host == "about:blank" {
|
124
|
+
decisionHandler(.allow)
|
125
|
+
return
|
126
|
+
}
|
127
|
+
|
128
|
+
let isInternalDomain = internalDomains.contains(where: { host.hasSuffix($0) })
|
129
|
+
|
130
|
+
if host != webView.url?.host && !isInternalDomain {
|
131
|
+
log("Intercepted external URL via navigation action: \(url.absoluteString). Opening externally.")
|
132
|
+
UIApplication.shared.open(url, options: [:], completionHandler: nil)
|
133
|
+
decisionHandler(.cancel)
|
134
|
+
return
|
135
|
+
}
|
136
|
+
|
137
|
+
log("Allowed navigation to: \(url.absoluteString)")
|
138
|
+
decisionHandler(.allow)
|
139
|
+
}
|
140
|
+
|
141
|
+
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
|
142
|
+
|
143
|
+
guard let url = navigationAction.request.url else {
|
144
|
+
return nil
|
145
|
+
}
|
146
|
+
|
147
|
+
let isInternalDomain = internalDomains.contains(where: { url.host?.hasSuffix($0) ?? false })
|
148
|
+
|
149
|
+
if !isInternalDomain {
|
150
|
+
log("Intercepted new window via UI delegate: \(url.absoluteString). Opening externally.")
|
151
|
+
UIApplication.shared.open(url, options: [:], completionHandler: nil)
|
152
|
+
return nil
|
153
|
+
}
|
154
|
+
|
155
|
+
log("Allowed new window for internal domain: \(url.absoluteString)")
|
156
|
+
return nil
|
157
|
+
}
|
158
|
+
|
159
|
+
public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
|
160
|
+
log("WebView navigation failed with error: \(error.localizedDescription)")
|
161
|
+
}
|
162
|
+
|
163
|
+
public func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
|
164
|
+
log("WebView provisional navigation failed with error: \(error.localizedDescription)")
|
165
|
+
}
|
166
|
+
|
167
|
+
deinit {
|
168
|
+
webView.configuration.userContentController.removeScriptMessageHandler(forName: "clickHandler")
|
169
|
+
log("AcmoWebViewController deinitialized. Message handler removed.")
|
170
|
+
}
|
171
|
+
}
|