Skip to content

Commit 5ca55e3

Browse files
author
SojiroNishimura
committed
Merge release/2024.12.05T06.22.57 into master
2 parents 395d5f3 + 5b5d33b commit 5ca55e3

13 files changed

+175
-36
lines changed

.spm-version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.17.0
1+
2.18.0

CHANGELOG.md

+13-2
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,26 @@
22

33
| モジュール名 | Description | 最新のバージョン |
44
| :-- | :-- | :-- |
5-
| KarteCore | イベントトラッキング機能を提供します。 | 2.29.0 |
6-
| KarteInAppMessaging | アプリ内メッセージ機能を提供します。 | 2.18.0 |
5+
| KarteCore | イベントトラッキング機能を提供します。 | 2.30.0 |
6+
| KarteInAppMessaging | アプリ内メッセージ機能を提供します。 | 2.19.0 |
77
| KarteRemoteNotification | プッシュ通知の受信および効果測定機能を提供します。 | 2.11.0 |
88
| KarteVariables | 設定値配信機能を提供します。 | 2.10.0 |
99
| KarteVisualTracking | ビジュアルトラッキング機能を提供します。 | 2.12.0 |
1010
| KarteCrashReporting | クラッシュイベントのトラッキング機能を提供します。 | 2.8.0 |
1111
| KarteUtilities | KarteCore モジュール等が利用するUtility機能を提供します。通常直接参照する必要はありません。 | 3.12.0 |
1212
| KarteNotificationServiceExtension | リッチプッシュ通知機能を提供します。 | 1.2.0 |
1313

14+
# Releases - 2024.12.05
15+
## Version 2.18.0
16+
17+
### Core 2.30.0
18+
** 🎉 FEATURE**
19+
- Native機能呼び出しにATT許諾ダイアログ表示を追加しました。
20+
21+
### InAppMessaging 2.19.0
22+
** 🔨CHANGED**
23+
- InAppMessagingDelegateの処理をMainActorに隔離しました。
24+
1425
# Releases - 2024.08.26
1526
## Version 2.17.0
1627

Karte.xcodeproj/project.pbxproj

+12-4
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,8 @@
434434
AF0A5F2F29546BB000209D4E /* Logger+Tag.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF0A5F2E29546BB000209D4E /* Logger+Tag.swift */; };
435435
AF0A5F31295475B300209D4E /* KarteInbox.m in Sources */ = {isa = PBXBuildFile; fileRef = AF0A5F30295475B300209D4E /* KarteInbox.m */; };
436436
AF0A5F352959986F00209D4E /* InboxLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = AF0A5F342959986F00209D4E /* InboxLoader.m */; };
437+
AF38FD9E2C7C7313009C1C20 /* RequestATTCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF38FD9D2C7C7313009C1C20 /* RequestATTCommand.swift */; };
438+
AF38FDA02C7C8108009C1C20 /* RequestATTCommandSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF38FD9F2C7C8108009C1C20 /* RequestATTCommandSpec.swift */; };
437439
AF49FAA1296ED953005A7575 /* CallerSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF49FAA0296ED953005A7575 /* CallerSpec.swift */; };
438440
AF5EDEB329C1C49000D05825 /* OpenMessagesRequestSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF5EDEB229C1C49000D05825 /* OpenMessagesRequestSpec.swift */; };
439441
AF5EDEB529C1C5A600D05825 /* OpenMessagesRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF5EDEB429C1C5A600D05825 /* OpenMessagesRequest.swift */; };
@@ -1031,6 +1033,8 @@
10311033
AF0A5F2E29546BB000209D4E /* Logger+Tag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Logger+Tag.swift"; sourceTree = "<group>"; };
10321034
AF0A5F30295475B300209D4E /* KarteInbox.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KarteInbox.m; sourceTree = "<group>"; };
10331035
AF0A5F342959986F00209D4E /* InboxLoader.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InboxLoader.m; sourceTree = "<group>"; };
1036+
AF38FD9D2C7C7313009C1C20 /* RequestATTCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestATTCommand.swift; sourceTree = "<group>"; };
1037+
AF38FD9F2C7C8108009C1C20 /* RequestATTCommandSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestATTCommandSpec.swift; sourceTree = "<group>"; };
10341038
AF49FAA0296ED953005A7575 /* CallerSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallerSpec.swift; sourceTree = "<group>"; };
10351039
AF5EDEB229C1C49000D05825 /* OpenMessagesRequestSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenMessagesRequestSpec.swift; sourceTree = "<group>"; };
10361040
AF5EDEB429C1C5A600D05825 /* OpenMessagesRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenMessagesRequest.swift; sourceTree = "<group>"; };
@@ -2255,6 +2259,7 @@
22552259
0CE33A0523F40C2200E2EB98 /* UserSyncParameterSpec.swift */,
22562260
681E83982483B54800A95083 /* RequestReviewCommandSpec.swift */,
22572261
681E839A2483B5C800A95083 /* OpenSettingsCommandSpec.swift */,
2262+
AF38FD9F2C7C8108009C1C20 /* RequestATTCommandSpec.swift */,
22582263
);
22592264
path = Core;
22602265
sourceTree = "<group>";
@@ -2383,6 +2388,7 @@
23832388
681E83942482A90E00A95083 /* OpenSettingsCommand.swift */,
23842389
680DB3C72480F74E00AE6800 /* Command.swift */,
23852390
681E838C248246B700A95083 /* RequestReviewCommand.swift */,
2391+
AF38FD9D2C7C7313009C1C20 /* RequestATTCommand.swift */,
23862392
681E838E2482510200A95083 /* CommandHandler.swift */,
23872393
681E8390248252EE00A95083 /* CommandHandlerLoader.m */,
23882394
);
@@ -3112,6 +3118,7 @@
31123118
777D605D274267FC00339D7E /* InvalidEventFieldNameFilterRule.swift in Sources */,
31133119
0C69D40F24EB9DB200D75893 /* InitializationEventFilterRule.swift in Sources */,
31143120
0C0822FB24EA615C0038EBDA /* CommandBundlerApplicationStateProvider.swift in Sources */,
3121+
AF38FD9E2C7C7313009C1C20 /* RequestATTCommand.swift in Sources */,
31153122
0C83928F2406C6AA0014C2BF /* InstallationStatus.swift in Sources */,
31163123
0C69D3FC24EB9D9D00D75893 /* TrackClientState.swift in Sources */,
31173124
0C8392B72406C7010014C2BF /* Module.swift in Sources */,
@@ -3380,6 +3387,7 @@
33803387
0CE79327238653AD00F0D932 /* SpecConfiguration.swift in Sources */,
33813388
0CC648B8238CCFC3009EB5DF /* StubBuilder.swift in Sources */,
33823389
0CCFA7B524A5814100E0F184 /* FCMTokenRegistrarSpec.swift in Sources */,
3390+
AF38FDA02C7C8108009C1C20 /* RequestATTCommandSpec.swift in Sources */,
33833391
0C839316240838050014C2BF /* ActionAppropriateViewDetectorSpec.swift in Sources */,
33843392
363F25F12582A1EB007E6E4B /* DefinitionsRequestSpec.swift in Sources */,
33853393
0C520BCC2990995000480B77 /* JSONConvertibleSpec.swift in Sources */,
@@ -3852,7 +3860,7 @@
38523860
"@executable_path/Frameworks",
38533861
"@loader_path/Frameworks",
38543862
);
3855-
MARKETING_VERSION = 2.29.0;
3863+
MARKETING_VERSION = 2.30.0;
38563864
PRODUCT_BUNDLE_IDENTIFIER = io.karte.KarteCore;
38573865
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
38583866
SKIP_INSTALL = YES;
@@ -3887,7 +3895,7 @@
38873895
"@executable_path/Frameworks",
38883896
"@loader_path/Frameworks",
38893897
);
3890-
MARKETING_VERSION = 2.29.0;
3898+
MARKETING_VERSION = 2.30.0;
38913899
PRODUCT_BUNDLE_IDENTIFIER = io.karte.KarteCore;
38923900
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
38933901
SKIP_INSTALL = YES;
@@ -3920,7 +3928,7 @@
39203928
"@executable_path/Frameworks",
39213929
"@loader_path/Frameworks",
39223930
);
3923-
MARKETING_VERSION = 2.18.0;
3931+
MARKETING_VERSION = 2.19.0;
39243932
PRODUCT_BUNDLE_IDENTIFIER = io.karte.KarteInAppMessaging;
39253933
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
39263934
SKIP_INSTALL = YES;
@@ -3953,7 +3961,7 @@
39533961
"@executable_path/Frameworks",
39543962
"@loader_path/Frameworks",
39553963
);
3956-
MARKETING_VERSION = 2.18.0;
3964+
MARKETING_VERSION = 2.19.0;
39573965
PRODUCT_BUNDLE_IDENTIFIER = io.karte.KarteInAppMessaging;
39583966
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
39593967
SKIP_INSTALL = YES;

KarteCore.podspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
Pod::Spec.new do |s|
1010
s.name = 'KarteCore'
11-
s.version = '2.29.0'
11+
s.version = '2.30.0'
1212
s.summary = 'KARTE Core SDK'
1313
s.homepage = 'https://karte.io'
1414
s.author = { 'PLAID' => '[email protected]' }

KarteCore/Core/Command/CommandHandler.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ extension CommandHandler: DeepLinkModule {
6262
public func handle(app: UIApplication, open url: URL) -> Bool {
6363
let commands: [Command] = [
6464
RequestReviewCommand(),
65-
OpenSettingsCommand()
65+
OpenSettingsCommand(),
66+
RequestATTCommand()
6667
]
6768
return commands.map { $0.run(url: url) }.contains(true)
6869
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//
2+
// Copyright 2024 PLAID, Inc.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// https://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
//
16+
17+
import AppTrackingTransparency
18+
19+
internal struct RequestATTCommand: Command {
20+
func validate(_ url: URL) -> Bool {
21+
url.host == "request-att"
22+
}
23+
24+
func execute() {
25+
if #available(iOS 14.5, *) {
26+
guard ATTrackingManager.trackingAuthorizationStatus == .notDetermined else {
27+
Logger.warn(tag: .core, message: "ATT is already determined, status = \(ATTrackingManager.trackingAuthorizationStatus)")
28+
return
29+
}
30+
31+
ATTrackingManager.requestTrackingAuthorization { status in
32+
switch status {
33+
case .authorized:
34+
Logger.info(tag: .core, message: "ATT status is authorized")
35+
case .denied:
36+
Logger.info(tag: .core, message: "ATT status is denied")
37+
case .notDetermined:
38+
Logger.info(tag: .core, message: "ATT status is notDetermined")
39+
case .restricted:
40+
Logger.info(tag: .core, message: "ATT status is restricted")
41+
@unknown default:
42+
Logger.warn(tag: .core, message: "ATT status is unknown: \(status)")
43+
}
44+
}
45+
} else {
46+
Logger.warn(tag: .core, message: "iOS version must be over 14.5, ATT is not available")
47+
}
48+
}
49+
}

KarteInAppMessaging.podspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
Pod::Spec.new do |s|
1010
s.name = 'KarteInAppMessaging'
11-
s.version = '2.18.0'
11+
s.version = '2.19.0'
1212
s.summary = 'KARTE In-app messaging SDK'
1313
s.homepage = 'https://karte.io'
1414
s.author = { 'PLAID' => '[email protected]' }

KarteInAppMessaging/IAMProcess.swift

+8-1
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,13 @@ extension IAMProcess {
247247

248248
private func handleJsMessageEvent(_ data: JsMessage.EventData) {
249249
Tracker.track(view: window, data: data)
250-
notifyCampaignOpenOrClose(data)
250+
if Thread.isMainThread {
251+
notifyCampaignOpenOrClose(data)
252+
} else {
253+
DispatchQueue.main.async {
254+
self.notifyCampaignOpenOrClose(data)
255+
}
256+
}
251257
}
252258

253259
private func handleJsMessageOpenURL(_ data: JsMessage.OpenURLData) {
@@ -347,6 +353,7 @@ extension IAMProcess: IAMWebViewDelegate {
347353
return true
348354
}
349355

356+
@MainActor
350357
func inAppMessagingWebView(_ webView: IAMWebView, shouldOpenURL url: URL) -> Bool {
351358
let iam = InAppMessaging.shared
352359
guard let delegate = iam.delegate else {

KarteInAppMessaging/InAppMessaging.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ extension InAppMessaging {
222222
}
223223
}
224224

225-
@objc
225+
@MainActor @objc
226226
private func observeWindowDidBecomeVisibleNotification(_ notification: Notification) {
227227
guard let window = notification.object as? UIWindow else {
228228
return
@@ -255,7 +255,7 @@ extension InAppMessaging {
255255
pool.storeProcess(process)
256256
}
257257

258-
@objc
258+
@MainActor @objc
259259
private func observeWindowDidBecomeHiddenNotification(_ notification: Notification) {
260260
guard let window = notification.object as? UIWindow else {
261261
return

KarteInAppMessaging/InAppMessagingDelegate.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import UIKit
1818

1919
/// アプリ内メッセージで発生するイベントを委譲するためのタイプです。
20-
@objc(KRTInAppMessagingDelegate)
20+
@preconcurrency @MainActor @objc(KRTInAppMessagingDelegate)
2121
public protocol InAppMessagingDelegate: AnyObject {
2222
/// アプリ内メッセージ用のWindowが表示されたことを通知します。
2323
///

KarteInAppMessaging/View/IAMWebView.swift

+22-20
Original file line numberDiff line numberDiff line change
@@ -172,34 +172,36 @@ internal class IAMWebView: WKWebView {
172172
}
173173

174174
func openURL(_ url: URL?, isReset: Bool) {
175-
guard let url = url else {
176-
Logger.debug(tag: .inAppMessaging, message: "Can't open URL because URL is nil.")
177-
return
178-
}
175+
DispatchQueue.main.async {
176+
guard let url = url else {
177+
Logger.debug(tag: .inAppMessaging, message: "Can't open URL because URL is nil.")
178+
return
179+
}
179180

180-
if isReset {
181-
reset(mode: .soft)
182-
}
181+
if isReset {
182+
self.reset(mode: .soft)
183+
}
183184

184-
if let delegate = delegate, !delegate.inAppMessagingWebView(self, shouldOpenURL: url) {
185-
Logger.info(tag: .inAppMessaging, message: "SDK delegates openURL to client app. URL=\(url)")
186-
return
187-
}
185+
if let delegate = self.delegate, !delegate.inAppMessagingWebView(self, shouldOpenURL: url) {
186+
Logger.info(tag: .inAppMessaging, message: "SDK delegates openURL to client app. URL=\(url)")
187+
return
188+
}
188189

189-
if #available(iOS 10.0, *) {
190-
UIApplication.shared.open(url, options: [:]) { successful in
191-
if successful {
190+
if #available(iOS 10.0, *) {
191+
UIApplication.shared.open(url, options: [:]) { successful in
192+
if successful {
193+
Logger.info(tag: .inAppMessaging, message: "Success to open URL: \(url)")
194+
} else {
195+
Logger.error(tag: .inAppMessaging, message: "Failed to open URL: \(url)")
196+
}
197+
}
198+
} else {
199+
if UIApplication.shared.openURL(url) {
192200
Logger.info(tag: .inAppMessaging, message: "Success to open URL: \(url)")
193201
} else {
194202
Logger.error(tag: .inAppMessaging, message: "Failed to open URL: \(url)")
195203
}
196204
}
197-
} else {
198-
if UIApplication.shared.openURL(url) {
199-
Logger.info(tag: .inAppMessaging, message: "Success to open URL: \(url)")
200-
} else {
201-
Logger.error(tag: .inAppMessaging, message: "Failed to open URL: \(url)")
202-
}
203205
}
204206
}
205207

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//
2+
// Copyright 2024 PLAID, Inc.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// https://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
//
16+
17+
import Quick
18+
import Nimble
19+
@testable import KarteCore
20+
21+
class RequestATTCommandSpec: QuickSpec {
22+
override func spec() {
23+
describe("its run") {
24+
context("when invalid value passed") {
25+
let examples = [
26+
"test:",
27+
"krt:",
28+
"krt://request-att",
29+
"aaa-karte-sdk://request-att",
30+
"krt-hSZM://request-att",
31+
"krt-hSZMcVyjwg6Y7pdYMa4YPqmyQ77EpALw://request-review",
32+
]
33+
examples.forEach { (input) in
34+
context("\(input)") {
35+
it("returns false") {
36+
let c = RequestATTCommand()
37+
let u = URL(string: input)!
38+
expect(c.run(url: u)).to(beFalse())
39+
}
40+
}
41+
}
42+
}
43+
44+
context("when valid value passed") {
45+
let examples = [
46+
"krt-hSZMcVyjwg6Y7pdYMa4YPqmyQ77EpALw://request-att",
47+
"krt-HRTwj9QEZGJrTaTkADrtdxFTyuXUJVMh://request-att"
48+
]
49+
examples.forEach { (input) in
50+
context("\(input)") {
51+
it("returns true") {
52+
let c = RequestATTCommand()
53+
let u = URL(string: input)!
54+
expect(c.run(url: u)).to(beTrue())
55+
}
56+
}
57+
}
58+
}
59+
}
60+
}
61+
}

Package.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ let package = Package(
5454
name: "KarteUtilities", url: "https://sdk.karte.io/ios/swiftpm/Utilities-3.12.0/KarteUtilities.xcframework.zip", checksum: "850abc71a8bc28e415f4b11e3072ff741a1d908c13b951a4676bc2e675eaf634"
5555
),
5656
.binaryTarget(
57-
name: "KarteCore", url: "https://sdk.karte.io/ios/swiftpm/Core-2.29.0/KarteCore.xcframework.zip", checksum: "5b4c1f3e7157a95e9fa6ff2227854a1c5cec76fb4b1571db787b1345e7efde61"
57+
name: "KarteCore", url: "https://sdk.karte.io/ios/swiftpm/Core-2.30.0/KarteCore.xcframework.zip", checksum: "b4814553acd31092d29a50b75b34680484d55eece5c7152dca694590c9263c60"
5858
),
5959
.binaryTarget(
60-
name: "KarteInAppMessaging", url: "https://sdk.karte.io/ios/swiftpm/InAppMessaging-2.18.0/KarteInAppMessaging.xcframework.zip", checksum: "d1625e74bac54bd63744c6297b742bb781ea1ab0bf4a4f652fd765245094ffcf"
60+
name: "KarteInAppMessaging", url: "https://sdk.karte.io/ios/swiftpm/InAppMessaging-2.19.0/KarteInAppMessaging.xcframework.zip", checksum: "b87a10043ac75d9c7ced8f7493bd8c8e8d4f590facc7dd51f843675157ecfad9"
6161
),
6262
.binaryTarget(
6363
name: "KarteVariables", url: "https://sdk.karte.io/ios/swiftpm/Variables-2.10.0/KarteVariables.xcframework.zip", checksum: "19665bf1c9eb5e04719b660839de4ca1145589a62669de6f12efb38fc39a4aad"

0 commit comments

Comments
 (0)