update: 更新和完善 GuruConsent 本地 iOS 库的文件和 podspec 配置
--story=1020278 --user=yufei.hu 【中台】【发行】【iOS】 将 GuruConsent 库升级到最新的版本, 将线上的 Pods 依赖改为 UPM 内部文件依赖 https://www.tapd.cn/33527076/s/1147977 Signed-off-by: huyufei <yufei.hu@castbox.fm>hotfix/v1.0.12.2
parent
5882d213c3
commit
d5c02418c7
|
|
@ -1,3 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: b88f29431cdd47f9bc1945ddd590c4df
|
|
||||||
timeCreated: 1717035321
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: c1d92ec4f77c4f179f05f8a7be17de86
|
|
||||||
timeCreated: 1717035338
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 4e5722a54ec94d72a304d981db2426f7
|
|
||||||
timeCreated: 1717035343
|
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 78bd1ca99d374a1f9f31be5cbf38b03c
|
||||||
|
timeCreated: 1717118600
|
||||||
|
|
@ -22,7 +22,7 @@ Pod::Spec.new do |s|
|
||||||
s.swift_version = '5.0'
|
s.swift_version = '5.0'
|
||||||
s.ios.deployment_target = '12.0'
|
s.ios.deployment_target = '12.0'
|
||||||
|
|
||||||
s.source_files = "Sources/**/*.swift"
|
s.source_files = "GuruConsent/Sources/**/*.swift"
|
||||||
|
|
||||||
s.requires_arc = true
|
s.requires_arc = true
|
||||||
|
|
||||||
|
|
@ -34,7 +34,7 @@ Pod::Spec.new do |s|
|
||||||
|
|
||||||
s.subspec 'Privacy' do |ss|
|
s.subspec 'Privacy' do |ss|
|
||||||
ss.resource_bundles = {
|
ss.resource_bundles = {
|
||||||
s.name => 'Resources/PrivacyInfo.xcprivacy'
|
s.name => 'GuruConsent/Resources/PrivacyInfo.xcprivacy'
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 CastBox Dev Team
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
@ -0,0 +1,282 @@
|
||||||
|
# GuruConsent-iOS
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 特性
|
||||||
|
|
||||||
|
- [x] 支持系统ATT权限引导弹窗.
|
||||||
|
- [x] 支持多国语言显示.
|
||||||
|
- [x] 支持调试EEA地理设置等.
|
||||||
|
- [x] 支持结果状态回调.
|
||||||
|
|
||||||
|
## 准备
|
||||||
|
|
||||||
|
将应用 ID 添加到 Info.plist 中:
|
||||||
|
|
||||||
|
```
|
||||||
|
<key>GADApplicationIdentifier</key>
|
||||||
|
<string>YOUR-APP-ID</string>
|
||||||
|
```
|
||||||
|
|
||||||
|
将ATT跟踪权限添加到 Info.plist 中:
|
||||||
|
|
||||||
|
```
|
||||||
|
<key>NSUserTrackingUsageDescription</key>
|
||||||
|
<string>This identifier will be used to deliver personalized ads to you.</string>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 安装
|
||||||
|
|
||||||
|
GuruConsent 仅支持CocoaPods.
|
||||||
|
|
||||||
|
**CocoaPods - Podfile**
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
source 'git@github.com:castbox/GuruSpecs.git'
|
||||||
|
|
||||||
|
pod 'GuruConsent'
|
||||||
|
```
|
||||||
|
|
||||||
|
## 使用
|
||||||
|
|
||||||
|
首先导入framework:
|
||||||
|
|
||||||
|
Swift:
|
||||||
|
|
||||||
|
```swift
|
||||||
|
import GuruConsent
|
||||||
|
```
|
||||||
|
|
||||||
|
Objective-C:
|
||||||
|
|
||||||
|
```objc
|
||||||
|
#import <GuruConsent/GuruConsent-Swift.h>
|
||||||
|
```
|
||||||
|
|
||||||
|
下面是一些简单示例. 支持所有设备和模拟器:
|
||||||
|
|
||||||
|
### 方式一: 自动
|
||||||
|
|
||||||
|
如果满足显示条件 自动显示弹窗 具有一定的延迟效果 但具体显示时机不定, 受网络影响.
|
||||||
|
|
||||||
|
__建议在应用启动后 延后一些调用开始 请务必确保首次启动后已授权网络请求权限再调用__
|
||||||
|
|
||||||
|
Swift:
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// 开始请求
|
||||||
|
GuruConsent.start(from: controller) { result in
|
||||||
|
switch result {
|
||||||
|
case .success(let status):
|
||||||
|
if #available(iOS 14, *) {
|
||||||
|
print("ATT 结果: \(ATTrackingManager.trackingAuthorizationStatus)")
|
||||||
|
}
|
||||||
|
print("GDPR 结果: \(status)")
|
||||||
|
|
||||||
|
case .failure(let error):
|
||||||
|
print("失败: \(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Objective-C:
|
||||||
|
|
||||||
|
```objc
|
||||||
|
// 开始请求
|
||||||
|
[GuruConsent startFrom:self success:^(enum GuruConsentGDPRStatus status) {
|
||||||
|
|
||||||
|
if (@available(iOS 14, *)) {
|
||||||
|
NSLog(@"ATT 结果: %lu", (unsigned long)ATTrackingManager.trackingAuthorizationStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (status) {
|
||||||
|
case GuruConsentGDPRStatusUnknown:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GuruConsentGDPRStatusRequired:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GuruConsentGDPRStatusNotRequired:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GuruConsentGDPRStatusObtained:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
NSLog(@"GDPR 结果: %ld", (long)status);
|
||||||
|
|
||||||
|
} failure:^(NSError * _Nonnull error) {
|
||||||
|
NSLog(@"失败: %@", error);
|
||||||
|
}];
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### 方式二: 手动
|
||||||
|
|
||||||
|
先调用准备, 准备完成后在合适的时机手动调用弹窗显示.
|
||||||
|
|
||||||
|
__建议在应用启动后 延后一些调用准备 请务必确保首次启动后已授权网络请求权限再调用__
|
||||||
|
|
||||||
|
Swift:
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// 准备
|
||||||
|
GuruConsent.prepare { result in
|
||||||
|
switch result {
|
||||||
|
case .success(let status):
|
||||||
|
print("GDPR 结果: \(status)")
|
||||||
|
|
||||||
|
case .failure(let error):
|
||||||
|
print("失败: \(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 显示 请确保status为.required 否则无法显示
|
||||||
|
GuruConsent.present(from: self) { result in
|
||||||
|
switch result {
|
||||||
|
case .success(let status):
|
||||||
|
if #available(iOS 14, *) {
|
||||||
|
print("ATT 结果: \(ATTrackingManager.trackingAuthorizationStatus)")
|
||||||
|
}
|
||||||
|
print("GDPR 结果: \(status)")
|
||||||
|
|
||||||
|
case .failure(let error):
|
||||||
|
print("失败: \(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Objective-C:
|
||||||
|
|
||||||
|
```objc
|
||||||
|
// 准备
|
||||||
|
[GuruConsent prepareWithSuccess:^(enum GuruConsentGDPRStatus status) {
|
||||||
|
|
||||||
|
switch (status) {
|
||||||
|
case GuruConsentGDPRStatusUnknown:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GuruConsentGDPRStatusRequired:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GuruConsentGDPRStatusNotRequired:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GuruConsentGDPRStatusObtained:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
NSLog(@"GDPR 结果: %ld", (long)status);
|
||||||
|
|
||||||
|
} failure:^(NSError * _Nonnull error) {
|
||||||
|
NSLog(@"失败: %@", error);
|
||||||
|
}];
|
||||||
|
|
||||||
|
|
||||||
|
// 显示 请确保status为.required 否则无法显示
|
||||||
|
[GuruConsent presentFrom:self success:^(enum GuruConsentGDPRStatus status) {
|
||||||
|
|
||||||
|
if (@available(iOS 14, *)) {
|
||||||
|
NSLog(@"ATT 结果: %lu", (unsigned long)ATTrackingManager.trackingAuthorizationStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (status) {
|
||||||
|
case GuruConsentGDPRStatusUnknown:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GuruConsentGDPRStatusRequired:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GuruConsentGDPRStatusNotRequired:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GuruConsentGDPRStatusObtained:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
NSLog(@"GDPR 结果: %ld", (long)status);
|
||||||
|
|
||||||
|
} failure:^(NSError * _Nonnull error) {
|
||||||
|
NSLog(@"%@", error);
|
||||||
|
}];
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### 调试设置
|
||||||
|
|
||||||
|
`testDeviceIdentifiers`获取方式: 当传入空置, 运行调用`GuruConsent.start(from:)` Xcode控制台会输出如下:
|
||||||
|
|
||||||
|
```
|
||||||
|
<UMP SDK> To enable debug mode for this device, set: UMPDebugSettings.testDeviceIdentifiers = @[ @"8C5E8576-5090-4C41-8FC4-A5A80FF77D9E" ];
|
||||||
|
```
|
||||||
|
将控制台的`8C5E8576-5090-4C41-8FC4-A5A80FF77D9E` 复制粘贴到代码中, 再次运行即可进行调试.
|
||||||
|
|
||||||
|
Swift:
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// 设置调试配置
|
||||||
|
let debug = GuruConsent.DebugSettings()
|
||||||
|
debug.testDeviceIdentifiers = ["8C5E8576-5090-4C41-8FC4-A5A80FF77D9E"]
|
||||||
|
debug.geography = .EEA
|
||||||
|
GuruConsent.debug = debug
|
||||||
|
```
|
||||||
|
|
||||||
|
Objective-C:
|
||||||
|
|
||||||
|
```objc
|
||||||
|
// 设置调试配置
|
||||||
|
GuruConsentDebugSettings *debug = [[GuruConsentDebugSettings alloc] init];
|
||||||
|
debug.testDeviceIdentifiers = @[@"8C5E8576-5090-4C41-8FC4-A5A80FF77D9E"];
|
||||||
|
debug.geography = GuruConsentDebugSettingsGeographyEEA;
|
||||||
|
GuruConsent.debug = debug;
|
||||||
|
```
|
||||||
|
|
||||||
|
重置状态
|
||||||
|
|
||||||
|
```swift
|
||||||
|
GuruConsent.reset()
|
||||||
|
```
|
||||||
|
|
||||||
|
## 运行
|
||||||
|
|
||||||
|
### 未授权过ATT权限 (非EEA地区):
|
||||||
|

|
||||||
|
|
||||||
|
点击`Continue`按钮弹出ATT授权弹窗
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### EEA地区:
|
||||||
|

|
||||||
|
|
||||||
|
未授权过ATT权限 点击同意等按钮弹出ATT授权弹窗
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
## 参考
|
||||||
|
|
||||||
|
[官方文档](https://developers.google.com/admob/ump/ios/quick-start)
|
||||||
|
|
||||||
|
## 协议
|
||||||
|
|
||||||
|
GuruConsent 使用 MIT 协议. 有关更多信息,请参阅 [LICENSE](LICENSE) 文件.
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-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>NSPrivacyCollectedDataTypes</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>NSPrivacyCollectedDataType</key>
|
||||||
|
<string>NSPrivacyCollectedDataTypeCoarseLocation</string>
|
||||||
|
<key>NSPrivacyCollectedDataTypeLinked</key>
|
||||||
|
<false/>
|
||||||
|
<key>NSPrivacyCollectedDataTypeTracking</key>
|
||||||
|
<false/>
|
||||||
|
<key>NSPrivacyCollectedDataTypePurposes</key>
|
||||||
|
<array>
|
||||||
|
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>NSPrivacyCollectedDataType</key>
|
||||||
|
<string>NSPrivacyCollectedDataTypePerformanceData</string>
|
||||||
|
<key>NSPrivacyCollectedDataTypeLinked</key>
|
||||||
|
<false/>
|
||||||
|
<key>NSPrivacyCollectedDataTypeTracking</key>
|
||||||
|
<false/>
|
||||||
|
<key>NSPrivacyCollectedDataTypePurposes</key>
|
||||||
|
<array>
|
||||||
|
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>NSPrivacyCollectedDataType</key>
|
||||||
|
<string>NSPrivacyCollectedDataTypeProductInteraction</string>
|
||||||
|
<key>NSPrivacyCollectedDataTypeLinked</key>
|
||||||
|
<false/>
|
||||||
|
<key>NSPrivacyCollectedDataTypeTracking</key>
|
||||||
|
<false/>
|
||||||
|
<key>NSPrivacyCollectedDataTypePurposes</key>
|
||||||
|
<array>
|
||||||
|
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>NSPrivacyAccessedAPITypes</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||||
|
<array>
|
||||||
|
<string>CA92.1</string>
|
||||||
|
</array>
|
||||||
|
<key>NSPrivacyAccessedAPIType</key>
|
||||||
|
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>NSPrivacyTrackingDomains</key>
|
||||||
|
<array/>
|
||||||
|
<key>NSPrivacyTracking</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 71f33675e1c99450686a549ba5f04505
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
: Any
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
Exclude Android: 1
|
||||||
|
Exclude Editor: 1
|
||||||
|
Exclude Linux64: 1
|
||||||
|
Exclude OSXUniversal: 1
|
||||||
|
Exclude Win: 1
|
||||||
|
Exclude Win64: 1
|
||||||
|
Exclude iOS: 1
|
||||||
|
- first:
|
||||||
|
Android: Android
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: ARMv7
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
OS: AnyOS
|
||||||
|
- first:
|
||||||
|
Standalone: Linux64
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
- first:
|
||||||
|
Standalone: OSXUniversal
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
- first:
|
||||||
|
Standalone: Win
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
- first:
|
||||||
|
Standalone: Win64
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
- first:
|
||||||
|
iPhone: iOS
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
AddToEmbeddedBinaries: false
|
||||||
|
CPU: AnyCPU
|
||||||
|
CompileFlags:
|
||||||
|
FrameworkDependencies:
|
||||||
|
- first:
|
||||||
|
tvOS: tvOS
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
//
|
||||||
|
// GuruConsent.GDPR.swift
|
||||||
|
// GuruConsent
|
||||||
|
//
|
||||||
|
// Created by 李响 on 2022/11/11.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import UserMessagingPlatform
|
||||||
|
|
||||||
|
public extension GuruConsent {
|
||||||
|
|
||||||
|
/// 当前状态
|
||||||
|
@objc
|
||||||
|
public static var status: GDPRStatus {
|
||||||
|
return .init(
|
||||||
|
rawValue: UMPConsentInformation.sharedInstance.consentStatus.rawValue
|
||||||
|
) ?? .unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 是否可以请求广告 (status为.obtained或.notRequired)
|
||||||
|
@objc
|
||||||
|
public static var canRequestAds: Bool {
|
||||||
|
return UMPConsentInformation.sharedInstance.canRequestAds
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 隐私选项状态
|
||||||
|
/// 初始状态为.unknown 如果status为.notRequired 该状态也是.notRequired
|
||||||
|
/// status为.obtained(弹窗同意后) 会变成.required, 代表可以让用户修改之前同意的隐私选项
|
||||||
|
/// 调用`func openPrivacyOptions(from: with:)`方法可以再次打开弹窗
|
||||||
|
/// 弹窗第二次打开后 用户可以重新勾选隐私选项并同意, 操作完成后状态会变为.unknown
|
||||||
|
@objc
|
||||||
|
public static var privacyOptionsRequirementStatus: GDPRPrivacyOptionsRequirementStatus {
|
||||||
|
return .init(
|
||||||
|
rawValue: UMPConsentInformation.sharedInstance.privacyOptionsRequirementStatus.rawValue
|
||||||
|
) ?? .unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
private static var form: UMPConsentForm?
|
||||||
|
|
||||||
|
internal static func request(with completion: @escaping ((Swift.Result<GDPRFormStatus, Error>) -> Void)) {
|
||||||
|
let parameters = UMPRequestParameters()
|
||||||
|
// 设置未满同意年龄的标签。此处false表示用户达到年龄
|
||||||
|
parameters.tagForUnderAgeOfConsent = tagForUnderAgeOfConsent
|
||||||
|
// 设置调试设置
|
||||||
|
if let debug = GuruConsent.debug {
|
||||||
|
let debugSettings = UMPDebugSettings()
|
||||||
|
debugSettings.testDeviceIdentifiers = debug.testDeviceIdentifiers
|
||||||
|
debugSettings.geography = .init(rawValue: debug.geography.rawValue) ?? .disabled
|
||||||
|
parameters.debugSettings = debugSettings
|
||||||
|
}
|
||||||
|
|
||||||
|
// 请求最新同意信息
|
||||||
|
UMPConsentInformation.sharedInstance.requestConsentInfoUpdate(
|
||||||
|
with: parameters,
|
||||||
|
completionHandler: { error in
|
||||||
|
if let error = error {
|
||||||
|
// 请求同意信息失败
|
||||||
|
completion(.failure(error))
|
||||||
|
|
||||||
|
} else {
|
||||||
|
let status = UMPConsentInformation.sharedInstance.formStatus
|
||||||
|
completion(.success(.init(rawValue: status.rawValue) ?? .unknown))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func loadForm(with completion: @escaping ((Swift.Result<GDPRStatus, Error>) -> Void)) {
|
||||||
|
// 加载表单
|
||||||
|
UMPConsentForm.load { form, error in
|
||||||
|
if let error = error {
|
||||||
|
// 表单加载失败
|
||||||
|
completion(.failure(error))
|
||||||
|
|
||||||
|
} else {
|
||||||
|
self.form = form
|
||||||
|
let status = UMPConsentInformation.sharedInstance.consentStatus
|
||||||
|
completion(.success(.init(rawValue: status.rawValue) ?? .unknown))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func openForm(from controller: UIViewController, with completion: @escaping ((Swift.Result<GDPRStatus, Error>) -> Void)) {
|
||||||
|
guard let form = form else {
|
||||||
|
completion(.failure(NSError(domain: "Form Empty.", code: -1)))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 打开弹窗
|
||||||
|
form.present(
|
||||||
|
from: controller,
|
||||||
|
completionHandler: { error in
|
||||||
|
if let error = error {
|
||||||
|
// 弹窗失败
|
||||||
|
completion(.failure(error))
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// 是否已同意
|
||||||
|
completion(.success(status))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 重置
|
||||||
|
@objc
|
||||||
|
public static func reset() {
|
||||||
|
UMPConsentInformation.sharedInstance.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 打开隐私选项弹窗 (privacyOptionsRequirementStatus必须为.required)
|
||||||
|
/// - Parameters:
|
||||||
|
/// - controller: 视图控制器
|
||||||
|
/// - completion: 完成回调
|
||||||
|
@objc
|
||||||
|
public static func openPrivacyOptions(from controller: UIViewController, with completion: @escaping ((Error?) -> Void)) {
|
||||||
|
UMPConsentForm.presentPrivacyOptionsForm(from: controller) { error in
|
||||||
|
completion(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 604558f3813844f3eaa13f84fde7e522
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
: Any
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
Exclude Android: 1
|
||||||
|
Exclude Editor: 1
|
||||||
|
Exclude Linux64: 1
|
||||||
|
Exclude OSXUniversal: 1
|
||||||
|
Exclude Win: 1
|
||||||
|
Exclude Win64: 1
|
||||||
|
Exclude iOS: 1
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
- first:
|
||||||
|
iPhone: iOS
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
tvOS: tvOS
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,204 @@
|
||||||
|
//
|
||||||
|
// GuruConsent.swift
|
||||||
|
// GuruConsent
|
||||||
|
//
|
||||||
|
// Created by 李响 on 2022/11/11.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
@objc
|
||||||
|
public class GuruConsent: NSObject {
|
||||||
|
|
||||||
|
/// CDPR状态
|
||||||
|
@objc(GuruConsentGDPRStatus)
|
||||||
|
public enum GDPRStatus: Int {
|
||||||
|
case unknown ///< Unknown consent status.
|
||||||
|
case required ///< User consent required but not yet obtained.
|
||||||
|
case notRequired ///< Consent not required.
|
||||||
|
case obtained ///< User consent obtained, personalized vs non-personalized undefined.
|
||||||
|
}
|
||||||
|
|
||||||
|
/// CDPR表单状态
|
||||||
|
internal enum GDPRFormStatus: Int {
|
||||||
|
case unknown
|
||||||
|
case available
|
||||||
|
case unavailable
|
||||||
|
}
|
||||||
|
|
||||||
|
/// GDPR隐私选项所需状态
|
||||||
|
@objc(GuruConsentGDPRPrivacyOptionsRequirementStatus)
|
||||||
|
public enum GDPRPrivacyOptionsRequirementStatus: Int {
|
||||||
|
case unknown ///< Requirement unknown.
|
||||||
|
case required ///< A way must be provided for the user to modify their privacy options.
|
||||||
|
case notRequired ///< User does not need to modify their privacy options. Either consent is not required, or the consent type does not require modification.
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 调试设置
|
||||||
|
@objc(GuruConsentDebugSettings)
|
||||||
|
public class DebugSettings: NSObject {
|
||||||
|
|
||||||
|
@objc(GuruConsentDebugSettingsGeography)
|
||||||
|
public enum Geography: Int {
|
||||||
|
case disabled
|
||||||
|
case EEA
|
||||||
|
case notEEA
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 测试设备ID
|
||||||
|
@objc
|
||||||
|
public var testDeviceIdentifiers: [String]
|
||||||
|
/// 地理位置
|
||||||
|
@objc
|
||||||
|
public var geography: Geography
|
||||||
|
|
||||||
|
@objc
|
||||||
|
public override init() {
|
||||||
|
testDeviceIdentifiers = []
|
||||||
|
geography = .disabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 调试设置
|
||||||
|
@objc
|
||||||
|
public static var debug: DebugSettings?
|
||||||
|
|
||||||
|
/// 设置未满同意年龄的标签 默认为false 表示用户达到年龄
|
||||||
|
@objc
|
||||||
|
public static var tagForUnderAgeOfConsent: Bool = false
|
||||||
|
|
||||||
|
/// 是否已同意 (status为.obtained)
|
||||||
|
@objc
|
||||||
|
public static var isObtained: Bool {
|
||||||
|
return status == .obtained
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 开始 OC
|
||||||
|
/// ATT未授权过(非EEA地区) 会弹出ATT引导弹窗 在点击继续按钮时弹出ATT权限弹窗
|
||||||
|
/// ATT未授权过(EEA地区) 会弹出GDPR弹窗 在点击同意时弹出ATT权限弹窗
|
||||||
|
/// - Parameters:
|
||||||
|
/// - controller: 视图控制器
|
||||||
|
/// - completion: 完成回调
|
||||||
|
@objc
|
||||||
|
public static func start(from controller: UIViewController, success: @escaping ((GDPRStatus) -> Void), failure: @escaping (Error) -> Void) {
|
||||||
|
start(from: controller) { result in
|
||||||
|
switch result {
|
||||||
|
case .success(let value):
|
||||||
|
success(value)
|
||||||
|
|
||||||
|
case .failure(let error):
|
||||||
|
failure(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 开始 Swift
|
||||||
|
/// ATT未授权过(非EEA地区) 会弹出ATT引导弹窗 在点击继续按钮时弹出ATT权限弹窗
|
||||||
|
/// ATT未授权过(EEA地区) 会弹出GDPR弹窗 在点击同意时弹出ATT权限弹窗
|
||||||
|
/// - Parameters:
|
||||||
|
/// - controller: 视图控制器
|
||||||
|
/// - completion: 完成回调
|
||||||
|
public static func start(from controller: UIViewController, with completion: @escaping ((Swift.Result<GDPRStatus, Error>) -> Void)) {
|
||||||
|
request { result in
|
||||||
|
switch result {
|
||||||
|
case .success(let value):
|
||||||
|
if value == .available {
|
||||||
|
// 加载表单
|
||||||
|
loadForm { result in
|
||||||
|
switch result {
|
||||||
|
case .success(let value):
|
||||||
|
switch value {
|
||||||
|
case .required:
|
||||||
|
// 打开表单
|
||||||
|
openForm(from: controller, with: completion)
|
||||||
|
|
||||||
|
default:
|
||||||
|
completion(.success(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
case .failure(let error):
|
||||||
|
// 表单加载失败
|
||||||
|
completion(.failure(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// 无表单需要加载
|
||||||
|
completion(.success(.notRequired))
|
||||||
|
}
|
||||||
|
|
||||||
|
case .failure(let error):
|
||||||
|
// 请求同意信息失败
|
||||||
|
completion(.failure(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ----------------------------------------
|
||||||
|
|
||||||
|
@objc
|
||||||
|
public static func prepare(success: @escaping ((GDPRStatus) -> Void), failure: @escaping (Error) -> Void) {
|
||||||
|
prepare { result in
|
||||||
|
switch result {
|
||||||
|
case .success(let value):
|
||||||
|
success(value)
|
||||||
|
|
||||||
|
case .failure(let error):
|
||||||
|
failure(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc
|
||||||
|
public static func present(from controller: UIViewController, success: @escaping ((GDPRStatus) -> Void), failure: @escaping (Error) -> Void) {
|
||||||
|
present(from: controller) { result in
|
||||||
|
switch result {
|
||||||
|
case .success(let value):
|
||||||
|
success(value)
|
||||||
|
|
||||||
|
case .failure(let error):
|
||||||
|
failure(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 预加载 (需在加载成功后 手动调用打开表单)
|
||||||
|
/// - Parameter completion: 完成回调
|
||||||
|
public static func prepare(with completion: @escaping ((Swift.Result<GDPRStatus, Error>) -> Void)) {
|
||||||
|
request { result in
|
||||||
|
switch result {
|
||||||
|
case .success(let value):
|
||||||
|
if value == .available {
|
||||||
|
// 加载表单
|
||||||
|
loadForm { result in
|
||||||
|
switch result {
|
||||||
|
case .success(let value):
|
||||||
|
// 表单加载成功
|
||||||
|
completion(.success(value))
|
||||||
|
|
||||||
|
case .failure(let error):
|
||||||
|
// 表单加载失败
|
||||||
|
completion(.failure(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// 无表单需要加载
|
||||||
|
completion(.success(.notRequired))
|
||||||
|
}
|
||||||
|
|
||||||
|
case .failure(let error):
|
||||||
|
// 请求同意信息失败
|
||||||
|
completion(.failure(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 打开表单 请确保status为.required 否则无效
|
||||||
|
/// - Parameters:
|
||||||
|
/// - controller: 视图控制器
|
||||||
|
/// - completion: 完成回调
|
||||||
|
public static func present(from controller: UIViewController, with completion: @escaping ((Swift.Result<GDPRStatus, Error>) -> Void)) {
|
||||||
|
openForm(from: controller, with: completion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0b11b5b1fa30a432eaf1b02602717dc9
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
: Any
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
Exclude Android: 1
|
||||||
|
Exclude Editor: 1
|
||||||
|
Exclude Linux64: 1
|
||||||
|
Exclude OSXUniversal: 1
|
||||||
|
Exclude Win: 1
|
||||||
|
Exclude Win64: 1
|
||||||
|
Exclude iOS: 1
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
- first:
|
||||||
|
iPhone: iOS
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
tvOS: tvOS
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
/Users/huyfuei/Workspace/Castbox/SDK/Native/GuruConsent-iOS/LICENSE
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
/Users/huyfuei/Workspace/Castbox/SDK/Native/GuruConsent-iOS/README.md
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
/Users/huyfuei/Workspace/Castbox/SDK/Native/GuruConsent-iOS/Resources
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
/Users/huyfuei/Workspace/Castbox/SDK/Native/GuruConsent-iOS/Sources
|
|
||||||
|
|
@ -1,16 +1,23 @@
|
||||||
# Guru Unity Consent
|
# Guru Unity Consent
|
||||||
|
|
||||||
## Version 1.0.8
|
## 1.0.9
|
||||||
|
* 更新 iOS 库版为本地 Pod 库, 直接引用源码 `1.4.6`
|
||||||
|
> 78dfe631fc97da53023577a7fcebb71400c3c873
|
||||||
|
* Anroid 库同步 github 仓库最新版本 `1.0.0`
|
||||||
|
> f8355aecfb36132c252d216331ad6d8f2c4b6363
|
||||||
|
|
||||||
|
## 1.0.8
|
||||||
* 更新 GuruConsent 的 iOS 库版本至 `1.4.6`
|
* 更新 GuruConsent 的 iOS 库版本至 `1.4.6`
|
||||||
* 更新 iOS 库添加 Privacy Policy 的配置项
|
* 更新 iOS 库添加 Privacy Policy 的配置项
|
||||||
* 更新 iOS 依赖的 cocospods 库地址
|
* 更新 iOS 依赖的 cocospods 库地址
|
||||||
|
|
||||||
|
|
||||||
## Version 1.0.7
|
|
||||||
|
## 1.0.7
|
||||||
* 更新 Consent 针对 Json 参数的回调和解析逻辑.
|
* 更新 Consent 针对 Json 参数的回调和解析逻辑.
|
||||||
|
|
||||||
|
|
||||||
## Version 1.0.6
|
## 1.0.6
|
||||||
* 更新了Google DMA 合规策略, 请查询详细的 [Google Ads Consent Mode DMA合规 技术需求文档](https://docs.google.com/document/d/1p7ad-W6XnqPjMgFkvoVf1Yylsogm_PykD9_nauInVoI/edit#heading=h.42lwhi7yczmk)
|
* 更新了Google DMA 合规策略, 请查询详细的 [Google Ads Consent Mode DMA合规 技术需求文档](https://docs.google.com/document/d/1p7ad-W6XnqPjMgFkvoVf1Yylsogm_PykD9_nauInVoI/edit#heading=h.42lwhi7yczmk)
|
||||||
* 已集成了中台的 `dma_gg` 点位
|
* 已集成了中台的 `dma_gg` 点位
|
||||||
* 云控可控变量 `dma_map_rule`, `dma_country_check` 两个参数来改变 TFC 策略以及开启地区检测
|
* 云控可控变量 `dma_map_rule`, `dma_country_check` 两个参数来改变 TFC 策略以及开启地区检测
|
||||||
|
|
@ -18,12 +25,12 @@
|
||||||
- 
|
- 
|
||||||
> 已知问题: 基于用户选择结果的 Purpose 在 iOS 上会产生乱码, 因此针对返回空串或非 "0","1" 的结果处理为非EEA地区的用户, 即不上报 DMA 数据
|
> 已知问题: 基于用户选择结果的 Purpose 在 iOS 上会产生乱码, 因此针对返回空串或非 "0","1" 的结果处理为非EEA地区的用户, 即不上报 DMA 数据
|
||||||
|
|
||||||
## Version 1.0.3
|
## 1.0.3
|
||||||
* 更新了SDKCallback对象的名称和逻辑, 同SDK本体进行区分
|
* 更新了SDKCallback对象的名称和逻辑, 同SDK本体进行区分
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Version 1.0.2
|
## 1.0.2
|
||||||
|
|
||||||
- 注意本插件库依赖 `LitJson` 用于解析Json格式数据. 请确保项目内引入此库.
|
- 注意本插件库依赖 `LitJson` 用于解析Json格式数据. 请确保项目内引入此库.
|
||||||
- 使用了 *EDM* 插件实现自动依赖注入.
|
- 使用了 *EDM* 插件实现自动依赖注入.
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ namespace Guru
|
||||||
public class GuruConsent
|
public class GuruConsent
|
||||||
{
|
{
|
||||||
// Guru Consent Version
|
// Guru Consent Version
|
||||||
public static string Version = "1.0.8";
|
public static string Version = "1.0.9";
|
||||||
public static string Tag = "[GuruConsent]";
|
public static string Tag = "[GuruConsent]";
|
||||||
|
|
||||||
#region 公用接口
|
#region 公用接口
|
||||||
|
|
@ -56,7 +56,7 @@ namespace Guru
|
||||||
string deviceId = "", int debugGeography = -1,
|
string deviceId = "", int debugGeography = -1,
|
||||||
string dmaMapRule = "", bool enableCountryCheck = false)
|
string dmaMapRule = "", bool enableCountryCheck = false)
|
||||||
{
|
{
|
||||||
Debug.Log($"{Tag} --- GuruConsent::StartConsent - deviceId:[{deviceId}] debugGeography:[{debugGeography}] dmaMapRule:[{dmaMapRule}] enableCountryCheck:[{enableCountryCheck}]");
|
Debug.Log($"{Tag} --- GuruConsent::StartConsent [{Version}] - deviceId:[{deviceId}] debugGeography:[{debugGeography}] dmaMapRule:[{dmaMapRule}] enableCountryCheck:[{enableCountryCheck}]");
|
||||||
|
|
||||||
_dmaMapRule = dmaMapRule;
|
_dmaMapRule = dmaMapRule;
|
||||||
_enableCountryCheck = enableCountryCheck;
|
_enableCountryCheck = enableCountryCheck;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue