Compare commits
16 Commits
main-touch
...
main-touch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5d4c319f0a | ||
|
|
fe4936f29a | ||
|
|
acd13e8d86 | ||
|
|
5909bbc526 | ||
|
|
2f9a63b00a | ||
|
|
d151e6fb46 | ||
|
|
e2df65105c | ||
|
|
0d4ebde870 | ||
|
|
17894d4301 | ||
|
|
666ed69389 | ||
|
|
ce087ab67c | ||
|
|
2f9093bcc9 | ||
|
|
4225b1e92a | ||
|
|
a55c7f47ec | ||
|
|
1addaa2658 | ||
|
|
006e8692e8 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,5 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
Pods/
|
Pods/
|
||||||
build/
|
build/
|
||||||
|
|
||||||
|
.fake
|
||||||
418
App.log
Normal file
418
App.log
Normal file
@ -0,0 +1,418 @@
|
|||||||
|
2026-01-04 01:18:25.596 PlayBTopOn[92135:47321797] XHook: Hooks started for com.TastePickEatWheel.TastePickEatWheel; IDFA: 338815A7-3BCF-4DDE-A46F-86DEAD099185
|
||||||
|
2026-01-04 01:18:25.621 PlayBTopOn[92135:47321797] [Enable]
|
||||||
|
2026-01-04 01:18:25.621 PlayBTopOn[92135:47321797] [Enable]
|
||||||
|
2026-01-04 01:18:25.656 PlayBTopOn[92135:47321797] XS- app start:C0D932AD-A331-448F-B3DA-F33E9E72DB7D
|
||||||
|
2026-01-04 01:18:25.657 PlayBTopOn[92135:47321797] XS- app start 2:C0D932AD-A331-448F-B3DA-F33E9E72DB7D
|
||||||
|
2026-01-04 01:18:25.666 PlayBTopOn[92135:47321797] XS- app start 21:C0D932AD-A331-448F-B3DA-F33E9E72DB7D
|
||||||
|
2026-01-04 01:18:25.666 PlayBTopOn[92135:47321797] XS- 准备访问 BbbAdManager.shared
|
||||||
|
2026-01-04 01:18:25.666 PlayBTopOn[92135:47321797] XS- 开始创建 BbbAdManager.shared 单例
|
||||||
|
2026-01-04 01:18:25.666 PlayBTopOn[92135:47321797] XS- BbbAdManager init 开始
|
||||||
|
2026-01-04 01:18:25.666 PlayBTopOn[92135:47321797] XS- BbbAdManager init 完成
|
||||||
|
2026-01-04 01:18:25.666 PlayBTopOn[92135:47321797] XS- BbbAdManager.shared 单例创建完成
|
||||||
|
2026-01-04 01:18:25.666 PlayBTopOn[92135:47321797] XS- BbbAdManager.shared 访问成功
|
||||||
|
2026-01-04 01:18:25.667 PlayBTopOn[92135:47321797] XS- 准备调用 initConfig()
|
||||||
|
2026-01-04 01:18:25.667 PlayBTopOn[92135:47321797] XS- init config
|
||||||
|
2026-01-04 01:18:25.667 PlayBTopOn[92135:47321797] IDFA: 338815A7-3BCF-4DDE-A46F-86DEAD099185
|
||||||
|
2026-01-04 01:18:25.667 PlayBTopOn[92135:47321797] XS- 开始创建 BbbAdManager.config
|
||||||
|
2026-01-04 01:18:25.667 PlayBTopOn[92135:47321797] XS- bConfig init 开始
|
||||||
|
2026-01-04 01:18:25.667 PlayBTopOn[92135:47321797] XS- bConfig init: allAdIds count = 3
|
||||||
|
2026-01-04 01:18:25.667 PlayBTopOn[92135:47321797] XS- bConfig init 完成
|
||||||
|
2026-01-04 01:18:25.667 PlayBTopOn[92135:47321797] XS- BbbAdManager.config 创建完成
|
||||||
|
2026-01-04 01:18:25.667 PlayBTopOn[92135:47321797] XS- init config 1
|
||||||
|
2026-01-04 01:18:25.668 PlayBTopOn[92135:47321797] XS- init config 2
|
||||||
|
2026-01-04 01:18:25.671 PlayBTopOn[92135:47321797] XS- init config 3
|
||||||
|
2026-01-04 01:18:25.671 PlayBTopOn[92135:47321797] XS- app start 3:C0D932AD-A331-448F-B3DA-F33E9E72DB7D
|
||||||
|
2026-01-04 01:18:25.672 PlayBTopOn[92135:47321797] XS- app start 5:C0D932AD-A331-448F-B3DA-F33E9E72DB7D
|
||||||
|
2026-01-04 01:18:25.672 PlayBTopOn[92135:47321810] XS- app start 4:C0D932AD-A331-448F-B3DA-F33E9E72DB7D
|
||||||
|
2026-01-04 01:18:25.672 PlayBTopOn[92135:47321810] XS- init ad
|
||||||
|
2026-01-04 01:18:25.673 PlayBTopOn[92135:47321810] ironSourceSDK: Initializing with appKey: 24aee521d, userId: 602443
|
||||||
|
2026-01-04 01:18:25.673 PlayBTopOn[92135:47321810] [LevelPlay SDK] API: UITHREAD: false [LevelPlay setAdaptersDebug:] - flag: YES
|
||||||
|
2026-01-04 01:18:25.685 PlayBTopOn[92135:47321797] XS- app start 6:C0D932AD-A331-448F-B3DA-F33E9E72DB7D
|
||||||
|
2026-01-04 01:18:25.698 PlayBTopOn[92135:47321797] XS- YL_PlayVC viewDidLoad 开始
|
||||||
|
2026-01-04 01:18:25.698 PlayBTopOn[92135:47321797] XS- YL_PlayVC 准备调用 waitForSDKInitialization
|
||||||
|
2026-01-04 01:18:25.698 PlayBTopOn[92135:47321797] XS- waitForSDKInitialization 被调用,当前状态:false
|
||||||
|
2026-01-04 01:18:25.698 PlayBTopOn[92135:47321797] XS- SDK 未初始化,添加回调到等待队列
|
||||||
|
2026-01-04 01:18:25.698 PlayBTopOn[92135:47321797] XS- YL_PlayVC waitForSDKInitialization 调用完成
|
||||||
|
2026-01-04 01:18:25.761 PlayBTopOn[92135:47321810] XS- init ad end
|
||||||
|
2026-01-04 01:18:25.761 PlayBTopOn[92135:47321804] [LevelPlay SDK] API: UITHREAD: false [LevelPlayInternal initInstanceInternalWithRequest:completion:] - [LevelPlay initWithRequest:completion:] appkey 24aee521d userId (null) legacyAdFormats (
|
||||||
|
)
|
||||||
|
2026-01-04 01:18:25.761 PlayBTopOn[92135:47321804] [LevelPlay SDK] INTERNAL: UITHREAD: false [IronSourceSdk prepareSdkInitWithAppKey:adUnits:internal:isDemandOnly:delegate:newInitCompletionHandler:completion:] - GitHash: cfa6fb4
|
||||||
|
2026-01-04 01:18:25.762 PlayBTopOn[92135:47321804] [LevelPlay SDK] INTERNAL: The Mediation SDK has changed its state to SDK_INIT_IN_PROGRESS
|
||||||
|
2026-01-04 01:18:25.780 PlayBTopOn[92135:47321810] 请求配置成功: ["code": 0, "data": {
|
||||||
|
clickThroughRate = 80;
|
||||||
|
clientType = 1;
|
||||||
|
ecpmCool = "0.003";
|
||||||
|
ecpmLow = "0.001";
|
||||||
|
mobileDataTableName = "<null>";
|
||||||
|
packageName = "com.TastePickEatWheel.TastePickEatWheel";
|
||||||
|
quantity = 5;
|
||||||
|
specifyGaidTableName = "data_ios_topecpm";
|
||||||
|
status = 1;
|
||||||
|
washParam = 0;
|
||||||
|
}, "msg": success]
|
||||||
|
2026-01-04 01:18:25.785 PlayBTopOn[92135:47321815] [LevelPlay SDK] EVENT: {
|
||||||
|
connectionType = cellular;
|
||||||
|
eventId = 14;
|
||||||
|
eventSessionId = "268F07DC-930C-4515-824B-92353B954A76";
|
||||||
|
ext1 = "appLanguage=Swift";
|
||||||
|
firstSessionTimestamp = 1767518305762;
|
||||||
|
isMultipleAdUnits = 1;
|
||||||
|
provider = Mediation;
|
||||||
|
rawConnectionType = CTRadioAccessTechnologyLTE;
|
||||||
|
sessionDepth = 1;
|
||||||
|
timestamp = 1767518305770;
|
||||||
|
}
|
||||||
|
2026-01-04 01:18:27.582 PlayBTopOn[92135:47321806] [LevelPlay SDK] INTERNAL: rewarded settings: {parallelLoad=2, bidderExclusive=YES}
|
||||||
|
2026-01-04 01:18:27.586 PlayBTopOn[92135:47321806] [LevelPlay SDK] INTERNAL: interstitial settings: {parallelLoad=2, bidderExclusive=NO}
|
||||||
|
2026-01-04 01:18:27.593 PlayBTopOn[92135:47321806] [LevelPlay SDK] INTERNAL: rewarded settings: {parallelLoad=2, bidderExclusive=YES}
|
||||||
|
2026-01-04 01:18:27.593 PlayBTopOn[92135:47321806] [LevelPlay SDK] INTERNAL: interstitial settings: {parallelLoad=2, bidderExclusive=NO}
|
||||||
|
2026-01-04 01:18:27.667 PlayBTopOn[92135:47321797] [INFO] IronSource AdQuality: ISAdQuality: Initializing with app key 24aee521d
|
||||||
|
2026-01-04 01:18:29.726 PlayBTopOn[92135:47321797] Initialization successful with config: <LPMConfiguration: 0x2819fc6b0>
|
||||||
|
2026-01-04 01:18:29.726 PlayBTopOn[92135:47321797] XS- IronSource SDK initialized successfully
|
||||||
|
2026-01-04 01:18:29.727 PlayBTopOn[92135:47321797] XS- SDK 初始化完成,开始加载广告
|
||||||
|
2026-01-04 01:18:29.727 PlayBTopOn[92135:47321797] XS- load ad
|
||||||
|
2026-01-04 01:18:29.727 PlayBTopOn[92135:47321797] XS- view 已设置: <PlayBTopOn.YL_PlayVC: 0x108f3cbe0>
|
||||||
|
2026-01-04 01:18:29.727 PlayBTopOn[92135:47321797] XS- 初始化广告队列: ["no7750uspiuvwwcx", "hhh5ve5yjpptfdcp", "snlrr8jxxljp375n"]
|
||||||
|
2026-01-04 01:18:29.727 PlayBTopOn[92135:47321797] XS- 添加广告位: no7750uspiuvwwcx
|
||||||
|
2026-01-04 01:18:29.729 PlayBTopOn[92135:47321797] XS- 添加广告位: hhh5ve5yjpptfdcp
|
||||||
|
2026-01-04 01:18:29.729 PlayBTopOn[92135:47321797] XS- 添加广告位: snlrr8jxxljp375n
|
||||||
|
2026-01-04 01:18:29.730 PlayBTopOn[92135:47321797] XS- loadNextAd 被调用
|
||||||
|
2026-01-04 01:18:29.730 PlayBTopOn[92135:47321797] XS- 尝试加载广告: no7750uspiuvwwcx
|
||||||
|
2026-01-04 01:18:29.730 PlayBTopOn[92135:47321797] XS- 开始加载广告: no7750uspiuvwwcx
|
||||||
|
2026-01-04 01:18:29.731 PlayBTopOn[92135:47321797] XS- load ad end
|
||||||
|
2026-01-04 01:18:30.890 PlayBTopOn[92135:47321797] [LevelPlay SDK] API: ISAdQuality SDK config load timeout
|
||||||
|
2026-01-04 01:18:50.112 PlayBTopOn[92135:47321797] Created timestamp file at: /User/Documents/ad/load/1767518330
|
||||||
|
2026-01-04 01:18:50.112 PlayBTopOn[92135:47321797] XS- 广告加载完成,准备自动展示: no7750uspiuvwwcx
|
||||||
|
2026-01-04 01:18:50.112 PlayBTopOn[92135:47321797] XS- IronSourceinterstitialAd.show 被调用: no7750uspiuvwwcx
|
||||||
|
2026-01-04 01:18:50.112 PlayBTopOn[92135:47321797] XS- 广告准备状态 isAdReady: true, adID: no7750uspiuvwwcx
|
||||||
|
2026-01-04 01:18:50.112 PlayBTopOn[92135:47321797] XS- ✓ 调用 showAd,准备展示广告: no7750uspiuvwwcx
|
||||||
|
2026-01-04 01:18:50.112 PlayBTopOn[92135:47321797] XS- showAd 调用完成,等待 didDisplayAd 回调
|
||||||
|
2026-01-04 01:18:50.112 PlayBTopOn[92135:47321797] XS- show :true
|
||||||
|
2026-01-04 01:18:50.112 PlayBTopOn[92135:47321797] XS- ad load ok:D663DE2F-6759-48DA-A2B4-0E89478D41EC - no7750uspiuvwwcx ecpm:0.4272784
|
||||||
|
2026-01-04 01:18:50.112 PlayBTopOn[92135:47321797] XS- ad no7750uspiuvwwcx load time: 20384 ms
|
||||||
|
2026-01-04 01:18:50.579 PlayBTopOn[92135:47321797] XS- ✓✓✓ didDisplayAd 回调被触发: no7750uspiuvwwcx
|
||||||
|
2026-01-04 01:18:50.579 PlayBTopOn[92135:47321797] XS- 广告展示成功,准备上报 Show 日志
|
||||||
|
2026-01-04 01:18:50.579 PlayBTopOn[92135:47321797] XS- 广告信息: ecpm=0.0004272784, network=ironsourceads, country=US
|
||||||
|
2026-01-04 01:18:50.580 PlayBTopOn[92135:47321797] Created timestamp file at: /User/Documents/ad/show/1767518330
|
||||||
|
2026-01-04 01:18:50.580 PlayBTopOn[92135:47321797] Random click at: (174.00, 584.00)
|
||||||
|
2026-01-04 01:18:50.580 PlayBTopOn[92135:47321797] XS- didDisplayAd 处理完成
|
||||||
|
2026-01-04 01:18:50.630 PlayBTopOn[92135:47321807] XS- Uploading AD Load with data: {
|
||||||
|
"online" : false,
|
||||||
|
"localIp" : "172.25.202.160",
|
||||||
|
"linkId" : "D663DE2F-6759-48DA-A2B4-0E89478D41EC",
|
||||||
|
"countryCode" : "US",
|
||||||
|
"getIpResponseTime" : 0,
|
||||||
|
"carrierId" : 0,
|
||||||
|
"remoteIp" : "",
|
||||||
|
"dataId" : "26",
|
||||||
|
"network" : "ironsourceads",
|
||||||
|
"gaid" : "338815A7-3BCF-4DDE-A46F-86DEAD099185",
|
||||||
|
"packageVersion" : "1.1",
|
||||||
|
"shelfNumber" : "uploadAD_Load",
|
||||||
|
"adId" : "no7750uspiuvwwcx",
|
||||||
|
"packageName" : "com.TastePickEatWheel.TastePickEatWheel",
|
||||||
|
"dsp" : "MTG",
|
||||||
|
"phoneVersion" : "iPhone8,1",
|
||||||
|
"adPlatform" : "IS",
|
||||||
|
"loadTime" : 20384,
|
||||||
|
"platformResponseTime" : 20,
|
||||||
|
"washParam" : false,
|
||||||
|
"ecpm" : 0.00042727839999999998,
|
||||||
|
"succeed" : true,
|
||||||
|
"deviceId" : "6094A4AA-97F8-4E9C-AABE-12A3B2679115"
|
||||||
|
}
|
||||||
|
2026-01-04 01:18:50.655 PlayBTopOn[92135:47321814] XS- 开始上报 uploadAD_Show: no7750uspiuvwwcx
|
||||||
|
2026-01-04 01:18:50.658 PlayBTopOn[92135:47321814] XS- Uploading AD Show with data: {
|
||||||
|
"online" : false,
|
||||||
|
"phoneVersion" : "iPhone8,1",
|
||||||
|
"carrierId" : 0,
|
||||||
|
"shelfNumber" : "uploadAD_Load",
|
||||||
|
"packageName" : "com.TastePickEatWheel.TastePickEatWheel",
|
||||||
|
"loadTime" : 0,
|
||||||
|
"countryCode" : "US",
|
||||||
|
"network" : "ironsourceads",
|
||||||
|
"adId" : "no7750uspiuvwwcx",
|
||||||
|
"packageVersion" : "1.1",
|
||||||
|
"getIpResponseTime" : 0,
|
||||||
|
"dsp" : "IronSource",
|
||||||
|
"linkId" : "D663DE2F-6759-48DA-A2B4-0E89478D41EC",
|
||||||
|
"platformResponseTime" : 0,
|
||||||
|
"succeed" : true,
|
||||||
|
"deviceId" : "6094A4AA-97F8-4E9C-AABE-12A3B2679115",
|
||||||
|
"localIp" : "172.25.202.160",
|
||||||
|
"ecpm" : 0.00042727839999999998,
|
||||||
|
"remoteIp" : "",
|
||||||
|
"gaid" : "338815A7-3BCF-4DDE-A46F-86DEAD099185",
|
||||||
|
"dataId" : "26",
|
||||||
|
"adPlatform" : "IS"
|
||||||
|
}
|
||||||
|
2026-01-04 01:18:50.659 PlayBTopOn[92135:47321814] XS- uploadAD_Show 调用完成
|
||||||
|
2026-01-04 01:18:50.659 PlayBTopOn[92135:47321814] XS- 设置广告定时关闭
|
||||||
|
2026-01-04 01:18:50.669 PlayBTopOn[92135:47321987] XS- Upload AD Show response: ["code": 0, "msg": success, "data": <null>]
|
||||||
|
2026-01-04 01:18:50.674 PlayBTopOn[92135:47321987] XS- Result: ["code": 0, "data": <null>, "msg": success]
|
||||||
|
2026-01-04 01:18:55.953 PlayBTopOn[92135:47321797] XS- find Controller 1 <UINavigationController: 0x109024e00>
|
||||||
|
2026-01-04 01:18:55.954 PlayBTopOn[92135:47321797] XS- find Controller 1 <PlayBTopOn.YL_PlayVC: 0x108f3cbe0>
|
||||||
|
2026-01-04 01:18:55.954 PlayBTopOn[92135:47321797] XS- find Controller 1 <ISNProductViewController: 0x107f75df0>
|
||||||
|
2026-01-04 01:18:55.955 PlayBTopOn[92135:47321797] XS- find Controller 1 <ISNProductViewController: 0x107f75df0> ok
|
||||||
|
2026-01-04 01:18:55.955 PlayBTopOn[92135:47321797] 执行了 prepareViewsForClose
|
||||||
|
2026-01-04 01:18:55.955 PlayBTopOn[92135:47321797] Found FullScreenPresenter instance: <ISNProductViewController: 0x107f75df0>
|
||||||
|
2026-01-04 01:18:55.956 PlayBTopOn[92135:47321797] Executing closeADWindow - First Pass
|
||||||
|
2026-01-04 01:18:55.957 PlayBTopOn[92135:47321797] XS- find Controller 2<UITransitionView: 0x107f12160; frame = (0 0; 360 640); autoresize = W+H; layer = <CALayer: 0x281be39c0>>
|
||||||
|
2026-01-04 01:18:55.957 PlayBTopOn[92135:47321797] XS- find Controller 1 <UINavigationController: 0x109024e00>
|
||||||
|
2026-01-04 01:18:55.958 PlayBTopOn[92135:47321797] XS- find Controller 1 <PlayBTopOn.YL_PlayVC: 0x108f3cbe0>
|
||||||
|
2026-01-04 01:18:55.958 PlayBTopOn[92135:47321797] XS- find Controller 1 <ISNProductViewController: 0x107f75df0>
|
||||||
|
2026-01-04 01:18:55.959 PlayBTopOn[92135:47321797] XS- find Controller 1 <ISNProductViewController: 0x107f75df0> ok
|
||||||
|
2026-01-04 01:18:55.959 PlayBTopOn[92135:47321797] 执行了 prepareViewsForClose
|
||||||
|
2026-01-04 01:18:55.961 PlayBTopOn[92135:47321797] Found FullScreenPresenter instance: <ISNProductViewController: 0x107f75df0>
|
||||||
|
2026-01-04 01:18:55.961 PlayBTopOn[92135:47321797] XS- find Controller 2<ISNProductViewController: 0x107f75df0>
|
||||||
|
2026-01-04 01:18:55.961 PlayBTopOn[92135:47321797] XS- find Controller 1 <UINavigationController: 0x109024e00>
|
||||||
|
2026-01-04 01:18:55.961 PlayBTopOn[92135:47321797] XS- find Controller 1 <PlayBTopOn.YL_PlayVC: 0x108f3cbe0>
|
||||||
|
2026-01-04 01:18:55.962 PlayBTopOn[92135:47321797] XS- find Controller 1 <ISNProductViewController: 0x107f75df0>
|
||||||
|
2026-01-04 01:18:55.962 PlayBTopOn[92135:47321797] XS- find Controller 1 <ISNProductViewController: 0x107f75df0> ok
|
||||||
|
2026-01-04 01:18:55.962 PlayBTopOn[92135:47321797] 执行了 prepareViewsForClose
|
||||||
|
2026-01-04 01:18:55.963 PlayBTopOn[92135:47321797] Found FullScreenPresenter instance: <ISNProductViewController: 0x107f75df0>
|
||||||
|
2026-01-04 01:18:55.963 PlayBTopOn[92135:47321797] Executing closeADWindow - Second Pass
|
||||||
|
2026-01-04 01:18:55.963 PlayBTopOn[92135:47321797] XS- find Controller 2<UITransitionView: 0x107f12160; frame = (0 0; 360 640); autoresize = W+H; layer = <CALayer: 0x281be39c0>>
|
||||||
|
2026-01-04 01:18:55.963 PlayBTopOn[92135:47321797] XS- find Controller 1 <UINavigationController: 0x109024e00>
|
||||||
|
2026-01-04 01:18:55.963 PlayBTopOn[92135:47321797] XS- find Controller 1 <PlayBTopOn.YL_PlayVC: 0x108f3cbe0>
|
||||||
|
2026-01-04 01:18:55.964 PlayBTopOn[92135:47321797] XS- find Controller 1 <ISNProductViewController: 0x107f75df0>
|
||||||
|
2026-01-04 01:18:55.964 PlayBTopOn[92135:47321797] XS- find Controller 1 <ISNProductViewController: 0x107f75df0> ok
|
||||||
|
2026-01-04 01:18:55.964 PlayBTopOn[92135:47321797] 执行了 prepareViewsForClose
|
||||||
|
2026-01-04 01:18:55.964 PlayBTopOn[92135:47321797] Found FullScreenPresenter instance: <ISNProductViewController: 0x107f75df0>
|
||||||
|
2026-01-04 01:18:55.964 PlayBTopOn[92135:47321797] XS- find Controller 2<ISNProductViewController: 0x107f75df0>
|
||||||
|
2026-01-04 01:18:55.964 PlayBTopOn[92135:47321797] XS- find Controller 1 <UINavigationController: 0x109024e00>
|
||||||
|
2026-01-04 01:18:55.965 PlayBTopOn[92135:47321797] XS- find Controller 1 <PlayBTopOn.YL_PlayVC: 0x108f3cbe0>
|
||||||
|
2026-01-04 01:18:55.965 PlayBTopOn[92135:47321797] XS- find Controller 1 <ISNProductViewController: 0x107f75df0>
|
||||||
|
2026-01-04 01:18:55.966 PlayBTopOn[92135:47321797] XS- find Controller 1 <ISNProductViewController: 0x107f75df0> ok
|
||||||
|
2026-01-04 01:18:55.966 PlayBTopOn[92135:47321797] 执行了 prepareViewsForClose
|
||||||
|
2026-01-04 01:18:55.966 PlayBTopOn[92135:47321797] Found FullScreenPresenter instance: <ISNProductViewController: 0x107f75df0>
|
||||||
|
2026-01-04 01:18:55.966 PlayBTopOn[92135:47321797] AdViewController,UINavigationController
|
||||||
|
2026-01-04 01:18:55.966 PlayBTopOn[92135:47321797] AdViewController,PlayBTopOn.YL_PlayVC
|
||||||
|
2026-01-04 01:18:55.966 PlayBTopOn[92135:47321797] AdViewController,ISNProductViewController
|
||||||
|
2026-01-04 01:18:55.967 PlayBTopOn[92135:47321797] AdViewController,ISNProductViewController
|
||||||
|
2026-01-04 01:18:55.967 PlayBTopOn[92135:47321797] Found ad controller: ISNProductViewController
|
||||||
|
2026-01-04 01:18:55.967 PlayBTopOn[92135:47321797] Found ad controller: ISNProductViewController
|
||||||
|
2026-01-04 01:18:55.967 PlayBTopOn[92135:47321797] XS- loadNextAd 被调用
|
||||||
|
2026-01-04 01:18:55.967 PlayBTopOn[92135:47321797] XS- 尝试加载广告: hhh5ve5yjpptfdcp
|
||||||
|
2026-01-04 01:18:55.967 PlayBTopOn[92135:47321797] XS- 开始加载广告: hhh5ve5yjpptfdcp
|
||||||
|
2026-01-04 01:18:56.489 PlayBTopOn[92135:47321797] XS- close ad view 1
|
||||||
|
2026-01-04 01:18:56.489 PlayBTopOn[92135:47321797] XS- close ad view 1
|
||||||
|
2026-01-04 01:18:56.489 PlayBTopOn[92135:47321797] XS- close ad view 1
|
||||||
|
2026-01-04 01:18:56.489 PlayBTopOn[92135:47321797] XS- close ad view 1
|
||||||
|
2026-01-04 01:18:56.489 PlayBTopOn[92135:47321797] XS- close ad view 1
|
||||||
|
2026-01-04 01:18:56.490 PlayBTopOn[92135:47321797] Ad controller dismissed: ISNProductViewController
|
||||||
|
2026-01-04 01:18:56.490 PlayBTopOn[92135:47321797] Ad controller dismissed: ISNProductViewController
|
||||||
|
2026-01-04 01:18:57.197 PlayBTopOn[92135:47321797] XS- find Controller 1 <UINavigationController: 0x109024e00>
|
||||||
|
2026-01-04 01:18:57.198 PlayBTopOn[92135:47321797] XS- find Controller 1 <PlayBTopOn.YL_PlayVC: 0x108f3cbe0>
|
||||||
|
2026-01-04 01:18:57.198 PlayBTopOn[92135:47321797] FullScreenPresenter not found.
|
||||||
|
2026-01-04 01:18:57.198 PlayBTopOn[92135:47321797] Executing closeADWindow - First Pass
|
||||||
|
2026-01-04 01:18:57.199 PlayBTopOn[92135:47321797] XS- find Controller 2<UITransitionView: 0x107f12160; frame = (0 0; 360 640); autoresize = W+H; layer = <CALayer: 0x281be39c0>>
|
||||||
|
2026-01-04 01:18:57.199 PlayBTopOn[92135:47321797] XS- find Controller 1 <UINavigationController: 0x109024e00>
|
||||||
|
2026-01-04 01:18:57.199 PlayBTopOn[92135:47321797] XS- find Controller 1 <PlayBTopOn.YL_PlayVC: 0x108f3cbe0>
|
||||||
|
2026-01-04 01:18:57.200 PlayBTopOn[92135:47321797] FullScreenPresenter not found.
|
||||||
|
2026-01-04 01:18:57.200 PlayBTopOn[92135:47321797] Executing closeADWindow - Second Pass
|
||||||
|
2026-01-04 01:18:57.200 PlayBTopOn[92135:47321797] XS- find Controller 2<UITransitionView: 0x107f12160; frame = (0 0; 360 640); autoresize = W+H; layer = <CALayer: 0x281be39c0>>
|
||||||
|
2026-01-04 01:18:57.200 PlayBTopOn[92135:47321797] XS- find Controller 1 <UINavigationController: 0x109024e00>
|
||||||
|
2026-01-04 01:18:57.200 PlayBTopOn[92135:47321797] XS- find Controller 1 <PlayBTopOn.YL_PlayVC: 0x108f3cbe0>
|
||||||
|
2026-01-04 01:18:57.201 PlayBTopOn[92135:47321797] FullScreenPresenter not found.
|
||||||
|
2026-01-04 01:18:57.201 PlayBTopOn[92135:47321797] AdViewController,UINavigationController
|
||||||
|
2026-01-04 01:18:57.201 PlayBTopOn[92135:47321797] AdViewController,PlayBTopOn.YL_PlayVC
|
||||||
|
2026-01-04 01:18:57.201 PlayBTopOn[92135:47321797] XS- loadNextAd 被调用
|
||||||
|
2026-01-04 01:18:57.201 PlayBTopOn[92135:47321797] XS- 尝试加载广告: snlrr8jxxljp375n
|
||||||
|
2026-01-04 01:18:57.201 PlayBTopOn[92135:47321797] XS- 开始加载广告: snlrr8jxxljp375n
|
||||||
|
2026-01-04 01:18:57.202 PlayBTopOn[92135:47321797] XS- 广告定时关闭触发: no7750uspiuvwwcx
|
||||||
|
2026-01-04 01:18:57.305 PlayBTopOn[92135:47321816] [ERROR] IronSource AdQuality: ISAdQualitySDK: -------------- ByteDance connector 7.1.51 --------------
|
||||||
|
2026-01-04 01:18:57.305 PlayBTopOn[92135:47321816] [ERROR] IronSource AdQuality: ISAdQualitySDK: ByteDance SDK version: 7.8.0.5
|
||||||
|
2026-01-04 01:18:57.305 PlayBTopOn[92135:47321816] [ERROR] IronSource AdQuality: ISAdQualitySDK: SDK Versions supported: 2.5.1.2 - 7.4.1.0
|
||||||
|
2026-01-04 01:18:57.305 PlayBTopOn[92135:47321816] [ERROR] IronSource AdQuality: ISAdQualitySDK: Status: ERROR
|
||||||
|
2026-01-04 01:18:57.305 PlayBTopOn[92135:47321816] [ERROR] IronSource AdQuality: ISAdQualitySDK: Message: ByteDance SDK version 7.8.0.5 is not yet supported by the connector
|
||||||
|
2026-01-04 01:18:57.305 PlayBTopOn[92135:47321816] [ERROR] IronSource AdQuality: ISAdQualityConnectorManager: Details: ByteDance SDK version 7.8.0.5 is not yet supported by the connector
|
||||||
|
2026-01-04 01:19:02.626 PlayBTopOn[92135:47321797] -canOpenURL: failed for URL: "weixin://" - error: "The operation couldn’t be completed. (OSStatus error -10814.)"
|
||||||
|
2026-01-04 01:19:02.628 PlayBTopOn[92135:47321797] -canOpenURL: failed for URL: "weixinULAPI://" - error: "This app is not allowed to query for scheme weixinulapi"
|
||||||
|
2026-01-04 01:19:02.629 PlayBTopOn[92135:47321797] -canOpenURL: failed for URL: "weixinURLParamsAPI://" - error: "This app is not allowed to query for scheme weixinurlparamsapi"
|
||||||
|
2026-01-04 01:19:04.970 PlayBTopOn[92135:47321797] Created timestamp file at: /User/Documents/ad/load/1767518344
|
||||||
|
2026-01-04 01:19:04.970 PlayBTopOn[92135:47321797] XS- 广告加载完成,准备自动展示: hhh5ve5yjpptfdcp
|
||||||
|
2026-01-04 01:19:04.970 PlayBTopOn[92135:47321797] XS- IronSourceinterstitialAd.show 被调用: hhh5ve5yjpptfdcp
|
||||||
|
2026-01-04 01:19:04.970 PlayBTopOn[92135:47321797] XS- 广告准备状态 isAdReady: true, adID: hhh5ve5yjpptfdcp
|
||||||
|
2026-01-04 01:19:04.971 PlayBTopOn[92135:47321797] XS- ✓ 调用 showAd,准备展示广告: hhh5ve5yjpptfdcp
|
||||||
|
2026-01-04 01:19:04.972 PlayBTopOn[92135:47321797] XS- showAd 调用完成,等待 didDisplayAd 回调
|
||||||
|
2026-01-04 01:19:04.972 PlayBTopOn[92135:47321797] XS- show :true
|
||||||
|
2026-01-04 01:19:04.973 PlayBTopOn[92135:47321797] XS- ad load ok:D663DE2F-6759-48DA-A2B4-0E89478D41EC - hhh5ve5yjpptfdcp ecpm:1.2572349
|
||||||
|
2026-01-04 01:19:04.973 PlayBTopOn[92135:47321797] XS- ad hhh5ve5yjpptfdcp load time: 35243 ms
|
||||||
|
2026-01-04 01:19:04.996 PlayBTopOn[92135:47321987] XS- Uploading AD Load with data: {
|
||||||
|
"localIp" : "172.25.202.160",
|
||||||
|
"dsp" : "MTG",
|
||||||
|
"adPlatform" : "IS",
|
||||||
|
"dataId" : "26",
|
||||||
|
"countryCode" : "US",
|
||||||
|
"packageName" : "com.TastePickEatWheel.TastePickEatWheel",
|
||||||
|
"gaid" : "338815A7-3BCF-4DDE-A46F-86DEAD099185",
|
||||||
|
"carrierId" : 0,
|
||||||
|
"shelfNumber" : "uploadAD_Load",
|
||||||
|
"remoteIp" : "",
|
||||||
|
"ecpm" : 0.0012572349,
|
||||||
|
"linkId" : "D663DE2F-6759-48DA-A2B4-0E89478D41EC",
|
||||||
|
"network" : "ironsourceads",
|
||||||
|
"adId" : "hhh5ve5yjpptfdcp",
|
||||||
|
"loadTime" : 35243,
|
||||||
|
"online" : false,
|
||||||
|
"succeed" : true,
|
||||||
|
"washParam" : false,
|
||||||
|
"phoneVersion" : "iPhone8,1",
|
||||||
|
"deviceId" : "6094A4AA-97F8-4E9C-AABE-12A3B2679115",
|
||||||
|
"platformResponseTime" : 35,
|
||||||
|
"packageVersion" : "1.1",
|
||||||
|
"getIpResponseTime" : 0
|
||||||
|
}
|
||||||
|
2026-01-04 01:19:05.057 PlayBTopOn[92135:47321797] XS- ✗✗✗ didFailToDisplayAd 回调被触发: hhh5ve5yjpptfdcp
|
||||||
|
2026-01-04 01:19:05.057 PlayBTopOn[92135:47321797] XS- 广告展示失败!错误: Cannot+engage+offer+at+this+time
|
||||||
|
2026-01-04 01:19:05.057 PlayBTopOn[92135:47321797] XS- 错误详情: Error Domain=com.levelplay.error Code=0 "Cannot+engage+offer+at+this+time" UserInfo={adId=C2FB92E3-169C-4ABC-B978-C84C7CFED372, NSLocalizedDescription=Cannot+engage+offer+at+this+time}
|
||||||
|
2026-01-04 01:19:05.058 PlayBTopOn[92135:47321797] XS- loadNextAd 被调用
|
||||||
|
2026-01-04 01:19:05.058 PlayBTopOn[92135:47321797] XS- 广告队列为空,所有广告已尝试加载
|
||||||
|
2026-01-04 01:19:05.058 PlayBTopOn[92135:47321797] loadend: Started with
|
||||||
|
2026-01-04 01:19:05.058 PlayBTopOn[92135:47321797] loadend: Created timestamp file at /var/mobile/Documents/ad/append/1767518345
|
||||||
|
2026-01-04 01:19:05.058 PlayBTopOn[92135:47321797] XS- didFailToDisplayAd 处理完成
|
||||||
|
2026-01-04 01:19:05.073 PlayBTopOn[92135:47321810] XS- 开始上报 uploadAD_Show: hhh5ve5yjpptfdcp
|
||||||
|
2026-01-04 01:19:05.073 PlayBTopOn[92135:47321810] XS- Uploading AD Show with data: {
|
||||||
|
"countryCode" : "US",
|
||||||
|
"linkId" : "D663DE2F-6759-48DA-A2B4-0E89478D41EC",
|
||||||
|
"platformResponseTime" : 0,
|
||||||
|
"dataId" : "26",
|
||||||
|
"phoneVersion" : "iPhone8,1",
|
||||||
|
"gaid" : "338815A7-3BCF-4DDE-A46F-86DEAD099185",
|
||||||
|
"shelfNumber" : "uploadAD_Load",
|
||||||
|
"network" : "ironsourceads",
|
||||||
|
"packageVersion" : "1.1",
|
||||||
|
"ecpm" : 0,
|
||||||
|
"localIp" : "172.25.202.160",
|
||||||
|
"adPlatform" : "IS",
|
||||||
|
"deviceId" : "6094A4AA-97F8-4E9C-AABE-12A3B2679115",
|
||||||
|
"loadTime" : 0,
|
||||||
|
"packageName" : "com.TastePickEatWheel.TastePickEatWheel",
|
||||||
|
"succeed" : false,
|
||||||
|
"dsp" : "IronSource",
|
||||||
|
"online" : false,
|
||||||
|
"adId" : "hhh5ve5yjpptfdcp",
|
||||||
|
"remoteIp" : "",
|
||||||
|
"getIpResponseTime" : 0,
|
||||||
|
"carrierId" : 0
|
||||||
|
}
|
||||||
|
2026-01-04 01:19:05.076 PlayBTopOn[92135:47321810] XS- uploadAD_Show 调用完成
|
||||||
|
2026-01-04 01:19:05.083 PlayBTopOn[92135:47321810] XS- Result: ["code": 0, "data": <null>, "msg": success]
|
||||||
|
2026-01-04 01:19:05.107 PlayBTopOn[92135:47321812] XS- Upload AD Show response: ["code": 0, "data": <null>, "msg": success]
|
||||||
|
2026-01-04 01:19:06.631 PlayBTopOn[92177:47322285] XHook: Hooks started for com.TastePickEatWheel.TastePickEatWheel; IDFA: C6B31B70-3E57-40AB-92CB-8377D875A308
|
||||||
|
2026-01-04 01:19:06.660 PlayBTopOn[92177:47322285] [Enable]
|
||||||
|
2026-01-04 01:19:06.660 PlayBTopOn[92177:47322285] [Enable]
|
||||||
|
2026-01-04 01:19:06.697 PlayBTopOn[92177:47322285] XS- app start:06DD0221-32CD-4677-BF9C-198DBFDA287A
|
||||||
|
2026-01-04 01:19:06.697 PlayBTopOn[92177:47322285] XS- app start 2:06DD0221-32CD-4677-BF9C-198DBFDA287A
|
||||||
|
2026-01-04 01:19:06.707 PlayBTopOn[92177:47322285] XS- app start 21:06DD0221-32CD-4677-BF9C-198DBFDA287A
|
||||||
|
2026-01-04 01:19:06.707 PlayBTopOn[92177:47322285] XS- 准备访问 BbbAdManager.shared
|
||||||
|
2026-01-04 01:19:06.707 PlayBTopOn[92177:47322285] XS- 开始创建 BbbAdManager.shared 单例
|
||||||
|
2026-01-04 01:19:06.707 PlayBTopOn[92177:47322285] XS- BbbAdManager init 开始
|
||||||
|
2026-01-04 01:19:06.707 PlayBTopOn[92177:47322285] XS- BbbAdManager init 完成
|
||||||
|
2026-01-04 01:19:06.708 PlayBTopOn[92177:47322285] XS- BbbAdManager.shared 单例创建完成
|
||||||
|
2026-01-04 01:19:06.708 PlayBTopOn[92177:47322285] XS- BbbAdManager.shared 访问成功
|
||||||
|
2026-01-04 01:19:06.708 PlayBTopOn[92177:47322285] XS- 准备调用 initConfig()
|
||||||
|
2026-01-04 01:19:06.708 PlayBTopOn[92177:47322285] XS- init config
|
||||||
|
2026-01-04 01:19:06.708 PlayBTopOn[92177:47322285] IDFA: C6B31B70-3E57-40AB-92CB-8377D875A308
|
||||||
|
2026-01-04 01:19:06.708 PlayBTopOn[92177:47322285] XS- 开始创建 BbbAdManager.config
|
||||||
|
2026-01-04 01:19:06.708 PlayBTopOn[92177:47322285] XS- bConfig init 开始
|
||||||
|
2026-01-04 01:19:06.708 PlayBTopOn[92177:47322285] XS- bConfig init: allAdIds count = 3
|
||||||
|
2026-01-04 01:19:06.708 PlayBTopOn[92177:47322285] XS- bConfig init 完成
|
||||||
|
2026-01-04 01:19:06.708 PlayBTopOn[92177:47322285] XS- BbbAdManager.config 创建完成
|
||||||
|
2026-01-04 01:19:06.708 PlayBTopOn[92177:47322285] XS- init config 1
|
||||||
|
2026-01-04 01:19:06.709 PlayBTopOn[92177:47322285] XS- init config 2
|
||||||
|
2026-01-04 01:19:06.711 PlayBTopOn[92177:47322285] XS- init config 3
|
||||||
|
2026-01-04 01:19:06.712 PlayBTopOn[92177:47322285] XS- app start 3:06DD0221-32CD-4677-BF9C-198DBFDA287A
|
||||||
|
2026-01-04 01:19:06.712 PlayBTopOn[92177:47322285] XS- app start 5:06DD0221-32CD-4677-BF9C-198DBFDA287A
|
||||||
|
2026-01-04 01:19:06.712 PlayBTopOn[92177:47322298] XS- app start 4:06DD0221-32CD-4677-BF9C-198DBFDA287A
|
||||||
|
2026-01-04 01:19:06.712 PlayBTopOn[92177:47322298] XS- init ad
|
||||||
|
2026-01-04 01:19:06.712 PlayBTopOn[92177:47322298] ironSourceSDK: Initializing with appKey: 24aee521d, userId: 602443
|
||||||
|
2026-01-04 01:19:06.713 PlayBTopOn[92177:47322298] [LevelPlay SDK] API: UITHREAD: false [LevelPlay setAdaptersDebug:] - flag: YES
|
||||||
|
2026-01-04 01:19:06.725 PlayBTopOn[92177:47322285] XS- app start 6:06DD0221-32CD-4677-BF9C-198DBFDA287A
|
||||||
|
2026-01-04 01:19:06.739 PlayBTopOn[92177:47322285] XS- YL_PlayVC viewDidLoad 开始
|
||||||
|
2026-01-04 01:19:06.740 PlayBTopOn[92177:47322285] XS- YL_PlayVC 准备调用 waitForSDKInitialization
|
||||||
|
2026-01-04 01:19:06.740 PlayBTopOn[92177:47322285] XS- waitForSDKInitialization 被调用,当前状态:false
|
||||||
|
2026-01-04 01:19:06.740 PlayBTopOn[92177:47322285] XS- SDK 未初始化,添加回调到等待队列
|
||||||
|
2026-01-04 01:19:06.740 PlayBTopOn[92177:47322285] XS- YL_PlayVC waitForSDKInitialization 调用完成
|
||||||
|
2026-01-04 01:19:06.806 PlayBTopOn[92177:47322298] XS- init ad end
|
||||||
|
2026-01-04 01:19:06.806 PlayBTopOn[92177:47322299] [LevelPlay SDK] API: UITHREAD: false [LevelPlayInternal initInstanceInternalWithRequest:completion:] - [LevelPlay initWithRequest:completion:] appkey 24aee521d userId (null) legacyAdFormats (
|
||||||
|
)
|
||||||
|
2026-01-04 01:19:06.806 PlayBTopOn[92177:47322299] [LevelPlay SDK] INTERNAL: UITHREAD: false [IronSourceSdk prepareSdkInitWithAppKey:adUnits:internal:isDemandOnly:delegate:newInitCompletionHandler:completion:] - GitHash: cfa6fb4
|
||||||
|
2026-01-04 01:19:06.809 PlayBTopOn[92177:47322299] [LevelPlay SDK] INTERNAL: The Mediation SDK has changed its state to SDK_INIT_IN_PROGRESS
|
||||||
|
2026-01-04 01:19:06.812 PlayBTopOn[92177:47322292] 请求配置成功: ["msg": success, "code": 0, "data": {
|
||||||
|
clickThroughRate = 80;
|
||||||
|
clientType = 1;
|
||||||
|
ecpmCool = "0.003";
|
||||||
|
ecpmLow = "0.001";
|
||||||
|
mobileDataTableName = "<null>";
|
||||||
|
packageName = "com.TastePickEatWheel.TastePickEatWheel";
|
||||||
|
quantity = 5;
|
||||||
|
specifyGaidTableName = "data_ios_topecpm";
|
||||||
|
status = 1;
|
||||||
|
washParam = 0;
|
||||||
|
}]
|
||||||
|
2026-01-04 01:19:06.825 PlayBTopOn[92177:47322292] [LevelPlay SDK] EVENT: {
|
||||||
|
connectionType = cellular;
|
||||||
|
eventId = 14;
|
||||||
|
eventSessionId = "8458A4C7-7C36-42A2-8860-5BC988DA4CB9";
|
||||||
|
ext1 = "appLanguage=Swift";
|
||||||
|
firstSessionTimestamp = 1767518346807;
|
||||||
|
isMultipleAdUnits = 1;
|
||||||
|
provider = Mediation;
|
||||||
|
rawConnectionType = CTRadioAccessTechnologyNR;
|
||||||
|
sessionDepth = 1;
|
||||||
|
timestamp = 1767518346811;
|
||||||
|
}
|
||||||
|
2026-01-04 01:19:08.189 PlayBTopOn[92177:47322298] [LevelPlay SDK] INTERNAL: rewarded settings: {parallelLoad=2, bidderExclusive=YES}
|
||||||
|
2026-01-04 01:19:08.192 PlayBTopOn[92177:47322298] [LevelPlay SDK] INTERNAL: interstitial settings: {parallelLoad=2, bidderExclusive=NO}
|
||||||
|
2026-01-04 01:19:08.198 PlayBTopOn[92177:47322298] [LevelPlay SDK] INTERNAL: rewarded settings: {parallelLoad=2, bidderExclusive=YES}
|
||||||
|
2026-01-04 01:19:08.199 PlayBTopOn[92177:47322298] [LevelPlay SDK] INTERNAL: interstitial settings: {parallelLoad=2, bidderExclusive=NO}
|
||||||
|
2026-01-04 01:19:08.280 PlayBTopOn[92177:47322285] [INFO] IronSource AdQuality: ISAdQuality: Initializing with app key 24aee521d
|
||||||
|
2026-01-04 01:19:10.331 PlayBTopOn[92177:47322285] Initialization successful with config: <LPMConfiguration: 0x280983ba0>
|
||||||
|
2026-01-04 01:19:10.331 PlayBTopOn[92177:47322285] XS- IronSource SDK initialized successfully
|
||||||
|
2026-01-04 01:19:10.331 PlayBTopOn[92177:47322285] XS- SDK 初始化完成,开始加载广告
|
||||||
|
2026-01-04 01:19:10.332 PlayBTopOn[92177:47322285] XS- load ad
|
||||||
|
2026-01-04 01:19:10.332 PlayBTopOn[92177:47322285] XS- view 已设置: <PlayBTopOn.YL_PlayVC: 0x12ddcdd50>
|
||||||
|
2026-01-04 01:19:10.332 PlayBTopOn[92177:47322285] XS- 初始化广告队列: ["no7750uspiuvwwcx", "hhh5ve5yjpptfdcp", "snlrr8jxxljp375n"]
|
||||||
|
2026-01-04 01:19:10.332 PlayBTopOn[92177:47322285] XS- 添加广告位: no7750uspiuvwwcx
|
||||||
|
2026-01-04 01:19:10.335 PlayBTopOn[92177:47322285] XS- 添加广告位: hhh5ve5yjpptfdcp
|
||||||
|
2026-01-04 01:19:10.337 PlayBTopOn[92177:47322285] XS- 添加广告位: snlrr8jxxljp375n
|
||||||
|
2026-01-04 01:19:10.339 PlayBTopOn[92177:47322285] XS- loadNextAd 被调用
|
||||||
|
2026-01-04 01:19:10.339 PlayBTopOn[92177:47322285] XS- 尝试加载广告: no7750uspiuvwwcx
|
||||||
|
2026-01-04 01:19:10.339 PlayBTopOn[92177:47322285] XS- 开始加载广告: no7750uspiuvwwcx
|
||||||
|
2026-01-04 01:19:10.339 PlayBTopOn[92177:47322285] XS- load ad end
|
||||||
|
2026-01-04 01:19:12.356 PlayBTopOn[92177:47322285] Created timestamp file at: /User/Documents/ad/load/1767518352
|
||||||
|
2026-01-04 01:19:12.356 PlayBTopOn[92177:47322285] XS- loadno7750uspiuvwwcx err.... :Error Domain=com.levelplay.error Code=509 "Mediation No fill" UserInfo={adId=30107435-5DC3-45C6-A1AA-D81AC07AA5EA, NSLocalizedDescription=Mediation No fill}
|
||||||
|
2026-01-04 01:19:12.356 PlayBTopOn[92177:47322285] XS- ad no7750uspiuvwwcx load time: 2021 ms
|
||||||
|
2026-01-04 01:19:12.356 PlayBTopOn[92177:47322285] XS- 广告加载失败,尝试加载下一个
|
||||||
|
2026-01-04 01:19:12.356 PlayBTopOn[92177:47322285] XS- loadNextAd 被调用
|
||||||
|
2026-01-04 01:19:12.357 PlayBTopOn[92177:47322285] XS- 尝试加载广告: hhh5ve5yjpptfdcp
|
||||||
|
2026-01-04 01:19:12.357 PlayBTopOn[92177:47322285] XS- 开始加载广告: hhh5ve5yjpptfdcp
|
||||||
|
2026-01-04 01:19:12.384 PlayBTopOn[92177:47322292] XS- Uploading AD Load with data: {
|
||||||
|
"packageVersion" : "1.1",
|
||||||
|
"shelfNumber" : "uploadAD_Load",
|
||||||
|
"online" : false,
|
||||||
|
"gaid" : "C6B31B70-3E57-40AB-92CB-8377D875A308",
|
||||||
|
"countryCode" : "",
|
||||||
|
"remoteIp" : "",
|
||||||
|
"adId" : "no7750uspiuvwwcx",
|
||||||
|
"getIpResponseTime" : 0,
|
||||||
|
"adPlatform" : "IS",
|
||||||
|
"dsp" : "MTG",
|
||||||
|
"dataId" : "13",
|
||||||
|
"loadTime" : 2021,
|
||||||
|
"ecpm" : 0,
|
||||||
|
"network" : "",
|
||||||
|
"deviceId" : "6094A4AA-97F8-4E9C-AABE-12A3B2679115",
|
||||||
|
"succeed" : false,
|
||||||
|
"localIp" : "172.25.202.160",
|
||||||
|
"linkId" : "21CD1B53-24DA-4149-A740-B7C7E1E0A422",
|
||||||
|
"carrierId" : 0,
|
||||||
|
"platformResponseTime" : 2,
|
||||||
|
"washParam" : false,
|
||||||
|
"packageName" : "com.TastePickEatWheel.TastePickEatWheel",
|
||||||
|
"phoneVersion" : "iPhone8,1",
|
||||||
|
"errorData" : "Error Domain=com.levelplay.error Code=509 \"Mediation No fill\" UserInfo={adId=30107435-5DC3-45C6-A1AA-D81AC07AA5EA, NSLocalizedDescription=Mediation No fill}"
|
||||||
|
}
|
||||||
|
2026-01-04 01:19:12.391 PlayBTopOn[92177:47322292] XS- Result: ["msg": success, "data": <null>, "code": 0]
|
||||||
4
build.py
4
build.py
@ -13,12 +13,12 @@ def build_json(json_path):
|
|||||||
build_topon(json_path)
|
build_topon(json_path)
|
||||||
|
|
||||||
def build_max(json_path):
|
def build_max(json_path):
|
||||||
build_path = "/Volumes/mfast/workspaces/projects/ios/build-ipa/max"
|
build_path = "/Users/mac/workspaces/projects/ios/build-ipa/max"
|
||||||
build_script(build_path, json_path, "playb-max.ipa")
|
build_script(build_path, json_path, "playb-max.ipa")
|
||||||
|
|
||||||
|
|
||||||
def build_topon(json_path):
|
def build_topon(json_path):
|
||||||
build_path = "/Volumes/mfast/workspaces/projects/ios/build-ipa/topon"
|
build_path = "/Users/mac/workspaces/projects/ios/build-ipa/topon"
|
||||||
build_script(build_path, json_path, "playb-topon.ipa")
|
build_script(build_path, json_path, "playb-topon.ipa")
|
||||||
|
|
||||||
def build_script(build_path, json_path, ipa_name):
|
def build_script(build_path, json_path, ipa_name):
|
||||||
|
|||||||
16
build.sh
Normal file
16
build.sh
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
xcodebuild clean build -workspace wallpaper_Game_Project.xcworkspace -configuration Release -scheme wallpaper_Game_Project -derivedDataPath "../Target" -destination "platform=iOS,id=00008150-001114363E7A401C"
|
||||||
|
mkdir -p ./build/ipas
|
||||||
|
cp -rfv ./build/Target/Build/Products/Release-iphoneos/wallpaper_Game_Project.app ./build/ipas/
|
||||||
|
cp ./build/embedded.mobileprovision ./build/ipas/wallpaper_Game_Project.app/embedded.mobileprovision
|
||||||
|
|
||||||
|
find "./build/ipas/wallpaper_Game_Project.app" -name "*.framework" -exec codesign -f -s "Apple Distribution: YX C (3AJQST798X)" {} \;
|
||||||
|
|
||||||
|
find "./build/ipas/wallpaper_Game_Project.app" -name "*.dylib" -exec codesign -f -s "Apple Distribution: YX C (3AJQST798X)" {} \;
|
||||||
|
|
||||||
|
echo "codesign"
|
||||||
|
codesign --entitlements ./build/Filza.entitlements -f -s "Apple Distribution: YX C (3AJQST798X)" ./build/ipas/wallpaper_Game_Project.app
|
||||||
|
|
||||||
|
mkdir -p ./build/ipas/Payload
|
||||||
|
mv ./build/ipas/wallpaper_Game_Project.app ./build/ipas/Payload
|
||||||
|
cd ./build/ipas
|
||||||
|
zip -r mytest.ipa Payload/
|
||||||
214
ironSource/PlayBTopOn/AD_DISPLAY_FIX.md
Normal file
214
ironSource/PlayBTopOn/AD_DISPLAY_FIX.md
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
# 广告展示问题修复说明
|
||||||
|
|
||||||
|
## 问题描述
|
||||||
|
|
||||||
|
**症状:**
|
||||||
|
- 后台日志显示 `uploadAD_Load` 有记录(广告加载成功)
|
||||||
|
- 广告的 ecpm 满足条件(>= adbrush_ecpm)
|
||||||
|
- 但是 `uploadAD_Show` 日志缺失(广告没有展示)
|
||||||
|
|
||||||
|
## 可能的原因
|
||||||
|
|
||||||
|
1. **广告未准备好**:`isAdReady()` 返回 false
|
||||||
|
2. **展示失败但未捕获**:SDK 调用了 `didFailToDisplayAd` 但未实现该回调
|
||||||
|
3. **状态问题**:`isshow` 标志阻止了展示
|
||||||
|
4. **视图问题**:view 为 nil 或无效
|
||||||
|
|
||||||
|
## ✅ 已修复的问题
|
||||||
|
|
||||||
|
### 1. 添加了展示失败回调
|
||||||
|
|
||||||
|
**文件:** `IronSourceinterstitialAd.swift`
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// 新增方法
|
||||||
|
func didFailToDisplayAd(with adInfo: LPMAdInfo, error: Error) {
|
||||||
|
NSLog("XS- ✗✗✗ didFailToDisplayAd 回调被触发")
|
||||||
|
NSLog("XS- 广告展示失败!错误: \(error.localizedDescription)")
|
||||||
|
|
||||||
|
// 改变状态为展示失败
|
||||||
|
changeStatus(st: 6)
|
||||||
|
|
||||||
|
// 触发关闭回调,让外部可以重试
|
||||||
|
self.onAdClosed()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 增强了详细日志
|
||||||
|
|
||||||
|
#### bbbAdManager.swift - showAd 方法
|
||||||
|
|
||||||
|
```swift
|
||||||
|
✓ 显示当前 isshow 状态
|
||||||
|
✓ 显示遍历的广告总数
|
||||||
|
✓ 每个广告的详细信息(ID, ecpm, status)
|
||||||
|
✓ 判断条件的详细说明
|
||||||
|
✓ show() 返回值的记录
|
||||||
|
✓ 最终结果的总结
|
||||||
|
```
|
||||||
|
|
||||||
|
#### IronSourceinterstitialAd.swift - show 方法
|
||||||
|
|
||||||
|
```swift
|
||||||
|
✓ 显示 isAdReady() 状态
|
||||||
|
✓ 显示 showAd() 调用过程
|
||||||
|
✓ 区分广告未准备好和其他失败
|
||||||
|
```
|
||||||
|
|
||||||
|
#### IronSourceinterstitialAd.swift - didDisplayAd 方法
|
||||||
|
|
||||||
|
```swift
|
||||||
|
✓ 明确标记展示成功
|
||||||
|
✓ 显示上报 Show 日志的过程
|
||||||
|
✓ 显示广告信息(ecpm, network, country)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 修复了 view 为 nil 的崩溃
|
||||||
|
|
||||||
|
**文件:** `bbbAdManager.swift`
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// 安全地检查 view
|
||||||
|
if self.isshow == false, let viewController = self.view {
|
||||||
|
self.showAd(v: viewController)
|
||||||
|
} else if self.view == nil {
|
||||||
|
NSLog("XS- 警告: view 为 nil,无法展示广告")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 改进了展示逻辑
|
||||||
|
|
||||||
|
- 当一个广告 `show()` 返回 false 时,继续尝试下一个
|
||||||
|
- 只有成功调用 `show()` 才设置 `isshow = true`
|
||||||
|
- 展示失败时自动重置状态,允许重试
|
||||||
|
|
||||||
|
## 📊 日志分析指南
|
||||||
|
|
||||||
|
### 正常流程的日志
|
||||||
|
|
||||||
|
```
|
||||||
|
XS- showAd 被调用,当前 isshow: false
|
||||||
|
XS- 开始遍历广告位,总数: 3
|
||||||
|
XS- 检查广告 [0]: ID=xxx, ecpm=0.05, status=2, 要求ecpm>=0.0005
|
||||||
|
XS- ✓ 找到合适的广告,准备展示: xxx
|
||||||
|
XS- IronSourceinterstitialAd.show 被调用: xxx
|
||||||
|
XS- 广告准备状态 isAdReady: true, adID: xxx
|
||||||
|
XS- ✓ 调用 showAd,准备展示广告: xxx
|
||||||
|
XS- showAd 调用完成,等待 didDisplayAd 回调
|
||||||
|
XS- ✓ 广告 show() 返回 true,标记 isshow=true
|
||||||
|
XS- ✓✓✓ didDisplayAd 回调被触发: xxx
|
||||||
|
XS- 广告展示成功,准备上报 Show 日志
|
||||||
|
XS- 开始上报 uploadAD_Show: xxx
|
||||||
|
XS- uploadAD_Show 调用完成
|
||||||
|
```
|
||||||
|
|
||||||
|
### 场景 1: 广告未准备好
|
||||||
|
|
||||||
|
```
|
||||||
|
XS- 广告准备状态 isAdReady: false, adID: xxx
|
||||||
|
XS- ✗ 广告未准备好,无法展示: xxx
|
||||||
|
XS- ✗ 广告 show() 返回 false,可能未准备好,尝试下一个
|
||||||
|
```
|
||||||
|
|
||||||
|
**原因:** 虽然 status=2(加载完成),但 SDK 的 `isAdReady()` 返回 false
|
||||||
|
|
||||||
|
**解决:**
|
||||||
|
- 检查是否过早调用 show
|
||||||
|
- 检查广告是否已过期
|
||||||
|
- 查看 SDK 文档的广告有效期
|
||||||
|
|
||||||
|
### 场景 2: 展示失败(SDK 错误)
|
||||||
|
|
||||||
|
```
|
||||||
|
XS- ✓ 调用 showAd,准备展示广告: xxx
|
||||||
|
XS- showAd 调用完成,等待 didDisplayAd 回调
|
||||||
|
XS- ✗✗✗ didFailToDisplayAd 回调被触发: xxx
|
||||||
|
XS- 广告展示失败!错误: Ad expired
|
||||||
|
```
|
||||||
|
|
||||||
|
**原因:** SDK 尝试展示但失败(广告过期、网络问题等)
|
||||||
|
|
||||||
|
**解决:**
|
||||||
|
- 广告过期:缩短 load 到 show 的时间
|
||||||
|
- 网络问题:检查网络连接
|
||||||
|
- 其他错误:根据错误信息排查
|
||||||
|
|
||||||
|
### 场景 3: ecpm 不足
|
||||||
|
|
||||||
|
```
|
||||||
|
XS- 检查广告 [0]: ID=xxx, ecpm=0.0003, status=2, 要求ecpm>=0.0005
|
||||||
|
XS- ✗ 广告 ecpm 不足: xxx, ecpm=0.0003 < 0.0005
|
||||||
|
```
|
||||||
|
|
||||||
|
**原因:** 广告 ecpm 太低,不满足展示条件
|
||||||
|
|
||||||
|
**解决:**
|
||||||
|
- 调整 `adbrush_ecpm` 阈值
|
||||||
|
- 等待更高 ecpm 的广告
|
||||||
|
|
||||||
|
### 场景 4: isshow 阻塞
|
||||||
|
|
||||||
|
```
|
||||||
|
XS- showAd 被调用,当前 isshow: true
|
||||||
|
XS- ✗ isshow=true,已有广告在展示中,跳过
|
||||||
|
```
|
||||||
|
|
||||||
|
**原因:** 已经有广告在展示,防止重复展示
|
||||||
|
|
||||||
|
**解决:** 正常情况,等待当前广告关闭
|
||||||
|
|
||||||
|
### 场景 5: view 为 nil
|
||||||
|
|
||||||
|
```
|
||||||
|
XS- 警告: view 为 nil,无法展示广告
|
||||||
|
```
|
||||||
|
|
||||||
|
**原因:** `loadAd()` 还未被调用,或 start() 在 loadAd() 之前触发
|
||||||
|
|
||||||
|
**解决:** 已在代码中修复,确保 loadAd 后才调用 start
|
||||||
|
|
||||||
|
## 🔍 调试步骤
|
||||||
|
|
||||||
|
1. **查看完整日志**,从 `XS- showAd 被调用` 开始
|
||||||
|
|
||||||
|
2. **定位问题类型**:
|
||||||
|
- 没有 "✓ 找到合适的广告" → ecpm 或 status 问题
|
||||||
|
- 有 "找到" 但 show() 返回 false → 广告未准备好
|
||||||
|
- show() 返回 true 但无 didDisplayAd → 查看是否有 didFailToDisplayAd
|
||||||
|
|
||||||
|
3. **根据场景排查**:
|
||||||
|
- 使用上面的场景分析
|
||||||
|
- 查看具体的错误信息
|
||||||
|
|
||||||
|
4. **验证修复**:
|
||||||
|
- 看到 "✓✓✓ didDisplayAd" 和 "uploadAD_Show 调用完成"
|
||||||
|
|
||||||
|
## 📝 状态说明
|
||||||
|
|
||||||
|
| Status | 含义 | 说明 |
|
||||||
|
|--------|------|------|
|
||||||
|
| 0 | 初始 | 刚创建,未开始加载 |
|
||||||
|
| 1 | 加载中 | 正在请求广告 |
|
||||||
|
| 2 | 加载完成 | 广告已加载,可以展示 |
|
||||||
|
| 3 | 展示中 | 广告正在展示 |
|
||||||
|
| 4 | 关闭 | 广告已关闭 |
|
||||||
|
| 5 | 加载失败 | 广告加载失败 |
|
||||||
|
| 6 | 展示失败 | 广告展示失败(新增) |
|
||||||
|
|
||||||
|
## 🎯 关键检查点
|
||||||
|
|
||||||
|
运行应用后,如果出现 Load 有但 Show 没有的情况,检查日志中:
|
||||||
|
|
||||||
|
1. ✅ `isAdReady` 是 true 还是 false?
|
||||||
|
2. ✅ `show()` 返回 true 还是 false?
|
||||||
|
3. ✅ 是否有 `didFailToDisplayAd` 回调?
|
||||||
|
4. ✅ 错误信息是什么?
|
||||||
|
5. ✅ `isshow` 状态是否正确?
|
||||||
|
|
||||||
|
把这些信息发给我,我可以精确定位问题!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**修复时间:** 2025-01-01
|
||||||
|
**影响范围:** 广告展示逻辑
|
||||||
|
**向后兼容:** ✅ 完全兼容
|
||||||
259
ironSource/PlayBTopOn/CANNOT_ENGAGE_FIX.md
Normal file
259
ironSource/PlayBTopOn/CANNOT_ENGAGE_FIX.md
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
# "Cannot engage offer at this time" 错误修复
|
||||||
|
|
||||||
|
## 📊 问题分析
|
||||||
|
|
||||||
|
### 日志显示
|
||||||
|
|
||||||
|
```
|
||||||
|
XS- ✓ 找到合适的广告,准备展示: hhh5ve5yjpptfdcp
|
||||||
|
XS- 广告准备状态 isAdReady: true ✓
|
||||||
|
XS- ✓ 调用 showAd,准备展示广告
|
||||||
|
XS- ✓ 广告 show() 返回 true ✓
|
||||||
|
XS- ✗✗✗ didFailToDisplayAd 回调被触发 ✗
|
||||||
|
XS- 广告展示失败!错误: Cannot+engage+offer+at+this+time
|
||||||
|
```
|
||||||
|
|
||||||
|
### 错误原因
|
||||||
|
|
||||||
|
`Cannot engage offer at this time` 通常表示:
|
||||||
|
|
||||||
|
1. **广告展示频率限制**
|
||||||
|
- SDK 有频率控制(如:同一广告 X 分钟内只能展示一次)
|
||||||
|
- 该广告最近刚展示过
|
||||||
|
|
||||||
|
2. **广告已过期**
|
||||||
|
- 虽然 `isAdReady()` 返回 true
|
||||||
|
- 但在调用 `showAd()` 时广告已失效
|
||||||
|
- Load 到 Show 的时间间隔过长
|
||||||
|
|
||||||
|
3. **SDK 内部状态问题**
|
||||||
|
- 广告正在被其他地方使用
|
||||||
|
- SDK 内部锁定了该广告
|
||||||
|
|
||||||
|
## ✅ 已实现的解决方案
|
||||||
|
|
||||||
|
### 1. 展示失败后自动重新加载
|
||||||
|
|
||||||
|
**文件:** `IronSourceinterstitialAd.swift`
|
||||||
|
|
||||||
|
```swift
|
||||||
|
func didFailToDisplayAd(with adInfo: LPMAdInfo, error: Error) {
|
||||||
|
// 改变状态为展示失败 (status = 6)
|
||||||
|
changeStatus(st: 6)
|
||||||
|
|
||||||
|
// 触发关闭回调,重置 isshow = false
|
||||||
|
self.onAdClosed()
|
||||||
|
|
||||||
|
// 1秒后重新加载这个广告
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
|
||||||
|
self.changeStatus(st: 1) // 标记为加载中
|
||||||
|
self.load()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 跳过失败的广告,尝试下一个
|
||||||
|
|
||||||
|
**文件:** `bbbAdManager.swift`
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// 跳过状态为6(展示失败)的广告
|
||||||
|
if ad.status == 6 {
|
||||||
|
NSLog("跳过展示失败的广告,等待重新加载")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 继续尝试其他广告
|
||||||
|
if (ad.status == 2 && ad.ecpm >= adbrush_ecpm) {
|
||||||
|
let showResult = ad.show(...)
|
||||||
|
if !showResult {
|
||||||
|
continue // 尝试下一个
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 广告关闭后自动尝试展示下一个
|
||||||
|
|
||||||
|
```swift
|
||||||
|
ad.show(viewController: v) {
|
||||||
|
self.isshow = false
|
||||||
|
|
||||||
|
// 0.5秒后尝试展示其他广告
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||||
|
self.showAd(v: viewController)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔄 完整的流程
|
||||||
|
|
||||||
|
### 场景 1: 单个广告展示失败
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 尝试展示广告 A
|
||||||
|
↓ 失败: "Cannot engage offer"
|
||||||
|
2. 标记广告 A 状态为 6(展示失败)
|
||||||
|
↓
|
||||||
|
3. 触发 onAdClosed,重置 isshow = false
|
||||||
|
↓
|
||||||
|
4. 1秒后重新加载广告 A(状态变为 1 → 2)
|
||||||
|
↓
|
||||||
|
5. 下次定时器触发时,继续尝试展示
|
||||||
|
```
|
||||||
|
|
||||||
|
### 场景 2: 多个广告位,轮流尝试
|
||||||
|
|
||||||
|
```
|
||||||
|
广告 A: Load成功 → Show失败 → 跳过(status=6)→ 重新加载
|
||||||
|
广告 B: Load成功 → 尝试Show → 成功 ✓
|
||||||
|
广告 C: 待命
|
||||||
|
|
||||||
|
下一轮:
|
||||||
|
广告 A: 重新加载完成 → 尝试Show
|
||||||
|
广告 B: 已展示
|
||||||
|
广告 C: 尝试Show
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📈 改进效果
|
||||||
|
|
||||||
|
### 之前的问题
|
||||||
|
|
||||||
|
- ❌ 展示失败后,广告一直保持 status=2
|
||||||
|
- ❌ 定时器反复尝<E5A48D><E5B09D><EFBFBD>同一个失败的广告
|
||||||
|
- ❌ 其他可用的广告无法展示
|
||||||
|
- ❌ Show 日志缺失,无法追踪
|
||||||
|
|
||||||
|
### 现在的改进
|
||||||
|
|
||||||
|
- ✅ 展示失败后立即标记状态(status=6)
|
||||||
|
- ✅ 跳过失败的广告,尝试其他广告
|
||||||
|
- ✅ 失败的广告自动重新加载
|
||||||
|
- ✅ 完整的日志追踪
|
||||||
|
- ✅ 自动轮换展示机制
|
||||||
|
|
||||||
|
## 🎯 预期日志(修复后)
|
||||||
|
|
||||||
|
### 第一次尝试
|
||||||
|
|
||||||
|
```
|
||||||
|
XS- 检查广告 [0]: ID=hhh5ve5yjpptfdcp, status=2 ✓
|
||||||
|
XS- ✓ 找到合适的广告[尝试1]
|
||||||
|
XS- ✗✗✗ didFailToDisplayAd: Cannot engage offer
|
||||||
|
XS- 展示失败后重新加载广告
|
||||||
|
XS- 广告关闭回调被触发
|
||||||
|
```
|
||||||
|
|
||||||
|
### 自动尝试下一个
|
||||||
|
|
||||||
|
```
|
||||||
|
XS- 检查广告 [0]: ID=hhh5ve5yjpptfdcp, status=6
|
||||||
|
XS- ✗ 跳过展示失败的广告,等待重新加载
|
||||||
|
XS- 检查广告 [1]: ID=no7750uspiuvwwcx, status=2 ✓
|
||||||
|
XS- ✓ 找到合适的广告[尝试1]
|
||||||
|
XS- ✓✓✓ didDisplayAd 回调被触发 ✓✓✓
|
||||||
|
XS- 开始上报 uploadAD_Show
|
||||||
|
```
|
||||||
|
|
||||||
|
### 广告 A 重新加载完成
|
||||||
|
|
||||||
|
```
|
||||||
|
XS- ad load ok: hhh5ve5yjpptfdcp (重新加载完成)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 下一轮尝试
|
||||||
|
|
||||||
|
```
|
||||||
|
XS- 检查广告 [0]: ID=hhh5ve5yjpptfdcp, status=2 ✓
|
||||||
|
XS- ✓ 找到合适的广告[尝试1]
|
||||||
|
XS- ✓✓✓ didDisplayAd 回调被触发 ✓✓✓
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🛠️ 调整建议
|
||||||
|
|
||||||
|
### 1. 调整展示频率
|
||||||
|
|
||||||
|
如果 "Cannot engage offer" 频繁出现,可以:
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// 在 bbbAdManager.swift 中
|
||||||
|
let kOpenADPerSec: CGFloat = 2 // 从1改为2,降低尝试频率
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 调整重新加载延迟
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// 在 IronSourceinterstitialAd.swift 中
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { // 从1秒改为2秒
|
||||||
|
self.load()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 添加展示间隔限制
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// 记录最后展示时间
|
||||||
|
var lastShowTime: Date?
|
||||||
|
|
||||||
|
// 检查是否满足展示间隔
|
||||||
|
if let lastTime = lastShowTime,
|
||||||
|
Date().timeIntervalSince(lastTime) < 30 { // 30秒内不重复展示
|
||||||
|
NSLog("距离上次展示不足30秒,跳过")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📝 状态码说明(更新)
|
||||||
|
|
||||||
|
| Status | 含义 | 后续动作 |
|
||||||
|
|--------|------|---------|
|
||||||
|
| 0 | 初始 | 等待开始加载 |
|
||||||
|
| 1 | 加载中 | 等待加载完成 |
|
||||||
|
| 2 | 加载完成 | **可以展示** ✓ |
|
||||||
|
| 3 | 展示中 | 等待关闭 |
|
||||||
|
| 4 | 已关闭 | 可以重新加载 |
|
||||||
|
| 5 | 加载失败 | 需要重新加载 |
|
||||||
|
| 6 | 展示失败 | **自动重新加载** ← 新增 |
|
||||||
|
|
||||||
|
## 🎁 额外改进
|
||||||
|
|
||||||
|
### 展示成功率统计
|
||||||
|
|
||||||
|
可以添加统计代码:
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// 在 bbbAdManager 中添加
|
||||||
|
var showSuccessCount = 0
|
||||||
|
var showFailCount = 0
|
||||||
|
|
||||||
|
// didDisplayAd 中
|
||||||
|
showSuccessCount += 1
|
||||||
|
|
||||||
|
// didFailToDisplayAd 中
|
||||||
|
showFailCount += 1
|
||||||
|
|
||||||
|
// 计算成功率
|
||||||
|
let successRate = Double(showSuccessCount) / Double(showSuccessCount + showFailCount)
|
||||||
|
NSLog("广告展示成功率: \(successRate * 100)%")
|
||||||
|
```
|
||||||
|
|
||||||
|
## ✅ 总结
|
||||||
|
|
||||||
|
现在的系统能够:
|
||||||
|
1. ✅ 捕获所有展示失败
|
||||||
|
2. ✅ 自动重新加载失败的广告
|
||||||
|
3. ✅ 自动尝试其他可用广告
|
||||||
|
4. ✅ 完整的日志追踪
|
||||||
|
5. ✅ 自动轮换展示机制
|
||||||
|
|
||||||
|
重新编译运行后,即使某个广告展示失败,系统也会:
|
||||||
|
- 立即尝试展示其他广告
|
||||||
|
- 在后台重新加载失败的广告
|
||||||
|
- 下一轮继续尝试
|
||||||
|
|
||||||
|
这样大大提高了广告展示的成功率!🎉
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**修复时间:** 2025-01-04
|
||||||
|
**问题类型:** SDK 展示频率限制
|
||||||
|
**解决方案:** 自动重新加载 + 轮换展示
|
||||||
213
ironSource/PlayBTopOn/CHANGES_SUMMARY.md
Normal file
213
ironSource/PlayBTopOn/CHANGES_SUMMARY.md
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
# iOS 12/13 兼容性修复总结
|
||||||
|
|
||||||
|
## 修复时间
|
||||||
|
2025-01-01
|
||||||
|
|
||||||
|
## 问题描述
|
||||||
|
应用在 iOS 12/13 系统上启动时崩溃,原因:
|
||||||
|
1. 使用了 `Task { await ... }` 等 Swift Concurrency API(需要 iOS 15+)
|
||||||
|
2. 无条件导入 `AppTrackingTransparency` 框架(仅 iOS 14+ 可用)
|
||||||
|
|
||||||
|
## 已修复的文件
|
||||||
|
|
||||||
|
### 1. PlayBTopOn/AppDelegate.swift
|
||||||
|
**修改内容:**
|
||||||
|
- ❌ 移除:`Task { await BbbAdManager.shared.initAd() }`
|
||||||
|
- ✅ 替换为:`DispatchQueue.global(qos: .userInitiated).async { BbbAdManager.shared.initAd() }`
|
||||||
|
|
||||||
|
**影响:** 兼容 iOS 12+,使用传统的 GCD 异步方式
|
||||||
|
|
||||||
|
### 2. PlayBTopOn/playB/YL_PlayVC.swift
|
||||||
|
**修改内容:**
|
||||||
|
- ❌ 移除:`Task { await BbbAdManager.shared.waitForSDKInitialization() ... }`
|
||||||
|
- ✅ 替换为:`BbbAdManager.shared.waitForSDKInitialization { BbbAdManager.shared.loadAd(view: self) }`
|
||||||
|
|
||||||
|
**影响:** 使用回调方式等待 SDK 初始化完成
|
||||||
|
|
||||||
|
### 3. PlayBTopOn/playB/bbbAdManager.swift
|
||||||
|
**修改内容:**
|
||||||
|
- ✅ 新增:`initAd(completion:)` - 基于回调的初始化方法(兼容所有版本)
|
||||||
|
- ✅ 新增:`waitForSDKInitialization(completion:)` - 基于回调的等待方法
|
||||||
|
- ✅ 重命名:原 `initAd() async` → `initAdAsync()` 并标记 `@available(iOS 15.0, *)`
|
||||||
|
- ✅ 重命名:原 `waitForSDKInitialization() async` → `waitForSDKInitializationAsync()` 并标记 `@available(iOS 15.0, *)`
|
||||||
|
- 🔴 **关键修复:** 移除 `CheckedContinuation` 类型,改用普通闭包数组
|
||||||
|
- ❌ `private var initializationContinuations: [CheckedContinuation<Void, Never>] = []`
|
||||||
|
- ✅ `private var initializationCallbacks: [() -> Void] = []`
|
||||||
|
|
||||||
|
**影响:** 提供双版本 API,默认使用回调方式,移除了导致 iOS 12 崩溃的 Swift Concurrency 类型
|
||||||
|
|
||||||
|
### 4. PlayBTopOn/playB/idfa.swift
|
||||||
|
**修改内容:**
|
||||||
|
- ❌ 移除:顶部的 `import AppTrackingTransparency`
|
||||||
|
- ✅ 添加:`#if canImport(AppTrackingTransparency) import AppTrackingTransparency #endif`
|
||||||
|
- ✅ 添加:所有 ATT 相关代码都用 `#if canImport(AppTrackingTransparency)` 包裹
|
||||||
|
- ✅ 修改:`checkATT()` 方法使用条件编译,低版本自动降级到旧 API
|
||||||
|
|
||||||
|
**影响:** 编译时只在支持的平台引入 ATT,运行时自动选择合适的 IDFA 获取方式
|
||||||
|
|
||||||
|
### 5. PlayBTopOn/playB/YL_NetWorkManager.swift
|
||||||
|
**修改内容:**
|
||||||
|
- ❌ 移除:顶部的 `import AppTrackingTransparency`
|
||||||
|
- ✅ 添加:`#if canImport(AppTrackingTransparency) import AppTrackingTransparency #endif`
|
||||||
|
- ✅ 修改:`getAdvertisingTrackingStatus()` 使用条件编译
|
||||||
|
- ✅ 修改:`isAdvertisingTrackingEnabled()` 使用条件编译
|
||||||
|
|
||||||
|
**影响:** ATT API 调用被条件编译保护,低版本使用 `ASIdentifierManager` 旧 API
|
||||||
|
|
||||||
|
## 新增文件
|
||||||
|
|
||||||
|
### 1. iOS12_COMPATIBILITY_GUIDE.md
|
||||||
|
详细的配置指南,包括:
|
||||||
|
- 问题说明
|
||||||
|
- Xcode 配置步骤
|
||||||
|
- 测试验证方法
|
||||||
|
- 常见问题解答
|
||||||
|
|
||||||
|
### 2. check_ios12_compatibility.sh
|
||||||
|
自动化检查脚本,检测:
|
||||||
|
- Task/async/await 未保护的使用
|
||||||
|
- AppTrackingTransparency 导入保护
|
||||||
|
- Podfile 和项目配置
|
||||||
|
- 其他潜在问题
|
||||||
|
|
||||||
|
### 3. CHANGES_SUMMARY.md
|
||||||
|
本文件,记录所有修改内容
|
||||||
|
|
||||||
|
## 验证结果
|
||||||
|
|
||||||
|
✅ **所有代码检查通过!**
|
||||||
|
|
||||||
|
```
|
||||||
|
======================================
|
||||||
|
iOS 12/13 兼容性检查
|
||||||
|
======================================
|
||||||
|
|
||||||
|
✓ 未发现 Task 调用
|
||||||
|
✓ 所有 async 函数都已保护
|
||||||
|
✓ AppTrackingTransparency 导入已正确保护
|
||||||
|
✓ Podfile 最低版本: iOS 12.0
|
||||||
|
✓ 找到 Info.plist
|
||||||
|
|
||||||
|
错误: 0
|
||||||
|
警告: 3
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔴 关键崩溃修复
|
||||||
|
|
||||||
|
**问题:** 应用在打印 `"XS- 开始创建 BbbAdManager.shared 单例"` 后崩溃
|
||||||
|
|
||||||
|
**原因:** `CheckedContinuation` 类型在 iOS 12 上不存在
|
||||||
|
|
||||||
|
**解决:** 已替换为普通闭包数组
|
||||||
|
|
||||||
|
详细信息请查看:[CRITICAL_FIX.md](./CRITICAL_FIX.md)
|
||||||
|
|
||||||
|
## 仍需手动操作的事项
|
||||||
|
|
||||||
|
### ⚠️ 重要:在 Xcode 中配置弱链接
|
||||||
|
|
||||||
|
1. **打开 Xcode 项目**
|
||||||
|
```
|
||||||
|
open PlayBTopOn.xcworkspace
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **配置 AppTrackingTransparency 为 Optional**
|
||||||
|
- 选择项目 → TARGETS → PlayBTopOn
|
||||||
|
- Build Phases → Link Binary With Libraries
|
||||||
|
- 找到或添加 `AppTrackingTransparency.framework`
|
||||||
|
- 将 Status 改为 **Optional** (不是 Required)
|
||||||
|
|
||||||
|
3. **验证 Deployment Target**
|
||||||
|
- General → Deployment Info
|
||||||
|
- iOS Deployment Target 设置为 **12.0**
|
||||||
|
|
||||||
|
### 可选:添加 ATT 权限说明
|
||||||
|
|
||||||
|
如果需要在 iOS 14+ 上请求追踪权限,在 `Info.plist` 中添加:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<key>NSUserTrackingUsageDescription</key>
|
||||||
|
<string>我们需要获取您的广告标识符以提供个性化广告体验</string>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 兼容性矩阵
|
||||||
|
|
||||||
|
| iOS 版本 | 支持状态 | IDFA 获取方式 | 异步调用方式 |
|
||||||
|
|---------|---------|-------------|------------|
|
||||||
|
| iOS 12.x | ✅ 完全支持 | ASIdentifierManager | DispatchQueue + 回调 |
|
||||||
|
| iOS 13.x | ✅ 完全支持 | ASIdentifierManager | DispatchQueue + 回调 |
|
||||||
|
| iOS 14.x | ✅ 完全支持 | ATTrackingManager | DispatchQueue + 回调 |
|
||||||
|
| iOS 15+ | ✅ 完全支持 | ATTrackingManager | async/await 或 回调 |
|
||||||
|
|
||||||
|
## 测试建议
|
||||||
|
|
||||||
|
### 1. 编译测试
|
||||||
|
```bash
|
||||||
|
# 清理构建
|
||||||
|
xcodebuild clean
|
||||||
|
|
||||||
|
# 构建项目
|
||||||
|
xcodebuild build -workspace PlayBTopOn.xcworkspace \
|
||||||
|
-scheme PlayBTopOn \
|
||||||
|
-destination 'platform=iOS Simulator,name=iPhone 8,OS=12.4'
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 模拟器测试
|
||||||
|
- iOS 12.4 (iPhone 8)
|
||||||
|
- iOS 13.7 (iPhone 11)
|
||||||
|
- iOS 14.8 (iPhone 12)
|
||||||
|
- iOS 15.0+ (任意设备)
|
||||||
|
|
||||||
|
### 3. 真机测试
|
||||||
|
在实际设备上测试,特别是:
|
||||||
|
- 旧设备运行 iOS 12/13
|
||||||
|
- 新设备运行 iOS 14+
|
||||||
|
|
||||||
|
## 回滚方法
|
||||||
|
|
||||||
|
如果需要回滚这些更改:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git log --oneline # 查看提交历史
|
||||||
|
git revert <commit-hash> # 回滚指定提交
|
||||||
|
```
|
||||||
|
|
||||||
|
或者从备份恢复:
|
||||||
|
```bash
|
||||||
|
cp -r PlayBTopOn.backup/* PlayBTopOn/
|
||||||
|
```
|
||||||
|
|
||||||
|
## 技术要点总结
|
||||||
|
|
||||||
|
### Swift Concurrency 兼容性
|
||||||
|
- `Task` / `async` / `await` 需要 iOS 15+
|
||||||
|
- 使用 `@available(iOS 15.0, *)` 标记
|
||||||
|
- 提供基于 `DispatchQueue` 和回调的替代方案
|
||||||
|
|
||||||
|
### 弱链接 (Weak Linking)
|
||||||
|
- 框架在 Build Phases 中设置为 Optional
|
||||||
|
- 运行时动态加载,不存在也不崩溃
|
||||||
|
- 代码中用 `#if canImport()` 条件编译
|
||||||
|
|
||||||
|
### 版本检查
|
||||||
|
- `@available(iOS 14, *)` - 运行时检查
|
||||||
|
- `#if canImport()` - 编译时检查
|
||||||
|
- 两者结合使用最安全
|
||||||
|
|
||||||
|
## 相关文档
|
||||||
|
|
||||||
|
- [iOS12_COMPATIBILITY_GUIDE.md](./iOS12_COMPATIBILITY_GUIDE.md) - 详细配置指南
|
||||||
|
- [check_ios12_compatibility.sh](./check_ios12_compatibility.sh) - 自动检查脚本
|
||||||
|
|
||||||
|
## 联系支持
|
||||||
|
|
||||||
|
如遇问题,请:
|
||||||
|
1. 运行 `./check_ios12_compatibility.sh` 检查配置
|
||||||
|
2. 查看 Xcode 控制台的崩溃日志
|
||||||
|
3. 确认 AppTrackingTransparency 已设置为 Optional
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**修复完成 ✅**
|
||||||
|
**最低支持版本:iOS 12.0**
|
||||||
|
**测试状态:代码验证通过,待真机测试**
|
||||||
205
ironSource/PlayBTopOn/CRITICAL_FIX.md
Normal file
205
ironSource/PlayBTopOn/CRITICAL_FIX.md
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
# 🔴 关键崩溃修复
|
||||||
|
|
||||||
|
## 问题定位
|
||||||
|
|
||||||
|
**症状:** 应用在打印 `"XS- 开始创建 BbbAdManager.shared 单例"` 后立即崩溃
|
||||||
|
|
||||||
|
**根本原因:** `BbbAdManager` 类中使用了 Swift Concurrency 的类型
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// ❌ 这一行导致 iOS 12 崩溃!
|
||||||
|
private var initializationContinuations: [CheckedContinuation<Void, Never>] = []
|
||||||
|
```
|
||||||
|
|
||||||
|
**为什么崩溃:**
|
||||||
|
1. `CheckedContinuation` 是 Swift Concurrency 的类型,需要 iOS 13+
|
||||||
|
2. 在 iOS 12 上,这个类型根本不存在
|
||||||
|
3. 当 Swift 创建 `BbbAdManager` 实例时,会先初始化所有存储属性
|
||||||
|
4. 尝试初始化包含 `CheckedContinuation` 的数组时,因为类型不存在而崩溃
|
||||||
|
5. 崩溃发生在进入 `init()` 方法之前,所以 `"XS- BbbAdManager init 开始"` 日志永远不会打印
|
||||||
|
|
||||||
|
## ✅ 已修复
|
||||||
|
|
||||||
|
### 修改 1: 替换 Swift Concurrency 类型
|
||||||
|
|
||||||
|
**文件:** `PlayBTopOn/playB/bbbAdManager.swift`
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// ❌ 旧代码(iOS 13+ 才能用)
|
||||||
|
private var initializationContinuations: [CheckedContinuation<Void, Never>] = []
|
||||||
|
|
||||||
|
// ✅ 新代码(iOS 12+ 都能用)
|
||||||
|
private var initializationCallbacks: [() -> Void] = []
|
||||||
|
```
|
||||||
|
|
||||||
|
### 修改 2: 更新 initAd 方法
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// 调用所有等待的回调(而不是 resume continuations)
|
||||||
|
for callback in self.initializationCallbacks {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
self.initializationCallbacks.removeAll()
|
||||||
|
```
|
||||||
|
|
||||||
|
### 修改 3: 简化 waitForSDKInitialization
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// 基于回调队列的简单实现,无需轮询
|
||||||
|
func waitForSDKInitialization(completion: @escaping () -> Void) {
|
||||||
|
if isSDKInitialized {
|
||||||
|
completion()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加到队列,initAd 完成时会调用
|
||||||
|
initializationCallbacks.append(completion)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎯 所有修复总结
|
||||||
|
|
||||||
|
| 问题 | 解决方案 | 状态 |
|
||||||
|
|------|---------|------|
|
||||||
|
| Task { await ... } | 改用 DispatchQueue + 回调 | ✅ 已修复 |
|
||||||
|
| AppTrackingTransparency 导入 | 使用 #if canImport() | ✅ 已修复 |
|
||||||
|
| async/await 函数 | 标记 @available(iOS 15.0, *) | ✅ 已修复 |
|
||||||
|
| CheckedContinuation 类型 | 改用普通闭包数组 | ✅ 已修复 |
|
||||||
|
| Deployment Target = 17.4 | 需改为 12.0 | ⚠️ 需手动操作 |
|
||||||
|
| ATT 框架链接 | 需设为 Optional | ⚠️ 需手动操作 |
|
||||||
|
|
||||||
|
## 📝 接下来必须做的事
|
||||||
|
|
||||||
|
### 1. 在 Xcode 中修改 Deployment Target(最重要!)
|
||||||
|
|
||||||
|
```
|
||||||
|
打开 PlayBTopOn.xcworkspace
|
||||||
|
↓
|
||||||
|
选择项目 PlayBTopOn
|
||||||
|
↓
|
||||||
|
选择 TARGETS → PlayBTopOn
|
||||||
|
↓
|
||||||
|
General → Deployment Info
|
||||||
|
↓
|
||||||
|
iOS Deployment Target: 17.4 → 12.0
|
||||||
|
```
|
||||||
|
|
||||||
|
**同时修改 PROJECT 的设置:**
|
||||||
|
```
|
||||||
|
选择 PROJECT → PlayBTopOn
|
||||||
|
↓
|
||||||
|
Build Settings → Deployment
|
||||||
|
↓
|
||||||
|
iOS Deployment Target: 17.4 → 12.0
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 设置 AppTrackingTransparency 为弱链接
|
||||||
|
|
||||||
|
```
|
||||||
|
TARGETS → PlayBTopOn
|
||||||
|
↓
|
||||||
|
Build Phases → Link Binary With Libraries
|
||||||
|
↓
|
||||||
|
找到 AppTrackingTransparency.framework
|
||||||
|
↓
|
||||||
|
Status: Required → Optional
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 重新安装 Pods
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /Users/mac/workspaces/projects/ios/build-ipa/ironSource/PlayBTopOn
|
||||||
|
pod install
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 清理并重新编译
|
||||||
|
|
||||||
|
在 Xcode 中:
|
||||||
|
1. Product → Clean Build Folder (Cmd+Shift+K)
|
||||||
|
2. Product → Build (Cmd+B)
|
||||||
|
3. Product → Run (Cmd+R)
|
||||||
|
|
||||||
|
## 🔍 验证日志
|
||||||
|
|
||||||
|
成功运行后,你应该看到完整的日志序列:
|
||||||
|
|
||||||
|
```
|
||||||
|
XS- app start: xxx
|
||||||
|
XS- app start 2: xxx
|
||||||
|
XS- YL_PlayVC viewDidLoad 开始
|
||||||
|
XS- app start 21: xxx
|
||||||
|
XS- 准备访问 BbbAdManager.shared
|
||||||
|
XS- 开始创建 BbbAdManager.config
|
||||||
|
XS- bConfig init 开始
|
||||||
|
XS- bConfig init: allAdIds count = 3
|
||||||
|
XS- bConfig init 完成
|
||||||
|
XS- BbbAdManager.config 创建完成
|
||||||
|
XS- 开始创建 BbbAdManager.shared 单例
|
||||||
|
XS- BbbAdManager init 开始 ← 之前卡在这里之前
|
||||||
|
XS- BbbAdManager init 完成 ← 现在应该能看到这个
|
||||||
|
XS- BbbAdManager.shared 单例创建完成
|
||||||
|
XS- 准备调用 initConfig()
|
||||||
|
XS- init config ← 现在应该能看到这个了!
|
||||||
|
XS- init config 1
|
||||||
|
XS- init config 2
|
||||||
|
XS- init config 3
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
## 💡 技术要点
|
||||||
|
|
||||||
|
### Swift Concurrency 与 iOS 版本
|
||||||
|
|
||||||
|
| 特性 | 最低版本 |
|
||||||
|
|------|---------|
|
||||||
|
| Task | iOS 15.0 |
|
||||||
|
| async/await | iOS 15.0 |
|
||||||
|
| CheckedContinuation | iOS 13.0 |
|
||||||
|
| AsyncStream | iOS 15.0 |
|
||||||
|
| @MainActor | iOS 15.0 |
|
||||||
|
|
||||||
|
### 为什么 @available 不够用?
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// ❌ 这样还是会崩溃!
|
||||||
|
@available(iOS 15.0, *)
|
||||||
|
private var continuation: CheckedContinuation<Void, Never>?
|
||||||
|
|
||||||
|
// 原因:属性声明在类加载时就会处理,
|
||||||
|
// @available 只能保护方法调用,无法保护类型本身的存在
|
||||||
|
```
|
||||||
|
|
||||||
|
### 正确的做法
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// ✅ 方法 1: 使用与旧版本兼容的类型
|
||||||
|
private var callbacks: [() -> Void] = []
|
||||||
|
|
||||||
|
// ✅ 方法 2: 使用条件编译(但会增加代码复杂度)
|
||||||
|
#if swift(>=5.5)
|
||||||
|
private var continuation: CheckedContinuation<Void, Never>?
|
||||||
|
#endif
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚀 完成标志
|
||||||
|
|
||||||
|
当你完成所有修改后:
|
||||||
|
|
||||||
|
- [ ] Deployment Target 已改为 12.0
|
||||||
|
- [ ] AppTrackingTransparency 已设为 Optional
|
||||||
|
- [ ] 运行 `pod install` 完成
|
||||||
|
- [ ] 清理并重新编译成功
|
||||||
|
- [ ] 在 iOS 12/13 模拟器或真机上运行成功
|
||||||
|
- [ ] 看到完整的日志输出,包括 "XS- init config"
|
||||||
|
|
||||||
|
## 📚 相关文档
|
||||||
|
|
||||||
|
- [iOS12_COMPATIBILITY_GUIDE.md](./iOS12_COMPATIBILITY_GUIDE.md) - 详细配置指南
|
||||||
|
- [DEBUG_CRASH_GUIDE.md](./DEBUG_CRASH_GUIDE.md) - 调试崩溃指南
|
||||||
|
- [CHANGES_SUMMARY.md](./CHANGES_SUMMARY.md) - 完整修改记录
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**关键修复完成时间:** 2025-01-01
|
||||||
|
**修复的根本问题:** Swift Concurrency 类型在 iOS 12 上不可用
|
||||||
|
**测试状态:** 代码已完成,待 Xcode 配置和测试
|
||||||
186
ironSource/PlayBTopOn/DEBUG_CRASH_GUIDE.md
Normal file
186
ironSource/PlayBTopOn/DEBUG_CRASH_GUIDE.md
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
# 调试崩溃问题指南
|
||||||
|
|
||||||
|
## 问题现象
|
||||||
|
`NSLog("XS- init config")` 这个日志都没有打印出来,说明应用在调用 `BbbAdManager.shared.initConfig()` 之前就崩溃了。
|
||||||
|
|
||||||
|
## 已添加的调试日志
|
||||||
|
|
||||||
|
### 1. AppDelegate.swift
|
||||||
|
```swift
|
||||||
|
NSLog("XS- app start 21") // 第 26 行
|
||||||
|
NSLog("XS- 准备访问 BbbAdManager.shared") // 新增
|
||||||
|
NSLog("XS- BbbAdManager.shared 访问成功") // 新增
|
||||||
|
NSLog("XS- 准备调用 initConfig()") // 新增
|
||||||
|
adManager.initConfig()
|
||||||
|
NSLog("XS- app start 3") // 原有
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. bbbAdManager.swift - bConfig 初始化
|
||||||
|
```swift
|
||||||
|
NSLog("XS- bConfig init 开始")
|
||||||
|
NSLog("XS- bConfig init: allAdIds count = ...")
|
||||||
|
NSLog("XS- bConfig init 完成")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. bbbAdManager.swift - BbbAdManager 初始化
|
||||||
|
```swift
|
||||||
|
NSLog("XS- 开始创建 BbbAdManager.config")
|
||||||
|
NSLog("XS- BbbAdManager.config 创建完成")
|
||||||
|
NSLog("XS- 开始创建 BbbAdManager.shared 单例")
|
||||||
|
NSLog("XS- BbbAdManager init 开始")
|
||||||
|
NSLog("XS- BbbAdManager init 完成")
|
||||||
|
NSLog("XS- BbbAdManager.shared 单例创建完成")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. bbbAdManager.swift - initConfig
|
||||||
|
```swift
|
||||||
|
NSLog("XS- init config") // 第一行
|
||||||
|
NSLog("XS- init config 1")
|
||||||
|
NSLog("XS- init config 2")
|
||||||
|
NSLog("XS- init config 3")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. YL_PlayVC.swift
|
||||||
|
```swift
|
||||||
|
NSLog("XS- YL_PlayVC viewDidLoad 开始")
|
||||||
|
NSLog("XS- YL_PlayVC 准备调用 waitForSDKInitialization")
|
||||||
|
NSLog("XS- YL_PlayVC waitForSDKInitialization 调用完成")
|
||||||
|
```
|
||||||
|
|
||||||
|
## 下一步操作
|
||||||
|
|
||||||
|
### 步骤 1: 更新 CocoaPods 依赖
|
||||||
|
|
||||||
|
我已经更新了 `Podfile`,将最低版本设置为 iOS 12.0:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /Users/mac/workspaces/projects/ios/build-ipa/ironSource/PlayBTopOn
|
||||||
|
pod install
|
||||||
|
```
|
||||||
|
|
||||||
|
### 步骤 2: 在 Xcode 中配置弱链接
|
||||||
|
|
||||||
|
**重要!这一步必须做,否则还是会崩溃:**
|
||||||
|
|
||||||
|
1. 打开 `PlayBTopOn.xcworkspace`
|
||||||
|
2. 选择项目 → TARGETS → PlayBTopOn
|
||||||
|
3. Build Phases → Link Binary With Libraries
|
||||||
|
4. 将 `AppTrackingTransparency.framework` 的 Status 改为 **Optional**
|
||||||
|
|
||||||
|
### 步骤 3: 清理并重新编译
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 在 Xcode 中:
|
||||||
|
# 1. Product -> Clean Build Folder (Cmd+Shift+K)
|
||||||
|
# 2. Product -> Build (Cmd+B)
|
||||||
|
# 3. Product -> Run (Cmd+R)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 步骤 4: 查看控制台日志
|
||||||
|
|
||||||
|
运行应用后,查看 Xcode 控制台的输出,找到最后打印的日志,就能确定崩溃发生在哪一步。
|
||||||
|
|
||||||
|
## 可能的崩溃原因
|
||||||
|
|
||||||
|
根据日志输出,可以判断崩溃原因:
|
||||||
|
|
||||||
|
### 场景 1: 看不到 "XS- 开始创建 BbbAdManager.config"
|
||||||
|
**原因:** 导入 `AnyThinkSDK` 或 `AnyThinkInterstitial` 时崩溃
|
||||||
|
**解决:** 这些 SDK 可能不支持 iOS 12/13,需要检查 SDK 文档或升级版本
|
||||||
|
|
||||||
|
### 场景 2: 看到 "XS- 开始创建 BbbAdManager.config" 但没有 "完成"
|
||||||
|
**原因:** `bConfig()` 初始化时崩溃
|
||||||
|
**解决:** 检查 `bConfig` 的 `init()` 方法中的代码
|
||||||
|
|
||||||
|
### 场景 3: 看到 "XS- BbbAdManager.config 创建完成" 但没有 "开始创建 shared"
|
||||||
|
**原因:** 在创建 `shared` 单例之前的某个地方崩溃
|
||||||
|
**解决:** 检查类级别的其他静态变量
|
||||||
|
|
||||||
|
### 场景 4: 看到 "XS- 开始创建 BbbAdManager.shared" 但没有 "init 完成"
|
||||||
|
**原因:** `BbbAdManager` 的 `init()` 方法中崩溃
|
||||||
|
**解决:** 检查 init 方法的代码
|
||||||
|
|
||||||
|
### 场景 5: 看到 "XS- 准备访问 BbbAdManager.shared" 但没有 "访问成功"
|
||||||
|
**原因:** 访问 `BbbAdManager.shared` 时触发初始化崩溃
|
||||||
|
**解决:** 检查静态变量的初始化顺序
|
||||||
|
|
||||||
|
### 场景 6: 看到 "XS- 准备调用 initConfig()" 但没有 "XS- init config"
|
||||||
|
**原因:** 调用 `initConfig()` 方法时崩溃
|
||||||
|
**解决:** 检查方法调用本身是否有问题
|
||||||
|
|
||||||
|
## 最可能的原因
|
||||||
|
|
||||||
|
根据经验,最可能的原因是:
|
||||||
|
|
||||||
|
### 1. 广告 SDK 不支持 iOS 12/13
|
||||||
|
TopOn (AnyThink) SDK 6.4.93 版本可能需要 iOS 13+ 或更高。
|
||||||
|
|
||||||
|
**验证方法:**
|
||||||
|
查看 Pods 目录下的 SDK 文档或 Info.plist:
|
||||||
|
```bash
|
||||||
|
cat Pods/TPNiOS/core/AnyThinkSDK.xcframework/Info.plist | grep MinimumOSVersion
|
||||||
|
```
|
||||||
|
|
||||||
|
**解决方案:**
|
||||||
|
- 如果 SDK 不支持 iOS 12,需要降级到支持的版本
|
||||||
|
- 或者将最低支持版本改为 iOS 13
|
||||||
|
|
||||||
|
### 2. AppTrackingTransparency 框架未设置为 Optional
|
||||||
|
这个必须在 Xcode 中手动设置(见上面步骤 2)
|
||||||
|
|
||||||
|
### 3. 某些广告 SDK 框架也需要弱链接
|
||||||
|
某些广告平台的 SDK 可能也包含 iOS 14+ 的 API,需要设置为 Optional
|
||||||
|
|
||||||
|
## 如何查看详细的崩溃信息
|
||||||
|
|
||||||
|
### 方法 1: Xcode 控制台
|
||||||
|
直接在 Xcode 底部的控制台查看崩溃信息
|
||||||
|
|
||||||
|
### 方法 2: 设置异常断点
|
||||||
|
1. Xcode → Breakpoint Navigator (⌘7)
|
||||||
|
2. 点击左下角 `+` → Exception Breakpoint
|
||||||
|
3. 运行应用,崩溃时会自动在崩溃处暂停
|
||||||
|
|
||||||
|
### 方法 3: 查看设备日志
|
||||||
|
1. Xcode → Window → Devices and Simulators
|
||||||
|
2. 选择你的设备
|
||||||
|
3. 点击 "Open Console" 查看系统日志
|
||||||
|
|
||||||
|
## 临时解决方案:提高最低版本
|
||||||
|
|
||||||
|
如果广告 SDK 确实不支持 iOS 12,可以临时将最低版本改为 iOS 13:
|
||||||
|
|
||||||
|
### Podfile
|
||||||
|
```ruby
|
||||||
|
platform :ios, '13.0'
|
||||||
|
```
|
||||||
|
|
||||||
|
### project.pbxproj (在 Xcode 中设置)
|
||||||
|
1. 项目设置 → General → Deployment Info
|
||||||
|
2. iOS Deployment Target 设置为 13.0
|
||||||
|
|
||||||
|
## 需要反馈的信息
|
||||||
|
|
||||||
|
请运行应用后,把控制台的输出(特别是所有 "XS-" 开头的日志)发给我,我可以帮你精确定位问题。
|
||||||
|
|
||||||
|
示例输出:
|
||||||
|
```
|
||||||
|
XS- app start: xxx
|
||||||
|
XS- app start 2: xxx
|
||||||
|
XS- YL_PlayVC viewDidLoad 开始
|
||||||
|
XS- app start 21: xxx
|
||||||
|
XS- 准备访问 BbbAdManager.shared
|
||||||
|
XS- 开始创建 BbbAdManager.config
|
||||||
|
XS- bConfig init 开始
|
||||||
|
XS- bConfig init: allAdIds count = 3
|
||||||
|
[崩溃] <--- 如果在这里崩溃,就说明问题出在 bConfig 的 init 方法中
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**总结:**
|
||||||
|
1. ✅ 已添加详细日志
|
||||||
|
2. ✅ 已更新 Podfile
|
||||||
|
3. ⚠️ 需要运行 `pod install`
|
||||||
|
4. ⚠️ 需要在 Xcode 中设置 AppTrackingTransparency 为 Optional
|
||||||
|
5. ⚠️ 重新编译运行,查看日志确定崩溃点
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// PTFakeMetaTouch.h
|
||||||
|
// PTFakeTouch
|
||||||
|
//
|
||||||
|
// Created by PugaTang on 16/4/20.
|
||||||
|
// Copyright © 2016年 PugaTang. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface PTFakeMetaTouch : NSObject
|
||||||
|
/**
|
||||||
|
* Fake a touch event 构造一个触屏基础操作
|
||||||
|
*
|
||||||
|
* @param pointId 触屏操作的序列号
|
||||||
|
* @param point 操作的目的位置
|
||||||
|
* @param phase 操作的类别
|
||||||
|
*
|
||||||
|
* @return pointId 返回操作的序列号
|
||||||
|
*/
|
||||||
|
+ (NSInteger)fakeTouchId:(NSInteger)pointId AtPoint:(CGPoint)point withTouchPhase:(UITouchPhase)phase;
|
||||||
|
/**
|
||||||
|
* Get a not used pointId 获取一个没有使用过的触屏序列号
|
||||||
|
*
|
||||||
|
* @return pointId 返回序列号
|
||||||
|
*/
|
||||||
|
+ (NSInteger)getAvailablePointId;
|
||||||
|
|
||||||
|
@end
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// FakeTouch.h
|
||||||
|
// FakeTouch
|
||||||
|
//
|
||||||
|
// Created by PugaTang on 16/4/7.
|
||||||
|
// Copyright © 2016年 PugaTang. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
#import <PTFakeTouch/PTFakeMetaTouch.h>
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define RLog(fmt, ...)
|
||||||
|
#define DLog(fmt, ...) NSLog((@"PThelper " fmt), ##__VA_ARGS__);
|
||||||
|
#else
|
||||||
|
#define DLog(fmt, ...)
|
||||||
|
#define RLog(fmt, ...) NSLog((@"PThelper " fmt), ##__VA_ARGS__);
|
||||||
|
#endif
|
||||||
BIN
ironSource/PlayBTopOn/PTFakeTouch.framework/Info.plist
Normal file
BIN
ironSource/PlayBTopOn/PTFakeTouch.framework/Info.plist
Normal file
Binary file not shown.
@ -0,0 +1,6 @@
|
|||||||
|
framework module PTFakeTouch {
|
||||||
|
umbrella header "PTFakeTouch.h"
|
||||||
|
|
||||||
|
export *
|
||||||
|
module * { export * }
|
||||||
|
}
|
||||||
BIN
ironSource/PlayBTopOn/PTFakeTouch.framework/PTFakeTouch
Normal file
BIN
ironSource/PlayBTopOn/PTFakeTouch.framework/PTFakeTouch
Normal file
Binary file not shown.
626
ironSource/PlayBTopOn/PlayBTopOn.xcodeproj/project.pbxproj
Normal file
626
ironSource/PlayBTopOn/PlayBTopOn.xcodeproj/project.pbxproj
Normal file
@ -0,0 +1,626 @@
|
|||||||
|
// !$*UTF8*$!
|
||||||
|
{
|
||||||
|
archiveVersion = 1;
|
||||||
|
classes = {
|
||||||
|
};
|
||||||
|
objectVersion = 56;
|
||||||
|
objects = {
|
||||||
|
|
||||||
|
/* Begin PBXBuildFile section */
|
||||||
|
0418CFC72EBA05FC00C88966 /* PTFakeTouch.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0418CFC52EBA054100C88966 /* PTFakeTouch.framework */; };
|
||||||
|
0418CFC82EBA05FC00C88966 /* PTFakeTouch.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 0418CFC52EBA054100C88966 /* PTFakeTouch.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
|
0418CFCB2EBA079900C88966 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0418CFCA2EBA079900C88966 /* IOKit.framework */; };
|
||||||
|
049B446F2DACAB6D0005EB66 /* GCDAsyncUdpSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 049B446A2DACAB6D0005EB66 /* GCDAsyncUdpSocket.m */; };
|
||||||
|
049B44702DACAB6D0005EB66 /* bbbAdManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 049B446E2DACAB6D0005EB66 /* bbbAdManager.swift */; };
|
||||||
|
049B44712DACAB6D0005EB66 /* XUDPClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 049B446D2DACAB6D0005EB66 /* XUDPClient.m */; };
|
||||||
|
04AB48AE2EFBE61900CCC40B /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04AB48AD2EFBE61900CCC40B /* AdSupport.framework */; };
|
||||||
|
04AB48B02EFBE62C00CCC40B /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04AB48AF2EFBE62C00CCC40B /* JavaScriptCore.framework */; };
|
||||||
|
04AB48B22EFBE63B00CCC40B /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04AB48B12EFBE63B00CCC40B /* WebKit.framework */; };
|
||||||
|
04AB48B42EFBE64300CCC40B /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04AB48B32EFBE64300CCC40B /* SystemConfiguration.framework */; };
|
||||||
|
04AB48B82EFBE7F600CCC40B /* IronSourceinterstitialAd.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04AB48B72EFBE7F600CCC40B /* IronSourceinterstitialAd.swift */; };
|
||||||
|
04AB48BC2EFBEA9D00CCC40B /* AdItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04AB48BB2EFBEA9D00CCC40B /* AdItem.swift */; };
|
||||||
|
755ADA202D2D25C600C9D994 /* getIphone.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755ADA1E2D2D25C600C9D994 /* getIphone.swift */; };
|
||||||
|
755ADA212D2D25C600C9D994 /* idfa.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755ADA1F2D2D25C600C9D994 /* idfa.swift */; };
|
||||||
|
75F8FFD12CE7233B008E8DF6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75F8FFD02CE7233B008E8DF6 /* AppDelegate.swift */; };
|
||||||
|
75F8FFD52CE7233B008E8DF6 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75F8FFD42CE7233B008E8DF6 /* ViewController.swift */; };
|
||||||
|
75F8FFD82CE7233B008E8DF6 /* Base in Resources */ = {isa = PBXBuildFile; fileRef = 75F8FFD72CE7233B008E8DF6 /* Base */; };
|
||||||
|
75F8FFDA2CE72340008E8DF6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 75F8FFD92CE72340008E8DF6 /* Assets.xcassets */; };
|
||||||
|
75F8FFDD2CE72340008E8DF6 /* Base in Resources */ = {isa = PBXBuildFile; fileRef = 75F8FFDC2CE72340008E8DF6 /* Base */; };
|
||||||
|
75F8FFE82CE723FF008E8DF6 /* YL_PlayVC.xib in Resources */ = {isa = PBXBuildFile; fileRef = 75F8FFE52CE723FE008E8DF6 /* YL_PlayVC.xib */; };
|
||||||
|
75F8FFE92CE723FF008E8DF6 /* YL_PlayVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75F8FFE62CE723FF008E8DF6 /* YL_PlayVC.swift */; };
|
||||||
|
75F8FFF32CE72555008E8DF6 /* initializationTopOn.m in Sources */ = {isa = PBXBuildFile; fileRef = 75F8FFF12CE72555008E8DF6 /* initializationTopOn.m */; };
|
||||||
|
75F8FFF72CE72B7D008E8DF6 /* YL_NetWorkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75F8FFF62CE72B7D008E8DF6 /* YL_NetWorkManager.swift */; };
|
||||||
|
84921A6E873B758EF39EBDFA /* Pods_PlayBTopOn.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33A6D387585D55B3F340F5DB /* Pods_PlayBTopOn.framework */; };
|
||||||
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
|
0418CFC92EBA05FC00C88966 /* Embed Frameworks */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = "";
|
||||||
|
dstSubfolderSpec = 10;
|
||||||
|
files = (
|
||||||
|
0418CFC82EBA05FC00C88966 /* PTFakeTouch.framework in Embed Frameworks */,
|
||||||
|
);
|
||||||
|
name = "Embed Frameworks";
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXFileReference section */
|
||||||
|
0418CFC52EBA054100C88966 /* PTFakeTouch.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = PTFakeTouch.framework; sourceTree = "<group>"; };
|
||||||
|
0418CFCA2EBA079900C88966 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
|
||||||
|
049B44682DACAB6D0005EB66 /* CocoaAsyncSocket.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CocoaAsyncSocket.h; sourceTree = "<group>"; };
|
||||||
|
049B44692DACAB6D0005EB66 /* GCDAsyncUdpSocket.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GCDAsyncUdpSocket.h; sourceTree = "<group>"; };
|
||||||
|
049B446A2DACAB6D0005EB66 /* GCDAsyncUdpSocket.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GCDAsyncUdpSocket.m; sourceTree = "<group>"; };
|
||||||
|
049B446C2DACAB6D0005EB66 /* XUDPClient.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XUDPClient.h; sourceTree = "<group>"; };
|
||||||
|
049B446D2DACAB6D0005EB66 /* XUDPClient.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XUDPClient.m; sourceTree = "<group>"; };
|
||||||
|
049B446E2DACAB6D0005EB66 /* bbbAdManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = bbbAdManager.swift; sourceTree = "<group>"; };
|
||||||
|
04AB48AD2EFBE61900CCC40B /* AdSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdSupport.framework; path = System/Library/Frameworks/AdSupport.framework; sourceTree = SDKROOT; };
|
||||||
|
04AB48AF2EFBE62C00CCC40B /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
||||||
|
04AB48B12EFBE63B00CCC40B /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
|
||||||
|
04AB48B32EFBE64300CCC40B /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
|
||||||
|
04AB48B52EFBE65500CCC40B /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; };
|
||||||
|
04AB48B62EFBE66800CCC40B /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
|
||||||
|
04AB48B72EFBE7F600CCC40B /* IronSourceinterstitialAd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IronSourceinterstitialAd.swift; sourceTree = "<group>"; };
|
||||||
|
04AB48BB2EFBEA9D00CCC40B /* AdItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdItem.swift; sourceTree = "<group>"; };
|
||||||
|
33A6D387585D55B3F340F5DB /* Pods_PlayBTopOn.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PlayBTopOn.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
6297C68F5F2E4537B6CB3D1C /* Pods-PlayBTopOn.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PlayBTopOn.debug.xcconfig"; path = "Target Support Files/Pods-PlayBTopOn/Pods-PlayBTopOn.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
755ADA1E2D2D25C600C9D994 /* getIphone.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = getIphone.swift; sourceTree = "<group>"; };
|
||||||
|
755ADA1F2D2D25C600C9D994 /* idfa.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = idfa.swift; sourceTree = "<group>"; };
|
||||||
|
75F8FFCD2CE7233B008E8DF6 /* PlayBTopOn.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PlayBTopOn.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
75F8FFD02CE7233B008E8DF6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
|
75F8FFD42CE7233B008E8DF6 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
|
||||||
|
75F8FFD72CE7233B008E8DF6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||||
|
75F8FFD92CE72340008E8DF6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
|
75F8FFDC2CE72340008E8DF6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||||
|
75F8FFDE2CE72340008E8DF6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
|
75F8FFE52CE723FE008E8DF6 /* YL_PlayVC.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = YL_PlayVC.xib; sourceTree = "<group>"; };
|
||||||
|
75F8FFE62CE723FF008E8DF6 /* YL_PlayVC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = YL_PlayVC.swift; sourceTree = "<group>"; };
|
||||||
|
75F8FFEE2CE7250B008E8DF6 /* MyWallPaperHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyWallPaperHeader.h; sourceTree = "<group>"; };
|
||||||
|
75F8FFEF2CE7250B008E8DF6 /* MyWallpaperPCH.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyWallpaperPCH.pch; sourceTree = "<group>"; };
|
||||||
|
75F8FFF12CE72555008E8DF6 /* initializationTopOn.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = initializationTopOn.m; sourceTree = "<group>"; };
|
||||||
|
75F8FFF22CE72555008E8DF6 /* initializationTopOn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = initializationTopOn.h; sourceTree = "<group>"; };
|
||||||
|
75F8FFF62CE72B7D008E8DF6 /* YL_NetWorkManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = YL_NetWorkManager.swift; sourceTree = "<group>"; };
|
||||||
|
B423D6A110C2422F79FE6615 /* Pods-PlayBTopOn.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PlayBTopOn.release.xcconfig"; path = "Target Support Files/Pods-PlayBTopOn/Pods-PlayBTopOn.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
75F8FFCA2CE7233B008E8DF6 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
84921A6E873B758EF39EBDFA /* Pods_PlayBTopOn.framework in Frameworks */,
|
||||||
|
04AB48B42EFBE64300CCC40B /* SystemConfiguration.framework in Frameworks */,
|
||||||
|
04AB48AE2EFBE61900CCC40B /* AdSupport.framework in Frameworks */,
|
||||||
|
04AB48B22EFBE63B00CCC40B /* WebKit.framework in Frameworks */,
|
||||||
|
04AB48B02EFBE62C00CCC40B /* JavaScriptCore.framework in Frameworks */,
|
||||||
|
0418CFC72EBA05FC00C88966 /* PTFakeTouch.framework in Frameworks */,
|
||||||
|
0418CFCB2EBA079900C88966 /* IOKit.framework in Frameworks */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXGroup section */
|
||||||
|
049B446B2DACAB6D0005EB66 /* GCD */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
049B44692DACAB6D0005EB66 /* GCDAsyncUdpSocket.h */,
|
||||||
|
049B446A2DACAB6D0005EB66 /* GCDAsyncUdpSocket.m */,
|
||||||
|
);
|
||||||
|
path = GCD;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
75F8FFC42CE7233B008E8DF6 = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
75F8FFCF2CE7233B008E8DF6 /* PlayBTopOn */,
|
||||||
|
75F8FFCE2CE7233B008E8DF6 /* Products */,
|
||||||
|
CFE0CCAD1DCDC6DF946C8994 /* Pods */,
|
||||||
|
EC17E36934C0C7C23F86C29A /* Frameworks */,
|
||||||
|
);
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
75F8FFCE2CE7233B008E8DF6 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
75F8FFCD2CE7233B008E8DF6 /* PlayBTopOn.app */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
75F8FFCF2CE7233B008E8DF6 /* PlayBTopOn */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
75F8FFF02CE7250B008E8DF6 /* Header */,
|
||||||
|
75F8FFE42CE723E7008E8DF6 /* playB */,
|
||||||
|
75F8FFD02CE7233B008E8DF6 /* AppDelegate.swift */,
|
||||||
|
75F8FFD42CE7233B008E8DF6 /* ViewController.swift */,
|
||||||
|
75F8FFD62CE7233B008E8DF6 /* Main.storyboard */,
|
||||||
|
75F8FFD92CE72340008E8DF6 /* Assets.xcassets */,
|
||||||
|
75F8FFDB2CE72340008E8DF6 /* LaunchScreen.storyboard */,
|
||||||
|
75F8FFDE2CE72340008E8DF6 /* Info.plist */,
|
||||||
|
);
|
||||||
|
path = PlayBTopOn;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
75F8FFE42CE723E7008E8DF6 /* playB */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
049B44682DACAB6D0005EB66 /* CocoaAsyncSocket.h */,
|
||||||
|
049B446B2DACAB6D0005EB66 /* GCD */,
|
||||||
|
049B446C2DACAB6D0005EB66 /* XUDPClient.h */,
|
||||||
|
049B446D2DACAB6D0005EB66 /* XUDPClient.m */,
|
||||||
|
049B446E2DACAB6D0005EB66 /* bbbAdManager.swift */,
|
||||||
|
755ADA1E2D2D25C600C9D994 /* getIphone.swift */,
|
||||||
|
755ADA1F2D2D25C600C9D994 /* idfa.swift */,
|
||||||
|
75F8FFF62CE72B7D008E8DF6 /* YL_NetWorkManager.swift */,
|
||||||
|
75F8FFF22CE72555008E8DF6 /* initializationTopOn.h */,
|
||||||
|
75F8FFF12CE72555008E8DF6 /* initializationTopOn.m */,
|
||||||
|
75F8FFE62CE723FF008E8DF6 /* YL_PlayVC.swift */,
|
||||||
|
75F8FFE52CE723FE008E8DF6 /* YL_PlayVC.xib */,
|
||||||
|
04AB48B72EFBE7F600CCC40B /* IronSourceinterstitialAd.swift */,
|
||||||
|
04AB48BB2EFBEA9D00CCC40B /* AdItem.swift */,
|
||||||
|
);
|
||||||
|
path = playB;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
75F8FFF02CE7250B008E8DF6 /* Header */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
75F8FFEE2CE7250B008E8DF6 /* MyWallPaperHeader.h */,
|
||||||
|
75F8FFEF2CE7250B008E8DF6 /* MyWallpaperPCH.pch */,
|
||||||
|
);
|
||||||
|
path = Header;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
CFE0CCAD1DCDC6DF946C8994 /* Pods */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
6297C68F5F2E4537B6CB3D1C /* Pods-PlayBTopOn.debug.xcconfig */,
|
||||||
|
B423D6A110C2422F79FE6615 /* Pods-PlayBTopOn.release.xcconfig */,
|
||||||
|
);
|
||||||
|
path = Pods;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
EC17E36934C0C7C23F86C29A /* Frameworks */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
04AB48B62EFBE66800CCC40B /* libz.tbd */,
|
||||||
|
04AB48B52EFBE65500CCC40B /* libsqlite3.tbd */,
|
||||||
|
04AB48B32EFBE64300CCC40B /* SystemConfiguration.framework */,
|
||||||
|
04AB48B12EFBE63B00CCC40B /* WebKit.framework */,
|
||||||
|
04AB48AF2EFBE62C00CCC40B /* JavaScriptCore.framework */,
|
||||||
|
04AB48AD2EFBE61900CCC40B /* AdSupport.framework */,
|
||||||
|
0418CFCA2EBA079900C88966 /* IOKit.framework */,
|
||||||
|
0418CFC52EBA054100C88966 /* PTFakeTouch.framework */,
|
||||||
|
33A6D387585D55B3F340F5DB /* Pods_PlayBTopOn.framework */,
|
||||||
|
);
|
||||||
|
name = Frameworks;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXGroup section */
|
||||||
|
|
||||||
|
/* Begin PBXNativeTarget section */
|
||||||
|
75F8FFCC2CE7233B008E8DF6 /* PlayBTopOn */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 75F8FFE12CE72340008E8DF6 /* Build configuration list for PBXNativeTarget "PlayBTopOn" */;
|
||||||
|
buildPhases = (
|
||||||
|
9FD2AE384D5FEDF5FF939DD1 /* [CP] Check Pods Manifest.lock */,
|
||||||
|
75F8FFC92CE7233B008E8DF6 /* Sources */,
|
||||||
|
75F8FFCA2CE7233B008E8DF6 /* Frameworks */,
|
||||||
|
75F8FFCB2CE7233B008E8DF6 /* Resources */,
|
||||||
|
C0554906157B58199E7A6576 /* [CP] Copy Pods Resources */,
|
||||||
|
0418CFC92EBA05FC00C88966 /* Embed Frameworks */,
|
||||||
|
A8C0CAD2265AD3CE1CC35C98 /* [CP] Embed Pods Frameworks */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = PlayBTopOn;
|
||||||
|
productName = PlayBTopOn;
|
||||||
|
productReference = 75F8FFCD2CE7233B008E8DF6 /* PlayBTopOn.app */;
|
||||||
|
productType = "com.apple.product-type.application";
|
||||||
|
};
|
||||||
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
|
/* Begin PBXProject section */
|
||||||
|
75F8FFC52CE7233B008E8DF6 /* Project object */ = {
|
||||||
|
isa = PBXProject;
|
||||||
|
attributes = {
|
||||||
|
BuildIndependentTargetsInParallel = 1;
|
||||||
|
LastSwiftUpdateCheck = 1530;
|
||||||
|
LastUpgradeCheck = 1530;
|
||||||
|
TargetAttributes = {
|
||||||
|
75F8FFCC2CE7233B008E8DF6 = {
|
||||||
|
CreatedOnToolsVersion = 15.3;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
buildConfigurationList = 75F8FFC82CE7233B008E8DF6 /* Build configuration list for PBXProject "PlayBTopOn" */;
|
||||||
|
compatibilityVersion = "Xcode 14.0";
|
||||||
|
developmentRegion = en;
|
||||||
|
hasScannedForEncodings = 0;
|
||||||
|
knownRegions = (
|
||||||
|
en,
|
||||||
|
Base,
|
||||||
|
);
|
||||||
|
mainGroup = 75F8FFC42CE7233B008E8DF6;
|
||||||
|
productRefGroup = 75F8FFCE2CE7233B008E8DF6 /* Products */;
|
||||||
|
projectDirPath = "";
|
||||||
|
projectRoot = "";
|
||||||
|
targets = (
|
||||||
|
75F8FFCC2CE7233B008E8DF6 /* PlayBTopOn */,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
/* End PBXProject section */
|
||||||
|
|
||||||
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
|
75F8FFCB2CE7233B008E8DF6 /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
75F8FFDA2CE72340008E8DF6 /* Assets.xcassets in Resources */,
|
||||||
|
75F8FFE82CE723FF008E8DF6 /* YL_PlayVC.xib in Resources */,
|
||||||
|
75F8FFDD2CE72340008E8DF6 /* Base in Resources */,
|
||||||
|
75F8FFD82CE7233B008E8DF6 /* Base in Resources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
|
9FD2AE384D5FEDF5FF939DD1 /* [CP] Check Pods Manifest.lock */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||||
|
"${PODS_ROOT}/Manifest.lock",
|
||||||
|
);
|
||||||
|
name = "[CP] Check Pods Manifest.lock";
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
"$(DERIVED_FILE_DIR)/Pods-PlayBTopOn-checkManifestLockResult.txt",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
A8C0CAD2265AD3CE1CC35C98 /* [CP] Embed Pods Frameworks */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-PlayBTopOn/Pods-PlayBTopOn-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
name = "[CP] Embed Pods Frameworks";
|
||||||
|
outputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-PlayBTopOn/Pods-PlayBTopOn-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PlayBTopOn/Pods-PlayBTopOn-frameworks.sh\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
C0554906157B58199E7A6576 /* [CP] Copy Pods Resources */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-PlayBTopOn/Pods-PlayBTopOn-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
name = "[CP] Copy Pods Resources";
|
||||||
|
outputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-PlayBTopOn/Pods-PlayBTopOn-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PlayBTopOn/Pods-PlayBTopOn-resources.sh\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
75F8FFC92CE7233B008E8DF6 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
75F8FFF72CE72B7D008E8DF6 /* YL_NetWorkManager.swift in Sources */,
|
||||||
|
755ADA212D2D25C600C9D994 /* idfa.swift in Sources */,
|
||||||
|
04AB48B82EFBE7F600CCC40B /* IronSourceinterstitialAd.swift in Sources */,
|
||||||
|
75F8FFF32CE72555008E8DF6 /* initializationTopOn.m in Sources */,
|
||||||
|
049B446F2DACAB6D0005EB66 /* GCDAsyncUdpSocket.m in Sources */,
|
||||||
|
049B44702DACAB6D0005EB66 /* bbbAdManager.swift in Sources */,
|
||||||
|
049B44712DACAB6D0005EB66 /* XUDPClient.m in Sources */,
|
||||||
|
75F8FFE92CE723FF008E8DF6 /* YL_PlayVC.swift in Sources */,
|
||||||
|
75F8FFD52CE7233B008E8DF6 /* ViewController.swift in Sources */,
|
||||||
|
755ADA202D2D25C600C9D994 /* getIphone.swift in Sources */,
|
||||||
|
75F8FFD12CE7233B008E8DF6 /* AppDelegate.swift in Sources */,
|
||||||
|
04AB48BC2EFBEA9D00CCC40B /* AdItem.swift in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXVariantGroup section */
|
||||||
|
75F8FFD62CE7233B008E8DF6 /* Main.storyboard */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
75F8FFD72CE7233B008E8DF6 /* Base */,
|
||||||
|
);
|
||||||
|
name = Main.storyboard;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
75F8FFDB2CE72340008E8DF6 /* LaunchScreen.storyboard */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
75F8FFDC2CE72340008E8DF6 /* Base */,
|
||||||
|
);
|
||||||
|
name = LaunchScreen.storyboard;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXVariantGroup section */
|
||||||
|
|
||||||
|
/* Begin XCBuildConfiguration section */
|
||||||
|
75F8FFDF2CE72340008E8DF6 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_TESTABILITY = YES;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"DEBUG=1",
|
||||||
|
"$(inherited)",
|
||||||
|
);
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 17.4;
|
||||||
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
75F8FFE02CE72340008E8DF6 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 17.4;
|
||||||
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
|
VALIDATE_PRODUCT = YES;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
75F8FFE22CE72340008E8DF6 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 6297C68F5F2E4537B6CB3D1C /* Pods-PlayBTopOn.debug.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
|
CODE_SIGNING_ALLOWED = NO;
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||||
|
CODE_SIGN_STYLE = Manual;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 33FNMTSNA6;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||||
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"$(PROJECT_DIR)",
|
||||||
|
);
|
||||||
|
GCC_PREFIX_HEADER = "$(SRCROOT)/PlayBTopOn/Header/MyWallpaperPCH.pch";
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = PlayBTopOn/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = TastePick;
|
||||||
|
INFOPLIST_KEY_NSUserTrackingUsageDescription = "\"\" needs to request tracking permissions to provide a personalized advertising experience. We respect and protect your privacy and will not sell your data to third parties.";
|
||||||
|
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||||
|
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
|
||||||
|
INFOPLIST_KEY_UIMainStoryboardFile = Main;
|
||||||
|
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
|
||||||
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.1;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.TastePickEatWheel.TastePickEatWheel;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = smart;
|
||||||
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
|
SUPPORTS_MACCATALYST = NO;
|
||||||
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
|
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/PlayBTopOn/Header/MyWallPaperHeader.h";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = 1;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
75F8FFE32CE72340008E8DF6 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = B423D6A110C2422F79FE6615 /* Pods-PlayBTopOn.release.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
|
CODE_SIGNING_ALLOWED = NO;
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||||
|
CODE_SIGN_STYLE = Manual;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 33FNMTSNA6;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||||
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"$(PROJECT_DIR)",
|
||||||
|
);
|
||||||
|
GCC_PREFIX_HEADER = "$(SRCROOT)/PlayBTopOn/Header/MyWallpaperPCH.pch";
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = PlayBTopOn/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = TastePick;
|
||||||
|
INFOPLIST_KEY_NSUserTrackingUsageDescription = "\"\" needs to request tracking permissions to provide a personalized advertising experience. We respect and protect your privacy and will not sell your data to third parties.";
|
||||||
|
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||||
|
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
|
||||||
|
INFOPLIST_KEY_UIMainStoryboardFile = Main;
|
||||||
|
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
|
||||||
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.1;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.TastePickEatWheel.TastePickEatWheel;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = smart;
|
||||||
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
|
SUPPORTS_MACCATALYST = NO;
|
||||||
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
|
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
|
SWIFT_COMPILATION_MODE = singlefile;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/PlayBTopOn/Header/MyWallPaperHeader.h";
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = 1;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
|
/* Begin XCConfigurationList section */
|
||||||
|
75F8FFC82CE7233B008E8DF6 /* Build configuration list for PBXProject "PlayBTopOn" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
75F8FFDF2CE72340008E8DF6 /* Debug */,
|
||||||
|
75F8FFE02CE72340008E8DF6 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
75F8FFE12CE72340008E8DF6 /* Build configuration list for PBXNativeTarget "PlayBTopOn" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
75F8FFE22CE72340008E8DF6 /* Debug */,
|
||||||
|
75F8FFE32CE72340008E8DF6 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
/* End XCConfigurationList section */
|
||||||
|
};
|
||||||
|
rootObject = 75F8FFC52CE7233B008E8DF6 /* Project object */;
|
||||||
|
}
|
||||||
7
ironSource/PlayBTopOn/PlayBTopOn.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
ironSource/PlayBTopOn/PlayBTopOn.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
<FileRef
|
||||||
|
location = "self:">
|
||||||
|
</FileRef>
|
||||||
|
</Workspace>
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
<?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>IDEDidComputeMac32BitWarning</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
Binary file not shown.
@ -0,0 +1,14 @@
|
|||||||
|
<?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>SchemeUserState</key>
|
||||||
|
<dict>
|
||||||
|
<key>PlayBTopOn.xcscheme_^#shared#^_</key>
|
||||||
|
<dict>
|
||||||
|
<key>orderHint</key>
|
||||||
|
<integer>24</integer>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
<?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>SchemeUserState</key>
|
||||||
|
<dict>
|
||||||
|
<key>PlayBTopOn.xcscheme_^#shared#^_</key>
|
||||||
|
<dict>
|
||||||
|
<key>orderHint</key>
|
||||||
|
<integer>8</integer>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
10
ironSource/PlayBTopOn/PlayBTopOn.xcworkspace/contents.xcworkspacedata
generated
Normal file
10
ironSource/PlayBTopOn/PlayBTopOn.xcworkspace/contents.xcworkspacedata
generated
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
<FileRef
|
||||||
|
location = "group:PlayBTopOn.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
|
<FileRef
|
||||||
|
location = "group:Pods/Pods.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
|
</Workspace>
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
<?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>IDEDidComputeMac32BitWarning</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
BIN
ironSource/PlayBTopOn/PlayBTopOn.xcworkspace/xcuserdata/mac.xcuserdatad/UserInterfaceState.xcuserstate
generated
Normal file
BIN
ironSource/PlayBTopOn/PlayBTopOn.xcworkspace/xcuserdata/mac.xcuserdatad/UserInterfaceState.xcuserstate
generated
Normal file
Binary file not shown.
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Bucket
|
||||||
|
uuid = "F580337E-D970-439A-865D-31DED727615B"
|
||||||
|
type = "0"
|
||||||
|
version = "2.0">
|
||||||
|
<Breakpoints>
|
||||||
|
<BreakpointProxy
|
||||||
|
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||||
|
<BreakpointContent
|
||||||
|
uuid = "498D5B14-B3EB-4D48-BC25-8003C96FDC05"
|
||||||
|
shouldBeEnabled = "No"
|
||||||
|
ignoreCount = "0"
|
||||||
|
continueAfterRunningActions = "No"
|
||||||
|
filePath = "PlayBTopOn/playB/initializationTopOn.m"
|
||||||
|
startingColumnNumber = "9223372036854775807"
|
||||||
|
endingColumnNumber = "9223372036854775807"
|
||||||
|
startingLineNumber = "236"
|
||||||
|
endingLineNumber = "236"
|
||||||
|
landmarkName = "+findFullScreenPresenterInViewController:"
|
||||||
|
landmarkType = "7">
|
||||||
|
</BreakpointContent>
|
||||||
|
</BreakpointProxy>
|
||||||
|
</Breakpoints>
|
||||||
|
</Bucket>
|
||||||
Binary file not shown.
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Bucket
|
||||||
|
uuid = "2E5813EB-D56F-4286-86F7-D2DFA67869D4"
|
||||||
|
type = "0"
|
||||||
|
version = "2.0">
|
||||||
|
</Bucket>
|
||||||
54
ironSource/PlayBTopOn/PlayBTopOn/AppDelegate.swift
Normal file
54
ironSource/PlayBTopOn/PlayBTopOn/AppDelegate.swift
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
//
|
||||||
|
// AppDelegate.swift
|
||||||
|
// PlayBTopOn
|
||||||
|
//
|
||||||
|
// Created by 忆海16 on 2024/11/15.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
@main
|
||||||
|
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
|
|
||||||
|
static var shared: AppDelegate {
|
||||||
|
return UIApplication.shared.delegate as! AppDelegate
|
||||||
|
}
|
||||||
|
static let appid = UUID().uuidString
|
||||||
|
var window:UIWindow?
|
||||||
|
|
||||||
|
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||||
|
window = UIWindow()
|
||||||
|
window?.frame = UIScreen.main.bounds
|
||||||
|
NSLog("XS- app start:\(AppDelegate.appid)")
|
||||||
|
let vc = YL_PlayVC()
|
||||||
|
NSLog("XS- app start 2:\(AppDelegate.appid)")
|
||||||
|
window?.rootViewController = UINavigationController(rootViewController: vc)
|
||||||
|
NSLog("XS- app start 21:\(AppDelegate.appid)")
|
||||||
|
|
||||||
|
// 添加详细日志来定位崩溃点
|
||||||
|
NSLog("XS- 准备访问 BbbAdManager.shared")
|
||||||
|
let adManager = BbbAdManager.shared
|
||||||
|
NSLog("XS- BbbAdManager.shared 访问成功")
|
||||||
|
|
||||||
|
NSLog("XS- 准备调用 initConfig()")
|
||||||
|
adManager.initConfig()
|
||||||
|
NSLog("XS- app start 3:\(AppDelegate.appid)")
|
||||||
|
// 异步初始化广告 SDK(兼容 iOS 12+)
|
||||||
|
DispatchQueue.global(qos: .userInitiated).async {
|
||||||
|
NSLog("XS- app start 4:\(AppDelegate.appid)")
|
||||||
|
BbbAdManager.shared.initAd()
|
||||||
|
}
|
||||||
|
NSLog("XS- app start 5:\(AppDelegate.appid)")
|
||||||
|
window?.makeKeyAndVisible()
|
||||||
|
NSLog("XS- app start 6:\(AppDelegate.appid)")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func applicationWillEnterForeground(_ application: UIApplication) {
|
||||||
|
print("应用从后台进入前台")
|
||||||
|
BbbAdManager.shared.closeAd(v: 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "h687603756335b.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"platform" : "ios",
|
||||||
|
"size" : "1024x1024"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 179 KiB |
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||||
|
<dependencies>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
|
||||||
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<scenes>
|
||||||
|
<!--View Controller-->
|
||||||
|
<scene sceneID="EHf-IW-A2E">
|
||||||
|
<objects>
|
||||||
|
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||||
|
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||||
|
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
||||||
|
</view>
|
||||||
|
</viewController>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
<point key="canvasLocation" x="53" y="375"/>
|
||||||
|
</scene>
|
||||||
|
</scenes>
|
||||||
|
</document>
|
||||||
24
ironSource/PlayBTopOn/PlayBTopOn/Base.lproj/Main.storyboard
Normal file
24
ironSource/PlayBTopOn/PlayBTopOn/Base.lproj/Main.storyboard
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
|
||||||
|
<dependencies>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
|
||||||
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<scenes>
|
||||||
|
<!--View Controller-->
|
||||||
|
<scene sceneID="tne-QT-ifu">
|
||||||
|
<objects>
|
||||||
|
<viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
|
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||||
|
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
||||||
|
</view>
|
||||||
|
</viewController>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
</scene>
|
||||||
|
</scenes>
|
||||||
|
</document>
|
||||||
15
ironSource/PlayBTopOn/PlayBTopOn/Header/MyWallPaperHeader.h
Normal file
15
ironSource/PlayBTopOn/PlayBTopOn/Header/MyWallPaperHeader.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// MyWallPaperHeader.h
|
||||||
|
// Mywallpaper
|
||||||
|
//
|
||||||
|
// Created by 忆海16 on 2024/8/1.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef MyWallPaperHeader_h
|
||||||
|
#define MyWallPaperHeader_h
|
||||||
|
|
||||||
|
#import "initializationTopOn.h"
|
||||||
|
#import "XUDPClient.h"
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* MyWallPaperHeader_h */
|
||||||
14
ironSource/PlayBTopOn/PlayBTopOn/Header/MyWallpaperPCH.pch
Normal file
14
ironSource/PlayBTopOn/PlayBTopOn/Header/MyWallpaperPCH.pch
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// MyWallpaperPCH.pch
|
||||||
|
// Mywallpaper
|
||||||
|
//
|
||||||
|
// Created by 忆海16 on 2024/8/1.
|
||||||
|
//
|
||||||
|
#import "PlayBTopOn-Swift.h"
|
||||||
|
#ifndef MyWallpaperPCH_pch
|
||||||
|
#define MyWallpaperPCH_pch
|
||||||
|
|
||||||
|
// Include any system framework and library headers here that should be included in all compilation units.
|
||||||
|
// You will also need to set the Prefix Header build setting of one or more of your targets to reference this file.
|
||||||
|
|
||||||
|
#endif /* MyWallpaperPCH_pch */
|
||||||
694
ironSource/PlayBTopOn/PlayBTopOn/Info.plist
Normal file
694
ironSource/PlayBTopOn/PlayBTopOn/Info.plist
Normal file
@ -0,0 +1,694 @@
|
|||||||
|
<?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>LSApplicationQueriesSchemes</key>
|
||||||
|
<array>
|
||||||
|
<string>taobao</string>
|
||||||
|
<string>pinduoduo</string>
|
||||||
|
<string>openapp.jdmobile</string>
|
||||||
|
<string>imeituan</string>
|
||||||
|
<string>iosamap</string>
|
||||||
|
<string>alipay</string>
|
||||||
|
<string>baiduboxapp</string>
|
||||||
|
<string>vipshop</string>
|
||||||
|
<string>tmall</string>
|
||||||
|
<string>meituanwaimai</string>
|
||||||
|
<string>kwai</string>
|
||||||
|
<string>eleme</string>
|
||||||
|
<string>xhsdiscover</string>
|
||||||
|
<string>ksnebula</string>
|
||||||
|
<string>sinaweibo</string>
|
||||||
|
<string>fleamarket</string>
|
||||||
|
<string>id6443575749</string>
|
||||||
|
<string>com.pwrd.zhuxian2.zs</string>
|
||||||
|
<string>baiduboxlite</string>
|
||||||
|
<string>wireless1688</string>
|
||||||
|
<string>iqiyi</string>
|
||||||
|
<string>weixin</string>
|
||||||
|
<string>taobaotravel</string>
|
||||||
|
<string>alipays</string>
|
||||||
|
<string>youku</string>
|
||||||
|
</array>
|
||||||
|
<key>NSAppTransportSecurity</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSAllowsArbitraryLoads</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>SKAdNetworkItems</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>4w7y6s5ca2.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>44jx6755aq.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>9rd848q2bz.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>tl55sbb4fm.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>9t245vhmpl.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>a8cz6cu7e5.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>424m5254lk.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>wg4vff78zm.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>n9x2a789qt.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>s39g8k73mm.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>prcb7njmu6.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>238da6jt44.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>mlmmfzh3r3.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>mj797d8u6f.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>vhf287vqwu.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>5l3tpt7t6e.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>hs6bdukanm.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>wzmmz9fp6w.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>f38h382jlk.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>glqzh8vgby.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>5a6flpkh64.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>294l99pt4k.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>c6k4g5qg8m.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>4fzdc2evr5.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>x44k69ngh6.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>p78axxw29g.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>k6y4y55b64.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>5f5u5tfb26.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>7ug5zh24hu.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>f7s53z58qe.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>488r3q3dtq.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>t38b2kh725.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>e5fvkxwrpn.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>3qy4746246.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>32z4fx6l9h.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>9nlqeag3gk.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>m8dbw4sv7c.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>97r2b46745.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>4pfyvq9l8r.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>w9q455wk68.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>yclnxrl5pm.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>zmvfpc5aq8.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>xga6mpmplv.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>5tjdwbrq8w.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>cstr6suwn9.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>5lm9lj6jb7.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>22mmun2rn5.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>ppxm28t8ap.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>f73kdq92p3.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>v9wttpbfk9.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>3sh42y64q3.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>v79kvwwj4g.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>ydx93a7ass.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>k674qkevps.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>av6w8kgt66.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>578prtvx9j.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>uw77j35x4d.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>8s468mfl3y.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>pwa73g5rt2.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>3rd42ekr43.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>4dzt52r2t5.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>feyaarzu9v.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>g6gcrrvk4p.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>lr83yxwka7.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>2u9pt9hc89.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>v72qych5uu.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>mqn7fxpca7.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>kbd757ywx3.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>2fnua5tdw4.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>6yxyv74ff7.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>klf5c3l5u5.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>mp6xlyr22a.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>4468km3ulz.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>a2p9lx4jpn.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>zq492l623r.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>mls7yz5dvl.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>cg4yq2srnc.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>737z793b9f.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>6xzpu9s2p8.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>ludvb6z3bs.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>523jb4fst2.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>ggvn48r87g.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>24t9a8vw3c.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>cj5566h2ga.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>7rz58n8ntl.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>ejvt5qm6ak.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>dzg6xy7pwj.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>y45688jllp.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>hdw39hrw9y.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>mtkv5xtk9e.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>gta9lk7p23.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>g28c52eehv.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>su67r6k2v3.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>rx5hdcabgc.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>xy9t38ct57.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>54nzkqm89y.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>9b89h5y424.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>79pbpufp6p.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>kbmxgpxpgc.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>275upjj5gd.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>rvh3l7un93.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>qqp299437r.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>74b6s63p6l.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>44n7hlldy6.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>6p4ks3rnbw.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>3qcr597p9d.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>n6fk4nfna4.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>b9bk5wbcq9.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>84993kbrcf.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>24zw6aqk47.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>pwdxu55a5a.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>cs644xg564.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>6964rsfnh4.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>9vvzujtq5s.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>a7xqa6mtl2.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>r45fhb6rf7.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>c3frkrj4fj.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>6g9af3uyq4.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>u679fj5vs4.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>g2y4y55b64.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>dbu4b84rxf.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>ns5j362hk7.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>252b5q8x7y.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>7fmhfwg9en.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>cwn433xbcr.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>7953jerfzd.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>qu637u8glc.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>9yg77x724h.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>n66cz3y3bx.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>3l6bd9hu43.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>47vhws6wlr.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>4mn522wn87.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>52fl2v3hgk.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>6v7lgmsu45.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>89z7zv988g.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>8c4e2ghe7u.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>8m87ys6875.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>8r8llnkz5a.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>bxvub5ada5.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>cp8zw746q7.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>dkc879ngq3.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>ecpz2srf59.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>eh6m2bh4zr.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>gta8lk7p23.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>hb56zgv37p.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>krvm3zuq6h.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>m297p6643m.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>m5mvw97r93.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>n38lu8286q.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>nzq8sh4pbs.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>s69wq72ugq.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>v4nxqhlyqp.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>vcra2ehyfk.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>vutu7akeur.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>x5l83yy675.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>x8jxxk4ff5.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>x8uqf25wch.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>y5ghdn5j9k.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>55644vm79v.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>t6d3zquu66.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>55y65gfgn7.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>fq6vru337s.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>SKAdNetworkIdentifier</key>
|
||||||
|
<string>87u5trcl3r.skadnetwork</string>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
19
ironSource/PlayBTopOn/PlayBTopOn/ViewController.swift
Normal file
19
ironSource/PlayBTopOn/PlayBTopOn/ViewController.swift
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// ViewController.swift
|
||||||
|
// PlayBTopOn
|
||||||
|
//
|
||||||
|
// Created by 忆海16 on 2024/11/15.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class ViewController: UIViewController {
|
||||||
|
|
||||||
|
override func viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
// Do any additional setup after loading the view.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
52
ironSource/PlayBTopOn/PlayBTopOn/playB/AdItem.swift
Normal file
52
ironSource/PlayBTopOn/PlayBTopOn/playB/AdItem.swift
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
//
|
||||||
|
// AdItem.swift
|
||||||
|
// PlayBTopOn
|
||||||
|
//
|
||||||
|
// Created by mac on 2025/12/24.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class AdItem: NSObject {
|
||||||
|
// var interstitialAd:MAInterstitialAd!
|
||||||
|
var interstitialAdID: String = ""
|
||||||
|
|
||||||
|
// 定义广告关闭后的操作闭包
|
||||||
|
var _onAdClosed: (() -> Void)?
|
||||||
|
var onStatusChange:((_:String,_:Int, _:Double) -> Void)?
|
||||||
|
|
||||||
|
var startLoadTime: DispatchTime?
|
||||||
|
|
||||||
|
// 0: 初始,1:加载中,2:加载完成,3:展示中,4:关闭,5:加载失败,6:展示失败
|
||||||
|
private(set) var status: Int = 0
|
||||||
|
|
||||||
|
var ecpm:Double = 0.0
|
||||||
|
|
||||||
|
|
||||||
|
init(adID:String){
|
||||||
|
|
||||||
|
super.init()
|
||||||
|
self.interstitialAdID = adID
|
||||||
|
// loadInterstitialAd()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func onAdClosed() {
|
||||||
|
if self._onAdClosed != nil {
|
||||||
|
self._onAdClosed!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func changeStatus(st:Int) {
|
||||||
|
self.status = st
|
||||||
|
onStatusChange?(self.interstitialAdID, st, self.ecpm)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 辅助函数以毫秒为单位计算经过的时间
|
||||||
|
func calculateElapsedTime(since startTime: DispatchTime) -> Int {
|
||||||
|
let endTime = DispatchTime.now()
|
||||||
|
let nanoseconds = endTime.uptimeNanoseconds - startTime.uptimeNanoseconds
|
||||||
|
return Int(nanoseconds / 1_000_000) // 转换为毫秒
|
||||||
|
}
|
||||||
|
}
|
||||||
19
ironSource/PlayBTopOn/PlayBTopOn/playB/CocoaAsyncSocket.h
Executable file
19
ironSource/PlayBTopOn/PlayBTopOn/playB/CocoaAsyncSocket.h
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// CocoaAsyncSocket.h
|
||||||
|
// CocoaAsyncSocket
|
||||||
|
//
|
||||||
|
// Created by Derek Clarkson on 10/08/2015.
|
||||||
|
// CocoaAsyncSocket project is in the public domain.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
//! Project version number for CocoaAsyncSocket.
|
||||||
|
FOUNDATION_EXPORT double cocoaAsyncSocketVersionNumber;
|
||||||
|
|
||||||
|
//! Project version string for CocoaAsyncSocket.
|
||||||
|
FOUNDATION_EXPORT const unsigned char cocoaAsyncSocketVersionString[];
|
||||||
|
|
||||||
|
|
||||||
|
#import "GCD/GCDAsyncUdpSocket.h"
|
||||||
|
|
||||||
1036
ironSource/PlayBTopOn/PlayBTopOn/playB/GCD/GCDAsyncUdpSocket.h
Executable file
1036
ironSource/PlayBTopOn/PlayBTopOn/playB/GCD/GCDAsyncUdpSocket.h
Executable file
File diff suppressed because it is too large
Load Diff
5632
ironSource/PlayBTopOn/PlayBTopOn/playB/GCD/GCDAsyncUdpSocket.m
Executable file
5632
ironSource/PlayBTopOn/PlayBTopOn/playB/GCD/GCDAsyncUdpSocket.m
Executable file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,174 @@
|
|||||||
|
//
|
||||||
|
// IronSourceinterstitialAd.swift
|
||||||
|
// PlayBTopOn
|
||||||
|
//
|
||||||
|
// Created by mac on 2025/12/24.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import IronSource
|
||||||
|
|
||||||
|
class IronSourceinterstitialAd :AdItem,LPMInterstitialAdDelegate {
|
||||||
|
|
||||||
|
var interstitialAd:LPMInterstitialAd? = nil
|
||||||
|
|
||||||
|
func setup(adUnitId:String) {
|
||||||
|
self.interstitialAd = LPMInterstitialAd(adUnitId: adUnitId)
|
||||||
|
self.interstitialAd!.setDelegate(self)
|
||||||
|
startLoadTime = DispatchTime.now()
|
||||||
|
}
|
||||||
|
|
||||||
|
func load() {
|
||||||
|
if self.interstitialAd != nil {
|
||||||
|
self.interstitialAd?.loadAd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func show(viewController:UIViewController,onAdClosed: @escaping () -> Void) -> Bool {
|
||||||
|
NSLog("XS- IronSourceinterstitialAd.show 被调用: \(self.interstitialAdID)")
|
||||||
|
self._onAdClosed = onAdClosed
|
||||||
|
|
||||||
|
if let adItem = self.interstitialAd {
|
||||||
|
let isReady = adItem.isAdReady()
|
||||||
|
NSLog("XS- 广告准备状态 isAdReady: \(isReady), adID: \(self.interstitialAdID)")
|
||||||
|
|
||||||
|
if isReady {
|
||||||
|
NSLog("XS- ✓ 调用 showAd,准备展示广告: \(self.interstitialAdID)")
|
||||||
|
adItem.showAd(viewController: viewController, placementName: self.interstitialAdID)
|
||||||
|
NSLog("XS- showAd 调用完成,等待 didDisplayAd 回调")
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
NSLog("XS- ✗ 广告未准备好,无法展示: \(self.interstitialAdID)")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
NSLog("XS- ✗ interstitialAd 为 nil: \(self.interstitialAdID)")
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func didLoadAd(with adInfo: LPMAdInfo) {
|
||||||
|
YL_NetWorkManager.onLoad()
|
||||||
|
changeStatus(st: 2)
|
||||||
|
BbbAdManager.config.loadcount += 1
|
||||||
|
|
||||||
|
|
||||||
|
let thatecpm = adInfo.revenue.doubleValue
|
||||||
|
if thatecpm > self.ecpm {
|
||||||
|
self.ecpm = thatecpm
|
||||||
|
}
|
||||||
|
NSLog("XS- ad load ok:\(BbbAdManager.config.linkId) - \(String(describing: adInfo.adUnitId)) ecpm:\(self.ecpm * 1000)")
|
||||||
|
// 计算并打印加载时间
|
||||||
|
var time = 0
|
||||||
|
if let startTime = startLoadTime {
|
||||||
|
let loadDuration = calculateElapsedTime(since: startTime)
|
||||||
|
NSLog("XS- ad \(String(describing: adInfo.adUnitId)) load time: \(loadDuration) ms")
|
||||||
|
time = loadDuration
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let network = adInfo.adNetwork
|
||||||
|
let country = adInfo.country
|
||||||
|
|
||||||
|
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "加载广告: \(String(describing: adInfo.adUnitId)) 成功 - \(network), ecpm:\(String(format: "%.2f", self.ecpm * 1000)) \(country) \(BbbAdManager.config.loadcount)"])
|
||||||
|
|
||||||
|
|
||||||
|
DispatchQueue.global(qos: .utility).async { [weak self] in
|
||||||
|
guard self != nil else { return }
|
||||||
|
YL_NetWorkManager.uploadAD_Load(adid: adInfo.adUnitId, ecpm: thatecpm , network: network, countryCode: country , platformResponseTime: TimeInterval(time/1000) , dsp: "MTG", loadTime: time)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func didFailToLoadAd(withAdUnitId adUnitId: String, error: any Error) {
|
||||||
|
YL_NetWorkManager.onLoad()
|
||||||
|
BbbAdManager.config.loadcount += 1
|
||||||
|
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "加载:\(String(describing: adUnitId) ),\(String(describing: error)) 失败"])
|
||||||
|
NSLog("XS- load\(String(describing: adUnitId)) err.... :\(String(describing: error))")
|
||||||
|
// NotificationCenter.default.post(name: .adDidFailToLoad, object: nil, userInfo: ["adId": adUnitIdentifier])
|
||||||
|
var time = 0
|
||||||
|
if let startTime = startLoadTime {
|
||||||
|
let loadDuration = calculateElapsedTime(since: startTime)
|
||||||
|
NSLog("XS- ad \(String(describing: adUnitId)) load time: \(loadDuration) ms")
|
||||||
|
time = loadDuration
|
||||||
|
}
|
||||||
|
DispatchQueue.global(qos: .utility).async { [weak self] in
|
||||||
|
guard self != nil else { return }
|
||||||
|
YL_NetWorkManager.uploadAD_Load(adid: adUnitId, ecpm: 0.0 , network: "", countryCode: "", platformResponseTime: TimeInterval(time/1000) , dsp: "MTG", loadTime: time,errMsg: "\(String(describing: error))")
|
||||||
|
}
|
||||||
|
// self.onAdClosed()
|
||||||
|
changeStatus(st: 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
func didDisplayAd(with adInfo: LPMAdInfo) {
|
||||||
|
NSLog("XS- ✓✓✓ didDisplayAd 回调被触发: \(adInfo.adUnitId)")
|
||||||
|
NSLog("XS- 广告展示成功,准备上报 Show 日志")
|
||||||
|
|
||||||
|
let ecpmprice = adInfo.revenue.doubleValue
|
||||||
|
let network = adInfo.adNetwork
|
||||||
|
let country = adInfo.country
|
||||||
|
|
||||||
|
NSLog("XS- 广告信息: ecpm=\(ecpmprice), network=\(network), country=\(country)")
|
||||||
|
|
||||||
|
// 先改变状态为展示中
|
||||||
|
changeStatus(st: 3)
|
||||||
|
YL_NetWorkManager.onShow()
|
||||||
|
|
||||||
|
// 上报 Show 日志
|
||||||
|
DispatchQueue.global(qos: .utility).async { [weak self] in
|
||||||
|
guard self != nil else { return }
|
||||||
|
NSLog("XS- 开始上报 uploadAD_Show: \(adInfo.adUnitId)")
|
||||||
|
YL_NetWorkManager.uploadAD_Show(adid: adInfo.adUnitId, ecpm: ecpmprice, network: network, countryCode: country , platformResponseTime:0 , dsp: "IronSource")
|
||||||
|
NSLog("XS- uploadAD_Show 调用完成")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置定时关闭
|
||||||
|
DispatchQueue.global(qos: .utility).async { [weak self] in
|
||||||
|
guard self != nil else { return }
|
||||||
|
NSLog("XS- 设置广告定时关闭")
|
||||||
|
YL_NetWorkManager.showAd(adId: adInfo.adUnitId, ecpm: ecpmprice, ad: true) {
|
||||||
|
self?.changeStatus(st: 4)
|
||||||
|
NSLog("XS- 广告定时关闭触发: \(adInfo.adUnitId)")
|
||||||
|
self?.onAdClosed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "成功展示了ad\(adInfo.adUnitId)"])
|
||||||
|
|
||||||
|
initializationTopOn.performRandomClick()
|
||||||
|
NSLog("XS- didDisplayAd 处理完成")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 展示失败回调
|
||||||
|
func didFailToDisplayAd(with adInfo: LPMAdInfo, error: Error) {
|
||||||
|
NSLog("XS- ✗✗✗ didFailToDisplayAd 回调被触发: \(adInfo.adUnitId)")
|
||||||
|
CallStackHelper.printDetailedCallStack()
|
||||||
|
NSLog("XS- 广告展示失败!错误: \(error.localizedDescription)")
|
||||||
|
NSLog("XS- 错误详情: \(error)")
|
||||||
|
let network = adInfo.adNetwork
|
||||||
|
let country = adInfo.country
|
||||||
|
// 改变状态为展示失败
|
||||||
|
changeStatus(st: 6)
|
||||||
|
|
||||||
|
// 通知界面
|
||||||
|
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "展示广告失败: \(adInfo.adUnitId), 错误: \(error.localizedDescription)"])
|
||||||
|
// 上报 Show 日志
|
||||||
|
DispatchQueue.global(qos: .utility).async { [weak self] in
|
||||||
|
guard self != nil else { return }
|
||||||
|
NSLog("XS- 开始上报 uploadAD_Show: \(adInfo.adUnitId)")
|
||||||
|
YL_NetWorkManager.uploadAD_Show(adid: adInfo.adUnitId, ecpm: 0, network: network, countryCode: country , platformResponseTime:0 , dsp: "IronSource")
|
||||||
|
NSLog("XS- uploadAD_Show 调用完成")
|
||||||
|
}
|
||||||
|
// 触发关闭回调,让 isshow 重置为 false
|
||||||
|
// 在新的串行加载逻辑中,关闭回调会触发加载下一个广告
|
||||||
|
self.onAdClosed()
|
||||||
|
|
||||||
|
NSLog("XS- didFailToDisplayAd 处理完成")
|
||||||
|
}
|
||||||
|
|
||||||
|
func didCloseAd(with adInfo: LPMAdInfo) {
|
||||||
|
changeStatus(st: 4)
|
||||||
|
NSLog("XS- close ad ok\(adInfo.adUnitId)")
|
||||||
|
self.onAdClosed()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
41
ironSource/PlayBTopOn/PlayBTopOn/playB/XUDPClient.h
Normal file
41
ironSource/PlayBTopOn/PlayBTopOn/playB/XUDPClient.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
//
|
||||||
|
// XUDPClient.h
|
||||||
|
// xcmd
|
||||||
|
//
|
||||||
|
// Created by mac on 2025/2/17.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef XUDPClient_h
|
||||||
|
#define XUDPClient_h
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import "CocoaAsyncSocket.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@interface XUDPClient : NSObject<GCDAsyncUdpSocketDelegate>
|
||||||
|
|
||||||
|
// ⭐️ 单例方法
|
||||||
|
+ (instancetype)sharedInstance;
|
||||||
|
|
||||||
|
// 阻止使用 init 创建新实例
|
||||||
|
+ (instancetype)new NS_UNAVAILABLE;
|
||||||
|
- (instancetype)init NS_UNAVAILABLE;
|
||||||
|
|
||||||
|
// 启动/停止
|
||||||
|
- (void)start;
|
||||||
|
- (void)stop;
|
||||||
|
|
||||||
|
// 发送方法
|
||||||
|
- (void)onLoad:(NSDictionary *)data toPort:(uint16_t)port;
|
||||||
|
- (void)onShow:(NSDictionary *)data toPort:(uint16_t)port;
|
||||||
|
- (void)onEnd:(NSDictionary *)data toPort:(uint16_t)port;
|
||||||
|
- (void)send:(NSString *)msg toPort:(uint16_t)port;
|
||||||
|
|
||||||
|
// 接收消息回调
|
||||||
|
@property (nonatomic, copy, nullable) void(^hintBlock)(NSString *message);
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#endif /* XUDPClient_h */
|
||||||
448
ironSource/PlayBTopOn/PlayBTopOn/playB/XUDPClient.m
Normal file
448
ironSource/PlayBTopOn/PlayBTopOn/playB/XUDPClient.m
Normal file
@ -0,0 +1,448 @@
|
|||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "XUDPClient.h"
|
||||||
|
#import <sys/socket.h>
|
||||||
|
#import <netinet/in.h>
|
||||||
|
#import <arpa/inet.h>
|
||||||
|
|
||||||
|
#define HOST @"127.0.0.1"
|
||||||
|
#define SEND_TIMEOUT 5.0 // 发送超时时间(秒)
|
||||||
|
|
||||||
|
@interface XUDPClient() {
|
||||||
|
@private
|
||||||
|
GCDAsyncUdpSocket *_udpSocket;
|
||||||
|
dispatch_queue_t _clientQueue;
|
||||||
|
NSTimer *_healthCheckTimer;
|
||||||
|
BOOL _isConnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
@property (nonatomic, strong) NSMutableDictionary<NSNumber *, NSDictionary *> *pendingSends;
|
||||||
|
@property (nonatomic, assign) long currentTag;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation XUDPClient
|
||||||
|
|
||||||
|
#pragma mark - Singleton
|
||||||
|
|
||||||
|
+ (instancetype)sharedInstance {
|
||||||
|
static XUDPClient *_sharedInstance = nil;
|
||||||
|
static dispatch_once_t oncePredicate;
|
||||||
|
dispatch_once(&oncePredicate, ^{
|
||||||
|
_sharedInstance = [[XUDPClient alloc] init];
|
||||||
|
});
|
||||||
|
return _sharedInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ⭐️ 防止通过alloc/init创建新实例
|
||||||
|
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
|
||||||
|
return [XUDPClient sharedInstance];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)copyWithZone:(NSZone *)zone {
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)mutableCopyWithZone:(NSZone *)zone {
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)init {
|
||||||
|
|
||||||
|
if (self = [super init]) {
|
||||||
|
self->_isConnected = NO;
|
||||||
|
self->_currentTag = 0;
|
||||||
|
self->_pendingSends = [NSMutableDictionary dictionary];
|
||||||
|
|
||||||
|
// 创建专用串行队列
|
||||||
|
self->_clientQueue = dispatch_queue_create("com.xudpclient.queue", DISPATCH_QUEUE_SERIAL);
|
||||||
|
|
||||||
|
[self start];
|
||||||
|
[self startHealthCheck];
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)start {
|
||||||
|
dispatch_async(_clientQueue, ^{
|
||||||
|
[self _startInternal];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)_startInternal {
|
||||||
|
NSLog(@"XC- Starting UDP client");
|
||||||
|
|
||||||
|
// 清理旧socket
|
||||||
|
if (_udpSocket) {
|
||||||
|
[_udpSocket close];
|
||||||
|
_udpSocket = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
_udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self
|
||||||
|
delegateQueue:_clientQueue];
|
||||||
|
|
||||||
|
// ⭐️ 启用地址重用,避免TIME_WAIT问题
|
||||||
|
NSError *error = nil;
|
||||||
|
if (![_udpSocket enableReusePort:YES error:&error]) {
|
||||||
|
NSLog(@"❌ Error enabling reuse port: %@", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ⭐️ 设置SO_REUSEADDR
|
||||||
|
[self _setSocketOptions];
|
||||||
|
|
||||||
|
// 绑定到任意可用端口
|
||||||
|
if (![_udpSocket bindToPort:0 error:&error]) {
|
||||||
|
NSLog(@"❌ Error binding: %@", error);
|
||||||
|
[self _handleBindError:error];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (![_udpSocket beginReceiving:&error]) {
|
||||||
|
NSLog(@"❌ Error receiving: %@", error);
|
||||||
|
[self _scheduleRestart];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_isConnected = YES;
|
||||||
|
NSLog(@"✅ UDP client started successfully");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ⭐️ 设置socket选项
|
||||||
|
- (void)_setSocketOptions {
|
||||||
|
if (!_udpSocket) return;
|
||||||
|
|
||||||
|
int fd = [_udpSocket socketFD];
|
||||||
|
if (fd == -1) return;
|
||||||
|
|
||||||
|
// 设置SO_REUSEADDR,允许快速重启
|
||||||
|
int reuseAddr = 1;
|
||||||
|
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuseAddr, sizeof(reuseAddr)) == -1) {
|
||||||
|
NSLog(@"⚠️ Failed to set SO_REUSEADDR: %s", strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置发送缓冲区大小
|
||||||
|
int sendBufferSize = 65536;
|
||||||
|
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sendBufferSize, sizeof(sendBufferSize)) == -1) {
|
||||||
|
NSLog(@"⚠️ Failed to set send buffer size: %s", strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置接收缓冲区大小
|
||||||
|
int recvBufferSize = 65536;
|
||||||
|
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &recvBufferSize, sizeof(recvBufferSize)) == -1) {
|
||||||
|
NSLog(@"⚠️ Failed to set receive buffer size: %s", strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ⭐️ 处理绑定错误
|
||||||
|
- (void)_handleBindError:(NSError *)error {
|
||||||
|
if (error.code == 48) { // EADDRINUSE
|
||||||
|
NSLog(@"⚠️ Address already in use, checking TIME_WAIT status");
|
||||||
|
[self _checkTimeWaitStatus];
|
||||||
|
}
|
||||||
|
|
||||||
|
[self _scheduleRestart];
|
||||||
|
}
|
||||||
|
|
||||||
|
// ⭐️ 检查TIME_WAIT状态
|
||||||
|
- (void)_checkTimeWaitStatus {
|
||||||
|
int testSocket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (testSocket < 0) {
|
||||||
|
NSLog(@"❌ Cannot create test socket");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置SO_REUSEADDR后再测试
|
||||||
|
int reuseAddr = 1;
|
||||||
|
setsockopt(testSocket, SOL_SOCKET, SO_REUSEADDR, &reuseAddr, sizeof(reuseAddr));
|
||||||
|
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = htons(0);
|
||||||
|
addr.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
|
||||||
|
int result = bind(testSocket, (struct sockaddr *)&addr, sizeof(addr));
|
||||||
|
close(testSocket);
|
||||||
|
|
||||||
|
if (result != 0) {
|
||||||
|
NSLog(@"⚠️ Possible TIME_WAIT issue detected: %s", strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ⭐️ 自动重启调度
|
||||||
|
- (void)_scheduleRestart {
|
||||||
|
NSLog(@"⏰ Scheduling client restart in 3 seconds");
|
||||||
|
|
||||||
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)),
|
||||||
|
_clientQueue, ^{
|
||||||
|
[self _startInternal];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)stop {
|
||||||
|
dispatch_async(_clientQueue, ^{
|
||||||
|
[self _stopInternal];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)_stopInternal {
|
||||||
|
NSLog(@"XC- Stopping UDP client");
|
||||||
|
|
||||||
|
[self stopHealthCheck];
|
||||||
|
|
||||||
|
if (_udpSocket) {
|
||||||
|
// ⭐️ 设置SO_LINGER强制立即关闭,避免TIME_WAIT
|
||||||
|
int fd = [_udpSocket socketFD];
|
||||||
|
if (fd != -1) {
|
||||||
|
struct linger lingerOption = {1, 0};
|
||||||
|
setsockopt(fd, SOL_SOCKET, SO_LINGER, &lingerOption, sizeof(lingerOption));
|
||||||
|
}
|
||||||
|
|
||||||
|
[_udpSocket close];
|
||||||
|
_udpSocket = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
_isConnected = NO;
|
||||||
|
[_pendingSends removeAllObjects];
|
||||||
|
}
|
||||||
|
|
||||||
|
// ⭐️ 健康检查
|
||||||
|
- (void)startHealthCheck {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
self->_healthCheckTimer = [NSTimer scheduledTimerWithTimeInterval:30.0
|
||||||
|
target:self
|
||||||
|
selector:@selector(_performHealthCheck)
|
||||||
|
userInfo:nil
|
||||||
|
repeats:YES];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)stopHealthCheck {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
if (self->_healthCheckTimer) {
|
||||||
|
[self->_healthCheckTimer invalidate];
|
||||||
|
self->_healthCheckTimer = nil;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)_performHealthCheck {
|
||||||
|
dispatch_async(_clientQueue, ^{
|
||||||
|
if (!self->_udpSocket || self->_udpSocket.isClosed) {
|
||||||
|
NSLog(@"⚠️ Health check failed: socket is closed");
|
||||||
|
[self _startInternal];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Send Methods
|
||||||
|
|
||||||
|
// ⭐️ 发送到指定端口
|
||||||
|
- (void)onShow:(NSDictionary *)data toPort:(uint16_t)port {
|
||||||
|
NSDictionary *rq = @{
|
||||||
|
@"url": @"/adtask/show",
|
||||||
|
@"body": data
|
||||||
|
};
|
||||||
|
[self send:[self dic2Json:rq] toPort:port];
|
||||||
|
}
|
||||||
|
- (void)onLoad:(NSDictionary *)data toPort:(uint16_t)port {
|
||||||
|
NSDictionary *rq = @{
|
||||||
|
@"url": @"/adtask/load",
|
||||||
|
@"body": data
|
||||||
|
};
|
||||||
|
[self send:[self dic2Json:rq] toPort:port];
|
||||||
|
}
|
||||||
|
|
||||||
|
// ⭐️ 发送到指定端口
|
||||||
|
- (void)onEnd:(NSDictionary *)data toPort:(uint16_t)port {
|
||||||
|
NSDictionary *rq = @{
|
||||||
|
@"url": @"/adtask/end",
|
||||||
|
@"body": data
|
||||||
|
};
|
||||||
|
[self send:[self dic2Json:rq] toPort:port];
|
||||||
|
}
|
||||||
|
|
||||||
|
// ⭐️ 发送方法接收端口参数
|
||||||
|
- (void)send:(NSString *)msg toPort:(uint16_t)port {
|
||||||
|
if (!msg) {
|
||||||
|
NSLog(@"⚠️ Cannot send nil message");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch_async(_clientQueue, ^{
|
||||||
|
[self _sendInternal:msg toPort:port];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)_sendInternal:(NSString *)msg toPort:(uint16_t)port {
|
||||||
|
if (!_udpSocket || _udpSocket.isClosed) {
|
||||||
|
NSLog(@"❌ Socket not ready, cannot send message to port %d", port);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
long tag = ++_currentTag;
|
||||||
|
|
||||||
|
// ⭐️ 保存待发送数据,用于超时检测
|
||||||
|
_pendingSends[@(tag)] = @{
|
||||||
|
@"message": msg,
|
||||||
|
@"port": @(port),
|
||||||
|
@"timestamp": @([[NSDate date] timeIntervalSince1970])
|
||||||
|
};
|
||||||
|
|
||||||
|
NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
|
||||||
|
|
||||||
|
NSLog(@"📤 Sending to %@:%d (tag: %ld)", HOST, port, tag);
|
||||||
|
|
||||||
|
// ⭐️ 设置超时时间
|
||||||
|
[_udpSocket sendData:data
|
||||||
|
toHost:HOST
|
||||||
|
port:port
|
||||||
|
withTimeout:SEND_TIMEOUT
|
||||||
|
tag:tag];
|
||||||
|
|
||||||
|
// ⭐️ 设置超时检查
|
||||||
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)((SEND_TIMEOUT + 1.0) * NSEC_PER_SEC)),
|
||||||
|
_clientQueue, ^{
|
||||||
|
[self _checkSendTimeout:tag];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ⭐️ 检查发送超时
|
||||||
|
- (void)_checkSendTimeout:(long)tag {
|
||||||
|
NSDictionary *pendingData = _pendingSends[@(tag)];
|
||||||
|
if (pendingData) {
|
||||||
|
NSString *msg = pendingData[@"message"];
|
||||||
|
uint16_t port = [pendingData[@"port"] unsignedShortValue];
|
||||||
|
NSTimeInterval timestamp = [pendingData[@"timestamp"] doubleValue];
|
||||||
|
NSTimeInterval elapsed = [[NSDate date] timeIntervalSince1970] - timestamp;
|
||||||
|
|
||||||
|
NSLog(@"⏱️ Send timeout for tag %ld (port: %d, elapsed: %.1fs)",
|
||||||
|
tag, port, elapsed);
|
||||||
|
|
||||||
|
[_pendingSends removeObjectForKey:@(tag)];
|
||||||
|
|
||||||
|
// 超时后不重试,只记录日志
|
||||||
|
NSLog(@"❌ Message failed to send within timeout: %@",
|
||||||
|
[msg substringToIndex:MIN(100, msg.length)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - GCDAsyncUdpSocket Delegate
|
||||||
|
|
||||||
|
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didConnectToAddress:(NSData *)address {
|
||||||
|
NSLog(@"✅ Connected to address");
|
||||||
|
_isConnected = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didNotConnect:(NSError *)error {
|
||||||
|
NSLog(@"❌ Did not connect: %@", error);
|
||||||
|
_isConnected = NO;
|
||||||
|
[self _scheduleRestart];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)udpSocket:(GCDAsyncUdpSocket *)sock
|
||||||
|
didSendDataWithTag:(long)tag {
|
||||||
|
NSDictionary *pendingData = _pendingSends[@(tag)];
|
||||||
|
uint16_t port = pendingData ? [pendingData[@"port"] unsignedShortValue] : 0;
|
||||||
|
|
||||||
|
NSLog(@"✅ Message sent successfully (tag: %ld, port: %d)", tag, port);
|
||||||
|
|
||||||
|
// ⭐️ 清除待发送记录
|
||||||
|
[_pendingSends removeObjectForKey:@(tag)];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)udpSocket:(GCDAsyncUdpSocket *)sock
|
||||||
|
didNotSendDataWithTag:(long)tag
|
||||||
|
dueToError:(NSError *)error {
|
||||||
|
NSDictionary *pendingData = _pendingSends[@(tag)];
|
||||||
|
uint16_t port = pendingData ? [pendingData[@"port"] unsignedShortValue] : 0;
|
||||||
|
|
||||||
|
NSLog(@"❌ Failed to send (tag: %ld, port: %d): %@", tag, port, error);
|
||||||
|
|
||||||
|
[_pendingSends removeObjectForKey:@(tag)];
|
||||||
|
|
||||||
|
// ⭐️ 检查错误类型并处理
|
||||||
|
if (error.code == 57) { // ENOTCONN - Socket is not connected
|
||||||
|
NSLog(@"⚠️ Socket disconnected (ENOTCONN), restarting...");
|
||||||
|
[self _startInternal];
|
||||||
|
} else if (error.code == 55) { // ENOBUFS - No buffer space available
|
||||||
|
NSLog(@"⚠️ Buffer full (ENOBUFS)");
|
||||||
|
} else if (error.code == 64) { // EHOSTDOWN - Host is down
|
||||||
|
NSLog(@"⚠️ Host is down (EHOSTDOWN)");
|
||||||
|
} else if (error.code == 65) { // EHOSTUNREACH - No route to host
|
||||||
|
NSLog(@"⚠️ Host unreachable (EHOSTUNREACH)");
|
||||||
|
} else if (error.code == 60) { // ETIMEDOUT - Operation timed out
|
||||||
|
NSLog(@"⚠️ Send operation timed out (ETIMEDOUT)");
|
||||||
|
} else {
|
||||||
|
NSLog(@"⚠️ Unknown error code: %ld", (long)error.code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)udpSocket:(GCDAsyncUdpSocket *)sock
|
||||||
|
didReceiveData:(NSData *)data
|
||||||
|
fromAddress:(NSData *)address
|
||||||
|
withFilterContext:(id)filterContext {
|
||||||
|
@autoreleasepool {
|
||||||
|
NSString *revData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||||
|
|
||||||
|
if (!revData) {
|
||||||
|
NSLog(@"⚠️ Failed to decode received data");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSLog(@"📨 Received: %@", revData);
|
||||||
|
|
||||||
|
if (self.hintBlock) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
self.hintBlock(revData);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ⭐️ Socket异常关闭处理
|
||||||
|
- (void)udpSocketDidClose:(GCDAsyncUdpSocket *)sock withError:(NSError *)error {
|
||||||
|
NSLog(@"⚠️ Socket closed. Error: %@", error);
|
||||||
|
|
||||||
|
_isConnected = NO;
|
||||||
|
|
||||||
|
if (sock == _udpSocket) {
|
||||||
|
_udpSocket = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
NSLog(@"❌ Unexpected closure, scheduling restart");
|
||||||
|
[self _scheduleRestart];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Utility Methods
|
||||||
|
|
||||||
|
- (NSString *)dic2Json:(NSDictionary *)dict {
|
||||||
|
if (!dict) return nil;
|
||||||
|
|
||||||
|
NSError *error;
|
||||||
|
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict
|
||||||
|
options:0
|
||||||
|
error:&error];
|
||||||
|
if (error) {
|
||||||
|
NSLog(@"❌ dic2json error: %@", error);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSDictionary *)json2dic:(NSString *)jsstr {
|
||||||
|
if (!jsstr) return nil;
|
||||||
|
|
||||||
|
NSError *jsonError;
|
||||||
|
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:[jsstr dataUsingEncoding:NSUTF8StringEncoding]
|
||||||
|
options:NSJSONReadingMutableContainers
|
||||||
|
error:&jsonError];
|
||||||
|
if (jsonError) {
|
||||||
|
NSLog(@"❌ json2dic error: %@", jsonError);
|
||||||
|
}
|
||||||
|
return dic;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
1418
ironSource/PlayBTopOn/PlayBTopOn/playB/YL_NetWorkManager.swift
Normal file
1418
ironSource/PlayBTopOn/PlayBTopOn/playB/YL_NetWorkManager.swift
Normal file
File diff suppressed because it is too large
Load Diff
166
ironSource/PlayBTopOn/PlayBTopOn/playB/YL_PlayVC.swift
Normal file
166
ironSource/PlayBTopOn/PlayBTopOn/playB/YL_PlayVC.swift
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
//
|
||||||
|
// YL_PlayVC.swift
|
||||||
|
// playbtest
|
||||||
|
//
|
||||||
|
// Created by 忆海16 on 2024/11/5.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import AnyThinkInterstitial
|
||||||
|
import IronSource
|
||||||
|
class YL_PlayVC: UIViewController {
|
||||||
|
|
||||||
|
@IBOutlet weak var textSDKView: UITextView!
|
||||||
|
@IBOutlet weak var bundleIdLab: UILabel!
|
||||||
|
@IBOutlet weak var deviceIdLab: UILabel!
|
||||||
|
@IBOutlet weak var ipLab: UILabel!
|
||||||
|
@IBOutlet weak var idfaLab: UILabel!
|
||||||
|
@IBOutlet weak var ad1Lab: UILabel!
|
||||||
|
@IBOutlet weak var ad2Lab: UILabel!
|
||||||
|
@IBOutlet weak var ad3Lab: UILabel!
|
||||||
|
|
||||||
|
private var observation: NSKeyValueObservation?
|
||||||
|
|
||||||
|
private var observationis: NSKeyValueObservation?
|
||||||
|
|
||||||
|
var openADTimer:Timer?
|
||||||
|
let kOpenADPerSec: CGFloat = 0.1 // 假设的秒数
|
||||||
|
let kOpenAdCTimeLength: CGFloat = 30 // 假设的超时时长
|
||||||
|
|
||||||
|
static var totalTimeC: CGFloat = 0.0
|
||||||
|
var firstShow = true
|
||||||
|
|
||||||
|
|
||||||
|
override func viewDidLoad() {
|
||||||
|
NSLog("XS- YL_PlayVC viewDidLoad 开始")
|
||||||
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
NSLog("XS- YL_PlayVC 准备调用 waitForSDKInitialization")
|
||||||
|
// 等待 SDK 初始化完成后再加载广告(兼容 iOS 12+)
|
||||||
|
BbbAdManager.shared.waitForSDKInitialization {
|
||||||
|
NSLog("XS- SDK 初始化完成,开始加载广告")
|
||||||
|
BbbAdManager.shared.loadAd(view: self)
|
||||||
|
}
|
||||||
|
NSLog("XS- YL_PlayVC waitForSDKInitialization 调用完成")
|
||||||
|
|
||||||
|
let bundleId = Bundle.main.bundleIdentifier ?? ""
|
||||||
|
bundleIdLab.text = "Name:\(bundleId)"
|
||||||
|
let deviceId = BbbAdManager.config.adbrush_deviceid ?? ""
|
||||||
|
deviceIdLab.text = "DeviceID:\(deviceId)"
|
||||||
|
let locIp = BbbAdManager.config.adbrush_localip ?? ""
|
||||||
|
let remoteIp = BbbAdManager.config.remoteIp
|
||||||
|
ipLab.text = "LocIP:\(locIp),RemoteIp:\(remoteIp)"
|
||||||
|
|
||||||
|
if #available(iOS 14, *) {
|
||||||
|
IDFA.shared.checkATT { idfa in
|
||||||
|
if let idfa = idfa {
|
||||||
|
print("IDFA: \(idfa)")
|
||||||
|
self.idfaLab.text = "IDFA:\(idfa)"
|
||||||
|
} else {
|
||||||
|
print("无法获取 IDFA")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
IDFA.shared.getIDFAForOlderVersions { idfa in
|
||||||
|
if let idfa = idfa {
|
||||||
|
print("IDFA: \(idfa)")
|
||||||
|
self.idfaLab.text = "IDFA:\(idfa)"
|
||||||
|
} else {
|
||||||
|
print("无法获取 IDFA")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 原来的 start 调用已经移到 loadAd 回调中,这里可以删除
|
||||||
|
// DispatchQueue.main.asyncAfter(deadline: .now() + 4 ) {
|
||||||
|
// BbbAdManager.shared.start()
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
|
super.viewWillAppear(animated)
|
||||||
|
if (!firstShow) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
firstShow = false
|
||||||
|
|
||||||
|
ad1Lab.text = BbbAdManager.config.adids[0]
|
||||||
|
ad2Lab.text = BbbAdManager.config.adids[1]
|
||||||
|
ad3Lab.text = BbbAdManager.config.adids[2]
|
||||||
|
|
||||||
|
|
||||||
|
self.navigationController?.navigationBar.isHidden = true
|
||||||
|
|
||||||
|
NotificationCenter.default.addObserver(self, selector: #selector(addTextToTextView), name: NSNotification.Name("adinfo"), object: nil)
|
||||||
|
|
||||||
|
NotificationCenter.default.addObserver(self, selector: #selector(adStatusChange), name: NSNotification.Name("adStatus"), object: nil)
|
||||||
|
|
||||||
|
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "adbrush_base_url:\(BbbAdManager.config.adbrush_base_url),adbrush_deviceid:\(String(describing: BbbAdManager.config.adbrush_deviceid)),adbrush_localip:\(String(describing: BbbAdManager.config.adbrush_localip)),adbrush_local_url:\(BbbAdManager.config.adbrush_local_url),adbrush_ecpm:\(BbbAdManager.config.adbrush_ecpm)"])
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func addTextToTextView(notification: Notification) {
|
||||||
|
if let newText = notification.userInfo?["text"] as? String {
|
||||||
|
// 正确的方式
|
||||||
|
DispatchQueue.global().async {
|
||||||
|
// 后台线程处理数据
|
||||||
|
|
||||||
|
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
// 主线程更新UI
|
||||||
|
self.textSDKView.text.append("\(newText)\n\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 向文本末尾追加 100 行空白行
|
||||||
|
func appendExtraLines1() {
|
||||||
|
let extraLines = String(repeating: "\n", count: 100)
|
||||||
|
let currentText = textSDKView.text ?? ""
|
||||||
|
|
||||||
|
// 检查末尾是否已经有额外行,避免重复追加
|
||||||
|
if !currentText.hasSuffix(extraLines) {
|
||||||
|
textSDKView.text = currentText.trimmingCharacters(in: .whitespacesAndNewlines) + extraLines
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@objc func adStatusChange(notification: Notification) {
|
||||||
|
if let newText = notification.userInfo?["text"] as? String, let id = notification.userInfo?["id"] as? String {
|
||||||
|
var lab = ad1Lab
|
||||||
|
if id == BbbAdManager.config.adids[1] {
|
||||||
|
lab = ad2Lab
|
||||||
|
} else if id == BbbAdManager.config.adids[2] {
|
||||||
|
lab = ad3Lab
|
||||||
|
}
|
||||||
|
DispatchQueue.global().async {
|
||||||
|
// 后台线程处理数据
|
||||||
|
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
// 主线程更新UI
|
||||||
|
lab?.text = "\(id):\(newText)" }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
NotificationCenter.default.removeObserver(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Notification.Name {
|
||||||
|
static let adStatusChanged = Notification.Name("adStatusChanged")
|
||||||
|
|
||||||
|
}
|
||||||
113
ironSource/PlayBTopOn/PlayBTopOn/playB/YL_PlayVC.xib
Normal file
113
ironSource/PlayBTopOn/PlayBTopOn/playB/YL_PlayVC.xib
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23727" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||||
|
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="iOS"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23721"/>
|
||||||
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
|
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<objects>
|
||||||
|
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="YL_PlayVC" customModule="PlayBTopOn" customModuleProvider="target">
|
||||||
|
<connections>
|
||||||
|
<outlet property="ad1Lab" destination="8pI-KB-RPz" id="8gK-jO-9UZ"/>
|
||||||
|
<outlet property="ad2Lab" destination="hYm-nF-cOH" id="qND-g7-RRo"/>
|
||||||
|
<outlet property="ad3Lab" destination="qR0-SE-dDl" id="SX0-6w-Hbl"/>
|
||||||
|
<outlet property="bundleIdLab" destination="uzL-Gm-nJe" id="PLT-mH-rhM"/>
|
||||||
|
<outlet property="deviceIdLab" destination="afH-me-Sl0" id="cTn-FZ-z8s"/>
|
||||||
|
<outlet property="idfaLab" destination="DOY-uf-pQH" id="wh7-A3-jFy"/>
|
||||||
|
<outlet property="ipLab" destination="ahK-Kk-DtA" id="oe0-Rs-OLS"/>
|
||||||
|
<outlet property="textSDKView" destination="vmc-eE-E2h" id="Pil-hd-AvH"/>
|
||||||
|
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
|
||||||
|
</connections>
|
||||||
|
</placeholder>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||||
|
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="ZCJ-fb-TIS">
|
||||||
|
<rect key="frame" x="1" y="21" width="373" height="645"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="bundleIdLab" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="uzL-Gm-nJe">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="373" height="21.5"/>
|
||||||
|
<fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
|
||||||
|
<nil key="textColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="deviceIdLab" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="afH-me-Sl0">
|
||||||
|
<rect key="frame" x="0.0" y="21.5" width="373" height="19.5"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||||
|
<color key="textColor" systemColor="systemBlueColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="idfaLab" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="DOY-uf-pQH">
|
||||||
|
<rect key="frame" x="0.0" y="41" width="373" height="20.5"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
|
<color key="textColor" systemColor="systemPinkColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="ipLab" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ahK-Kk-DtA">
|
||||||
|
<rect key="frame" x="0.0" y="61.5" width="373" height="20.5"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
|
<color key="textColor" systemColor="systemGreenColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="ad1Lab" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8pI-KB-RPz">
|
||||||
|
<rect key="frame" x="0.0" y="82" width="373" height="19.5"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||||
|
<color key="textColor" systemColor="systemOrangeColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="ad2Lab" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hYm-nF-cOH">
|
||||||
|
<rect key="frame" x="0.0" y="101.5" width="373" height="19.5"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||||
|
<color key="textColor" systemColor="systemOrangeColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="ad3Lab" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qR0-SE-dDl">
|
||||||
|
<rect key="frame" x="0.0" y="121" width="373" height="19.5"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||||
|
<color key="textColor" systemColor="systemOrangeColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" editable="NO" textAlignment="natural" selectable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vmc-eE-E2h">
|
||||||
|
<rect key="frame" x="0.0" y="140.5" width="373" height="504.5"/>
|
||||||
|
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
|
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
|
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
|
||||||
|
</textView>
|
||||||
|
</subviews>
|
||||||
|
</stackView>
|
||||||
|
</subviews>
|
||||||
|
<viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
|
||||||
|
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="ZCJ-fb-TIS" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="1" id="DhW-gV-Eip"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="ZCJ-fb-TIS" secondAttribute="trailing" constant="1" id="Mbh-GB-cWt"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="ZCJ-fb-TIS" secondAttribute="bottom" constant="1" id="Rxy-Zg-zNH"/>
|
||||||
|
<constraint firstItem="ZCJ-fb-TIS" firstAttribute="top" secondItem="fnl-2z-Ty3" secondAttribute="top" constant="1" id="fDq-DA-QtM"/>
|
||||||
|
</constraints>
|
||||||
|
<point key="canvasLocation" x="128.98550724637681" y="-12.053571428571429"/>
|
||||||
|
</view>
|
||||||
|
</objects>
|
||||||
|
<resources>
|
||||||
|
<systemColor name="systemBackgroundColor">
|
||||||
|
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
|
</systemColor>
|
||||||
|
<systemColor name="systemBlueColor">
|
||||||
|
<color red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
</systemColor>
|
||||||
|
<systemColor name="systemGreenColor">
|
||||||
|
<color red="0.20392156859999999" green="0.78039215689999997" blue="0.34901960780000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
</systemColor>
|
||||||
|
<systemColor name="systemOrangeColor">
|
||||||
|
<color red="1" green="0.58431372550000005" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
</systemColor>
|
||||||
|
<systemColor name="systemPinkColor">
|
||||||
|
<color red="1" green="0.1764705882" blue="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
</systemColor>
|
||||||
|
</resources>
|
||||||
|
</document>
|
||||||
358
ironSource/PlayBTopOn/PlayBTopOn/playB/bbbAdManager.swift
Normal file
358
ironSource/PlayBTopOn/PlayBTopOn/playB/bbbAdManager.swift
Normal file
@ -0,0 +1,358 @@
|
|||||||
|
//
|
||||||
|
// bbbAdManager.swift
|
||||||
|
// playbtest
|
||||||
|
//
|
||||||
|
// Created by mac on 2025/3/11.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import AnyThinkInterstitial
|
||||||
|
import AnyThinkSDK
|
||||||
|
|
||||||
|
class bConfig: NSObject {
|
||||||
|
var appId:String = "h6938d7554f1f5"
|
||||||
|
/// 广告Key
|
||||||
|
var adKey:String = "24aee521d"
|
||||||
|
|
||||||
|
var userId:String = "602443"
|
||||||
|
|
||||||
|
/// 广告数组
|
||||||
|
var allAdIds:[String] = ["no7750uspiuvwwcx","hhh5ve5yjpptfdcp","snlrr8jxxljp375n"]
|
||||||
|
/// 广告数组
|
||||||
|
var adids:[String] = []
|
||||||
|
///设备ID
|
||||||
|
var adbrush_deviceid:String?
|
||||||
|
///最低ecpm
|
||||||
|
var adbrush_ecpm:Double = 0.0005
|
||||||
|
/// 本地ip
|
||||||
|
var adbrush_localip:String?
|
||||||
|
/// A面load show
|
||||||
|
var adbrush_base_url:String = "http://192.168.40.8:8080"
|
||||||
|
/// 本地服务
|
||||||
|
var adbrush_local_url:String = "http://127.0.0.1:6000"
|
||||||
|
|
||||||
|
/// 远程ip
|
||||||
|
var remoteIp:String = ""
|
||||||
|
/// dataId
|
||||||
|
var dataId:String = ""
|
||||||
|
|
||||||
|
///IDFA
|
||||||
|
var idfa:String = ""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
var washParam:Bool = false
|
||||||
|
///
|
||||||
|
var linkId:String = ""
|
||||||
|
var device_model:String = ""
|
||||||
|
|
||||||
|
///load次数
|
||||||
|
var loadcount:Int = 0
|
||||||
|
///load次数
|
||||||
|
var loadcount1:Int = 0
|
||||||
|
|
||||||
|
var ipTime:Int = 0
|
||||||
|
var udp_port:Int = 6001
|
||||||
|
|
||||||
|
override init() {
|
||||||
|
NSLog("XS- bConfig init 开始")
|
||||||
|
super.init()
|
||||||
|
|
||||||
|
NSLog("XS- bConfig init: allAdIds count = \(self.allAdIds.count)")
|
||||||
|
if self.allAdIds.count > 3 {
|
||||||
|
self.adids = Array(self.allAdIds.shuffled().prefix(3))
|
||||||
|
} else {
|
||||||
|
self.adids = self.allAdIds
|
||||||
|
}
|
||||||
|
NSLog("XS- bConfig init 完成")
|
||||||
|
}
|
||||||
|
|
||||||
|
///是否正在展示中
|
||||||
|
@objc dynamic var isadsureshow:Bool = false
|
||||||
|
|
||||||
|
|
||||||
|
func getRandomString() -> String? {
|
||||||
|
return adids.randomElement()
|
||||||
|
}
|
||||||
|
// 判断当前是否为广告不量模式
|
||||||
|
func isADSSMode() -> Bool {
|
||||||
|
// return true
|
||||||
|
return UserDefaults.standard.bool(forKey: "kLuxSSFaceKey")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class BbbAdManager: NSObject {
|
||||||
|
static let shared = {
|
||||||
|
NSLog("XS- 开始创建 BbbAdManager.shared 单例")
|
||||||
|
let instance = BbbAdManager()
|
||||||
|
NSLog("XS- BbbAdManager.shared 单例创建完成")
|
||||||
|
return instance
|
||||||
|
}()
|
||||||
|
|
||||||
|
static let config = {
|
||||||
|
NSLog("XS- 开始创建 BbbAdManager.config")
|
||||||
|
let config = bConfig()
|
||||||
|
NSLog("XS- BbbAdManager.config 创建完成")
|
||||||
|
return config
|
||||||
|
}()
|
||||||
|
|
||||||
|
///是否正在展示中
|
||||||
|
@objc dynamic var isshow:Bool = false
|
||||||
|
|
||||||
|
// 用于存储多个广告位的管理器,Key 是广告位的 ID
|
||||||
|
private var adItems: [String: IronSourceinterstitialAd] = [:]
|
||||||
|
|
||||||
|
var openADTimer:Timer?
|
||||||
|
let kOpenADPerSec: CGFloat = 1 // 假设的秒数
|
||||||
|
let kOpenAdCTimeLength: CGFloat = 60 // 假设的超时时长
|
||||||
|
private var view:UIViewController?
|
||||||
|
|
||||||
|
static var totalTimeC: CGFloat = 0.0
|
||||||
|
|
||||||
|
var isLoaded = false
|
||||||
|
|
||||||
|
// SDK 初始化完成标志
|
||||||
|
private var isSDKInitialized = false
|
||||||
|
|
||||||
|
// 存储等待 SDK 初始化的回调(兼容 iOS 12+)
|
||||||
|
private var initializationCallbacks: [() -> Void] = []
|
||||||
|
|
||||||
|
// 串行加载队列
|
||||||
|
private var adIdQueue: [String] = []
|
||||||
|
private var currentLoadingAdId: String?
|
||||||
|
private var isLoadingAd = false
|
||||||
|
|
||||||
|
|
||||||
|
// 添加广告位管理器
|
||||||
|
func add(adId: String) {
|
||||||
|
NSLog("XS- 添加广告位: \(adId)")
|
||||||
|
let adManager = IronSourceinterstitialAd(adID: adId)
|
||||||
|
adManager.onStatusChange = { [weak self] id, st, ecpm in
|
||||||
|
// 0: 初始,1:加载中,2:加载完成,3:展示中,4:关闭,5:加载失败,6:展示失败
|
||||||
|
var text = "初始"
|
||||||
|
if st == 1 {
|
||||||
|
text = "加载中"
|
||||||
|
} else if st == 2 {
|
||||||
|
text = "加载完成"
|
||||||
|
// 加载完成,自动展示
|
||||||
|
NSLog("XS- 广告加载完成,准备自动展示: \(id)")
|
||||||
|
let showRs = adManager.show(viewController: (self?.view)!) {
|
||||||
|
self?.isshow = true
|
||||||
|
}
|
||||||
|
NSLog("XS- show :\(showRs)")
|
||||||
|
}
|
||||||
|
else if st == 3 {
|
||||||
|
text = "展示中"
|
||||||
|
|
||||||
|
}
|
||||||
|
else if st == 4 {
|
||||||
|
text = "关闭"
|
||||||
|
self?.loadNextAd()
|
||||||
|
}
|
||||||
|
else if st == 5 {
|
||||||
|
text = "加载失败"
|
||||||
|
// 加载失败,尝试加载下一个
|
||||||
|
NSLog("XS- 广告加载失败,尝试加载下一个")
|
||||||
|
self?.loadNextAd()
|
||||||
|
}
|
||||||
|
else if st == 6 {
|
||||||
|
text = "展示失败"
|
||||||
|
self?.loadNextAd()
|
||||||
|
}
|
||||||
|
NotificationCenter.default.post(name: NSNotification.Name("adStatus"), object: nil, userInfo: ["id": id, "text":"\(text),ecpm:\(String(format: "%.2f", ecpm * 1000))"])
|
||||||
|
}
|
||||||
|
adManager.setup(adUnitId: adId)
|
||||||
|
adItems[adId] = adManager
|
||||||
|
// 不再立即加载,由 loadNextAd 控制
|
||||||
|
}
|
||||||
|
|
||||||
|
override init(){
|
||||||
|
NSLog("XS- BbbAdManager init 开始")
|
||||||
|
super.init()
|
||||||
|
NSLog("XS- BbbAdManager init 完成")
|
||||||
|
}
|
||||||
|
|
||||||
|
func initConfig () {
|
||||||
|
NSLog("XS- init config")
|
||||||
|
if #available(iOS 14, *) {
|
||||||
|
IDFA.shared.checkATT { idfa in
|
||||||
|
if let idfa = idfa {
|
||||||
|
NSLog("IDFA: \(idfa)")
|
||||||
|
BbbAdManager.config.idfa = idfa
|
||||||
|
} else {
|
||||||
|
NSLog("无法获取 IDFA")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
IDFA.shared.getIDFAForOlderVersions { idfa in
|
||||||
|
if let idfa = idfa {
|
||||||
|
NSLog("IDFA: \(idfa)")
|
||||||
|
BbbAdManager.config.idfa = idfa
|
||||||
|
} else {
|
||||||
|
NSLog("无法获取 IDFA")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NSLog("XS- init config 1")
|
||||||
|
if let bfaceDict = UserDefaults.standard.dictionary(forKey: "bfaceDictKey"){
|
||||||
|
|
||||||
|
BbbAdManager.config.adbrush_base_url = bfaceDict["adbrush_base_url"] as? String ?? "http://192.168.40.8:8080"
|
||||||
|
|
||||||
|
BbbAdManager.config.adbrush_deviceid = bfaceDict["adbrush_deviceid"] as? String ?? ""
|
||||||
|
BbbAdManager.config.adbrush_localip = bfaceDict["adbrush_localip"] as? String ?? ""
|
||||||
|
BbbAdManager.config.remoteIp = bfaceDict["remoteIp"] as? String ?? ""
|
||||||
|
BbbAdManager.config.udp_port = bfaceDict["udp_port"] as? Int ?? 6001
|
||||||
|
|
||||||
|
BbbAdManager.config.adbrush_local_url = bfaceDict["adbrush_local_url"] as? String ?? "http://127.0.0.1:6000"
|
||||||
|
BbbAdManager.config.dataId = bfaceDict["dataId"] as? String ?? ""
|
||||||
|
|
||||||
|
|
||||||
|
BbbAdManager.config.adbrush_ecpm = 0.0005
|
||||||
|
BbbAdManager.config.linkId = bfaceDict["linkId"] as? String ?? ""
|
||||||
|
BbbAdManager.config.washParam = bfaceDict["washParam"] as? Bool ?? false
|
||||||
|
BbbAdManager.config.device_model = bfaceDict["device_model"] as? String ?? ""
|
||||||
|
|
||||||
|
} else {
|
||||||
|
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "获取字典失败"])
|
||||||
|
}
|
||||||
|
NSLog("XS- init config 2")
|
||||||
|
let pkg = Bundle.main.bundleIdentifier ?? ""
|
||||||
|
YL_NetWorkManager.performGetRequest(url: "\(BbbAdManager.config.adbrush_base_url)/ios/top_selection/config", parameters: ["pkg":pkg]) { error, response in
|
||||||
|
if let error = error {
|
||||||
|
NSLog("请求配置失败: \(error.localizedDescription)")
|
||||||
|
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "请求配置失败: \(error.localizedDescription)"])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if let response = response {
|
||||||
|
NSLog("请求配置成功: \(response)")
|
||||||
|
let data = response["data"] as? [String: Any]
|
||||||
|
BbbAdManager.config.adbrush_ecpm = data?["ecpmLow"] as? Double ?? 0.001
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NSLog("XS- init config 3")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 基于回调的初始化方法(兼容 iOS 12+)
|
||||||
|
func initAd(completion: (() -> Void)? = nil) {
|
||||||
|
NSLog("XS- init ad")
|
||||||
|
initializationTopOn.ironSourceSDK(BbbAdManager.config.adKey, userId: BbbAdManager.config.userId) { success, error in
|
||||||
|
if success {
|
||||||
|
NSLog("XS- IronSource SDK initialized successfully")
|
||||||
|
self.isSDKInitialized = true
|
||||||
|
} else {
|
||||||
|
NSLog("XS- IronSource SDK initialization failed: \(error?.localizedDescription ?? "Unknown error")")
|
||||||
|
self.isSDKInitialized = true // 即使失败也标记为已初始化,避免阻塞
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用所有等待的回调
|
||||||
|
for callback in self.initializationCallbacks {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
self.initializationCallbacks.removeAll()
|
||||||
|
|
||||||
|
completion?()
|
||||||
|
}
|
||||||
|
NSLog("XS- init ad end")
|
||||||
|
}
|
||||||
|
|
||||||
|
// async/await 版本的初始化方法(iOS 15+)
|
||||||
|
@available(iOS 15.0, *)
|
||||||
|
func initAdAsync() async {
|
||||||
|
await withCheckedContinuation { continuation in
|
||||||
|
initAd {
|
||||||
|
continuation.resume()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 等待 SDK 初始化完成(基于回调,兼容 iOS 12+)
|
||||||
|
func waitForSDKInitialization(completion: @escaping () -> Void) {
|
||||||
|
NSLog("XS- waitForSDKInitialization 被调用,当前状态:\(isSDKInitialized)")
|
||||||
|
|
||||||
|
if isSDKInitialized {
|
||||||
|
NSLog("XS- SDK 已初始化,直接执行回调")
|
||||||
|
completion()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// SDK 还未初始化,将回调添加到等待队列
|
||||||
|
NSLog("XS- SDK 未初始化,添加回调到等待队列")
|
||||||
|
initializationCallbacks.append(completion)
|
||||||
|
}
|
||||||
|
|
||||||
|
// async/await 版本(iOS 15+)
|
||||||
|
@available(iOS 15.0, *)
|
||||||
|
func waitForSDKInitializationAsync() async {
|
||||||
|
if isSDKInitialized {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await withCheckedContinuation { continuation in
|
||||||
|
waitForSDKInitialization {
|
||||||
|
continuation.resume()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadAd(view:UIViewController) {
|
||||||
|
NSLog("XS- load ad")
|
||||||
|
if self.isLoaded {
|
||||||
|
NSLog("XS- 广告已加载,跳过")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.isLoaded = true
|
||||||
|
self.view = view
|
||||||
|
NSLog("XS- view 已设置: \(view)")
|
||||||
|
|
||||||
|
// 初始化广告队列
|
||||||
|
adIdQueue = BbbAdManager.config.adids
|
||||||
|
NSLog("XS- 初始化广告队列: \(adIdQueue)")
|
||||||
|
|
||||||
|
// 为所有广告创建管理器(但不加载)
|
||||||
|
for adId in BbbAdManager.config.adids {
|
||||||
|
BbbAdManager.shared.add(adId: adId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始串行加载第一个
|
||||||
|
loadNextAd()
|
||||||
|
|
||||||
|
NSLog("XS- load ad end")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载队列中的下一个广告
|
||||||
|
func loadNextAd() {
|
||||||
|
NSLog("XS- loadNextAd 被调用")
|
||||||
|
if adIdQueue.isEmpty {
|
||||||
|
NSLog("XS- 广告队列为空,所有广告已尝试加载")
|
||||||
|
YL_NetWorkManager.loadend()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let nextAdId = adIdQueue.removeFirst()
|
||||||
|
NSLog("XS- 尝试加载广告: \(nextAdId)")
|
||||||
|
if let adManager = adItems[nextAdId] {
|
||||||
|
NSLog("XS- 开始加载广告: \(nextAdId)")
|
||||||
|
adManager.load()
|
||||||
|
} else {
|
||||||
|
NSLog("XS- 未找到广告管理器: \(nextAdId),继续加载下一个")
|
||||||
|
loadNextAd()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func closeAd(v:Int) {
|
||||||
|
initializationTopOn.removeADVC(byDelayTime: v, onclose:{
|
||||||
|
for (_, ad) in BbbAdManager.shared.adItems {
|
||||||
|
if(ad.status == 3) {
|
||||||
|
ad.changeStatus(st: 4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
self.isshow = false
|
||||||
|
}
|
||||||
|
}
|
||||||
154
ironSource/PlayBTopOn/PlayBTopOn/playB/getIphone.swift
Normal file
154
ironSource/PlayBTopOn/PlayBTopOn/playB/getIphone.swift
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
//
|
||||||
|
// getIphone.swift
|
||||||
|
// playbtest
|
||||||
|
//
|
||||||
|
// Created by 忆海16 on 2024/12/31.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class getIpne {
|
||||||
|
static var shard = getIpne()
|
||||||
|
private init() {}
|
||||||
|
|
||||||
|
func getIPhoneModel() -> iPhoneModel {
|
||||||
|
var systemInfo = utsname()
|
||||||
|
uname(&systemInfo)
|
||||||
|
|
||||||
|
let machineMirror = Mirror(reflecting: systemInfo.machine)
|
||||||
|
let identifier = machineMirror.children.reduce("") { identifier, element in
|
||||||
|
guard let value = element.value as? Int8, value != 0 else { return identifier }
|
||||||
|
return identifier + String(UnicodeScalar(UInt8(value)))
|
||||||
|
}
|
||||||
|
|
||||||
|
switch identifier {
|
||||||
|
case "iPhone5,1", "iPhone5,2": return .iPhone5
|
||||||
|
case "iPhone5,3", "iPhone5,4": return .iPhone5C
|
||||||
|
case "iPhone6,1", "iPhone6,2": return .iPhone5S
|
||||||
|
case "iPhone7.2": return .iPhone6
|
||||||
|
case "iPhone7,1": return .iPhone6Plus
|
||||||
|
case "iPhone8,1": return .iPhone6s
|
||||||
|
case "iPhone8,2": return .iPhone6Plus
|
||||||
|
case "iPhone8,4": return .iPhoneSE1
|
||||||
|
case "iPhone9,1", "iPhone9,3": return .iPhone7
|
||||||
|
case "iPhone9,2", "iPhone9,4": return .iPhone7Plus
|
||||||
|
case "iPhone10,1", "iPhone10,4": return .iPhone8
|
||||||
|
case "iPhone10,2", "iPhone10,5": return .iPhone8Plus
|
||||||
|
case "iPhone10,3", "iPhone10,6": return .iPhoneX
|
||||||
|
case "iPhone11,8": return .iPhoneXR
|
||||||
|
case "iPhone11,2": return .iPhoneXS
|
||||||
|
case "iPhone11,6", "iPhone11,4": return .iPhoneXSMax
|
||||||
|
case "iPhone12,1": return .iPhone11
|
||||||
|
case "iPhone12,3": return .iPhone11Pro
|
||||||
|
case "iPhone12,5": return .iPhone11ProMax
|
||||||
|
case "iPhone12,8": return .iPhoneSE2
|
||||||
|
case "iPhone13,1": return .iPhone12Mini
|
||||||
|
case "iPhone13,2": return .iPhone12
|
||||||
|
case "iPhone13,3": return .iPhone12Pro
|
||||||
|
case "iPhone13,4": return .iPhone12ProMax
|
||||||
|
case "iPhone14,4": return .iPhone13Mini
|
||||||
|
case "iPhone14,5": return .iPhone13
|
||||||
|
case "iPhone14,2": return .iPhone13Pro
|
||||||
|
case "iPhone14,3": return .iPhone13ProMax
|
||||||
|
case "iPhone14,6": return .iPhoneSE3
|
||||||
|
case "iPhone14,7": return .iPhone14
|
||||||
|
case "iPhone14,8": return .iPhone14Plus
|
||||||
|
case "iPhone15,2": return .iPhone14Pro
|
||||||
|
case "iPhone15,3": return .iPhone14ProMax
|
||||||
|
case "iPhone15,4": return .iPhone15
|
||||||
|
case "iPhone15,5": return .iPhone15Plus
|
||||||
|
case "iPhone16,1": return .iPhone15Pro
|
||||||
|
case "iPhone16,2": return .iPhone15ProMax
|
||||||
|
case "i386": return .simulator
|
||||||
|
case "x86_64": return .simulator
|
||||||
|
default: return .unknown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum iPhoneModel {
|
||||||
|
case iPhone15
|
||||||
|
case iPhone15Plus
|
||||||
|
case iPhone15Pro
|
||||||
|
case iPhone15ProMax
|
||||||
|
case iPhone14
|
||||||
|
case iPhone14Plus
|
||||||
|
case iPhone14Pro
|
||||||
|
case iPhone14ProMax
|
||||||
|
case iPhone13ProMax
|
||||||
|
case iPhone13Pro
|
||||||
|
case iPhone13
|
||||||
|
case iPhone13Mini
|
||||||
|
case iPhone12ProMax
|
||||||
|
case iPhone12Pro
|
||||||
|
case iPhone12
|
||||||
|
case iPhone12Mini
|
||||||
|
case iPhone11ProMax
|
||||||
|
case iPhone11Pro
|
||||||
|
case iPhone11
|
||||||
|
case iPhoneXSMax
|
||||||
|
case iPhoneXS
|
||||||
|
case iPhoneXR
|
||||||
|
case iPhoneX
|
||||||
|
case iPhone8Plus
|
||||||
|
case iPhone8
|
||||||
|
case iPhone7Plus
|
||||||
|
case iPhone7
|
||||||
|
case iPhone6sPlus
|
||||||
|
case iPhone6s
|
||||||
|
case iPhone6Plus
|
||||||
|
case iPhone6
|
||||||
|
case iPhone5S
|
||||||
|
case iPhone5C
|
||||||
|
case iPhone5
|
||||||
|
case iPhoneSE3
|
||||||
|
case iPhoneSE2
|
||||||
|
case iPhoneSE1
|
||||||
|
case simulator
|
||||||
|
case unknown
|
||||||
|
|
||||||
|
public func getName() -> String {
|
||||||
|
switch self {
|
||||||
|
case .iPhone5: return "iPhone 5"
|
||||||
|
case .iPhone5C: return "iPhone 5C"
|
||||||
|
case .iPhone5S: return "iPhone 5S"
|
||||||
|
case .iPhone6: return "iPhone 6"
|
||||||
|
case .iPhone6Plus: return "iPhone 6 Plus"
|
||||||
|
case .iPhone6s: return "iPhone 6s"
|
||||||
|
case .iPhone6sPlus: return "iPhone 6s Plus"
|
||||||
|
case .iPhoneSE1: return "iPhone SE1"
|
||||||
|
case .iPhone7: return "iPhone 7"
|
||||||
|
case .iPhone7Plus: return "iPhone 7 Plus"
|
||||||
|
case .iPhone8: return "iPhone 8"
|
||||||
|
case .iPhone8Plus: return "iPhone 8 Plus"
|
||||||
|
case .iPhoneX: return "iPhone X"
|
||||||
|
case .iPhoneXR: return "iPhone XR"
|
||||||
|
case .iPhoneXS: return "iPhone XS"
|
||||||
|
case .iPhoneXSMax: return "iPhone XS Max"
|
||||||
|
case .iPhone11: return "iPhone 11"
|
||||||
|
case .iPhone11Pro: return "iPhone 11 Pro"
|
||||||
|
case .iPhone11ProMax: return "iPhone 11 Pro Max"
|
||||||
|
case .iPhoneSE2: return "iPhone SE2"
|
||||||
|
case .iPhone12Mini: return "iPhone 12 mini"
|
||||||
|
case .iPhone12: return "iPhone 12"
|
||||||
|
case .iPhone12Pro: return "iPhone 12 Pro"
|
||||||
|
case .iPhone12ProMax: return "iPhone 12 Pro Max"
|
||||||
|
case .iPhone13Mini: return "iPhone 13 mini"
|
||||||
|
case .iPhone13: return "iPhone 13"
|
||||||
|
case .iPhone13Pro: return "iPhone 13 Pro"
|
||||||
|
case .iPhone13ProMax: return "iPhone 13 Pro Max"
|
||||||
|
case .simulator: return "Simulator"
|
||||||
|
case .unknown: return "unknown"
|
||||||
|
case .iPhone14: return "iPhone 14"
|
||||||
|
case .iPhone14Plus: return "iPhone 14 Plus"
|
||||||
|
case .iPhone14Pro: return "iPhone 14 Pro"
|
||||||
|
case .iPhone14ProMax: return "iPhone 14 Pro Max"
|
||||||
|
case .iPhoneSE3: return "iPhone SE3"
|
||||||
|
case .iPhone15: return "iPhone 15"
|
||||||
|
case .iPhone15Plus: return "iPhone 15 Plus"
|
||||||
|
case .iPhone15Pro: return "iPhone 15 Pro"
|
||||||
|
case .iPhone15ProMax: return "iPhone 15 Pro Max"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
119
ironSource/PlayBTopOn/PlayBTopOn/playB/idfa.swift
Normal file
119
ironSource/PlayBTopOn/PlayBTopOn/playB/idfa.swift
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
//
|
||||||
|
// idfa.swift
|
||||||
|
// playbtest
|
||||||
|
//
|
||||||
|
// Created by 忆海16 on 2024/12/31.
|
||||||
|
//
|
||||||
|
|
||||||
|
import AdSupport
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// 注意:AppTrackingTransparency 需要在项目的 Build Settings 中设置为 "Optional" (弱链接)
|
||||||
|
// 否则在 iOS 12/13 上会因为找不到框架而崩溃
|
||||||
|
// 路径:项目设置 -> Build Phases -> Link Binary With Libraries -> AppTrackingTransparency.framework -> 设置为 Optional
|
||||||
|
|
||||||
|
#if canImport(AppTrackingTransparency)
|
||||||
|
import AppTrackingTransparency
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class IDFA {
|
||||||
|
static let shared = IDFA()
|
||||||
|
|
||||||
|
/// 检查并请求 ATT 授权(兼容 iOS 12+)
|
||||||
|
func checkATT(completion: @escaping (String?) -> Void) {
|
||||||
|
if #available(iOS 14, *) {
|
||||||
|
#if canImport(AppTrackingTransparency)
|
||||||
|
requestATTAuthorization(completion: completion)
|
||||||
|
#else
|
||||||
|
// 如果 AppTrackingTransparency 不可用,使用旧方法
|
||||||
|
getIDFAForOlderVersions(completion: completion)
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
// iOS 14 以下,使用旧方法
|
||||||
|
getIDFAForOlderVersions(completion: completion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// iOS 14+ 的 ATT 授权请求
|
||||||
|
#if canImport(AppTrackingTransparency)
|
||||||
|
@available(iOS 14, *)
|
||||||
|
private func requestATTAuthorization(completion: @escaping (String?) -> Void) {
|
||||||
|
let status = ATTrackingManager.trackingAuthorizationStatus
|
||||||
|
switch status {
|
||||||
|
case .notDetermined:
|
||||||
|
// 请求授权
|
||||||
|
ATTrackingManager.requestTrackingAuthorization { newStatus in
|
||||||
|
self.handleATTStatus(newStatus, completion: completion)
|
||||||
|
}
|
||||||
|
case .authorized, .denied, .restricted:
|
||||||
|
// 处理已有的状态
|
||||||
|
handleATTStatus(status, completion: completion)
|
||||||
|
@unknown default:
|
||||||
|
completion(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 处理 ATT 授权状态
|
||||||
|
@available(iOS 14, *)
|
||||||
|
private func handleATTStatus(
|
||||||
|
_ status: ATTrackingManager.AuthorizationStatus,
|
||||||
|
completion: @escaping (String?) -> Void
|
||||||
|
) {
|
||||||
|
switch status {
|
||||||
|
case .authorized:
|
||||||
|
// 用户已授权,获取 IDFA
|
||||||
|
let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
|
||||||
|
completion(idfa)
|
||||||
|
case .denied, .restricted:
|
||||||
|
// 用户拒绝或受限,返回 nil
|
||||||
|
print("用户拒绝授权或功能受限")
|
||||||
|
completion(nil)
|
||||||
|
case .notDetermined:
|
||||||
|
// 不应该出现,预防性处理
|
||||||
|
print("授权状态仍未确定")
|
||||||
|
completion(nil)
|
||||||
|
@unknown default:
|
||||||
|
completion(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// iOS 14 以下版本获取 IDFA
|
||||||
|
func getIDFAForOlderVersions(completion: @escaping (String?) -> Void) {
|
||||||
|
if ASIdentifierManager.shared().isAdvertisingTrackingEnabled {
|
||||||
|
let idfa = ASIdentifierManager.shared().advertisingIdentifier
|
||||||
|
.uuidString
|
||||||
|
completion(idfa)
|
||||||
|
} else {
|
||||||
|
print("广告跟踪受限")
|
||||||
|
completion(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//func requestIDFA(completion: @escaping (String?) -> Void) {
|
||||||
|
// if #available(iOS 14.5, *) {
|
||||||
|
// // 检查跟踪授权状态
|
||||||
|
// ATTrackingManager.requestTrackingAuthorization { status in
|
||||||
|
// switch status {
|
||||||
|
// case .authorized:
|
||||||
|
// // 用户授权后,获取 IDFA
|
||||||
|
// let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
|
||||||
|
// completion(idfa)
|
||||||
|
// case .denied, .restricted, .notDetermined:
|
||||||
|
// // 用户拒绝、限制或未决定时,IDFA 将不可用
|
||||||
|
// completion(nil)
|
||||||
|
// @unknown default:
|
||||||
|
// completion(nil)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// // 对于 iOS 14.4 及以下版本,直接获取 IDFA
|
||||||
|
// if ASIdentifierManager.shared().isAdvertisingTrackingEnabled {
|
||||||
|
// let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
|
||||||
|
// completion(idfa)
|
||||||
|
// } else {
|
||||||
|
// completion(nil)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
37
ironSource/PlayBTopOn/PlayBTopOn/playB/initializationTopOn.h
Normal file
37
ironSource/PlayBTopOn/PlayBTopOn/playB/initializationTopOn.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
//
|
||||||
|
// test.h
|
||||||
|
// wallpaper_project
|
||||||
|
//
|
||||||
|
// Created by 忆海16 on 2024/8/2.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import <execinfo.h>
|
||||||
|
#import <dlfcn.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
typedef void (^OnClose) (void);
|
||||||
|
|
||||||
|
void post(id dic, NSString* p);
|
||||||
|
|
||||||
|
@interface initializationTopOn : NSObject
|
||||||
|
|
||||||
|
+(void)toponeSDK:(NSString*) appId appKey:(NSString*) appKey;
|
||||||
|
+ (void)ironSourceSDK:(NSString*)appKey
|
||||||
|
userId:(NSString*)userId
|
||||||
|
completion:(void (^)(BOOL success, NSError * _Nullable error))completion;
|
||||||
|
|
||||||
|
+ (void)closeADWindow;
|
||||||
|
|
||||||
|
+ (void)removeADVCByDelayTime:(NSInteger)delayTime onclose: (OnClose) onclose;
|
||||||
|
+ (void)performRandomClick;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface CallStackHelper : NSObject
|
||||||
|
+ (void)printDetailedCallStack;
|
||||||
|
+ (NSArray *)getCallStackSymbols;
|
||||||
|
+ (NSString *)getCallStackString;
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
1208
ironSource/PlayBTopOn/PlayBTopOn/playB/initializationTopOn.m
Normal file
1208
ironSource/PlayBTopOn/PlayBTopOn/playB/initializationTopOn.m
Normal file
File diff suppressed because it is too large
Load Diff
24
ironSource/PlayBTopOn/Podfile
Normal file
24
ironSource/PlayBTopOn/Podfile
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Uncomment the next line to define a global platform for your project
|
||||||
|
platform :ios, '12.0'
|
||||||
|
source 'http://192.168.9.103:8083/repository/ios-pods/'
|
||||||
|
target 'PlayBTopOn' do
|
||||||
|
# Comment the next line if you don't want to use dynamic frameworks
|
||||||
|
use_frameworks!
|
||||||
|
|
||||||
|
# Pods for PlayBTopOn
|
||||||
|
# pod 'TPNiOS','6.3.66'
|
||||||
|
# pod 'TPNVungleSDKAdapter','6.3.66'
|
||||||
|
# pod 'TPNMintegralSDKAdapter','6.3.66'
|
||||||
|
|
||||||
|
pod 'IronSourceSDK'
|
||||||
|
pod 'TPNiOS','6.4.93'
|
||||||
|
pod 'TPNVungleSDKAdapter','6.4.93'
|
||||||
|
pod 'TPNUnityAdsSDKAdapter','6.4.93.5'
|
||||||
|
pod 'TPNIronSourceSDKAdapter','6.4.93.1'
|
||||||
|
pod 'TPNPangleSDKAdapter','6.4.93.5'
|
||||||
|
pod 'TPNInmobiSDKAdapter','6.4.93'
|
||||||
|
pod 'TPNApplovinSDKAdapter','6.4.93.1'
|
||||||
|
pod 'TPNMintegralSDKAdapter','6.4.93'
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
120
ironSource/PlayBTopOn/Podfile.lock
Normal file
120
ironSource/PlayBTopOn/Podfile.lock
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
PODS:
|
||||||
|
- Ads-Global (7.8.0.5):
|
||||||
|
- Ads-Global/BUAdSDK (= 7.8.0.5)
|
||||||
|
- Ads-Global/BUAdSDK (7.8.0.5):
|
||||||
|
- Ads-Global/PangleSDK
|
||||||
|
- Ads-Global/TikTokBusinessSDK
|
||||||
|
- Ads-Global/PangleSDK (7.8.0.5)
|
||||||
|
- Ads-Global/TikTokBusinessSDK (7.8.0.5)
|
||||||
|
- AppLovinSDK (13.5.0)
|
||||||
|
- InMobiSDK (10.8.6)
|
||||||
|
- IronSourceAdQualitySDK (7.26.2)
|
||||||
|
- IronSourceSDK (8.11.0.0):
|
||||||
|
- IronSourceSDK/AdQuality (= 8.11.0.0)
|
||||||
|
- IronSourceSDK/Ads (= 8.11.0.0)
|
||||||
|
- IronSourceSDK/AdQuality (8.11.0.0):
|
||||||
|
- IronSourceAdQualitySDK (~> 7.26.1)
|
||||||
|
- IronSourceSDK/Ads (8.11.0.0)
|
||||||
|
- MintegralAdSDK/All (7.7.9):
|
||||||
|
- MintegralAdSDK/BannerAd
|
||||||
|
- MintegralAdSDK/BidNativeAd
|
||||||
|
- MintegralAdSDK/InterstitialVideoAd
|
||||||
|
- MintegralAdSDK/NativeAd
|
||||||
|
- MintegralAdSDK/NativeAdvancedAd
|
||||||
|
- MintegralAdSDK/NewInterstitialAd
|
||||||
|
- MintegralAdSDK/RewardVideoAd
|
||||||
|
- MintegralAdSDK/SplashAd
|
||||||
|
- MintegralAdSDK/BannerAd (7.7.9):
|
||||||
|
- MintegralAdSDK/NativeAd
|
||||||
|
- MintegralAdSDK/BidNativeAd (7.7.9):
|
||||||
|
- MintegralAdSDK/NativeAd
|
||||||
|
- MintegralAdSDK/InterstitialVideoAd (7.7.9):
|
||||||
|
- MintegralAdSDK/NativeAd
|
||||||
|
- MintegralAdSDK/NativeAd (7.7.9)
|
||||||
|
- MintegralAdSDK/NativeAdvancedAd (7.7.9):
|
||||||
|
- MintegralAdSDK/NativeAd
|
||||||
|
- MintegralAdSDK/NewInterstitialAd (7.7.9):
|
||||||
|
- MintegralAdSDK/InterstitialVideoAd
|
||||||
|
- MintegralAdSDK/NativeAd
|
||||||
|
- MintegralAdSDK/RewardVideoAd (7.7.9):
|
||||||
|
- MintegralAdSDK/NativeAd
|
||||||
|
- MintegralAdSDK/SplashAd (7.7.9):
|
||||||
|
- MintegralAdSDK/NativeAd
|
||||||
|
- TPNApplovinSDKAdapter (6.4.93.1):
|
||||||
|
- AppLovinSDK (= 13.5.0)
|
||||||
|
- TPNiOS (= 6.4.93)
|
||||||
|
- TPNInmobiSDKAdapter (6.4.93):
|
||||||
|
- InMobiSDK (= 10.8.6)
|
||||||
|
- TPNiOS (= 6.4.93)
|
||||||
|
- TPNiOS (6.4.93):
|
||||||
|
- TPNiOS/TPNSDK (= 6.4.93)
|
||||||
|
- TPNiOS/TPNSDK (6.4.93)
|
||||||
|
- TPNIronSourceSDKAdapter (6.4.93.1):
|
||||||
|
- IronSourceSDK (= 8.11.0)
|
||||||
|
- TPNiOS (= 6.4.93)
|
||||||
|
- TPNMintegralSDKAdapter (6.4.93):
|
||||||
|
- MintegralAdSDK/All (= 7.7.9)
|
||||||
|
- TPNiOS (= 6.4.93)
|
||||||
|
- TPNPangleSDKAdapter (6.4.93.5):
|
||||||
|
- Ads-Global (= 7.8.0.5)
|
||||||
|
- TPNiOS (= 6.4.93)
|
||||||
|
- TPNUnityAdsSDKAdapter (6.4.93.5):
|
||||||
|
- TPNiOS (= 6.4.93)
|
||||||
|
- UnityAds (= 4.16.4)
|
||||||
|
- TPNVungleSDKAdapter (6.4.93):
|
||||||
|
- TPNiOS (= 6.4.93)
|
||||||
|
- VungleAds (= 7.5.3)
|
||||||
|
- UnityAds (4.16.4)
|
||||||
|
- VungleAds (7.5.3)
|
||||||
|
|
||||||
|
DEPENDENCIES:
|
||||||
|
- IronSourceSDK
|
||||||
|
- TPNApplovinSDKAdapter (= 6.4.93.1)
|
||||||
|
- TPNInmobiSDKAdapter (= 6.4.93)
|
||||||
|
- TPNiOS (= 6.4.93)
|
||||||
|
- TPNIronSourceSDKAdapter (= 6.4.93.1)
|
||||||
|
- TPNMintegralSDKAdapter (= 6.4.93)
|
||||||
|
- TPNPangleSDKAdapter (= 6.4.93.5)
|
||||||
|
- TPNUnityAdsSDKAdapter (= 6.4.93.5)
|
||||||
|
- TPNVungleSDKAdapter (= 6.4.93)
|
||||||
|
|
||||||
|
SPEC REPOS:
|
||||||
|
trunk:
|
||||||
|
- Ads-Global
|
||||||
|
- AppLovinSDK
|
||||||
|
- InMobiSDK
|
||||||
|
- IronSourceAdQualitySDK
|
||||||
|
- IronSourceSDK
|
||||||
|
- MintegralAdSDK
|
||||||
|
- TPNApplovinSDKAdapter
|
||||||
|
- TPNInmobiSDKAdapter
|
||||||
|
- TPNiOS
|
||||||
|
- TPNIronSourceSDKAdapter
|
||||||
|
- TPNMintegralSDKAdapter
|
||||||
|
- TPNPangleSDKAdapter
|
||||||
|
- TPNUnityAdsSDKAdapter
|
||||||
|
- TPNVungleSDKAdapter
|
||||||
|
- UnityAds
|
||||||
|
- VungleAds
|
||||||
|
|
||||||
|
SPEC CHECKSUMS:
|
||||||
|
Ads-Global: f4958eaa8e92b32a05fab125fed7822be81cf878
|
||||||
|
AppLovinSDK: bf8974163120910e6b902e9610e7c5a2c0f577b6
|
||||||
|
InMobiSDK: a6e7bfbecb698c83183f42c5a3cfa1ac52f16bff
|
||||||
|
IronSourceAdQualitySDK: 03888a0ac60e1f24ff6277672c3184f00813af64
|
||||||
|
IronSourceSDK: 32eeb199f608b590112a8263028a485e50f8d1b7
|
||||||
|
MintegralAdSDK: 054814f99bb7e967b8974fe635d9005b225cbe42
|
||||||
|
TPNApplovinSDKAdapter: 84ae11eae89859cebc13fc7072b0a5e1e458553d
|
||||||
|
TPNInmobiSDKAdapter: 6942e9076af9e2e29321b675628ad60068692e3f
|
||||||
|
TPNiOS: 1c5f1a4a449e1e6483dffd3d6fef44dd41aa33e9
|
||||||
|
TPNIronSourceSDKAdapter: 37ccf8b61c371ae7068132192937aec2d31b5f1e
|
||||||
|
TPNMintegralSDKAdapter: dbaa2e5a1a1aeca587821682488d7bce240e2c7b
|
||||||
|
TPNPangleSDKAdapter: b31be2094b193313ff3634db5e946229922a6560
|
||||||
|
TPNUnityAdsSDKAdapter: 974e314f5d1977b95af39f766ace5520c54d39d7
|
||||||
|
TPNVungleSDKAdapter: 89ac6e8d8ef77f1650af22d8781c549fb3bcc3c9
|
||||||
|
UnityAds: 91a5d786c1e79fcbf702c525af4700158aeb36c8
|
||||||
|
VungleAds: 3b273eba0219680dbef90d51e690d165422702d9
|
||||||
|
|
||||||
|
PODFILE CHECKSUM: 670f54c3a0f27f69bfcc7ed4e3ee35e21fe2066c
|
||||||
|
|
||||||
|
COCOAPODS: 1.16.2
|
||||||
109
ironSource/PlayBTopOn/QUICK_START.md
Normal file
109
ironSource/PlayBTopOn/QUICK_START.md
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
# 🚀 快速开始 - iOS 12/13 兼容性修复
|
||||||
|
|
||||||
|
## ✅ 代码修复已完成
|
||||||
|
|
||||||
|
所有代码已经修复完成,现在只需要在 Xcode 中做一些配置即可。
|
||||||
|
|
||||||
|
## ⚡ 3 步完成配置
|
||||||
|
|
||||||
|
### 步骤 1: 修改 Deployment Target(5 分钟)
|
||||||
|
|
||||||
|
1. 打开项目:
|
||||||
|
```bash
|
||||||
|
open PlayBTopOn.xcworkspace
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 在 Xcode 中:
|
||||||
|
- 左侧选择项目 `PlayBTopOn`
|
||||||
|
- 选择 `PROJECT` → `PlayBTopOn`
|
||||||
|
- `Build Settings` → 搜索 "Deployment"
|
||||||
|
- `iOS Deployment Target` 改为 **12.0**
|
||||||
|
|
||||||
|
3. 同样地,配置 TARGETS:
|
||||||
|
- 选择 `TARGETS` → `PlayBTopOn`
|
||||||
|
- `General` → `Deployment Info`
|
||||||
|
- `iOS Deployment Target` 改为 **12.0**
|
||||||
|
|
||||||
|
### 步骤 2: 设置 AppTrackingTransparency 为弱链接(2 分钟)
|
||||||
|
|
||||||
|
1. 在 Xcode 中:
|
||||||
|
- 选择 `TARGETS` → `PlayBTopOn`
|
||||||
|
- 点击 `Build Phases` 标签
|
||||||
|
- 展开 `Link Binary With Libraries`
|
||||||
|
|
||||||
|
2. 找到或添加 `AppTrackingTransparency.framework`:
|
||||||
|
- 如果没有,点击 `+` 添加
|
||||||
|
- 将 Status 从 `Required` 改为 **`Optional`**
|
||||||
|
|
||||||
|
### 步骤 3: 重新编译(3 分钟)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 进入项目目录
|
||||||
|
cd /Users/mac/workspaces/projects/ios/build-ipa/ironSource/PlayBTopOn
|
||||||
|
|
||||||
|
# 2. 重新安装 Pods
|
||||||
|
pod install
|
||||||
|
|
||||||
|
# 3. 在 Xcode 中清理并编译
|
||||||
|
# Product → Clean Build Folder (Cmd+Shift+K)
|
||||||
|
# Product → Build (Cmd+B)
|
||||||
|
# Product → Run (Cmd+R)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎯 验证成功的标志
|
||||||
|
|
||||||
|
运行应用后,在控制台应该看到:
|
||||||
|
|
||||||
|
```
|
||||||
|
XS- app start: xxx
|
||||||
|
XS- BbbAdManager init 开始
|
||||||
|
XS- BbbAdManager init 完成
|
||||||
|
XS- init config ← 看到这个说明成功了!
|
||||||
|
XS- init config 1
|
||||||
|
XS- init config 2
|
||||||
|
XS- init config 3
|
||||||
|
```
|
||||||
|
|
||||||
|
## ❌ 常见错误
|
||||||
|
|
||||||
|
### 错误 1: 应用启动即崩溃,没有任何日志
|
||||||
|
**原因:** Deployment Target 还是 17.4
|
||||||
|
**解决:** 按照步骤 1 修改为 12.0
|
||||||
|
|
||||||
|
### 错误 2: 编译报错找不到 AppTrackingTransparency
|
||||||
|
**原因:** 框架未设置为 Optional
|
||||||
|
**解决:** 按照步骤 2 设置为 Optional
|
||||||
|
|
||||||
|
### 错误 3: 运行到 "XS- 开始创建 BbbAdManager.shared" 就崩溃
|
||||||
|
**原因:** 代码未更新(CheckedContinuation 问题)
|
||||||
|
**解决:** 确保已接受所有代码更改
|
||||||
|
|
||||||
|
## 📋 检查清单
|
||||||
|
|
||||||
|
- [ ] ✅ Deployment Target 改为 12.0(PROJECT 和 TARGET 都要改)
|
||||||
|
- [ ] ✅ AppTrackingTransparency 设为 Optional
|
||||||
|
- [ ] ✅ 运行 `pod install`
|
||||||
|
- [ ] ✅ Clean Build Folder
|
||||||
|
- [ ] ✅ 编译成功
|
||||||
|
- [ ] ✅ 运行成功,看到 "XS- init config" 日志
|
||||||
|
|
||||||
|
## 🆘 需要帮助?
|
||||||
|
|
||||||
|
如果遇到问题,查看详细文档:
|
||||||
|
|
||||||
|
| 问题类型 | 查看文档 |
|
||||||
|
|---------|---------|
|
||||||
|
| 崩溃定位 | [DEBUG_CRASH_GUIDE.md](./DEBUG_CRASH_GUIDE.md) |
|
||||||
|
| 关键修复说明 | [CRITICAL_FIX.md](./CRITICAL_FIX.md) |
|
||||||
|
| 完整配置指南 | [iOS12_COMPATIBILITY_GUIDE.md](./iOS12_COMPATIBILITY_GUIDE.md) |
|
||||||
|
| 所有修改记录 | [CHANGES_SUMMARY.md](./CHANGES_SUMMARY.md) |
|
||||||
|
|
||||||
|
## 🎉 完成!
|
||||||
|
|
||||||
|
配置完成后,你的应用就可以在 iOS 12、13、14、15、16、17 上运行了!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**最后更新:** 2025-01-01
|
||||||
|
**预计配置时间:** 10 分钟
|
||||||
|
**难度:** ⭐⭐ (简单)
|
||||||
314
ironSource/PlayBTopOn/SERIAL_LOAD_LOGIC.md
Normal file
314
ironSource/PlayBTopOn/SERIAL_LOAD_LOGIC.md
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
# 串行加载广告逻辑说明
|
||||||
|
|
||||||
|
## 🔄 新的加载逻辑
|
||||||
|
|
||||||
|
### 之前的问题
|
||||||
|
- ❌ 一次性加载 3 个广告(并行)
|
||||||
|
- ❌ 浪费资源和流量
|
||||||
|
- ❌ 可能导致频率限制
|
||||||
|
- ❌ 定时器轮询检查是否可以展示
|
||||||
|
|
||||||
|
### 现在的改进
|
||||||
|
- ✅ 一个一个加载(串行)
|
||||||
|
- ✅ 加载失败 → 自动加载下一个
|
||||||
|
- ✅ 加载成功 → 立即展示
|
||||||
|
- ✅ 不需要定时器
|
||||||
|
- ✅ 节省资源和流量
|
||||||
|
|
||||||
|
## 📊 完整流程
|
||||||
|
|
||||||
|
### 场景 1: 第一个广告就成功
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 初始化队列: [A, B, C]
|
||||||
|
↓
|
||||||
|
2. 加载广告 A
|
||||||
|
↓ 加载成功 (ecpm 满足条件)
|
||||||
|
3. 自动展示广告 A ✓
|
||||||
|
↓
|
||||||
|
4. 清空队列(不再加载 B 和 C)
|
||||||
|
↓
|
||||||
|
5. 用户关闭广告
|
||||||
|
↓
|
||||||
|
6. 结束
|
||||||
|
```
|
||||||
|
|
||||||
|
### 场景 2: 第一个广告失败,第二个成功
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 初始化队列: [A, B, C]
|
||||||
|
↓
|
||||||
|
2. 加载广告 A
|
||||||
|
↓ 加载失败 ✗
|
||||||
|
3. 从队列取出下一个: B
|
||||||
|
↓
|
||||||
|
4. 加载广告 B
|
||||||
|
↓ 加载成功 (ecpm 满足条件)
|
||||||
|
5. 自动展示广告 B ✓
|
||||||
|
↓
|
||||||
|
6. 清空队列(不再加载 C)
|
||||||
|
↓
|
||||||
|
7. 用户关闭广告
|
||||||
|
↓
|
||||||
|
8. 结束
|
||||||
|
```
|
||||||
|
|
||||||
|
### 场景 3: 广告 ecpm 不足
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 初始化队列: [A, B, C]
|
||||||
|
↓
|
||||||
|
2. 加载广告 A
|
||||||
|
↓ 加载成功,但 ecpm < 阈值 ✗
|
||||||
|
3. 从队列取出下一个: B
|
||||||
|
↓
|
||||||
|
4. 加载广告 B
|
||||||
|
↓ 加载成功 (ecpm 满足条件)
|
||||||
|
5. 自动展示广告 B ✓
|
||||||
|
```
|
||||||
|
|
||||||
|
### 场景 4: 展示失败
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 加载广告 A → 加载成功
|
||||||
|
↓
|
||||||
|
2. 尝试展示 → didFailToDisplayAd
|
||||||
|
↓ "Cannot engage offer"
|
||||||
|
3. 触发 onAdClosed 回调
|
||||||
|
↓
|
||||||
|
4. 检查队列是否还有广告
|
||||||
|
↓ 如果有
|
||||||
|
5. 1秒后加载下一个 (B)
|
||||||
|
↓
|
||||||
|
6. 加载成功 → 自动展示 B ✓
|
||||||
|
```
|
||||||
|
|
||||||
|
### 场景 5: 所有广告都失败
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 队列: [A, B, C]
|
||||||
|
↓
|
||||||
|
2. 加载 A → 失败 → 加载 B → 失败 → 加载 C → 失败
|
||||||
|
↓
|
||||||
|
3. 队列为空
|
||||||
|
↓
|
||||||
|
4. 日志: "广告队列已空,所有广告都已尝试加载"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔑 关键实现
|
||||||
|
|
||||||
|
### 1. 串行加载队列
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// 广告 ID 队列
|
||||||
|
private var adIdQueue: [String] = []
|
||||||
|
|
||||||
|
// 当前正在加载的广告
|
||||||
|
private var currentLoadingAdId: String?
|
||||||
|
|
||||||
|
// 是否正在加载
|
||||||
|
private var isLoadingAd = false
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 加载下一个广告
|
||||||
|
|
||||||
|
```swift
|
||||||
|
func loadNextAd() {
|
||||||
|
// 防止重复加载
|
||||||
|
if isLoadingAd { return }
|
||||||
|
|
||||||
|
// 队列为空,结束
|
||||||
|
if adIdQueue.isEmpty { return }
|
||||||
|
|
||||||
|
// 取出下一个
|
||||||
|
let nextAdId = adIdQueue.removeFirst()
|
||||||
|
isLoadingAd = true
|
||||||
|
|
||||||
|
// 开始加载
|
||||||
|
adItems[nextAdId]?.load()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 状态回调自动处理
|
||||||
|
|
||||||
|
```swift
|
||||||
|
adManager.onStatusChange = { id, st, ecpm in
|
||||||
|
if st == 2 {
|
||||||
|
// 加载完成 → 自动展示
|
||||||
|
self.autoShowLoadedAd(adId: id)
|
||||||
|
}
|
||||||
|
else if st == 5 {
|
||||||
|
// 加载失败 → 加载下一个
|
||||||
|
self.loadNextAd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 自动展示逻辑
|
||||||
|
|
||||||
|
```swift
|
||||||
|
private func autoShowLoadedAd(adId: String) {
|
||||||
|
isLoadingAd = false
|
||||||
|
|
||||||
|
// 检查 ecpm
|
||||||
|
if ad.ecpm < adbrush_ecpm {
|
||||||
|
loadNextAd() // 不满足,加载下一个
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 展示广告
|
||||||
|
let showResult = ad.show(viewController) {
|
||||||
|
self.isshow = false
|
||||||
|
|
||||||
|
// 关闭后,如果队列还有广告,继续加载
|
||||||
|
if !self.adIdQueue.isEmpty {
|
||||||
|
self.loadNextAd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if showResult {
|
||||||
|
self.isshow = true
|
||||||
|
adIdQueue.removeAll() // 成功后清空队列
|
||||||
|
} else {
|
||||||
|
loadNextAd() // 失败,加载下一个
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📝 日志示例
|
||||||
|
|
||||||
|
### 正常流程
|
||||||
|
|
||||||
|
```
|
||||||
|
XS- 初始化广告队列: ["A", "B", "C"]
|
||||||
|
XS- 添加广告位: A
|
||||||
|
XS- 添加广告位: B
|
||||||
|
XS- 添加广告位: C
|
||||||
|
XS- 开始加载广告 [1/3]: A
|
||||||
|
XS- ad load ok: A ecpm:0.05
|
||||||
|
XS- 广告加载完成,准备自动展示: A
|
||||||
|
XS- 广告满足条件,准备展示: ecpm=0.05 >= 0.0005
|
||||||
|
XS- ✓ 广告展示成功
|
||||||
|
XS- ✓✓✓ didDisplayAd 回调被触发: A
|
||||||
|
XS- 开始上报 uploadAD_Show: A
|
||||||
|
```
|
||||||
|
|
||||||
|
### 第一个失败,加载第二个
|
||||||
|
|
||||||
|
```
|
||||||
|
XS- 开始加载广告 [1/3]: A
|
||||||
|
XS- load A err: timeout
|
||||||
|
XS- 广告加载失败,尝试加载下一个
|
||||||
|
XS- 开始加载广告 [2/3]: B
|
||||||
|
XS- ad load ok: B ecpm:0.05
|
||||||
|
XS- 广告加载完成,准备自动展示: B
|
||||||
|
XS- ✓ 广告展示成功
|
||||||
|
```
|
||||||
|
|
||||||
|
### ecpm 不足
|
||||||
|
|
||||||
|
```
|
||||||
|
XS- 开始加载广告 [1/3]: A
|
||||||
|
XS- ad load ok: A ecpm:0.0003
|
||||||
|
XS- 广告 ecpm 不足: 0.0003 < 0.0005,尝试下一个
|
||||||
|
XS- 开始加载广告 [2/3]: B
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎯 优势
|
||||||
|
|
||||||
|
| 对比项 | 旧逻辑(并行) | 新逻辑(串行) |
|
||||||
|
|-------|-------------|-------------|
|
||||||
|
| 加载方式 | 同时加载 3 个 | 一个一个加载 |
|
||||||
|
| 资源消耗 | 高 | 低 |
|
||||||
|
| 流量消耗 | 高 | 低 |
|
||||||
|
| 触发展示 | 定时器轮询 | 加载完立即展示 |
|
||||||
|
| 响应速度 | 慢(等待定时器) | 快(立即展示) |
|
||||||
|
| 成功率 | 低(频率限制) | 高(按需加载) |
|
||||||
|
| 失败处理 | 等待定时器重试 | 立即加载下一个 |
|
||||||
|
|
||||||
|
## ⚙️ 配置说明
|
||||||
|
|
||||||
|
### 不再需要的配置
|
||||||
|
|
||||||
|
以下代码已经不再起作用(保留是为了兼容性):
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// YL_PlayVC.swift
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 4) {
|
||||||
|
BbbAdManager.shared.start() // 不再需要
|
||||||
|
}
|
||||||
|
|
||||||
|
// bbbAdManager.swift
|
||||||
|
func start() {
|
||||||
|
// 新逻辑下不需要定时器
|
||||||
|
}
|
||||||
|
|
||||||
|
func showAd(v:UIViewController) {
|
||||||
|
// 新逻辑下由 autoShowLoadedAd 自动处理
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 新的流程
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// YL_PlayVC.swift
|
||||||
|
BbbAdManager.shared.waitForSDKInitialization {
|
||||||
|
BbbAdManager.shared.loadAd(view: self)
|
||||||
|
// loadAd 会自动开始串行加载
|
||||||
|
// 加载完成后自动展示
|
||||||
|
// 不需要调用 start()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 可选优化
|
||||||
|
|
||||||
|
### 1. 调整展示失败后的延迟
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// 在 autoShowLoadedAd 的关闭回调中
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { // 可调整延迟时间
|
||||||
|
strongSelf.loadNextAd()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 添加最大重试次数
|
||||||
|
|
||||||
|
```swift
|
||||||
|
private var maxLoadAttempts = 3
|
||||||
|
private var currentAttempt = 0
|
||||||
|
|
||||||
|
func loadNextAd() {
|
||||||
|
if currentAttempt >= maxLoadAttempts {
|
||||||
|
NSLog("达到最大重试次数,停止加载")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
currentAttempt += 1
|
||||||
|
// ... 继续加载
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 记录失败原因
|
||||||
|
|
||||||
|
```swift
|
||||||
|
private var failedAds: [String: String] = [:] // adId -> error
|
||||||
|
|
||||||
|
// 在加载失败时记录
|
||||||
|
failedAds[adId] = error.localizedDescription
|
||||||
|
```
|
||||||
|
|
||||||
|
## ✅ 总结
|
||||||
|
|
||||||
|
新的串行加载逻辑:
|
||||||
|
- ✅ 更节省资源(按需加载)
|
||||||
|
- ✅ 响应更快(加载完立即展示)
|
||||||
|
- ✅ 成功率更高(避免频率限制)
|
||||||
|
- ✅ 逻辑更清晰(状态驱动)
|
||||||
|
- ✅ 日志更完整(每一步都有记录)
|
||||||
|
|
||||||
|
重新编译运行后,你会看到广告一个一个地加载和展示!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**修改时间:** 2025-01-04
|
||||||
|
**主要改进:** 并行 → 串行,定时器轮询 → 事件驱动
|
||||||
|
**向后兼容:** ✅ 保留了 start() 和 showAd() 方法
|
||||||
234
ironSource/PlayBTopOn/SERIAL_VS_PARALLEL.md
Normal file
234
ironSource/PlayBTopOn/SERIAL_VS_PARALLEL.md
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
# 串行加载 vs 并行加载对比
|
||||||
|
|
||||||
|
## 📊 旧逻辑(并行加载)
|
||||||
|
|
||||||
|
```
|
||||||
|
时间轴:
|
||||||
|
0s ┌──────┐
|
||||||
|
│loadAd│ 启动
|
||||||
|
└──┬───┘
|
||||||
|
├─────────┐
|
||||||
|
1s │ 加载 A │
|
||||||
|
├─────────┤
|
||||||
|
2s │ 加载 B │ (同时进行)
|
||||||
|
├─────────┤
|
||||||
|
3s │ 加载 C │
|
||||||
|
└─────────┘
|
||||||
|
4s ┌──────┐
|
||||||
|
│start │ 启动定时器
|
||||||
|
└──┬───┘
|
||||||
|
│
|
||||||
|
5s ├→ 检查是否有可展示的广告
|
||||||
|
6s ├→ 检查
|
||||||
|
7s ├→ 检查
|
||||||
|
8s ├→ 检查(找到 A,ecpm 满足)
|
||||||
|
├→ 展示 A ✓
|
||||||
|
|
||||||
|
问题:
|
||||||
|
❌ 浪费:B 和 C 也加载了但可能用不上
|
||||||
|
❌ 等待:4-8秒才检查到可以展示
|
||||||
|
❌ 频率限制:3个广告同时请求
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎯 新逻辑(串行加载)
|
||||||
|
|
||||||
|
```
|
||||||
|
时间轴:
|
||||||
|
0s ┌──────┐
|
||||||
|
│loadAd│ 启动
|
||||||
|
└──┬───┘
|
||||||
|
│
|
||||||
|
0.5s ├─────────┐
|
||||||
|
│ 加载 A │
|
||||||
|
└─────────┘
|
||||||
|
1.5s ↓ 成功!ecpm 满足
|
||||||
|
├→ 立即展示 A ✓
|
||||||
|
|
||||||
|
优势:
|
||||||
|
✓ 节省:只加载了 A
|
||||||
|
✓ 快速:1.5秒就展示
|
||||||
|
✓ 成功率高:单个请求不触发频率限制
|
||||||
|
|
||||||
|
如果 A 失败的情况:
|
||||||
|
0.5s ├─────────┐
|
||||||
|
│ 加载 A │
|
||||||
|
└─────────┘
|
||||||
|
1.5s ↓ 失败 ✗
|
||||||
|
1.6s ├─────────┐
|
||||||
|
│ 加载 B │
|
||||||
|
└─────────┘
|
||||||
|
2.6s ↓ 成功!
|
||||||
|
├→ 立即展示 B ✓
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📈 性能对比
|
||||||
|
|
||||||
|
| 指标 | 旧逻辑 | 新逻辑 | 改进 |
|
||||||
|
|-----|--------|--------|------|
|
||||||
|
| 最快展示时间 | ~8秒 | ~1.5秒 | **5倍提速** |
|
||||||
|
| 平均流量消耗 | 3个广告 | 1-2个广告 | **节省50%+** |
|
||||||
|
| SDK请求次数 | 3次 | 1-3次 | **按需请求** |
|
||||||
|
| CPU占用 | 定时器持续轮询 | 事件驱动 | **更低** |
|
||||||
|
| 成功率 | 受频率限制影响 | 避免频率限制 | **更高** |
|
||||||
|
|
||||||
|
## 🔄 真实场景模拟
|
||||||
|
|
||||||
|
### 场景A: 第一个就成功(最常见)
|
||||||
|
|
||||||
|
**旧逻辑:**
|
||||||
|
```
|
||||||
|
0s: 加载 A、B、C(同时)
|
||||||
|
5s: A完成(✓), B完成(✓), C完成(✓)
|
||||||
|
8s: 定时器检查 → 展示A
|
||||||
|
总耗时: 8秒
|
||||||
|
浪费: B和C的流量
|
||||||
|
```
|
||||||
|
|
||||||
|
**新逻辑:**
|
||||||
|
```
|
||||||
|
0s: 加载 A
|
||||||
|
1.5s: A完成(✓) → 立即展示A
|
||||||
|
总耗时: 1.5秒
|
||||||
|
浪费: 0
|
||||||
|
```
|
||||||
|
|
||||||
|
### 场景B: 第一个失败,第二个成功
|
||||||
|
|
||||||
|
**旧逻辑:**
|
||||||
|
```
|
||||||
|
0s: 加载 A、B、C(同时)
|
||||||
|
5s: A失败(✗), B完成(✓), C完成(✓)
|
||||||
|
8s: 定时器检查 → 跳过A → 展示B
|
||||||
|
总耗时: 8秒
|
||||||
|
浪费: C的流量
|
||||||
|
```
|
||||||
|
|
||||||
|
**新逻辑:**
|
||||||
|
```
|
||||||
|
0s: 加载 A
|
||||||
|
1.5s: A失败(✗) → 立即加载B
|
||||||
|
3s: B完成(✓) → 立即展示B
|
||||||
|
总耗时: 3秒
|
||||||
|
浪费: 0
|
||||||
|
```
|
||||||
|
|
||||||
|
### 场景C: ecpm不足需要多个
|
||||||
|
|
||||||
|
**旧逻辑:**
|
||||||
|
```
|
||||||
|
0s: 加载 A、B、C(同时)
|
||||||
|
5s: A(ecpm低), B(ecpm低), C(ecpm高)
|
||||||
|
8s: 定时器检查 → 跳过A,B → 展示C
|
||||||
|
总耗时: 8秒
|
||||||
|
```
|
||||||
|
|
||||||
|
**新逻辑:**
|
||||||
|
```
|
||||||
|
0s: 加载 A
|
||||||
|
1.5s: A完成但ecpm低 → 立即加载B
|
||||||
|
3s: B完成但ecpm低 → 立即加载C
|
||||||
|
4.5s: C完成ecpm高 → 立即展示C
|
||||||
|
总耗时: 4.5秒
|
||||||
|
```
|
||||||
|
|
||||||
|
## 💰 成本节省(每天10000次展示)
|
||||||
|
|
||||||
|
### 流量成本
|
||||||
|
|
||||||
|
**旧逻辑:**
|
||||||
|
```
|
||||||
|
每次展示加载: 3个广告
|
||||||
|
每个广告请求: ~50KB
|
||||||
|
每天: 10000 × 3 × 50KB = 1.43GB
|
||||||
|
```
|
||||||
|
|
||||||
|
**新逻辑:**
|
||||||
|
```
|
||||||
|
成功率80%,平均1.2个广告
|
||||||
|
每天: 10000 × 1.2 × 50KB = 0.57GB
|
||||||
|
节省: 0.86GB (60%)
|
||||||
|
```
|
||||||
|
|
||||||
|
### SDK请求配额
|
||||||
|
|
||||||
|
很多 SDK 有每日请求限制,新逻辑可以:
|
||||||
|
- 减少请求次数
|
||||||
|
- 延长配额使用时间
|
||||||
|
- 避免触发频率限制
|
||||||
|
|
||||||
|
## 📱 用户体验对比
|
||||||
|
|
||||||
|
| 用户场景 | 旧逻辑 | 新逻辑 |
|
||||||
|
|---------|--------|--------|
|
||||||
|
| 打开应用到看到广告 | 8-10秒 | 1.5-3秒 |
|
||||||
|
| 等待时的体验 | 长时间空白 | 快速响应 |
|
||||||
|
| 流量消耗感知 | 高(后台偷跑流量) | 低(按需加载) |
|
||||||
|
| 应用流畅度 | 卡顿(同时3个请求) | 流畅(单个请求) |
|
||||||
|
|
||||||
|
## 🎯 最佳实践建议
|
||||||
|
|
||||||
|
### 1. 广告位优先级排序
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// 按 ecpm 历史数据排序
|
||||||
|
var adids = config.allAdIds.sorted {
|
||||||
|
getHistoryEcpm($0) > getHistoryEcpm($1)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 添加超时机制
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// 单个广告加载超时
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
|
||||||
|
if self.isLoadingAd && self.currentLoadingAdId == adId {
|
||||||
|
self.loadNextAd() // 超时,加载下一个
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 智能重试
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// 网络错误可以重试,其他错误跳过
|
||||||
|
if error.code == .networkError {
|
||||||
|
retry(adId)
|
||||||
|
} else {
|
||||||
|
loadNextAd()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## ✅ 迁移检查清单
|
||||||
|
|
||||||
|
- [x] 修改 `add(adId:)` 方法,不立即加载
|
||||||
|
- [x] 添加队列管理逻辑
|
||||||
|
- [x] 实现 `loadNextAd()` 方法
|
||||||
|
- [x] 实现 `autoShowLoadedAd()` 方法
|
||||||
|
- [x] 修改状态回调处理
|
||||||
|
- [x] 移除定时器依赖
|
||||||
|
- [x] 保持 API 兼容性
|
||||||
|
- [x] 添加详细日志
|
||||||
|
- [x] 测试各种场景
|
||||||
|
|
||||||
|
## 🚀 预期结果
|
||||||
|
|
||||||
|
重新编译运行后,你会看到:
|
||||||
|
|
||||||
|
```
|
||||||
|
✅ 日志更清晰:
|
||||||
|
"开始加载广告 [1/3]: A"
|
||||||
|
"开始加载广告 [2/3]: B"
|
||||||
|
|
||||||
|
✅ 展示更快速:
|
||||||
|
1-3秒内展示(vs 之前的8秒)
|
||||||
|
|
||||||
|
✅ 流量更节省:
|
||||||
|
平均只加载1.2个广告(vs 之前的3个)
|
||||||
|
|
||||||
|
✅ 成功率更高:
|
||||||
|
避免频率限制,自动尝试下一个
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**总结:** 新的串行加载逻辑在速度、成本、成功率上都有显著提升!🎉
|
||||||
205
ironSource/PlayBTopOn/check_ios12_compatibility.sh
Executable file
205
ironSource/PlayBTopOn/check_ios12_compatibility.sh
Executable file
@ -0,0 +1,205 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# iOS 12/13 兼容性检查脚本
|
||||||
|
# 用于验证项目是否正确配置以支持低版本 iOS
|
||||||
|
|
||||||
|
echo "======================================"
|
||||||
|
echo "iOS 12/13 兼容性检查"
|
||||||
|
echo "======================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
ERRORS=0
|
||||||
|
WARNINGS=0
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# 检查函数
|
||||||
|
check_passed() {
|
||||||
|
echo -e "${GREEN}✓${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_failed() {
|
||||||
|
echo -e "${RED}✗${NC} $1"
|
||||||
|
ERRORS=$((ERRORS + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
check_warning() {
|
||||||
|
echo -e "${YELLOW}⚠${NC} $1"
|
||||||
|
WARNINGS=$((WARNINGS + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "1. 检查代码中是否还有 Task 关键字(Swift Concurrency)..."
|
||||||
|
if grep -r "Task\s*{" "$PROJECT_DIR/PlayBTopOn" --include="*.swift" 2>/dev/null | grep -v "//"; then
|
||||||
|
check_failed "发现未处理的 Task 调用,这会在 iOS 15 以下崩溃"
|
||||||
|
else
|
||||||
|
check_passed "未发现 Task 调用"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "2. 检查代码中是否有未保护的 async/await..."
|
||||||
|
# 检查 async 函数,同时检查前一行是否有 @available 或 #if 保护
|
||||||
|
UNPROTECTED_ASYNC=0
|
||||||
|
while IFS= read -r file; do
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
# 使用 awk 检查每个 async 函数前是否有保护
|
||||||
|
UNPROTECTED=$(awk '
|
||||||
|
/func.*async/ {
|
||||||
|
protected = 0
|
||||||
|
for (i = 1; i <= 3; i++) {
|
||||||
|
line_num = NR - i
|
||||||
|
if (line_num in lines) {
|
||||||
|
if (lines[line_num] ~ /@available/ || lines[line_num] ~ /#if/) {
|
||||||
|
protected = 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!protected && !/\/\//) print NR": "$0
|
||||||
|
}
|
||||||
|
{ lines[NR] = $0 }
|
||||||
|
' "$file")
|
||||||
|
if [ -n "$UNPROTECTED" ]; then
|
||||||
|
UNPROTECTED_ASYNC=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done < <(find "$PROJECT_DIR/PlayBTopOn" -name "*.swift" 2>/dev/null)
|
||||||
|
|
||||||
|
if [ "$UNPROTECTED_ASYNC" -eq 1 ]; then
|
||||||
|
check_warning "发现可能未保护的 async 函数(请手动确认)"
|
||||||
|
else
|
||||||
|
check_passed "所有 async 函数都已保护"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "3. 检查 AppTrackingTransparency 导入是否使用条件编译..."
|
||||||
|
# 检查 import AppTrackingTransparency 前面是否有 #if canImport
|
||||||
|
UNPROTECTED_IMPORTS=0
|
||||||
|
while IFS= read -r file; do
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
UNPROTECTED=$(awk '
|
||||||
|
/^import AppTrackingTransparency/ {
|
||||||
|
protected = 0
|
||||||
|
for (i = 1; i <= 2; i++) {
|
||||||
|
line_num = NR - i
|
||||||
|
if (line_num in lines) {
|
||||||
|
if (lines[line_num] ~ /#if canImport/) {
|
||||||
|
protected = 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!protected) print FILENAME":"NR": "$0
|
||||||
|
}
|
||||||
|
{ lines[NR] = $0 }
|
||||||
|
' "$file")
|
||||||
|
if [ -n "$UNPROTECTED" ]; then
|
||||||
|
echo "$UNPROTECTED"
|
||||||
|
UNPROTECTED_IMPORTS=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done < <(find "$PROJECT_DIR/PlayBTopOn" -name "*.swift" 2>/dev/null)
|
||||||
|
|
||||||
|
if [ "$UNPROTECTED_IMPORTS" -eq 1 ]; then
|
||||||
|
check_failed "发现无条件导入 AppTrackingTransparency,应使用 #if canImport()"
|
||||||
|
else
|
||||||
|
check_passed "AppTrackingTransparency 导入已正确保护"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "4. 检查 Podfile 的最低版本设置..."
|
||||||
|
if [ -f "$PROJECT_DIR/Podfile" ]; then
|
||||||
|
PLATFORM_VERSION=$(grep "platform :ios" "$PROJECT_DIR/Podfile" | grep -o "'[0-9.]*'" | tr -d "'")
|
||||||
|
if [ -n "$PLATFORM_VERSION" ]; then
|
||||||
|
MAJOR_VERSION=$(echo "$PLATFORM_VERSION" | cut -d. -f1)
|
||||||
|
if [ "$MAJOR_VERSION" -le 12 ]; then
|
||||||
|
check_passed "Podfile 最低版本: iOS $PLATFORM_VERSION"
|
||||||
|
else
|
||||||
|
check_warning "Podfile 最低版本较高: iOS $PLATFORM_VERSION,建议设置为 12.0"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
check_warning "未在 Podfile 中找到 platform 版本设置"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
check_warning "未找到 Podfile 文件"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "5. 检查 Info.plist 配置..."
|
||||||
|
if [ -f "$PROJECT_DIR/PlayBTopOn/Info.plist" ]; then
|
||||||
|
check_passed "找到 Info.plist"
|
||||||
|
|
||||||
|
# 检查是否有 NSUserTrackingUsageDescription(如果要在 iOS 14+ 请求 ATT)
|
||||||
|
if grep -q "NSUserTrackingUsageDescription" "$PROJECT_DIR/PlayBTopOn/Info.plist"; then
|
||||||
|
check_passed "已配置 NSUserTrackingUsageDescription"
|
||||||
|
else
|
||||||
|
check_warning "未配置 NSUserTrackingUsageDescription(如需在 iOS 14+ 请求追踪权限,需要添加此项)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
check_failed "未找到 Info.plist"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "6. 检查项目配置文件..."
|
||||||
|
if [ -f "$PROJECT_DIR/PlayBTopOn.xcodeproj/project.pbxproj" ]; then
|
||||||
|
# 检查 Deployment Target
|
||||||
|
DEPLOYMENT_TARGET=$(grep "IPHONEOS_DEPLOYMENT_TARGET" "$PROJECT_DIR/PlayBTopOn.xcodeproj/project.pbxproj" | head -1 | grep -o "[0-9.]*" | head -1)
|
||||||
|
if [ -n "$DEPLOYMENT_TARGET" ]; then
|
||||||
|
MAJOR=$(echo "$DEPLOYMENT_TARGET" | cut -d. -f1)
|
||||||
|
if [ "$MAJOR" -le 12 ]; then
|
||||||
|
check_passed "Deployment Target: iOS $DEPLOYMENT_TARGET"
|
||||||
|
else
|
||||||
|
check_warning "Deployment Target 较高: iOS $DEPLOYMENT_TARGET,建议设置为 12.0"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查 AppTrackingTransparency 是否存在(但无法确定是否为 Optional)
|
||||||
|
if grep -q "AppTrackingTransparency" "$PROJECT_DIR/PlayBTopOn.xcodeproj/project.pbxproj"; then
|
||||||
|
check_warning "项目中引用了 AppTrackingTransparency - 请手动确认在 Xcode 中设置为 Optional"
|
||||||
|
else
|
||||||
|
check_warning "项目中未显式链接 AppTrackingTransparency(可能是自动链接)- 请在 Xcode 中确认"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
check_failed "未找到项目配置文件"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "7. 检查其他可能导致崩溃的代码模式..."
|
||||||
|
# 检查 @MainActor
|
||||||
|
if grep -r "@MainActor" "$PROJECT_DIR/PlayBTopOn" --include="*.swift" 2>/dev/null | grep -v "//"; then
|
||||||
|
check_warning "发现 @MainActor 注解(需要 iOS 15+),请确认已用 @available 保护"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查 AsyncStream
|
||||||
|
if grep -r "AsyncStream" "$PROJECT_DIR/PlayBTopOn" --include="*.swift" 2>/dev/null | grep -v "//"; then
|
||||||
|
check_warning "发现 AsyncStream(需要 iOS 15+),请确认已用 @available 保护"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "======================================"
|
||||||
|
echo "检查完成"
|
||||||
|
echo "======================================"
|
||||||
|
echo -e "错误: ${RED}$ERRORS${NC}"
|
||||||
|
echo -e "警告: ${YELLOW}$WARNINGS${NC}"
|
||||||
|
|
||||||
|
if [ $ERRORS -eq 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}✓ 代码修改看起来没有问题!${NC}"
|
||||||
|
echo ""
|
||||||
|
echo "⚠️ 重要提醒:"
|
||||||
|
echo "1. 请在 Xcode 中手动检查 AppTrackingTransparency.framework 是否设置为 Optional"
|
||||||
|
echo " 路径: Build Phases -> Link Binary With Libraries -> AppTrackingTransparency.framework -> Status: Optional"
|
||||||
|
echo ""
|
||||||
|
echo "2. 在 iOS 12/13 真机或模拟器上测试,确保不会崩溃"
|
||||||
|
echo ""
|
||||||
|
echo "详细配置指南请查看: iOS12_COMPATIBILITY_GUIDE.md"
|
||||||
|
else
|
||||||
|
echo ""
|
||||||
|
echo -e "${RED}✗ 发现 $ERRORS 个错误,请修复后再编译${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit $ERRORS
|
||||||
153
ironSource/PlayBTopOn/check_sdk_versions.sh
Executable file
153
ironSource/PlayBTopOn/check_sdk_versions.sh
Executable file
@ -0,0 +1,153 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# SDK 最低版本检查脚本
|
||||||
|
|
||||||
|
echo "======================================"
|
||||||
|
echo "检查广告 SDK 的最低支持版本"
|
||||||
|
echo "======================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
echo "1. 检查 Pods 目录..."
|
||||||
|
if [ ! -d "$PROJECT_DIR/Pods" ]; then
|
||||||
|
echo -e "${RED}✗ Pods 目录不存在,请先运行 pod install${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "2. 检查各个 SDK 的最低版本要求..."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 检查函数
|
||||||
|
check_sdk_version() {
|
||||||
|
local sdk_name=$1
|
||||||
|
local framework_path=$2
|
||||||
|
|
||||||
|
if [ -f "$framework_path" ]; then
|
||||||
|
echo "检查: $sdk_name"
|
||||||
|
|
||||||
|
# 尝试从 Info.plist 中提取最低版本
|
||||||
|
min_version=$(plutil -extract MinimumOSVersion raw "$framework_path" 2>/dev/null)
|
||||||
|
|
||||||
|
if [ $? -eq 0 ] && [ -n "$min_version" ]; then
|
||||||
|
major_version=$(echo "$min_version" | cut -d. -f1)
|
||||||
|
if [ "$major_version" -le 12 ]; then
|
||||||
|
echo -e " ${GREEN}✓${NC} 最低版本: iOS $min_version (支持 iOS 12)"
|
||||||
|
elif [ "$major_version" -eq 13 ]; then
|
||||||
|
echo -e " ${YELLOW}⚠${NC} 最低版本: iOS $min_version (不支持 iOS 12)"
|
||||||
|
else
|
||||||
|
echo -e " ${RED}✗${NC} 最低版本: iOS $min_version (不支持 iOS 12/13)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e " ${YELLOW}?${NC} 无法确定最低版本"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e " ${YELLOW}?${NC} 未找到: $sdk_name"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查各个广告 SDK
|
||||||
|
echo "检查 TopOn SDK:"
|
||||||
|
check_sdk_version "AnyThinkSDK" "$PROJECT_DIR/Pods/TPNiOS/core/AnyThinkSDK.xcframework/Info.plist"
|
||||||
|
|
||||||
|
echo "检查 IronSource SDK:"
|
||||||
|
check_sdk_version "IronSource" "$PROJECT_DIR/Pods/IronSourceSDK/IronSource/IronSource.xcframework/Info.plist"
|
||||||
|
|
||||||
|
echo "检查 Vungle SDK:"
|
||||||
|
if [ -d "$PROJECT_DIR/Pods/VungleAds" ]; then
|
||||||
|
check_sdk_version "VungleAds" "$PROJECT_DIR/Pods/VungleAds/static/VungleAds.xcframework/Info.plist"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "检查 UnityAds SDK:"
|
||||||
|
if [ -d "$PROJECT_DIR/Pods/UnityAds" ]; then
|
||||||
|
check_sdk_version "UnityAds" "$PROJECT_DIR/Pods/UnityAds/UnityAds.xcframework/Info.plist"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "检查 AppLovin SDK:"
|
||||||
|
if [ -d "$PROJECT_DIR/Pods/AppLovinSDK" ]; then
|
||||||
|
check_sdk_version "AppLovinSDK" "$PROJECT_DIR/Pods/AppLovinSDK/applovin-ios-sdk-13.5.0/AppLovinSDK.xcframework/Info.plist"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "检查 Pangle SDK:"
|
||||||
|
if [ -d "$PROJECT_DIR/Pods/Ads-Global" ]; then
|
||||||
|
check_sdk_version "PAGAdSDK" "$PROJECT_DIR/Pods/Ads-Global/SDK/PAGAdSDK.xcframework/Info.plist"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "======================================"
|
||||||
|
echo "3. 检查 Podfile 中的平台设置..."
|
||||||
|
echo "======================================"
|
||||||
|
|
||||||
|
if [ -f "$PROJECT_DIR/Podfile" ]; then
|
||||||
|
platform_line=$(grep "platform :ios" "$PROJECT_DIR/Podfile" | grep -v "^#")
|
||||||
|
if [ -n "$platform_line" ]; then
|
||||||
|
echo -e "${GREEN}✓${NC} 找到平台设置: $platform_line"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}⚠${NC} Podfile 中未设置 platform 版本(已被注释或不存在)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗${NC} 未找到 Podfile"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "======================================"
|
||||||
|
echo "4. 检查项目的 Deployment Target..."
|
||||||
|
echo "======================================"
|
||||||
|
|
||||||
|
if [ -f "$PROJECT_DIR/PlayBTopOn.xcodeproj/project.pbxproj" ]; then
|
||||||
|
deployment_target=$(grep "IPHONEOS_DEPLOYMENT_TARGET" "$PROJECT_DIR/PlayBTopOn.xcodeproj/project.pbxproj" | head -1 | grep -o "[0-9.]*" | head -1)
|
||||||
|
if [ -n "$deployment_target" ]; then
|
||||||
|
major=$(echo "$deployment_target" | cut -d. -f1)
|
||||||
|
if [ "$major" -le 12 ]; then
|
||||||
|
echo -e "${GREEN}✓${NC} 项目 Deployment Target: iOS $deployment_target"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}⚠${NC} 项目 Deployment Target: iOS $deployment_target (高于 iOS 12)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}?${NC} 无法确定 Deployment Target"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗${NC} 未找到项目文件"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "======================================"
|
||||||
|
echo "建议"
|
||||||
|
echo "======================================"
|
||||||
|
echo ""
|
||||||
|
echo "如果某个 SDK 的最低版本高于 iOS 12:"
|
||||||
|
echo ""
|
||||||
|
echo "方案 1: 将项目的最低版本提高到 iOS 13"
|
||||||
|
echo " - 修改 Podfile: platform :ios, '13.0'"
|
||||||
|
echo " - 运行: pod install"
|
||||||
|
echo " - 在 Xcode 中设置 Deployment Target 为 13.0"
|
||||||
|
echo ""
|
||||||
|
echo "方案 2: 降级到支持 iOS 12 的 SDK 版本"
|
||||||
|
echo " - 查看 SDK 的版本历史文档"
|
||||||
|
echo " - 在 Podfile 中指定旧版本号"
|
||||||
|
echo " - 运行: pod install"
|
||||||
|
echo ""
|
||||||
|
echo "方案 3: 移除不兼容的 SDK"
|
||||||
|
echo " - 在 Podfile 中注释掉对应的 pod"
|
||||||
|
echo " - 运行: pod install"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "======================================"
|
||||||
|
echo "接下来的步骤"
|
||||||
|
echo "======================================"
|
||||||
|
echo ""
|
||||||
|
echo "1. 运行 'pod install' 应用 Podfile 的更改"
|
||||||
|
echo "2. 在 Xcode 中设置 AppTrackingTransparency 为 Optional"
|
||||||
|
echo "3. 清理并重新编译项目"
|
||||||
|
echo "4. 查看控制台日志,定位崩溃点"
|
||||||
|
echo ""
|
||||||
|
echo "详细步骤请参考: DEBUG_CRASH_GUIDE.md"
|
||||||
|
echo ""
|
||||||
125
ironSource/PlayBTopOn/iOS12_COMPATIBILITY_GUIDE.md
Normal file
125
ironSource/PlayBTopOn/iOS12_COMPATIBILITY_GUIDE.md
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
# iOS 12/13 兼容性配置指南
|
||||||
|
|
||||||
|
## 问题说明
|
||||||
|
在 iOS 12/13 系统上,如果应用使用了 `AppTrackingTransparency` 框架(iOS 14+ 才有),即使代码中有 `@available(iOS 14, *)` 检查,应用启动时也会因为找不到该框架而直接崩溃。
|
||||||
|
|
||||||
|
## 已完成的代码修复
|
||||||
|
✅ 移除了所有 `Task { await ... }` 代码,改用 `DispatchQueue` 和回调
|
||||||
|
✅ 使用 `#if canImport(AppTrackingTransparency)` 条件编译
|
||||||
|
✅ 所有 async/await 代码都标记了 `@available(iOS 15.0, *)`
|
||||||
|
|
||||||
|
## 需要在 Xcode 中手动配置的步骤
|
||||||
|
|
||||||
|
### ⚠️ 重要:将 AppTrackingTransparency 设置为弱链接
|
||||||
|
|
||||||
|
1. **打开 Xcode 项目**
|
||||||
|
- 打开 `PlayBTopOn.xcworkspace`
|
||||||
|
|
||||||
|
2. **进入项目设置**
|
||||||
|
- 在左侧项目导航栏中,点击项目根节点 `PlayBTopOn`
|
||||||
|
- 选择 `TARGETS` -> `PlayBTopOn`
|
||||||
|
|
||||||
|
3. **配置弱链接**
|
||||||
|
- 选择 `Build Phases` 标签
|
||||||
|
- 展开 `Link Binary With Libraries`
|
||||||
|
- 找到或添加 `AppTrackingTransparency.framework`
|
||||||
|
- 将右侧的 `Status` 列从 `Required` 改为 `Optional`
|
||||||
|
|
||||||
|
**如果列表中没有 AppTrackingTransparency.framework:**
|
||||||
|
- 点击 `+` 按钮
|
||||||
|
- 搜索 `AppTrackingTransparency.framework`
|
||||||
|
- 添加后,将其状态设置为 `Optional`
|
||||||
|
|
||||||
|
4. **验证设置**
|
||||||
|
- 确保 `AppTrackingTransparency.framework` 的状态显示为 `Optional`
|
||||||
|
- 这样在 iOS 12/13 上,即使框架不存在,应用也不会崩溃
|
||||||
|
|
||||||
|
### 检查部署目标
|
||||||
|
|
||||||
|
1. **设置最低支持版本**
|
||||||
|
- 在 `TARGETS` -> `PlayBTopOn` -> `General` 标签
|
||||||
|
- 找到 `Deployment Info` 部分
|
||||||
|
- 将 `iOS Deployment Target` 设置为 `iOS 12.0`
|
||||||
|
|
||||||
|
2. **检查 Podfile**
|
||||||
|
- 打开项目根目录的 `Podfile`
|
||||||
|
- 确保第一行包含:`platform :ios, '12.0'`
|
||||||
|
- 如果修改了,运行 `pod install`
|
||||||
|
|
||||||
|
### 可选:添加 NSUserTrackingUsageDescription(如果需要在 iOS 14+ 上请求 IDFA)
|
||||||
|
|
||||||
|
如果你计划在 iOS 14+ 上请求用户授权追踪,需要在 `Info.plist` 中添加说明:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<key>NSUserTrackingUsageDescription</key>
|
||||||
|
<string>我们需要获取您的广告标识符以提供个性化广告体验</string>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 测试验证
|
||||||
|
|
||||||
|
### 在 iOS 12/13 设备或模拟器上测试
|
||||||
|
1. 选择 iOS 12 或 iOS 13 的模拟器
|
||||||
|
2. 清理项目:`Product` -> `Clean Build Folder` (Cmd+Shift+K)
|
||||||
|
3. 编译运行:`Product` -> `Run` (Cmd+R)
|
||||||
|
4. 检查控制台日志,确保没有崩溃
|
||||||
|
|
||||||
|
### 在 iOS 14+ 设备上测试
|
||||||
|
1. 选择 iOS 14+ 的模拟器或真机
|
||||||
|
2. 运行应用,ATT 功能应该正常工作
|
||||||
|
3. 检查是否能正常请求广告追踪权限
|
||||||
|
|
||||||
|
## 代码修改总结
|
||||||
|
|
||||||
|
### 1. AppDelegate.swift
|
||||||
|
- ❌ 移除:`Task { await BbbAdManager.shared.initAd() }`
|
||||||
|
- ✅ 替换:`DispatchQueue.global(qos: .userInitiated).async { BbbAdManager.shared.initAd() }`
|
||||||
|
|
||||||
|
### 2. YL_PlayVC.swift
|
||||||
|
- ❌ 移除:`Task { await BbbAdManager.shared.waitForSDKInitialization() ... }`
|
||||||
|
- ✅ 替换:`BbbAdManager.shared.waitForSDKInitialization { ... }`
|
||||||
|
|
||||||
|
### 3. bbbAdManager.swift
|
||||||
|
- ✅ 添加:基于回调的 `initAd(completion:)` 方法
|
||||||
|
- ✅ 添加:基于回调的 `waitForSDKInitialization(completion:)` 方法
|
||||||
|
- ✅ 保留:async/await 版本(标记 `@available(iOS 15.0, *)`)
|
||||||
|
|
||||||
|
### 4. idfa.swift
|
||||||
|
- ✅ 使用:`#if canImport(AppTrackingTransparency)` 条件编译
|
||||||
|
- ✅ 移除:文件顶部的无条件 `import AppTrackingTransparency`
|
||||||
|
|
||||||
|
### 5. YL_NetWorkManager.swift
|
||||||
|
- ✅ 使用:`#if canImport(AppTrackingTransparency)` 条件编译
|
||||||
|
- ✅ 保护:所有使用 `ATTrackingManager` 的代码
|
||||||
|
|
||||||
|
## 兼容性保证
|
||||||
|
|
||||||
|
| iOS 版本 | 支持状态 | 说明 |
|
||||||
|
|---------|---------|------|
|
||||||
|
| iOS 12.x | ✅ 完全支持 | 使用旧版 IDFA API |
|
||||||
|
| iOS 13.x | ✅ 完全支持 | 使用旧版 IDFA API |
|
||||||
|
| iOS 14.x | ✅ 完全支持 | 使用 ATT 框架 |
|
||||||
|
| iOS 15+ | ✅ 完全支持 | 支持 async/await + ATT |
|
||||||
|
|
||||||
|
## 常见问题
|
||||||
|
|
||||||
|
### Q: 为什么需要设置为 Optional?
|
||||||
|
A: 因为 AppTrackingTransparency.framework 在 iOS 14 才引入,iOS 12/13 系统中不存在这个框架。设置为 Optional 后,系统会在运行时动态加载,如果不存在也不会崩溃。
|
||||||
|
|
||||||
|
### Q: 代码中的 `#if canImport()` 是什么?
|
||||||
|
A: 这是编译时检查,确保只在可以导入该框架的环境下才编译相关代码。
|
||||||
|
|
||||||
|
### Q: 如果忘记设置 Optional 会怎样?
|
||||||
|
A: 应用会在 iOS 12/13 启动时立即崩溃,错误信息类似于 "dyld: Library not loaded: /System/Library/Frameworks/AppTrackingTransparency.framework"
|
||||||
|
|
||||||
|
## 编译和发布
|
||||||
|
|
||||||
|
编译通过后,可以正常打包发布:
|
||||||
|
- Archive: `Product` -> `Archive`
|
||||||
|
- 导出 IPA 进行分发测试
|
||||||
|
- 确保在不同 iOS 版本上都进行了测试
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**修复完成时间**: 2025-01-01
|
||||||
|
**最低支持版本**: iOS 12.0
|
||||||
|
**推荐测试版本**: iOS 12.5, iOS 13.7, iOS 14.8, iOS 15.0+
|
||||||
18
ironSource/build.sh
Executable file
18
ironSource/build.sh
Executable file
@ -0,0 +1,18 @@
|
|||||||
|
rm -rfv ./build/*
|
||||||
|
xcodebuild clean build -workspace ./PlayBTopOn/PlayBTopOn.xcworkspace -scheme PlayBTopOn -configuration Release -destination "platform=iOS,id=00008150-001114363E7A401C" -derivedDataPath "./build/Target"
|
||||||
|
|
||||||
|
mkdir ./build/ipas
|
||||||
|
cp -rfv ./build/Target/Build/Products/Release-iphoneos/PlayBTopOn.app ./build/ipas/
|
||||||
|
cp ./template/embedded.mobileprovision ./build/ipas/PlayBTopOn.app/embedded.mobileprovision
|
||||||
|
|
||||||
|
|
||||||
|
find "./build/ipas/PlayBTopOn.app" -name "*.framework" -exec codesign -f -s "iPhone Distribution: zhenming Liu (446WP85XYW)" {} \;
|
||||||
|
find "./build/ipas/PlayBTopOn.app" -name "*.dylib" -exec codesign -f -s "iPhone Distribution: zhenming Liu (446WP85XYW)" {} \;
|
||||||
|
|
||||||
|
echo "codesign"
|
||||||
|
codesign --entitlements ./template/Filza.entitlements -f -s "iPhone Distribution: zhenming Liu (446WP85XYW)" ./build/ipas/PlayBTopOn.app
|
||||||
|
|
||||||
|
mkdir ./build/ipas/Payload
|
||||||
|
mv ./build/ipas/PlayBTopOn.app ./build/ipas/Payload
|
||||||
|
cd ./build/ipas
|
||||||
|
zip -r playb-is.ipa Payload/
|
||||||
26
ironSource/template/Filza.entitlements
Normal file
26
ironSource/template/Filza.entitlements
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?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>application-identifier</key>
|
||||||
|
<string>T23C6PFSKY.forecast.barometer.storm.radar.Weather10</string>
|
||||||
|
<key>aps-environment</key>
|
||||||
|
<string>production</string>
|
||||||
|
<key>com.apple.developer.associated-domains</key>
|
||||||
|
<string>*</string>
|
||||||
|
<key>com.apple.developer.team-identifier</key>
|
||||||
|
<string>T23C6PFSKY</string>
|
||||||
|
<key>com.apple.security.application-groups</key>
|
||||||
|
<array>
|
||||||
|
<string>group.forecast.barometer.storm.radar.Weather10.appshortcallid</string>
|
||||||
|
<string>group.forecast.barometer.storm.radar.Weather10.appcallid</string>
|
||||||
|
</array>
|
||||||
|
<key>get-task-allow</key>
|
||||||
|
<true/>
|
||||||
|
<key>keychain-access-groups</key>
|
||||||
|
<array>
|
||||||
|
<string>T23C6PFSKY.*</string>
|
||||||
|
<string>com.apple.token</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
BIN
ironSource/template/embedded.mobileprovision
Normal file
BIN
ironSource/template/embedded.mobileprovision
Normal file
Binary file not shown.
10
max/build.py
10
max/build.py
@ -52,7 +52,7 @@ def build(ad_key, ad_ids, app_display_name,app_bundle_id,app_version,app_icon):
|
|||||||
cmd = """
|
cmd = """
|
||||||
cd ./build/playbtest
|
cd ./build/playbtest
|
||||||
pod install --repo-update
|
pod install --repo-update
|
||||||
xcodebuild clean build -workspace playbtest.xcworkspace -configuration Release -scheme playbtest -derivedDataPath "../Target" -destination "platform=iOS,id=00008110-000815AE1179801E"
|
xcodebuild clean build -workspace playbtest.xcworkspace -configuration Release -scheme playbtest -derivedDataPath "../Target" -destination "platform=iOS,id=00008150-001114363E7A401C"
|
||||||
cd ../../
|
cd ../../
|
||||||
"""
|
"""
|
||||||
subprocess.call(cmd, shell=True)
|
subprocess.call(cmd, shell=True)
|
||||||
@ -69,11 +69,11 @@ def build(ad_key, ad_ids, app_display_name,app_bundle_id,app_version,app_icon):
|
|||||||
mkdir ./build/ipas
|
mkdir ./build/ipas
|
||||||
cp -rf ./build/Target/Build/Products/Release-iphoneos/playbtest.app ./build/ipas/
|
cp -rf ./build/Target/Build/Products/Release-iphoneos/playbtest.app ./build/ipas/
|
||||||
|
|
||||||
find "./build/ipas/playbtest.app" -name "*.framework" -exec codesign -f -s "Apple Distribution: Haiyang Tang (544LFS79WN)" {} \;
|
find "./build/ipas/playbtest.app" -name "*.framework" -exec codesign -f -s "Apple Distribution: YX C (3AJQST798X)" {} \;
|
||||||
find "./build/ipas/playbtest.app" -name "*.dylib" -exec codesign -f -s "Apple Distribution: Haiyang Tang (544LFS79WN)" {} \;
|
find "./build/ipas/playbtest.app" -name "*.dylib" -exec codesign -f -s "Apple Distribution: YX C (3AJQST798X)" {} \;
|
||||||
cp ./template/embedded.mobileprovision ./build/ipas/playbtest.app/embedded.mobileprovision
|
cp ./template/embedded.mobileprovision ./build/ipas/playbtest.app/embedded.mobileprovision
|
||||||
echo "codesign"
|
echo "codesign"
|
||||||
codesign --entitlements ./template/Filza.entitlements -f -s "Apple Distribution: Haiyang Tang (544LFS79WN)" ./build/ipas/playbtest.app
|
codesign --entitlements ./template/Filza.entitlements -f -s "Apple Distribution: YX C (3AJQST798X)" ./build/ipas/playbtest.app
|
||||||
|
|
||||||
mkdir ./build/ipas/Payload
|
mkdir ./build/ipas/Payload
|
||||||
mv ./build/ipas/playbtest.app ./build/ipas/Payload
|
mv ./build/ipas/playbtest.app ./build/ipas/Payload
|
||||||
@ -86,7 +86,7 @@ def build(ad_key, ad_ids, app_display_name,app_bundle_id,app_version,app_icon):
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app_icon = "/Volumes/mfast/workspaces/projects/ios/lux-ipas/SpeedyColor/appicon.png"
|
app_icon = "/Users/mac/workspaces/projects/ios/lux-ipas/SpeedyColor/appicon.png"
|
||||||
if len(sys.argv) < 2:
|
if len(sys.argv) < 2:
|
||||||
ad_key = "Dd37BrtbLDlaeiDhxVzaDbsI67Mc1h5lAGIinzo4v2IbkpufdtVmT5Tag9O3aGexzkS4txEPigaEexktewANIk"
|
ad_key = "Dd37BrtbLDlaeiDhxVzaDbsI67Mc1h5lAGIinzo4v2IbkpufdtVmT5Tag9O3aGexzkS4txEPigaEexktewANIk"
|
||||||
ad_ids = ["7468dbe129ab2afe","7b61678bf643a84a","c6b7477edc2aff7e","28fd7967e71c9203"]
|
ad_ids = ["7468dbe129ab2afe","7b61678bf643a84a","c6b7477edc2aff7e","28fd7967e71c9203"]
|
||||||
|
|||||||
@ -8,7 +8,6 @@ target 'playbtest' do
|
|||||||
# Pods for playbtest
|
# Pods for playbtest
|
||||||
|
|
||||||
pod 'AppLovinSDK','13.3.1'
|
pod 'AppLovinSDK','13.3.1'
|
||||||
pod 'AppLovinDSPLinkedInAdapter'
|
|
||||||
pod 'AppLovinMediationVungleAdapter'
|
pod 'AppLovinMediationVungleAdapter'
|
||||||
pod 'AppLovinMediationMintegralAdapter'
|
pod 'AppLovinMediationMintegralAdapter'
|
||||||
|
|
||||||
|
|||||||
@ -28,6 +28,7 @@
|
|||||||
- (void)stop;
|
- (void)stop;
|
||||||
|
|
||||||
// 发送方法
|
// 发送方法
|
||||||
|
- (void)onLoad:(NSDictionary *)data toPort:(uint16_t)port;
|
||||||
- (void)onShow:(NSDictionary *)data toPort:(uint16_t)port;
|
- (void)onShow:(NSDictionary *)data toPort:(uint16_t)port;
|
||||||
- (void)onEnd:(NSDictionary *)data toPort:(uint16_t)port;
|
- (void)onEnd:(NSDictionary *)data toPort:(uint16_t)port;
|
||||||
- (void)send:(NSString *)msg toPort:(uint16_t)port;
|
- (void)send:(NSString *)msg toPort:(uint16_t)port;
|
||||||
|
|||||||
@ -24,18 +24,17 @@
|
|||||||
|
|
||||||
#pragma mark - Singleton
|
#pragma mark - Singleton
|
||||||
|
|
||||||
+ (instancetype)sharedInstance {
|
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
|
||||||
static XUDPClient *_sharedInstance = nil;
|
static XUDPClient *_sharedInstance = nil;
|
||||||
static dispatch_once_t oncePredicate;
|
static dispatch_once_t oncePredicate;
|
||||||
dispatch_once(&oncePredicate, ^{
|
dispatch_once(&oncePredicate, ^{
|
||||||
_sharedInstance = [[XUDPClient alloc] init];
|
_sharedInstance = [super allocWithZone:zone];
|
||||||
});
|
});
|
||||||
return _sharedInstance;
|
return _sharedInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ⭐️ 防止通过alloc/init创建新实例
|
+ (instancetype)sharedInstance {
|
||||||
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
|
return [[self alloc] init];
|
||||||
return [XUDPClient sharedInstance];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)copyWithZone:(NSZone *)zone {
|
- (instancetype)copyWithZone:(NSZone *)zone {
|
||||||
@ -246,6 +245,14 @@
|
|||||||
[self send:[self dic2Json:rq] toPort:port];
|
[self send:[self dic2Json:rq] toPort:port];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)onLoad:(NSDictionary *)data toPort:(uint16_t)port {
|
||||||
|
NSDictionary *rq = @{
|
||||||
|
@"url": @"/adtask/load",
|
||||||
|
@"body": data
|
||||||
|
};
|
||||||
|
[self send:[self dic2Json:rq] toPort:port];
|
||||||
|
}
|
||||||
|
|
||||||
// ⭐️ 发送到指定端口
|
// ⭐️ 发送到指定端口
|
||||||
- (void)onEnd:(NSDictionary *)data toPort:(uint16_t)port {
|
- (void)onEnd:(NSDictionary *)data toPort:(uint16_t)port {
|
||||||
NSDictionary *rq = @{
|
NSDictionary *rq = @{
|
||||||
|
|||||||
@ -21,8 +21,8 @@ class YL_NetWorkManager{
|
|||||||
static var kBaseUrl = YL_NetWorkManager.bFaceLocalUrl()
|
static var kBaseUrl = YL_NetWorkManager.bFaceLocalUrl()
|
||||||
|
|
||||||
static var kURL_AD_Start = "/top_selection/save_app_start_log"
|
static var kURL_AD_Start = "/top_selection/save_app_start_log"
|
||||||
static var kURL_AD_Load = "/top_selection/save_ad_load_log"
|
static var kURL_AD_Load = "/ios/ad_report/save_ad_load_log"
|
||||||
static var kURL_AD_Show = "/top_selection/save_ad_show_log"
|
static var kURL_AD_Show = "/ios/ad_report/save_ad_show_log"
|
||||||
static var kURL_save_logs = "/ios/top_selection/save_iphone_logs"
|
static var kURL_save_logs = "/ios/top_selection/save_iphone_logs"
|
||||||
static var isloadend = false
|
static var isloadend = false
|
||||||
|
|
||||||
@ -133,6 +133,56 @@ class YL_NetWorkManager{
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static func performGetRequest(url: String, parameters: [String: String], completion: @escaping (Error?, [String: Any]?) -> Void) {
|
||||||
|
guard var urlComponents = URLComponents(string: url) else {
|
||||||
|
print("Invalid URL")
|
||||||
|
completion(NSError(domain: "Invalid URL", code: 400, userInfo: nil), nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加 URL 参数
|
||||||
|
urlComponents.queryItems = parameters.map { URLQueryItem(name: $0.key, value: $0.value) }
|
||||||
|
|
||||||
|
guard let finalURL = urlComponents.url else {
|
||||||
|
print("Failed to construct URL with parameters")
|
||||||
|
completion(NSError(domain: "URL Construction Error", code: 400, userInfo: nil), nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var request = URLRequest(url: finalURL)
|
||||||
|
request.httpMethod = "GET"
|
||||||
|
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||||
|
|
||||||
|
let task = URLSession.shared.dataTask(with: request) { data, response, error in
|
||||||
|
if let error = error {
|
||||||
|
print("HTTP GET Request Error: \(error.localizedDescription)")
|
||||||
|
completion(error, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let data = data else {
|
||||||
|
print("No data received")
|
||||||
|
completion(NSError(domain: "No Data", code: 204, userInfo: nil), nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
|
||||||
|
completion(nil, json)
|
||||||
|
} else {
|
||||||
|
print("Failed to parse JSON")
|
||||||
|
completion(NSError(domain: "JSON Parsing Error", code: 500, userInfo: nil), nil)
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
print("Error parsing JSON: \(error.localizedDescription)")
|
||||||
|
completion(error, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task.resume()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 请求远程IP
|
// 请求远程IP
|
||||||
func requestRemoteIp() {
|
func requestRemoteIp() {
|
||||||
ipLoadTime = DispatchTime.now()
|
ipLoadTime = DispatchTime.now()
|
||||||
@ -262,6 +312,10 @@ class YL_NetWorkManager{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func getProductName() -> String {
|
||||||
|
return UIDevice.current.name
|
||||||
|
}
|
||||||
|
|
||||||
// 电池电量
|
// 电池电量
|
||||||
static func getBatteryLevel() -> Float? {
|
static func getBatteryLevel() -> Float? {
|
||||||
return UIDevice.current.batteryLevel
|
return UIDevice.current.batteryLevel
|
||||||
@ -847,12 +901,13 @@ class YL_NetWorkManager{
|
|||||||
errorMsg:String = ""
|
errorMsg:String = ""
|
||||||
) {
|
) {
|
||||||
var mdic: [String: Any] = [:]
|
var mdic: [String: Any] = [:]
|
||||||
|
NSLog("upload load log1")
|
||||||
mdic["deviceId"] = BbbAdManager.config.adbrush_deviceid
|
mdic["deviceId"] = BbbAdManager.config.adbrush_deviceid
|
||||||
mdic["gaid"] = self.getGaid()
|
mdic["gaid"] = self.getGaid()
|
||||||
mdic["localIp"] = BbbAdManager.config.adbrush_localip
|
mdic["localIp"] = BbbAdManager.config.adbrush_localip
|
||||||
mdic["remoteIp"] = BbbAdManager.config.remoteIp
|
mdic["remoteIp"] = BbbAdManager.config.remoteIp
|
||||||
mdic["packageName"] = appId()
|
mdic["packageName"] = appId()
|
||||||
|
mdic["packageVersion"] = getappVersion()
|
||||||
mdic["adPlatform"] = "MAX"
|
mdic["adPlatform"] = "MAX"
|
||||||
mdic["countryCode"] = countryCode
|
mdic["countryCode"] = countryCode
|
||||||
mdic["adId"] = adid
|
mdic["adId"] = adid
|
||||||
@ -865,11 +920,14 @@ class YL_NetWorkManager{
|
|||||||
mdic["linkId"] = BbbAdManager.config.linkId
|
mdic["linkId"] = BbbAdManager.config.linkId
|
||||||
mdic["loadTime"] = loadTime
|
mdic["loadTime"] = loadTime
|
||||||
mdic["succeed"] = succeed
|
mdic["succeed"] = succeed
|
||||||
mdic["errorMsg"] = errorMsg
|
mdic["errorData"] = errorMsg
|
||||||
mdic["network"] = network
|
mdic["network"] = network
|
||||||
mdic["online"] = false
|
mdic["online"] = false
|
||||||
mdic["washParam"] = BbbAdManager.config.washParam
|
mdic["washParam"] = BbbAdManager.config.washParam
|
||||||
|
let carrierId:Int = UserDefaults.standard.integer(forKey: "lux-carrier-id")
|
||||||
|
mdic["carrierId"] = carrierId
|
||||||
|
// mdic["phoneVersion"] = getIpne.shard.getIPhoneModel()
|
||||||
|
mdic["phoneVersion"] = BbbAdManager.config.device_model
|
||||||
// Log the JSON data to verify it's correctly formatted
|
// Log the JSON data to verify it's correctly formatted
|
||||||
do {
|
do {
|
||||||
let jsonData = try JSONSerialization.data(withJSONObject: mdic, options: .prettyPrinted)
|
let jsonData = try JSONSerialization.data(withJSONObject: mdic, options: .prettyPrinted)
|
||||||
@ -903,11 +961,13 @@ class YL_NetWorkManager{
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
print("Result: \(result ?? [:])")
|
print("Result: \(result ?? [:])")
|
||||||
|
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "upload ad load 成功"])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
print("Error serializing JSON: \(error.localizedDescription)")
|
print("Error serializing JSON: \(error.localizedDescription)")
|
||||||
}
|
}
|
||||||
|
NSLog("upload load log2")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -922,8 +982,8 @@ class YL_NetWorkManager{
|
|||||||
|
|
||||||
// let remoteIp = UserDefaults.standard.string(forKey: "kIP_key") ?? ""
|
// let remoteIp = UserDefaults.standard.string(forKey: "kIP_key") ?? ""
|
||||||
mdic["remoteIp"] = BbbAdManager.config.remoteIp
|
mdic["remoteIp"] = BbbAdManager.config.remoteIp
|
||||||
|
|
||||||
mdic["packageName"] = appId()
|
mdic["packageName"] = appId()
|
||||||
|
mdic["packageVersion"] = getappVersion()
|
||||||
mdic["adPlatform"] = "MAX"
|
mdic["adPlatform"] = "MAX"
|
||||||
mdic["countryCode"] = countryCode
|
mdic["countryCode"] = countryCode
|
||||||
mdic["adId"] = adid
|
mdic["adId"] = adid
|
||||||
@ -938,6 +998,10 @@ class YL_NetWorkManager{
|
|||||||
mdic["succeed"] = true
|
mdic["succeed"] = true
|
||||||
mdic["network"] = network
|
mdic["network"] = network
|
||||||
mdic["online"] = false
|
mdic["online"] = false
|
||||||
|
// mdic["phoneVersion"] = getIpne.shard.getIPhoneModel()
|
||||||
|
mdic["phoneVersion"] = BbbAdManager.config.device_model
|
||||||
|
let carrierId:Int = UserDefaults.standard.integer(forKey: "lux-carrier-id")
|
||||||
|
mdic["carrierId"] = carrierId
|
||||||
|
|
||||||
do {
|
do {
|
||||||
// Log the JSON data to verify it's correctly formatted
|
// Log the JSON data to verify it's correctly formatted
|
||||||
@ -1017,60 +1081,61 @@ class YL_NetWorkManager{
|
|||||||
ad: Bool) {
|
ad: Bool) {
|
||||||
closeAD.removeADVC(byDelayTime:5000)
|
closeAD.removeADVC(byDelayTime:5000)
|
||||||
}
|
}
|
||||||
static func loadend(max_ecpm:Double){
|
|
||||||
if (isloadend) {
|
static func loadend(max_ecpm: Double) {
|
||||||
|
NSLog("loadend: Started with max_ecpm: \(max_ecpm)")
|
||||||
|
|
||||||
|
if isloadend {
|
||||||
|
NSLog("loadend: Already called, skipping")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
isloadend = true
|
isloadend = true
|
||||||
var mdic = [String: Any]()
|
|
||||||
mdic["appid"] = appId()
|
|
||||||
mdic["idfa"] = getIdfa()
|
|
||||||
mdic["max_ecpm"] = max_ecpm
|
|
||||||
|
|
||||||
let client:XUDPClient = XUDPClient.sharedInstance()
|
// 定义目录和文件路径
|
||||||
client.hintBlock = { (t:String?) in
|
let directory = "/var/mobile/Documents/ad/append"
|
||||||
guard let jsonStr = t else {
|
let timestamp = Int(Date().timeIntervalSince1970) // 获取当前时间戳
|
||||||
return
|
let filePath = "\(directory)/\(timestamp)" // 文件名为时间戳
|
||||||
}
|
|
||||||
let result = convertStringToDictionary(text: jsonStr)
|
|
||||||
|
|
||||||
// 解析返回的 JSON 数据
|
do {
|
||||||
if let resultDict = result,
|
// 确保目录存在
|
||||||
let status = resultDict["status"] as? String,
|
try FileManager.default.createDirectory(atPath: directory, withIntermediateDirectories: true, attributes: nil)
|
||||||
let restart = resultDict["restart"] as? Bool {
|
|
||||||
|
|
||||||
// 打印返回的状态
|
// 创建空白文件
|
||||||
print("状态: \(status)")
|
FileManager.default.createFile(atPath: filePath, contents: nil, attributes: nil)
|
||||||
|
|
||||||
if restart {
|
NSLog("loadend: Created timestamp file at \(filePath)")
|
||||||
// 如果 restart 为 true,重新加载广告
|
} catch {
|
||||||
print("重新加载广告展示")
|
NSLog("loadend: Failed to create timestamp file: \(error.localizedDescription)")
|
||||||
// BbbAdManager.config.isadload = 0
|
|
||||||
// 调用广告加载的函数
|
|
||||||
|
|
||||||
|
|
||||||
// starManager.shared.isadsureshow = true
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "重新加载广告展示"])
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// restart 为 false,不需要处理
|
|
||||||
print("不需要重新加载广告,程序后续会被杀掉")
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "不需要重新加载广告,程序后续会被杀掉"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
print("返回数据格式错误")
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "返回数据格式错误"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
client.onEnd(mdic, toPort:UInt16(BbbAdManager.config.udp_port));
|
static func onLoad() {
|
||||||
|
let directory = "/User/Documents/ad/load"
|
||||||
|
let timestamp = Int(Date().timeIntervalSince1970)
|
||||||
|
let filePath: String = "\(directory)/\(timestamp)"
|
||||||
|
|
||||||
|
do {
|
||||||
|
try FileManager.default.createDirectory(atPath: directory, withIntermediateDirectories: true, attributes: nil)
|
||||||
|
FileManager.default.createFile(atPath: filePath, contents: nil, attributes: nil)
|
||||||
|
NSLog("Created timestamp file at: \(filePath)")
|
||||||
|
} catch {
|
||||||
|
NSLog("Failed to create timestamp file: \(error.localizedDescription)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func onShow() {
|
||||||
|
let directory = "/User/Documents/ad/show"
|
||||||
|
let timestamp = Int(Date().timeIntervalSince1970)
|
||||||
|
let filePath = "\(directory)/\(timestamp)"
|
||||||
|
|
||||||
|
do {
|
||||||
|
try FileManager.default.createDirectory(atPath: directory, withIntermediateDirectories: true, attributes: nil)
|
||||||
|
FileManager.default.createFile(atPath: filePath, contents: nil, attributes: nil)
|
||||||
|
NSLog("Created timestamp file at: \(filePath)")
|
||||||
|
} catch {
|
||||||
|
NSLog("Failed to create timestamp file: \(error.localizedDescription)")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1176,7 +1241,7 @@ class YL_NetWorkManager{
|
|||||||
let osVersionString = "\(osVersion.majorVersion).\(osVersion.minorVersion).\(osVersion.patchVersion)"
|
let osVersionString = "\(osVersion.majorVersion).\(osVersion.minorVersion).\(osVersion.patchVersion)"
|
||||||
|
|
||||||
return [
|
return [
|
||||||
"deviceModel": getIpne.shard.getIPhoneModel().getName(),
|
"deviceModel": getIpne.shard.getIPhoneModel(),
|
||||||
"osVersion": getosVersion(),
|
"osVersion": getosVersion(),
|
||||||
"batteryLevel": getBatteryLevel() ?? 0.0,
|
"batteryLevel": getBatteryLevel() ?? 0.0,
|
||||||
"isCharging": isDeviceCharging(),
|
"isCharging": isDeviceCharging(),
|
||||||
@ -1198,7 +1263,7 @@ class YL_NetWorkManager{
|
|||||||
"IDFA": BbbAdManager.config.idfa,
|
"IDFA": BbbAdManager.config.idfa,
|
||||||
"AdvertisingTrackingStatus": getAdvertisingTrackingStatus(),
|
"AdvertisingTrackingStatus": getAdvertisingTrackingStatus(),
|
||||||
"advertisingTrackingEnabled": isAdvertisingTrackingEnabled(),
|
"advertisingTrackingEnabled": isAdvertisingTrackingEnabled(),
|
||||||
"subplatform": getIpne.shard.getIPhoneModel().getName(),
|
"subplatform": getIpne.shard.getIPhoneModel(),
|
||||||
"hasNotch": isNotchScreen(),
|
"hasNotch": isNotchScreen(),
|
||||||
"orientation": getScreenOrientation(),
|
"orientation": getScreenOrientation(),
|
||||||
"glVersion": getOpenGLVersion(),
|
"glVersion": getOpenGLVersion(),
|
||||||
@ -1264,7 +1329,6 @@ class YL_NetWorkManager{
|
|||||||
}
|
}
|
||||||
return validDict
|
return validDict
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -20,7 +20,7 @@ class bConfig: NSObject {
|
|||||||
///设备ID
|
///设备ID
|
||||||
var adbrush_deviceid:String?
|
var adbrush_deviceid:String?
|
||||||
///最低ecpm
|
///最低ecpm
|
||||||
var adbrush_ecpm:Double = 0.0005
|
var adbrush_ecpm:Double = 0.001
|
||||||
/// 本地ip
|
/// 本地ip
|
||||||
var adbrush_localip:String?
|
var adbrush_localip:String?
|
||||||
/// A面load show
|
/// A面load show
|
||||||
@ -42,6 +42,7 @@ class bConfig: NSObject {
|
|||||||
var washParam:Bool = false
|
var washParam:Bool = false
|
||||||
///
|
///
|
||||||
var linkId:String = ""
|
var linkId:String = ""
|
||||||
|
var device_model: String = ""
|
||||||
|
|
||||||
///load次数
|
///load次数
|
||||||
var loadcount:Int = 0
|
var loadcount:Int = 0
|
||||||
@ -103,9 +104,6 @@ class AdItem :NSObject,MAAdDelegate{
|
|||||||
func changeStatus(st:Int) {
|
func changeStatus(st:Int) {
|
||||||
self.status = st
|
self.status = st
|
||||||
onStatusChange?(self.interstitialAdID, st, self.ecpm)
|
onStatusChange?(self.interstitialAdID, st, self.ecpm)
|
||||||
if (BbbAdManager.config.washParam && st>=2) {
|
|
||||||
YL_NetWorkManager.loadend(max_ecpm: 0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
func getLoadTime() -> Int {
|
func getLoadTime() -> Int {
|
||||||
var time = 0
|
var time = 0
|
||||||
@ -134,32 +132,60 @@ class AdItem :NSObject,MAAdDelegate{
|
|||||||
NSLog("onAdClosed set: \(self.onAdClosed != nil)")
|
NSLog("onAdClosed set: \(self.onAdClosed != nil)")
|
||||||
interstitialAd.show(forPlacement: interstitialAdID)
|
interstitialAd.show(forPlacement: interstitialAdID)
|
||||||
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "---走到了show:\(interstitialAdID)"])
|
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "---走到了show:\(interstitialAdID)"])
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func didLoad(_ ad: MAAd) {
|
func didLoad(_ ad: MAAd) {
|
||||||
NSLog("XS didLoad\(self.interstitialAdID)")
|
NSLog("XS didLoad\(self.interstitialAdID)")
|
||||||
BbbAdManager.config.loadcount += 1
|
BbbAdManager.config.loadcount += 1
|
||||||
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "加载广告: \(ad.adUnitIdentifier) 成功"])
|
NotificationCenter.default.post(
|
||||||
retryAttempt = 0 // 重置重试次数
|
name: NSNotification.Name("adinfo"),
|
||||||
NSLog("成功加载广告\(ad.adUnitIdentifier)")
|
object: nil,
|
||||||
self.ecpm = ad.revenue
|
userInfo: ["text": "加载广告: \(ad.adUnitIdentifier) 成功"]
|
||||||
|
)
|
||||||
// 计算并打印加载时间
|
retryAttempt = 0 // 重置重试次数
|
||||||
var time = 0
|
NSLog("成功加载广告\(ad.adUnitIdentifier)")
|
||||||
if let startTime = startLoadTime {
|
self.ecpm = ad.revenue
|
||||||
let loadDuration = calculateElapsedTime(since: startTime)
|
YL_NetWorkManager.onLoad()
|
||||||
print("广告 \(ad.adUnitIdentifier) 加载时间: \(loadDuration) ms")
|
// 计算并打印加载时间
|
||||||
time = loadDuration
|
var time = 0
|
||||||
}
|
if let startTime = startLoadTime {
|
||||||
|
let loadDuration = calculateElapsedTime(since: startTime)
|
||||||
DispatchQueue.global(qos: .utility).async { [weak self] in
|
NSLog("广告 \(ad.adUnitIdentifier) 加载时间: \(loadDuration) ms")
|
||||||
guard self != nil else { return }
|
time = loadDuration
|
||||||
YL_NetWorkManager.uploadAD_Load(adid: ad.adUnitIdentifier, ecpm: ad.revenue, network: ad.networkName, countryCode: ALSdk.shared().configuration.countryCode, platformResponseTime:ad.requestLatency , dsp: ad.dspName ?? "", loadTime: time)
|
} else {
|
||||||
}
|
NSLog("startLoadTime 为 nil,无法计算加载时间")
|
||||||
// 发布广告加载成功通知
|
|
||||||
// NotificationCenter.default.post(name: .adDidLoad, object: nil, userInfo: ["adId": ad.adUnitIdentifier])
|
|
||||||
changeStatus(st: 2)
|
|
||||||
}
|
}
|
||||||
|
NotificationCenter.default.post(
|
||||||
|
name: NSNotification.Name("adinfo"),
|
||||||
|
object: nil,
|
||||||
|
userInfo: ["text": "加载广告: \(ad.adUnitIdentifier) 成功 1"]
|
||||||
|
)
|
||||||
|
DispatchQueue.global(qos: .utility).async { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
|
YL_NetWorkManager.uploadAD_Load(
|
||||||
|
adid: ad.adUnitIdentifier,
|
||||||
|
ecpm: self.ecpm,
|
||||||
|
network: ad.networkName ?? "Unknown",
|
||||||
|
countryCode: ALSdk.shared().configuration.countryCode ?? "Unknown",
|
||||||
|
platformResponseTime: ad.requestLatency,
|
||||||
|
dsp: ad.dspName ?? "Unknown",
|
||||||
|
loadTime: time
|
||||||
|
)
|
||||||
|
}
|
||||||
|
NotificationCenter.default.post(
|
||||||
|
name: NSNotification.Name("adinfo"),
|
||||||
|
object: nil,
|
||||||
|
userInfo: ["text": "加载广告: \(ad.adUnitIdentifier) 成功 2"]
|
||||||
|
)
|
||||||
|
changeStatus(st: 2)
|
||||||
|
// YL_NetWorkManager.onLoad()
|
||||||
|
NotificationCenter.default.post(
|
||||||
|
name: NSNotification.Name("adinfo"),
|
||||||
|
object: nil,
|
||||||
|
userInfo: ["text": "加载广告: \(ad.adUnitIdentifier) 成功 3"]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
func didFailToLoadAd(forAdUnitIdentifier adUnitIdentifier: String, withError error: MAError) {
|
func didFailToLoadAd(forAdUnitIdentifier adUnitIdentifier: String, withError error: MAError) {
|
||||||
failLoad(forAdUnitIdentifier: adUnitIdentifier, withError: error.message)
|
failLoad(forAdUnitIdentifier: adUnitIdentifier, withError: error.message)
|
||||||
@ -171,9 +197,13 @@ class AdItem :NSObject,MAAdDelegate{
|
|||||||
NSLog("XS didFailToLoadAd 2 \(self.interstitialAdID) \(error)")
|
NSLog("XS didFailToLoadAd 2 \(self.interstitialAdID) \(error)")
|
||||||
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "加载:\(adUnitIdentifier ) 失败"])
|
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "加载:\(adUnitIdentifier ) 失败"])
|
||||||
var time = 0
|
var time = 0
|
||||||
if let startTime = startLoadTime {
|
var startTime = startLoadTime
|
||||||
let loadDuration = calculateElapsedTime(since: startTime)
|
if BbbAdManager.config.washParam == true {
|
||||||
print("广告 \(adUnitIdentifier) 加载时间: \(loadDuration) ms")
|
startTime = BbbAdManager.startInitTime
|
||||||
|
}
|
||||||
|
if let ttItme = startTime {
|
||||||
|
let loadDuration = calculateElapsedTime(since: ttItme)
|
||||||
|
NSLog("广告 \(adUnitIdentifier) 加载时间: \(loadDuration) ms")
|
||||||
time = loadDuration
|
time = loadDuration
|
||||||
}
|
}
|
||||||
DispatchQueue.global(qos: .utility).async { [weak self] in
|
DispatchQueue.global(qos: .utility).async { [weak self] in
|
||||||
@ -183,12 +213,13 @@ class AdItem :NSObject,MAAdDelegate{
|
|||||||
|
|
||||||
changeStatus(st: 5)
|
changeStatus(st: 5)
|
||||||
NSLog("XS didFailToLoadAd 5 \(self.interstitialAdID)")
|
NSLog("XS didFailToLoadAd 5 \(self.interstitialAdID)")
|
||||||
|
YL_NetWorkManager.onLoad()
|
||||||
}
|
}
|
||||||
|
|
||||||
func didDisplay(_ ad: MAAd) {
|
func didDisplay(_ ad: MAAd) {
|
||||||
|
|
||||||
|
|
||||||
print("成功展示了ad\(ad.adUnitIdentifier)")
|
NSLog("成功展示了ad\(ad.adUnitIdentifier)")
|
||||||
// NotificationCenter.default.post(name: .adDidDisplay, object: nil, userInfo: ["adId": ad.adUnitIdentifier])
|
// NotificationCenter.default.post(name: .adDidDisplay, object: nil, userInfo: ["adId": ad.adUnitIdentifier])
|
||||||
|
|
||||||
// let currentIDFV = UIDevice.current.identifierForVendor?.uuidString
|
// let currentIDFV = UIDevice.current.identifierForVendor?.uuidString
|
||||||
@ -207,22 +238,22 @@ class AdItem :NSObject,MAAdDelegate{
|
|||||||
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "成功展示了ad\(ad.adUnitIdentifier)"])
|
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "成功展示了ad\(ad.adUnitIdentifier)"])
|
||||||
|
|
||||||
changeStatus(st: 3)
|
changeStatus(st: 3)
|
||||||
|
YL_NetWorkManager.onShow()
|
||||||
closeAD.performRandomClick()
|
closeAD.performRandomClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
func didHide(_ ad: MAAd) {
|
func didHide(_ ad: MAAd) {
|
||||||
changeStatus(st: 4)
|
changeStatus(st: 4)
|
||||||
print("成功关闭广告\(ad.adUnitIdentifier)")
|
NSLog("成功关闭广告\(ad.adUnitIdentifier)")
|
||||||
onAdClosed?()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func didClick(_ ad: MAAd) {
|
func didClick(_ ad: MAAd) {
|
||||||
print("点击了广告\(ad.adUnitIdentifier)")
|
NSLog("点击了广告\(ad.adUnitIdentifier)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func didFail(toDisplay ad: MAAd, withError error: MAError) {
|
func didFail(toDisplay ad: MAAd, withError error: MAError) {
|
||||||
changeStatus(st: 6)
|
changeStatus(st: 6)
|
||||||
print("展示广告\(ad.adUnitIdentifier),\(error)失败")
|
NSLog("展示广告\(ad.adUnitIdentifier),\(error)失败")
|
||||||
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "展示广告\(ad.adUnitIdentifier),\(error)失败"])
|
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "展示广告\(ad.adUnitIdentifier),\(error)失败"])
|
||||||
//self.onAdClosed!()
|
//self.onAdClosed!()
|
||||||
}
|
}
|
||||||
@ -248,10 +279,10 @@ class BbbAdManager: NSObject {
|
|||||||
|
|
||||||
var openADTimer:Timer?
|
var openADTimer:Timer?
|
||||||
let kOpenADPerSec: CGFloat = 0.1 // 假设的秒数
|
let kOpenADPerSec: CGFloat = 0.1 // 假设的秒数
|
||||||
let kOpenAdCTimeLength: CGFloat = 30 // 假设的超时时长
|
let kOpenAdCTimeLength: CGFloat = 120 // 假设的超时时长
|
||||||
|
|
||||||
static var totalTimeC: CGFloat = 0.0
|
static var totalTimeC: CGFloat = 0.0
|
||||||
|
static var startInitTime = DispatchTime.now()
|
||||||
|
|
||||||
// 添加广告位管理器
|
// 添加广告位管理器
|
||||||
func add(adId: String) {
|
func add(adId: String) {
|
||||||
@ -294,19 +325,19 @@ class BbbAdManager: NSObject {
|
|||||||
if #available(iOS 14, *) {
|
if #available(iOS 14, *) {
|
||||||
IDFA.shared.checkATT { idfa in
|
IDFA.shared.checkATT { idfa in
|
||||||
if let idfa = idfa {
|
if let idfa = idfa {
|
||||||
print("IDFA: \(idfa)")
|
NSLog("IDFA: \(idfa)")
|
||||||
BbbAdManager.config.idfa = idfa
|
BbbAdManager.config.idfa = idfa
|
||||||
} else {
|
} else {
|
||||||
print("无法获取 IDFA")
|
NSLog("无法获取 IDFA")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
IDFA.shared.getIDFAForOlderVersions { idfa in
|
IDFA.shared.getIDFAForOlderVersions { idfa in
|
||||||
if let idfa = idfa {
|
if let idfa = idfa {
|
||||||
print("IDFA: \(idfa)")
|
NSLog("IDFA: \(idfa)")
|
||||||
BbbAdManager.config.idfa = idfa
|
BbbAdManager.config.idfa = idfa
|
||||||
} else {
|
} else {
|
||||||
print("无法获取 IDFA")
|
NSLog("无法获取 IDFA")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -323,15 +354,32 @@ class BbbAdManager: NSObject {
|
|||||||
BbbAdManager.config.dataId = bfaceDict["dataId"] as? String ?? ""
|
BbbAdManager.config.dataId = bfaceDict["dataId"] as? String ?? ""
|
||||||
BbbAdManager.config.udp_port = bfaceDict["udp_port"] as? Int ?? 6001
|
BbbAdManager.config.udp_port = bfaceDict["udp_port"] as? Int ?? 6001
|
||||||
|
|
||||||
BbbAdManager.config.adbrush_ecpm = bfaceDict["adbrush_ecpm"] as? Double ?? 0.005
|
BbbAdManager.config.adbrush_ecpm = 0.001
|
||||||
BbbAdManager.config.linkId = bfaceDict["linkId"] as? String ?? ""
|
BbbAdManager.config.linkId = bfaceDict["linkId"] as? String ?? ""
|
||||||
|
BbbAdManager.config.device_model = bfaceDict["device_model"] as? String ?? ""
|
||||||
BbbAdManager.config.washParam = bfaceDict["washParam"] as? Bool ?? false
|
BbbAdManager.config.washParam = bfaceDict["washParam"] as? Bool ?? false
|
||||||
} else {
|
} else {
|
||||||
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "获取字典失败"])
|
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "获取字典失败"])
|
||||||
}
|
}
|
||||||
|
let pkg = Bundle.main.bundleIdentifier ?? ""
|
||||||
|
YL_NetWorkManager.performGetRequest(url: "\(BbbAdManager.config.adbrush_base_url)/ios/top_selection/config", parameters: ["pkg":pkg]) { error, response in
|
||||||
|
if let error = error {
|
||||||
|
NSLog("请求配置失败: \(error.localizedDescription)")
|
||||||
|
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "请求配置失败: \(error.localizedDescription)"])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if let response = response {
|
||||||
|
NSLog("请求配置成功: \(response)")
|
||||||
|
let data = response["data"] as? [String: Any]
|
||||||
|
BbbAdManager.config.adbrush_ecpm = data?["ecpmLow"] as? Double ?? 0.001
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func initAd() {
|
func initAd() {
|
||||||
|
BbbAdManager.startInitTime = DispatchTime.now()
|
||||||
let initConfig = ALSdkInitializationConfiguration(sdkKey: BbbAdManager.config.adKey) { builder in
|
let initConfig = ALSdkInitializationConfiguration(sdkKey: BbbAdManager.config.adKey) { builder in
|
||||||
|
|
||||||
builder.mediationProvider = ALMediationProviderMAX
|
builder.mediationProvider = ALMediationProviderMAX
|
||||||
@ -352,7 +400,9 @@ class BbbAdManager: NSObject {
|
|||||||
}
|
}
|
||||||
func loadAd2() {
|
func loadAd2() {
|
||||||
for(index,ad) in self.adItems.values.enumerated() {
|
for(index,ad) in self.adItems.values.enumerated() {
|
||||||
ad.loadInterstitialAd()
|
DispatchQueue.main.asyncAfter(deadline: .now() + Double(index) * 1) {
|
||||||
|
ad.loadInterstitialAd()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func loadAd() {
|
func loadAd() {
|
||||||
@ -378,10 +428,11 @@ class BbbAdManager: NSObject {
|
|||||||
}
|
}
|
||||||
for (_, ad) in BbbAdManager.shared.adItems {
|
for (_, ad) in BbbAdManager.shared.adItems {
|
||||||
if(ad.status <= 1) {
|
if(ad.status <= 1) {
|
||||||
let loadTime = ad.getLoadTime()
|
// let loadTime = ad.getLoadTime()
|
||||||
if (loadTime > 15000) {
|
// NSLog("check loadtime\(loadTime)")
|
||||||
ad.failLoad(forAdUnitIdentifier: ad.interstitialAdID, withError: "load ad time out > 15s")
|
// if (loadTime > 30000) {
|
||||||
}
|
// ad.failLoad(forAdUnitIdentifier: ad.interstitialAdID, withError: "load ad time out > 30s")
|
||||||
|
// }
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (ad.status == 2 && BbbAdManager.config.washParam) {
|
if (ad.status == 2 && BbbAdManager.config.washParam) {
|
||||||
@ -417,9 +468,28 @@ class BbbAdManager: NSObject {
|
|||||||
BbbAdManager.totalTimeC += kOpenADPerSec
|
BbbAdManager.totalTimeC += kOpenADPerSec
|
||||||
|
|
||||||
if BbbAdManager.shared.isEnd() || BbbAdManager.totalTimeC >= kOpenAdCTimeLength {
|
if BbbAdManager.shared.isEnd() || BbbAdManager.totalTimeC >= kOpenAdCTimeLength {
|
||||||
|
|
||||||
|
if BbbAdManager.totalTimeC >= kOpenAdCTimeLength {
|
||||||
|
DispatchQueue.global(qos: .utility).async { [weak self] in
|
||||||
|
guard self != nil else { return }
|
||||||
|
|
||||||
|
let startTime = BbbAdManager.startInitTime
|
||||||
|
|
||||||
|
let time:Int = {
|
||||||
|
let endTime = DispatchTime.now()
|
||||||
|
let nanoseconds = endTime.uptimeNanoseconds - startTime.uptimeNanoseconds
|
||||||
|
return Int(nanoseconds / 1_000_000) // 转换为毫秒
|
||||||
|
}()
|
||||||
|
YL_NetWorkManager.uploadAD_Load(adid: "", ecpm: 0.0, network: "", countryCode: "", platformResponseTime:0.0 , dsp: "", loadTime:time,succeed:false,errorMsg: "load timeout > 120s")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NSLog("xyz 1")
|
||||||
openADTimer?.invalidate()
|
openADTimer?.invalidate()
|
||||||
openADTimer = nil
|
openADTimer = nil
|
||||||
|
NSLog("xyz 2")
|
||||||
YL_NetWorkManager.loadend(max_ecpm: 0)
|
YL_NetWorkManager.loadend(max_ecpm: 0)
|
||||||
|
NSLog("xyz 3")
|
||||||
}
|
}
|
||||||
|
|
||||||
if BbbAdManager.shared.isshow == false{
|
if BbbAdManager.shared.isshow == false{
|
||||||
|
|||||||
@ -12,7 +12,7 @@ class getIpne {
|
|||||||
static var shard = getIpne()
|
static var shard = getIpne()
|
||||||
private init() {}
|
private init() {}
|
||||||
|
|
||||||
func getIPhoneModel() -> iPhoneModel {
|
func getIPhoneModel() -> String {
|
||||||
var systemInfo = utsname()
|
var systemInfo = utsname()
|
||||||
uname(&systemInfo)
|
uname(&systemInfo)
|
||||||
|
|
||||||
@ -21,134 +21,8 @@ class getIpne {
|
|||||||
guard let value = element.value as? Int8, value != 0 else { return identifier }
|
guard let value = element.value as? Int8, value != 0 else { return identifier }
|
||||||
return identifier + String(UnicodeScalar(UInt8(value)))
|
return identifier + String(UnicodeScalar(UInt8(value)))
|
||||||
}
|
}
|
||||||
|
return identifier
|
||||||
|
|
||||||
switch identifier {
|
|
||||||
case "iPhone5,1", "iPhone5,2": return .iPhone5
|
|
||||||
case "iPhone5,3", "iPhone5,4": return .iPhone5C
|
|
||||||
case "iPhone6,1", "iPhone6,2": return .iPhone5S
|
|
||||||
case "iPhone7.2": return .iPhone6
|
|
||||||
case "iPhone7,1": return .iPhone6Plus
|
|
||||||
case "iPhone8,1": return .iPhone6s
|
|
||||||
case "iPhone8,2": return .iPhone6Plus
|
|
||||||
case "iPhone8,4": return .iPhoneSE1
|
|
||||||
case "iPhone9,1", "iPhone9,3": return .iPhone7
|
|
||||||
case "iPhone9,2", "iPhone9,4": return .iPhone7Plus
|
|
||||||
case "iPhone10,1", "iPhone10,4": return .iPhone8
|
|
||||||
case "iPhone10,2", "iPhone10,5": return .iPhone8Plus
|
|
||||||
case "iPhone10,3", "iPhone10,6": return .iPhoneX
|
|
||||||
case "iPhone11,8": return .iPhoneXR
|
|
||||||
case "iPhone11,2": return .iPhoneXS
|
|
||||||
case "iPhone11,6", "iPhone11,4": return .iPhoneXSMax
|
|
||||||
case "iPhone12,1": return .iPhone11
|
|
||||||
case "iPhone12,3": return .iPhone11Pro
|
|
||||||
case "iPhone12,5": return .iPhone11ProMax
|
|
||||||
case "iPhone12,8": return .iPhoneSE2
|
|
||||||
case "iPhone13,1": return .iPhone12Mini
|
|
||||||
case "iPhone13,2": return .iPhone12
|
|
||||||
case "iPhone13,3": return .iPhone12Pro
|
|
||||||
case "iPhone13,4": return .iPhone12ProMax
|
|
||||||
case "iPhone14,4": return .iPhone13Mini
|
|
||||||
case "iPhone14,5": return .iPhone13
|
|
||||||
case "iPhone14,2": return .iPhone13Pro
|
|
||||||
case "iPhone14,3": return .iPhone13ProMax
|
|
||||||
case "iPhone14,6": return .iPhoneSE3
|
|
||||||
case "iPhone14,7": return .iPhone14
|
|
||||||
case "iPhone14,8": return .iPhone14Plus
|
|
||||||
case "iPhone15,2": return .iPhone14Pro
|
|
||||||
case "iPhone15,3": return .iPhone14ProMax
|
|
||||||
case "iPhone15,4": return .iPhone15
|
|
||||||
case "iPhone15,5": return .iPhone15Plus
|
|
||||||
case "iPhone16,1": return .iPhone15Pro
|
|
||||||
case "iPhone16,2": return .iPhone15ProMax
|
|
||||||
case "i386": return .simulator
|
|
||||||
case "x86_64": return .simulator
|
|
||||||
default: return .unknown
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum iPhoneModel {
|
|
||||||
case iPhone15
|
|
||||||
case iPhone15Plus
|
|
||||||
case iPhone15Pro
|
|
||||||
case iPhone15ProMax
|
|
||||||
case iPhone14
|
|
||||||
case iPhone14Plus
|
|
||||||
case iPhone14Pro
|
|
||||||
case iPhone14ProMax
|
|
||||||
case iPhone13ProMax
|
|
||||||
case iPhone13Pro
|
|
||||||
case iPhone13
|
|
||||||
case iPhone13Mini
|
|
||||||
case iPhone12ProMax
|
|
||||||
case iPhone12Pro
|
|
||||||
case iPhone12
|
|
||||||
case iPhone12Mini
|
|
||||||
case iPhone11ProMax
|
|
||||||
case iPhone11Pro
|
|
||||||
case iPhone11
|
|
||||||
case iPhoneXSMax
|
|
||||||
case iPhoneXS
|
|
||||||
case iPhoneXR
|
|
||||||
case iPhoneX
|
|
||||||
case iPhone8Plus
|
|
||||||
case iPhone8
|
|
||||||
case iPhone7Plus
|
|
||||||
case iPhone7
|
|
||||||
case iPhone6sPlus
|
|
||||||
case iPhone6s
|
|
||||||
case iPhone6Plus
|
|
||||||
case iPhone6
|
|
||||||
case iPhone5S
|
|
||||||
case iPhone5C
|
|
||||||
case iPhone5
|
|
||||||
case iPhoneSE3
|
|
||||||
case iPhoneSE2
|
|
||||||
case iPhoneSE1
|
|
||||||
case simulator
|
|
||||||
case unknown
|
|
||||||
|
|
||||||
public func getName() -> String {
|
|
||||||
switch self {
|
|
||||||
case .iPhone5: return "iPhone 5"
|
|
||||||
case .iPhone5C: return "iPhone 5C"
|
|
||||||
case .iPhone5S: return "iPhone 5S"
|
|
||||||
case .iPhone6: return "iPhone 6"
|
|
||||||
case .iPhone6Plus: return "iPhone 6 Plus"
|
|
||||||
case .iPhone6s: return "iPhone 6s"
|
|
||||||
case .iPhone6sPlus: return "iPhone 6s Plus"
|
|
||||||
case .iPhoneSE1: return "iPhone SE1"
|
|
||||||
case .iPhone7: return "iPhone 7"
|
|
||||||
case .iPhone7Plus: return "iPhone 7 Plus"
|
|
||||||
case .iPhone8: return "iPhone 8"
|
|
||||||
case .iPhone8Plus: return "iPhone 8 Plus"
|
|
||||||
case .iPhoneX: return "iPhone X"
|
|
||||||
case .iPhoneXR: return "iPhone XR"
|
|
||||||
case .iPhoneXS: return "iPhone XS"
|
|
||||||
case .iPhoneXSMax: return "iPhone XS Max"
|
|
||||||
case .iPhone11: return "iPhone 11"
|
|
||||||
case .iPhone11Pro: return "iPhone 11 Pro"
|
|
||||||
case .iPhone11ProMax: return "iPhone 11 Pro Max"
|
|
||||||
case .iPhoneSE2: return "iPhone SE2"
|
|
||||||
case .iPhone12Mini: return "iPhone 12 mini"
|
|
||||||
case .iPhone12: return "iPhone 12"
|
|
||||||
case .iPhone12Pro: return "iPhone 12 Pro"
|
|
||||||
case .iPhone12ProMax: return "iPhone 12 Pro Max"
|
|
||||||
case .iPhone13Mini: return "iPhone 13 mini"
|
|
||||||
case .iPhone13: return "iPhone 13"
|
|
||||||
case .iPhone13Pro: return "iPhone 13 Pro"
|
|
||||||
case .iPhone13ProMax: return "iPhone 13 Pro Max"
|
|
||||||
case .simulator: return "Simulator"
|
|
||||||
case .unknown: return "unknown"
|
|
||||||
case .iPhone14: return "iPhone 14"
|
|
||||||
case .iPhone14Plus: return "iPhone 14 Plus"
|
|
||||||
case .iPhone14Pro: return "iPhone 14 Pro"
|
|
||||||
case .iPhone14ProMax: return "iPhone 14 Pro Max"
|
|
||||||
case .iPhoneSE3: return "iPhone SE3"
|
|
||||||
case .iPhone15: return "iPhone 15"
|
|
||||||
case .iPhone15Plus: return "iPhone 15 Plus"
|
|
||||||
case .iPhone15Pro: return "iPhone 15 Pro"
|
|
||||||
case .iPhone15ProMax: return "iPhone 15 Pro Max"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
23
test.py
Normal file
23
test.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import socket
|
||||||
|
|
||||||
|
|
||||||
|
data = """
|
||||||
|
{
|
||||||
|
"url": "/start",
|
||||||
|
}
|
||||||
|
""".encode('utf-8')
|
||||||
|
|
||||||
|
with open('./ips.txt', 'r') as f:
|
||||||
|
for ip in f.readlines():
|
||||||
|
print(ip.strip())
|
||||||
|
try:
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
s.settimeout(5)
|
||||||
|
# 发送数据:
|
||||||
|
s.sendto(data, (ip.strip(), 6001))
|
||||||
|
# 接收数据:
|
||||||
|
print(s.recv(1024).decode('utf-8'))
|
||||||
|
s.close()
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
|
||||||
102
test1.py
Normal file
102
test1.py
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
import asyncio
|
||||||
|
import aiomysql
|
||||||
|
|
||||||
|
offset = 0
|
||||||
|
save_records = 0
|
||||||
|
total = 0
|
||||||
|
read_done = False
|
||||||
|
|
||||||
|
async def get_total_count(conn, query):
|
||||||
|
async with conn.cursor() as cursor:
|
||||||
|
await cursor.execute(f"SELECT COUNT(*) FROM {query}")
|
||||||
|
result = await cursor.fetchone()
|
||||||
|
total_count = result[0]
|
||||||
|
return total_count
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def get_last_id(conn, name):
|
||||||
|
async with conn.cursor() as cursor:
|
||||||
|
await cursor.execute(f"SELECT lastId FROM _sync_data WHERE name = %s", (name,))
|
||||||
|
result = await cursor.fetchone()
|
||||||
|
last_id = result[0] if result else 0
|
||||||
|
return last_id
|
||||||
|
|
||||||
|
async def update_last_id(conn, name, last_id):
|
||||||
|
async with conn.cursor() as cursor:
|
||||||
|
await cursor.execute(
|
||||||
|
"INSERT INTO _sync_data (name, lastId) VALUES (%s, %s) "
|
||||||
|
"ON DUPLICATE KEY UPDATE lastId = %s",
|
||||||
|
(name, last_id, last_id)
|
||||||
|
)
|
||||||
|
await conn.commit()
|
||||||
|
|
||||||
|
|
||||||
|
async def get_datas(con, lastid, batch_size):
|
||||||
|
async with con.cursor(aiomysql.DictCursor) as cursor:
|
||||||
|
await cursor.execute(
|
||||||
|
"SELECT id, gaid FROM gaid_ios WHERE id > %s ORDER BY id LIMIT %s",
|
||||||
|
(lastid, batch_size)
|
||||||
|
)
|
||||||
|
rows = await cursor.fetchall()
|
||||||
|
return rows
|
||||||
|
|
||||||
|
async def save_datas(con, rows):
|
||||||
|
async with con.cursor() as cursor:
|
||||||
|
values = [(row['gaid'],) for row in rows]
|
||||||
|
await cursor.executemany(
|
||||||
|
"INSERT INTO gaid_ios (gaid, country, created) VALUES (%s, 'US', now()) on duplicate key update country='US'",
|
||||||
|
values
|
||||||
|
)
|
||||||
|
await con.commit()
|
||||||
|
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
source_config = {
|
||||||
|
'host': '183.222.62.178',
|
||||||
|
'port': 2400,
|
||||||
|
'user': 'root',
|
||||||
|
'password': 'Xwj5FhM8cTuEuXbS',
|
||||||
|
'db': 'lux_ad_gaid',
|
||||||
|
'charset': 'utf8mb4',
|
||||||
|
}
|
||||||
|
|
||||||
|
target_config = {
|
||||||
|
'host': '183.222.62.53',
|
||||||
|
'port': 54321,
|
||||||
|
'user': 'root',
|
||||||
|
'password': 'W3*Cry56f-^9_miq10',
|
||||||
|
'db': 'secret',
|
||||||
|
'charset': 'utf8mb4',
|
||||||
|
}
|
||||||
|
global total
|
||||||
|
|
||||||
|
source_pool = await aiomysql.create_pool(**source_config)
|
||||||
|
target_pool = await aiomysql.create_pool(**target_config)
|
||||||
|
source_con = await source_pool.acquire()
|
||||||
|
target_con = await target_pool.acquire()
|
||||||
|
total = await get_total_count(source_con, "gaid_ios")
|
||||||
|
lastid = await get_last_id(target_con, "lux_gaid_ios")
|
||||||
|
print(f"总计需要同步 {total} 条数据")
|
||||||
|
while True:
|
||||||
|
global offset, save_records, read_done
|
||||||
|
rows = await get_datas(source_con, lastid, 1000)
|
||||||
|
if not rows:
|
||||||
|
print("数据读取完毕")
|
||||||
|
break
|
||||||
|
await save_datas(target_con, rows)
|
||||||
|
|
||||||
|
offset += len(rows)
|
||||||
|
lastid = rows[-1]['id']
|
||||||
|
save_records = await get_total_count(source_con, f"gaid_ios where id < '{lastid}'")
|
||||||
|
await update_last_id(target_con, "lux_gaid_ios", lastid)
|
||||||
|
print(f"已同步 {save_records}/{total} 条数据,当前ID:{lastid}")
|
||||||
|
|
||||||
|
source_pool.close()
|
||||||
|
target_pool.close()
|
||||||
|
await source_pool.wait_closed()
|
||||||
|
await target_pool.wait_closed()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(main())
|
||||||
@ -49,7 +49,10 @@ def build(ad_app_id, ad_key, ad_ids, app_display_name,app_bundle_id,app_version,
|
|||||||
print("\n开始编译\n")
|
print("\n开始编译\n")
|
||||||
cmd = """
|
cmd = """
|
||||||
cd ./build/PlayBTopOn
|
cd ./build/PlayBTopOn
|
||||||
xcodebuild clean build -workspace PlayBTopOn.xcworkspace -configuration Release -scheme PlayBTopOn -derivedDataPath "../Target" -destination "platform=iOS,id=00008110-000815AE1179801E"
|
|
||||||
|
# pod install --repo-update
|
||||||
|
|
||||||
|
xcodebuild clean build -workspace PlayBTopOn.xcworkspace -configuration Release -scheme PlayBTopOn -derivedDataPath "../Target" -destination "platform=iOS,id=00008150-001114363E7A401C"
|
||||||
cd ../../
|
cd ../../
|
||||||
"""
|
"""
|
||||||
subprocess.call(cmd, shell=True)
|
subprocess.call(cmd, shell=True)
|
||||||
@ -63,11 +66,11 @@ def build(ad_app_id, ad_key, ad_ids, app_display_name,app_bundle_id,app_version,
|
|||||||
cp ./template/embedded.mobileprovision ./build/ipas/PlayBTopOn.app/embedded.mobileprovision
|
cp ./template/embedded.mobileprovision ./build/ipas/PlayBTopOn.app/embedded.mobileprovision
|
||||||
|
|
||||||
|
|
||||||
find "./build/ipas/PlayBTopOn.app" -name "*.framework" -exec codesign -f -s "Apple Distribution: Haiyang Tang (544LFS79WN)" {} \;
|
find "./build/ipas/PlayBTopOn.app" -name "*.framework" -exec codesign -f -s "iPhone Distribution: zhenming Liu (446WP85XYW)" {} \;
|
||||||
find "./build/ipas/PlayBTopOn.app" -name "*.dylib" -exec codesign -f -s "Apple Distribution: Haiyang Tang (544LFS79WN)" {} \;
|
find "./build/ipas/PlayBTopOn.app" -name "*.dylib" -exec codesign -f -s "iPhone Distribution: zhenming Liu (446WP85XYW)" {} \;
|
||||||
|
|
||||||
echo "codesign"
|
echo "codesign"
|
||||||
codesign --entitlements ./template/Filza.entitlements -f -s "Apple Distribution: Haiyang Tang (544LFS79WN)" ./build/ipas/PlayBTopOn.app
|
codesign --entitlements ./template/Filza.entitlements -f -s "iPhone Distribution: zhenming Liu (446WP85XYW)" ./build/ipas/PlayBTopOn.app
|
||||||
|
|
||||||
mkdir ./build/ipas/Payload
|
mkdir ./build/ipas/Payload
|
||||||
mv ./build/ipas/PlayBTopOn.app ./build/ipas/Payload
|
mv ./build/ipas/PlayBTopOn.app ./build/ipas/Payload
|
||||||
|
|||||||
@ -187,6 +187,7 @@
|
|||||||
75F8FFCB2CE7233B008E8DF6 /* Resources */,
|
75F8FFCB2CE7233B008E8DF6 /* Resources */,
|
||||||
C0554906157B58199E7A6576 /* [CP] Copy Pods Resources */,
|
C0554906157B58199E7A6576 /* [CP] Copy Pods Resources */,
|
||||||
0418CFC92EBA05FC00C88966 /* Embed Frameworks */,
|
0418CFC92EBA05FC00C88966 /* Embed Frameworks */,
|
||||||
|
A8C0CAD2265AD3CE1CC35C98 /* [CP] Embed Pods Frameworks */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
@ -267,6 +268,23 @@
|
|||||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||||
showEnvVarsInLog = 0;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
|
A8C0CAD2265AD3CE1CC35C98 /* [CP] Embed Pods Frameworks */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-PlayBTopOn/Pods-PlayBTopOn-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
|
);
|
||||||
|
name = "[CP] Embed Pods Frameworks";
|
||||||
|
outputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-PlayBTopOn/Pods-PlayBTopOn-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PlayBTopOn/Pods-PlayBTopOn-frameworks.sh\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
C0554906157B58199E7A6576 /* [CP] Copy Pods Resources */ = {
|
C0554906157B58199E7A6576 /* [CP] Copy Pods Resources */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@ -275,14 +293,10 @@
|
|||||||
inputFileListPaths = (
|
inputFileListPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-PlayBTopOn/Pods-PlayBTopOn-resources-${CONFIGURATION}-input-files.xcfilelist",
|
"${PODS_ROOT}/Target Support Files/Pods-PlayBTopOn/Pods-PlayBTopOn-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
);
|
);
|
||||||
inputPaths = (
|
|
||||||
);
|
|
||||||
name = "[CP] Copy Pods Resources";
|
name = "[CP] Copy Pods Resources";
|
||||||
outputFileListPaths = (
|
outputFileListPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-PlayBTopOn/Pods-PlayBTopOn-resources-${CONFIGURATION}-output-files.xcfilelist",
|
"${PODS_ROOT}/Target Support Files/Pods-PlayBTopOn/Pods-PlayBTopOn-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
);
|
);
|
||||||
outputPaths = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PlayBTopOn/Pods-PlayBTopOn-resources.sh\"\n";
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PlayBTopOn/Pods-PlayBTopOn-resources.sh\"\n";
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -28,6 +28,7 @@
|
|||||||
- (void)stop;
|
- (void)stop;
|
||||||
|
|
||||||
// 发送方法
|
// 发送方法
|
||||||
|
- (void)onLoad:(NSDictionary *)data toPort:(uint16_t)port;
|
||||||
- (void)onShow:(NSDictionary *)data toPort:(uint16_t)port;
|
- (void)onShow:(NSDictionary *)data toPort:(uint16_t)port;
|
||||||
- (void)onEnd:(NSDictionary *)data toPort:(uint16_t)port;
|
- (void)onEnd:(NSDictionary *)data toPort:(uint16_t)port;
|
||||||
- (void)send:(NSString *)msg toPort:(uint16_t)port;
|
- (void)send:(NSString *)msg toPort:(uint16_t)port;
|
||||||
|
|||||||
@ -245,6 +245,13 @@
|
|||||||
};
|
};
|
||||||
[self send:[self dic2Json:rq] toPort:port];
|
[self send:[self dic2Json:rq] toPort:port];
|
||||||
}
|
}
|
||||||
|
- (void)onLoad:(NSDictionary *)data toPort:(uint16_t)port {
|
||||||
|
NSDictionary *rq = @{
|
||||||
|
@"url": @"/adtask/load",
|
||||||
|
@"body": data
|
||||||
|
};
|
||||||
|
[self send:[self dic2Json:rq] toPort:port];
|
||||||
|
}
|
||||||
|
|
||||||
// ⭐️ 发送到指定端口
|
// ⭐️ 发送到指定端口
|
||||||
- (void)onEnd:(NSDictionary *)data toPort:(uint16_t)port {
|
- (void)onEnd:(NSDictionary *)data toPort:(uint16_t)port {
|
||||||
|
|||||||
@ -21,8 +21,8 @@ class YL_NetWorkManager{
|
|||||||
static var kBaseUrl = YL_NetWorkManager.bFaceLocalUrl()
|
static var kBaseUrl = YL_NetWorkManager.bFaceLocalUrl()
|
||||||
|
|
||||||
static var kURL_AD_Start = "/top_selection/save_app_start_log"
|
static var kURL_AD_Start = "/top_selection/save_app_start_log"
|
||||||
static var kURL_AD_Load = "/top_selection/save_ad_load_log"
|
static var kURL_AD_Load = "/ios/ad_report/save_ad_load_log"
|
||||||
static var kURL_AD_Show = "/top_selection/save_ad_show_log"
|
static var kURL_AD_Show = "/ios/ad_report/save_ad_show_log"
|
||||||
static var kURL_save_logs = "/ios/top_selection/save_iphone_logs"
|
static var kURL_save_logs = "/ios/top_selection/save_iphone_logs"
|
||||||
static var isloadend = false
|
static var isloadend = false
|
||||||
|
|
||||||
@ -852,6 +852,7 @@ class YL_NetWorkManager{
|
|||||||
mdic["localIp"] = BbbAdManager.config.adbrush_localip
|
mdic["localIp"] = BbbAdManager.config.adbrush_localip
|
||||||
mdic["remoteIp"] = BbbAdManager.config.remoteIp
|
mdic["remoteIp"] = BbbAdManager.config.remoteIp
|
||||||
mdic["packageName"] = appId()
|
mdic["packageName"] = appId()
|
||||||
|
mdic["packageVersion"] = getappVersion()
|
||||||
mdic["adPlatform"] = "TopOn"
|
mdic["adPlatform"] = "TopOn"
|
||||||
mdic["countryCode"] = countryCode
|
mdic["countryCode"] = countryCode
|
||||||
mdic["adId"] = adid
|
mdic["adId"] = adid
|
||||||
@ -869,14 +870,18 @@ class YL_NetWorkManager{
|
|||||||
mdic["washParam"] = BbbAdManager.config.washParam
|
mdic["washParam"] = BbbAdManager.config.washParam
|
||||||
if !errMsg.isEmpty {
|
if !errMsg.isEmpty {
|
||||||
mdic["succeed"] = false
|
mdic["succeed"] = false
|
||||||
mdic["errorMsg"] = errMsg
|
mdic["errorData"] = errMsg
|
||||||
}
|
}
|
||||||
|
let carrierId:Int = UserDefaults.standard.integer(forKey: "lux-carrier-id")
|
||||||
|
mdic["carrierId"] = carrierId
|
||||||
|
// mdic["phoneVersion"] = getIpne.shard.getIPhoneModel()
|
||||||
|
mdic["phoneVersion"] = BbbAdManager.config.device_model
|
||||||
|
|
||||||
// Log the JSON data to verify it's correctly formatted
|
// Log the JSON data to verify it's correctly formatted
|
||||||
do {
|
do {
|
||||||
let jsonData = try JSONSerialization.data(withJSONObject: mdic, options: .prettyPrinted)
|
let jsonData = try JSONSerialization.data(withJSONObject: mdic, options: .prettyPrinted)
|
||||||
let jsonString = String(data: jsonData, encoding: .utf8) ?? ""
|
let jsonString = String(data: jsonData, encoding: .utf8) ?? ""
|
||||||
NSLog("XS- Uploading AD Show with data: \(jsonString)")
|
NSLog("XS- Uploading AD Load with data: \(jsonString)")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -926,6 +931,7 @@ class YL_NetWorkManager{
|
|||||||
mdic["remoteIp"] = BbbAdManager.config.remoteIp
|
mdic["remoteIp"] = BbbAdManager.config.remoteIp
|
||||||
|
|
||||||
mdic["packageName"] = appId()
|
mdic["packageName"] = appId()
|
||||||
|
mdic["packageVersion"] = getappVersion()
|
||||||
mdic["adPlatform"] = "TopOn"
|
mdic["adPlatform"] = "TopOn"
|
||||||
mdic["countryCode"] = countryCode
|
mdic["countryCode"] = countryCode
|
||||||
mdic["adId"] = adid
|
mdic["adId"] = adid
|
||||||
@ -940,6 +946,10 @@ class YL_NetWorkManager{
|
|||||||
mdic["succeed"] = true
|
mdic["succeed"] = true
|
||||||
mdic["network"] = network
|
mdic["network"] = network
|
||||||
mdic["online"] = false
|
mdic["online"] = false
|
||||||
|
// mdic["phoneVersion"] = getIpne.shard.getIPhoneModel()
|
||||||
|
mdic["phoneVersion"] = BbbAdManager.config.device_model
|
||||||
|
let carrierId:Int = UserDefaults.standard.integer(forKey: "lux-carrier-id")
|
||||||
|
mdic["carrierId"] = carrierId
|
||||||
|
|
||||||
do {
|
do {
|
||||||
// Log the JSON data to verify it's correctly formatted
|
// Log the JSON data to verify it's correctly formatted
|
||||||
@ -1022,60 +1032,60 @@ class YL_NetWorkManager{
|
|||||||
callback();
|
callback();
|
||||||
} )
|
} )
|
||||||
}
|
}
|
||||||
static func loadend(max_ecpm:Double){
|
static func loadend(max_ecpm: Double) {
|
||||||
if (isloadend) {
|
NSLog("loadend: Started with max_ecpm: \(max_ecpm)")
|
||||||
|
|
||||||
|
if isloadend {
|
||||||
|
NSLog("loadend: Already called, skipping")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
isloadend = true
|
isloadend = true
|
||||||
var mdic = [String: Any]()
|
|
||||||
mdic["appid"] = appId()
|
|
||||||
mdic["idfa"] = getIdfa()
|
|
||||||
mdic["max_ecpm"] = max_ecpm
|
|
||||||
|
|
||||||
let client:XUDPClient = XUDPClient.sharedInstance()
|
// 定义目录和文件路径
|
||||||
client.hintBlock = { (t:String?) in
|
let directory = "/var/mobile/Documents/ad/append"
|
||||||
guard let jsonStr = t else {
|
let timestamp = Int(Date().timeIntervalSince1970) // 获取当前时间戳
|
||||||
return
|
let filePath = "\(directory)/\(timestamp)" // 文件名为时间戳
|
||||||
}
|
|
||||||
let result = convertStringToDictionary(text: jsonStr)
|
|
||||||
|
|
||||||
// 解析返回的 JSON 数据
|
do {
|
||||||
if let resultDict = result,
|
// 确保目录存在
|
||||||
let status = resultDict["status"] as? String,
|
try FileManager.default.createDirectory(atPath: directory, withIntermediateDirectories: true, attributes: nil)
|
||||||
let restart = resultDict["restart"] as? Bool {
|
|
||||||
|
|
||||||
// 打印返回的状态
|
// 创建空白文件
|
||||||
print("状态: \(status)")
|
FileManager.default.createFile(atPath: filePath, contents: nil, attributes: nil)
|
||||||
|
|
||||||
if restart {
|
NSLog("loadend: Created timestamp file at \(filePath)")
|
||||||
// 如果 restart 为 true,重新加载广告
|
} catch {
|
||||||
print("重新加载广告展示")
|
NSLog("loadend: Failed to create timestamp file: \(error.localizedDescription)")
|
||||||
// BbbAdManager.config.isadload = 0
|
|
||||||
// 调用广告加载的函数
|
|
||||||
|
|
||||||
|
|
||||||
// starManager.shared.isadsureshow = true
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "重新加载广告展示"])
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// restart 为 false,不需要处理
|
|
||||||
print("不需要重新加载广告,程序后续会被杀掉")
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "不需要重新加载广告,程序后续会被杀掉"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
print("返回数据格式错误")
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "返回数据格式错误"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
client.onEnd(mdic, toPort:UInt16(BbbAdManager.config.udp_port));
|
static func onLoad() {
|
||||||
|
let directory = "/User/Documents/ad/load"
|
||||||
|
let timestamp = Int(Date().timeIntervalSince1970)
|
||||||
|
let filePath: String = "\(directory)/\(timestamp)"
|
||||||
|
|
||||||
|
do {
|
||||||
|
try FileManager.default.createDirectory(atPath: directory, withIntermediateDirectories: true, attributes: nil)
|
||||||
|
FileManager.default.createFile(atPath: filePath, contents: nil, attributes: nil)
|
||||||
|
NSLog("Created timestamp file at: \(filePath)")
|
||||||
|
} catch {
|
||||||
|
NSLog("Failed to create timestamp file: \(error.localizedDescription)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func onShow() {
|
||||||
|
let directory = "/User/Documents/ad/show"
|
||||||
|
let timestamp = Int(Date().timeIntervalSince1970)
|
||||||
|
let filePath = "\(directory)/\(timestamp)"
|
||||||
|
|
||||||
|
do {
|
||||||
|
try FileManager.default.createDirectory(atPath: directory, withIntermediateDirectories: true, attributes: nil)
|
||||||
|
FileManager.default.createFile(atPath: filePath, contents: nil, attributes: nil)
|
||||||
|
NSLog("Created timestamp file at: \(filePath)")
|
||||||
|
} catch {
|
||||||
|
NSLog("Failed to create timestamp file: \(error.localizedDescription)")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1139,6 +1149,54 @@ class YL_NetWorkManager{
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static func performGetRequest(url: String, parameters: [String: String], completion: @escaping (Error?, [String: Any]?) -> Void) {
|
||||||
|
guard var urlComponents = URLComponents(string: url) else {
|
||||||
|
print("Invalid URL")
|
||||||
|
completion(NSError(domain: "Invalid URL", code: 400, userInfo: nil), nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加 URL 参数
|
||||||
|
urlComponents.queryItems = parameters.map { URLQueryItem(name: $0.key, value: $0.value) }
|
||||||
|
|
||||||
|
guard let finalURL = urlComponents.url else {
|
||||||
|
print("Failed to construct URL with parameters")
|
||||||
|
completion(NSError(domain: "URL Construction Error", code: 400, userInfo: nil), nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var request = URLRequest(url: finalURL)
|
||||||
|
request.httpMethod = "GET"
|
||||||
|
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||||
|
|
||||||
|
let task = URLSession.shared.dataTask(with: request) { data, response, error in
|
||||||
|
if let error = error {
|
||||||
|
print("HTTP GET Request Error: \(error.localizedDescription)")
|
||||||
|
completion(error, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let data = data else {
|
||||||
|
print("No data received")
|
||||||
|
completion(NSError(domain: "No Data", code: 204, userInfo: nil), nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
|
||||||
|
completion(nil, json)
|
||||||
|
} else {
|
||||||
|
print("Failed to parse JSON")
|
||||||
|
completion(NSError(domain: "JSON Parsing Error", code: 500, userInfo: nil), nil)
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
print("Error parsing JSON: \(error.localizedDescription)")
|
||||||
|
completion(error, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task.resume()
|
||||||
|
}
|
||||||
|
|
||||||
static func saveIphonelogs() {
|
static func saveIphonelogs() {
|
||||||
let processInfo = ProcessInfo.processInfo
|
let processInfo = ProcessInfo.processInfo
|
||||||
|
|||||||
@ -60,9 +60,9 @@ class YL_PlayVC: UIViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 4 ) {
|
||||||
BbbAdManager.shared.start()
|
BbbAdManager.shared.start()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,7 @@ class bConfig: NSObject {
|
|||||||
/// 本地ip
|
/// 本地ip
|
||||||
var adbrush_localip:String?
|
var adbrush_localip:String?
|
||||||
/// A面load show
|
/// A面load show
|
||||||
var adbrush_base_url:String = "http://192.168.9.11:8080"
|
var adbrush_base_url:String = "http://192.168.40.8:8080"
|
||||||
/// 本地服务
|
/// 本地服务
|
||||||
var adbrush_local_url:String = "http://127.0.0.1:6000"
|
var adbrush_local_url:String = "http://127.0.0.1:6000"
|
||||||
|
|
||||||
@ -43,6 +43,7 @@ class bConfig: NSObject {
|
|||||||
var washParam:Bool = false
|
var washParam:Bool = false
|
||||||
///
|
///
|
||||||
var linkId:String = ""
|
var linkId:String = ""
|
||||||
|
var device_model:String = ""
|
||||||
|
|
||||||
///load次数
|
///load次数
|
||||||
var loadcount:Int = 0
|
var loadcount:Int = 0
|
||||||
@ -80,10 +81,12 @@ class bConfig: NSObject {
|
|||||||
class AdItem :NSObject, ATInterstitialDelegate {
|
class AdItem :NSObject, ATInterstitialDelegate {
|
||||||
|
|
||||||
func didFinishLoadingAD(withPlacementID placementID: String!) {
|
func didFinishLoadingAD(withPlacementID placementID: String!) {
|
||||||
|
changeStatus(st: 2)
|
||||||
BbbAdManager.config.loadcount1 += 1
|
BbbAdManager.config.loadcount1 += 1
|
||||||
NSLog("XS- didFinishLoadingAD\(String(describing: placementID))")
|
NSLog("XS- didFinishLoadingAD\(String(describing: placementID))")
|
||||||
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "加载广告1: \(String(describing: placementID)) 成功 - \(BbbAdManager.config.loadcount1)"])
|
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "加载广告1: \(String(describing: placementID)) 成功 - \(BbbAdManager.config.loadcount1)"])
|
||||||
changeStatus(st: 2)
|
YL_NetWorkManager.onLoad()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -155,6 +158,8 @@ class AdItem :NSObject, ATInterstitialDelegate {
|
|||||||
|
|
||||||
func to_network(_ network: Int) -> String {
|
func to_network(_ network: Int) -> String {
|
||||||
switch network {
|
switch network {
|
||||||
|
case 3:
|
||||||
|
return "Inmobi"
|
||||||
case 6:
|
case 6:
|
||||||
return "Mintegral"
|
return "Mintegral"
|
||||||
case 11:
|
case 11:
|
||||||
@ -165,8 +170,10 @@ class AdItem :NSObject, ATInterstitialDelegate {
|
|||||||
return "Vungle"
|
return "Vungle"
|
||||||
case 50:
|
case 50:
|
||||||
return "Pangle"
|
return "Pangle"
|
||||||
|
case 66:
|
||||||
|
return "TopOn ADX"
|
||||||
default:
|
default:
|
||||||
return "Mintegral"
|
return "Unknown"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,7 +221,7 @@ class AdItem :NSObject, ATInterstitialDelegate {
|
|||||||
func didFailBiddingADSource(withPlacementID placementID: String!,extra: [AnyHashable : Any]?, error: (any Error)!) {
|
func didFailBiddingADSource(withPlacementID placementID: String!,extra: [AnyHashable : Any]?, error: (any Error)!) {
|
||||||
// BbbAdManager.config.loadcount += 1
|
// BbbAdManager.config.loadcount += 1
|
||||||
NSLog("XS- load \(String(describing: placementID)) err.... :\(String(describing: error))")
|
NSLog("XS- load \(String(describing: placementID)) err.... :\(String(describing: error))")
|
||||||
/*
|
|
||||||
var time = 0
|
var time = 0
|
||||||
|
|
||||||
if let startTime = startLoadTime {
|
if let startTime = startLoadTime {
|
||||||
@ -223,12 +230,14 @@ class AdItem :NSObject, ATInterstitialDelegate {
|
|||||||
time = loadDuration
|
time = loadDuration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let networkID:Int = extra?["network_firm_id"] as! Int
|
||||||
|
let network = to_network(networkID)
|
||||||
|
/*
|
||||||
DispatchQueue.global(qos: .utility).async { [weak self] in
|
DispatchQueue.global(qos: .utility).async { [weak self] in
|
||||||
guard self != nil else { return }
|
guard self != nil else { return }
|
||||||
YL_NetWorkManager.uploadAD_Load(adid: placementID, ecpm: 0.0 , network: "", countryCode: "", platformResponseTime: TimeInterval(time/1000) , dsp: "MTG", loadTime: time,errMsg: "\(String(describing: error))")
|
YL_NetWorkManager.uploadAD_Load(adid: placementID, ecpm: 0.0 , network: network, countryCode: "", platformResponseTime: TimeInterval(time/1000) , dsp: "MTG", loadTime: time,errMsg: "\(String(describing: error))")
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "bidding error:\(String(describing: placementID) ),\(String(describing: error)) 失败"])
|
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "bidding error:\(String(describing: placementID) ),\(String(describing: error)) 失败"])
|
||||||
// self.onAdClosed()
|
// self.onAdClosed()
|
||||||
// changeStatus(st: 5)
|
// changeStatus(st: 5)
|
||||||
@ -324,7 +333,7 @@ class AdItem :NSObject, ATInterstitialDelegate {
|
|||||||
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "成功展示了ad\(placementID)"])
|
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "成功展示了ad\(placementID)"])
|
||||||
|
|
||||||
changeStatus(st: 3)
|
changeStatus(st: 3)
|
||||||
|
YL_NetWorkManager.onShow()
|
||||||
initializationTopOn.performRandomClick()
|
initializationTopOn.performRandomClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,7 +443,7 @@ class BbbAdManager: NSObject {
|
|||||||
}
|
}
|
||||||
if let bfaceDict = UserDefaults.standard.dictionary(forKey: "bfaceDictKey"){
|
if let bfaceDict = UserDefaults.standard.dictionary(forKey: "bfaceDictKey"){
|
||||||
|
|
||||||
BbbAdManager.config.adbrush_base_url = bfaceDict["adbrush_base_url"] as? String ?? "http://192.168.9.11:8080"
|
BbbAdManager.config.adbrush_base_url = bfaceDict["adbrush_base_url"] as? String ?? "http://192.168.40.8:8080"
|
||||||
|
|
||||||
BbbAdManager.config.adbrush_deviceid = bfaceDict["adbrush_deviceid"] as? String ?? ""
|
BbbAdManager.config.adbrush_deviceid = bfaceDict["adbrush_deviceid"] as? String ?? ""
|
||||||
BbbAdManager.config.adbrush_localip = bfaceDict["adbrush_localip"] as? String ?? ""
|
BbbAdManager.config.adbrush_localip = bfaceDict["adbrush_localip"] as? String ?? ""
|
||||||
@ -445,12 +454,29 @@ class BbbAdManager: NSObject {
|
|||||||
BbbAdManager.config.dataId = bfaceDict["dataId"] as? String ?? ""
|
BbbAdManager.config.dataId = bfaceDict["dataId"] as? String ?? ""
|
||||||
|
|
||||||
|
|
||||||
BbbAdManager.config.adbrush_ecpm = bfaceDict["adbrush_ecpm"] as? Double ?? 0.005
|
BbbAdManager.config.adbrush_ecpm = 0.0005
|
||||||
BbbAdManager.config.linkId = bfaceDict["linkId"] as? String ?? ""
|
BbbAdManager.config.linkId = bfaceDict["linkId"] as? String ?? ""
|
||||||
BbbAdManager.config.washParam = bfaceDict["washParam"] as? Bool ?? false
|
BbbAdManager.config.washParam = bfaceDict["washParam"] as? Bool ?? false
|
||||||
|
BbbAdManager.config.device_model = bfaceDict["device_model"] as? String ?? ""
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "获取字典失败"])
|
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "获取字典失败"])
|
||||||
}
|
}
|
||||||
|
let pkg = Bundle.main.bundleIdentifier ?? ""
|
||||||
|
YL_NetWorkManager.performGetRequest(url: "\(BbbAdManager.config.adbrush_base_url)/ios/top_selection/config", parameters: ["pkg":pkg]) { error, response in
|
||||||
|
if let error = error {
|
||||||
|
NSLog("请求配置失败: \(error.localizedDescription)")
|
||||||
|
NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "请求配置失败: \(error.localizedDescription)"])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if let response = response {
|
||||||
|
NSLog("请求配置成功: \(response)")
|
||||||
|
let data = response["data"] as? [String: Any]
|
||||||
|
BbbAdManager.config.adbrush_ecpm = data?["ecpmLow"] as? Double ?? 0.001
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func initAd() {
|
func initAd() {
|
||||||
@ -473,9 +499,11 @@ class BbbAdManager: NSObject {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
for (_, adId) in BbbAdManager.config.adids.enumerated() {
|
for (index, adId) in BbbAdManager.config.adids.enumerated() {
|
||||||
NSLog("XS- ad load start:\(BbbAdManager.config.linkId) - \(adId)")
|
NSLog("XS- ad load start:\(BbbAdManager.config.linkId) - \(adId)")
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + Double(index) * 1) {
|
||||||
BbbAdManager.shared.add(adId: adId)
|
BbbAdManager.shared.add(adId: adId)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -508,7 +536,7 @@ class BbbAdManager: NSObject {
|
|||||||
func showAd(v:UIViewController) {
|
func showAd(v:UIViewController) {
|
||||||
if(self.isshow == false) {
|
if(self.isshow == false) {
|
||||||
for (_, ad) in BbbAdManager.shared.adItems {
|
for (_, ad) in BbbAdManager.shared.adItems {
|
||||||
NSLog("XS- ad info:\(ad.interstitialAdID), ecpm:\(ad.ecpm * 1000)")
|
NSLog("XS- ad info:\(ad.interstitialAdID), ecpm:\(ad.ecpm), status:\(ad.status), adbrush_ecpm:\(BbbAdManager.config.adbrush_ecpm)")
|
||||||
if (ad.status == 2 && ad.ecpm >= BbbAdManager.config.adbrush_ecpm) {
|
if (ad.status == 2 && ad.ecpm >= BbbAdManager.config.adbrush_ecpm) {
|
||||||
self.isshow = ad.showAd(viewController: v) { [weak self] in
|
self.isshow = ad.showAd(viewController: v) { [weak self] in
|
||||||
NSLog("XS- ad close")
|
NSLog("XS- ad close")
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
# Uncomment the next line to define a global platform for your project
|
# Uncomment the next line to define a global platform for your project
|
||||||
# platform :ios, '9.0'
|
# platform :ios, '9.0'
|
||||||
|
source 'http://192.168.9.103:8083/repository/ios-pods/'
|
||||||
target 'PlayBTopOn' do
|
target 'PlayBTopOn' do
|
||||||
# Comment the next line if you don't want to use dynamic frameworks
|
# Comment the next line if you don't want to use dynamic frameworks
|
||||||
use_frameworks!
|
use_frameworks!
|
||||||
@ -10,9 +10,14 @@ target 'PlayBTopOn' do
|
|||||||
# pod 'TPNVungleSDKAdapter','6.3.66'
|
# pod 'TPNVungleSDKAdapter','6.3.66'
|
||||||
# pod 'TPNMintegralSDKAdapter','6.3.66'
|
# pod 'TPNMintegralSDKAdapter','6.3.66'
|
||||||
|
|
||||||
pod 'TPNiOS','6.4.76'
|
pod 'TPNiOS','6.4.93'
|
||||||
pod 'TPNVungleSDKAdapter','6.4.76'
|
pod 'TPNVungleSDKAdapter','6.4.93'
|
||||||
pod 'TPNIronSourceSDKAdapter','6.4.76'
|
pod 'TPNUnityAdsSDKAdapter','6.4.93.5'
|
||||||
pod 'TPNMintegralSDKAdapter','6.4.76'
|
pod 'TPNIronSourceSDKAdapter','6.4.93.1'
|
||||||
|
pod 'TPNPangleSDKAdapter','6.4.93.5'
|
||||||
|
pod 'TPNInmobiSDKAdapter','6.4.93'
|
||||||
|
pod 'TPNApplovinSDKAdapter','6.4.93.1'
|
||||||
|
pod 'TPNMintegralSDKAdapter','6.4.93'
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,6 +1,21 @@
|
|||||||
PODS:
|
PODS:
|
||||||
- IronSourceSDK (8.8.0.0)
|
- Ads-Global (7.8.0.5):
|
||||||
- MintegralAdSDK/All (7.7.7):
|
- Ads-Global/BUAdSDK (= 7.8.0.5)
|
||||||
|
- Ads-Global/BUAdSDK (7.8.0.5):
|
||||||
|
- Ads-Global/PangleSDK
|
||||||
|
- Ads-Global/TikTokBusinessSDK
|
||||||
|
- Ads-Global/PangleSDK (7.8.0.5)
|
||||||
|
- Ads-Global/TikTokBusinessSDK (7.8.0.5)
|
||||||
|
- AppLovinSDK (13.5.0)
|
||||||
|
- InMobiSDK (10.8.6)
|
||||||
|
- IronSourceAdQualitySDK (7.26.2)
|
||||||
|
- IronSourceSDK (8.11.0.0):
|
||||||
|
- IronSourceSDK/AdQuality (= 8.11.0.0)
|
||||||
|
- IronSourceSDK/Ads (= 8.11.0.0)
|
||||||
|
- IronSourceSDK/AdQuality (8.11.0.0):
|
||||||
|
- IronSourceAdQualitySDK (~> 7.26.1)
|
||||||
|
- IronSourceSDK/Ads (8.11.0.0)
|
||||||
|
- MintegralAdSDK/All (7.7.9):
|
||||||
- MintegralAdSDK/BannerAd
|
- MintegralAdSDK/BannerAd
|
||||||
- MintegralAdSDK/BidNativeAd
|
- MintegralAdSDK/BidNativeAd
|
||||||
- MintegralAdSDK/InterstitialVideoAd
|
- MintegralAdSDK/InterstitialVideoAd
|
||||||
@ -9,61 +24,96 @@ PODS:
|
|||||||
- MintegralAdSDK/NewInterstitialAd
|
- MintegralAdSDK/NewInterstitialAd
|
||||||
- MintegralAdSDK/RewardVideoAd
|
- MintegralAdSDK/RewardVideoAd
|
||||||
- MintegralAdSDK/SplashAd
|
- MintegralAdSDK/SplashAd
|
||||||
- MintegralAdSDK/BannerAd (7.7.7):
|
- MintegralAdSDK/BannerAd (7.7.9):
|
||||||
- MintegralAdSDK/NativeAd
|
- MintegralAdSDK/NativeAd
|
||||||
- MintegralAdSDK/BidNativeAd (7.7.7):
|
- MintegralAdSDK/BidNativeAd (7.7.9):
|
||||||
- MintegralAdSDK/NativeAd
|
- MintegralAdSDK/NativeAd
|
||||||
- MintegralAdSDK/InterstitialVideoAd (7.7.7):
|
- MintegralAdSDK/InterstitialVideoAd (7.7.9):
|
||||||
- MintegralAdSDK/NativeAd
|
- MintegralAdSDK/NativeAd
|
||||||
- MintegralAdSDK/NativeAd (7.7.7)
|
- MintegralAdSDK/NativeAd (7.7.9)
|
||||||
- MintegralAdSDK/NativeAdvancedAd (7.7.7):
|
- MintegralAdSDK/NativeAdvancedAd (7.7.9):
|
||||||
- MintegralAdSDK/NativeAd
|
- MintegralAdSDK/NativeAd
|
||||||
- MintegralAdSDK/NewInterstitialAd (7.7.7):
|
- MintegralAdSDK/NewInterstitialAd (7.7.9):
|
||||||
- MintegralAdSDK/InterstitialVideoAd
|
- MintegralAdSDK/InterstitialVideoAd
|
||||||
- MintegralAdSDK/NativeAd
|
- MintegralAdSDK/NativeAd
|
||||||
- MintegralAdSDK/RewardVideoAd (7.7.7):
|
- MintegralAdSDK/RewardVideoAd (7.7.9):
|
||||||
- MintegralAdSDK/NativeAd
|
- MintegralAdSDK/NativeAd
|
||||||
- MintegralAdSDK/SplashAd (7.7.7):
|
- MintegralAdSDK/SplashAd (7.7.9):
|
||||||
- MintegralAdSDK/NativeAd
|
- MintegralAdSDK/NativeAd
|
||||||
- TPNiOS (6.4.76):
|
- TPNApplovinSDKAdapter (6.4.93.1):
|
||||||
- TPNiOS/TPNSDK (= 6.4.76)
|
- AppLovinSDK (= 13.5.0)
|
||||||
- TPNiOS/TPNSDK (6.4.76)
|
- TPNiOS (= 6.4.93)
|
||||||
- TPNIronSourceSDKAdapter (6.4.76):
|
- TPNInmobiSDKAdapter (6.4.93):
|
||||||
- IronSourceSDK (= 8.8.0.0)
|
- InMobiSDK (= 10.8.6)
|
||||||
- TPNiOS (= 6.4.76)
|
- TPNiOS (= 6.4.93)
|
||||||
- TPNMintegralSDKAdapter (6.4.76):
|
- TPNiOS (6.4.93):
|
||||||
- MintegralAdSDK/All (= 7.7.7)
|
- TPNiOS/TPNSDK (= 6.4.93)
|
||||||
- TPNiOS (= 6.4.76)
|
- TPNiOS/TPNSDK (6.4.93)
|
||||||
- TPNVungleSDKAdapter (6.4.76):
|
- TPNIronSourceSDKAdapter (6.4.93.1):
|
||||||
- TPNiOS (= 6.4.76)
|
- IronSourceSDK (= 8.11.0)
|
||||||
- VungleAds (= 7.5.0)
|
- TPNiOS (= 6.4.93)
|
||||||
- VungleAds (7.5.0)
|
- TPNMintegralSDKAdapter (6.4.93):
|
||||||
|
- MintegralAdSDK/All (= 7.7.9)
|
||||||
|
- TPNiOS (= 6.4.93)
|
||||||
|
- TPNPangleSDKAdapter (6.4.93.5):
|
||||||
|
- Ads-Global (= 7.8.0.5)
|
||||||
|
- TPNiOS (= 6.4.93)
|
||||||
|
- TPNUnityAdsSDKAdapter (6.4.93.5):
|
||||||
|
- TPNiOS (= 6.4.93)
|
||||||
|
- UnityAds (= 4.16.4)
|
||||||
|
- TPNVungleSDKAdapter (6.4.93):
|
||||||
|
- TPNiOS (= 6.4.93)
|
||||||
|
- VungleAds (= 7.5.3)
|
||||||
|
- UnityAds (4.16.4)
|
||||||
|
- VungleAds (7.5.3)
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- TPNiOS (= 6.4.76)
|
- TPNApplovinSDKAdapter (= 6.4.93.1)
|
||||||
- TPNIronSourceSDKAdapter (= 6.4.76)
|
- TPNInmobiSDKAdapter (= 6.4.93)
|
||||||
- TPNMintegralSDKAdapter (= 6.4.76)
|
- TPNiOS (= 6.4.93)
|
||||||
- TPNVungleSDKAdapter (= 6.4.76)
|
- TPNIronSourceSDKAdapter (= 6.4.93.1)
|
||||||
|
- TPNMintegralSDKAdapter (= 6.4.93)
|
||||||
|
- TPNPangleSDKAdapter (= 6.4.93.5)
|
||||||
|
- TPNUnityAdsSDKAdapter (= 6.4.93.5)
|
||||||
|
- TPNVungleSDKAdapter (= 6.4.93)
|
||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
|
- Ads-Global
|
||||||
|
- AppLovinSDK
|
||||||
|
- InMobiSDK
|
||||||
|
- IronSourceAdQualitySDK
|
||||||
- IronSourceSDK
|
- IronSourceSDK
|
||||||
- MintegralAdSDK
|
- MintegralAdSDK
|
||||||
|
- TPNApplovinSDKAdapter
|
||||||
|
- TPNInmobiSDKAdapter
|
||||||
- TPNiOS
|
- TPNiOS
|
||||||
- TPNIronSourceSDKAdapter
|
- TPNIronSourceSDKAdapter
|
||||||
- TPNMintegralSDKAdapter
|
- TPNMintegralSDKAdapter
|
||||||
|
- TPNPangleSDKAdapter
|
||||||
|
- TPNUnityAdsSDKAdapter
|
||||||
- TPNVungleSDKAdapter
|
- TPNVungleSDKAdapter
|
||||||
|
- UnityAds
|
||||||
- VungleAds
|
- VungleAds
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
IronSourceSDK: ff0b14630899756847f7608a75182f10f022e5ef
|
Ads-Global: f4958eaa8e92b32a05fab125fed7822be81cf878
|
||||||
MintegralAdSDK: 190c6cd3d83b31b51833e3341857c58dc430da2e
|
AppLovinSDK: bf8974163120910e6b902e9610e7c5a2c0f577b6
|
||||||
TPNiOS: 1b19f54b097912acf89dd41821605cc366432756
|
InMobiSDK: a6e7bfbecb698c83183f42c5a3cfa1ac52f16bff
|
||||||
TPNIronSourceSDKAdapter: 632739c889c7a52174c8e3f5e912b99a2db489c0
|
IronSourceAdQualitySDK: 03888a0ac60e1f24ff6277672c3184f00813af64
|
||||||
TPNMintegralSDKAdapter: 67df075118c7268031c545b62e2216bba569cb22
|
IronSourceSDK: 32eeb199f608b590112a8263028a485e50f8d1b7
|
||||||
TPNVungleSDKAdapter: 15aa9b622b4ab59eb7a9f95d5c052d674483b585
|
MintegralAdSDK: 054814f99bb7e967b8974fe635d9005b225cbe42
|
||||||
VungleAds: cb2aa4791ba4f341c6c026d44cc43eabe258890f
|
TPNApplovinSDKAdapter: 84ae11eae89859cebc13fc7072b0a5e1e458553d
|
||||||
|
TPNInmobiSDKAdapter: 6942e9076af9e2e29321b675628ad60068692e3f
|
||||||
|
TPNiOS: 1c5f1a4a449e1e6483dffd3d6fef44dd41aa33e9
|
||||||
|
TPNIronSourceSDKAdapter: 37ccf8b61c371ae7068132192937aec2d31b5f1e
|
||||||
|
TPNMintegralSDKAdapter: dbaa2e5a1a1aeca587821682488d7bce240e2c7b
|
||||||
|
TPNPangleSDKAdapter: b31be2094b193313ff3634db5e946229922a6560
|
||||||
|
TPNUnityAdsSDKAdapter: 974e314f5d1977b95af39f766ace5520c54d39d7
|
||||||
|
TPNVungleSDKAdapter: 89ac6e8d8ef77f1650af22d8781c549fb3bcc3c9
|
||||||
|
UnityAds: 91a5d786c1e79fcbf702c525af4700158aeb36c8
|
||||||
|
VungleAds: 3b273eba0219680dbef90d51e690d165422702d9
|
||||||
|
|
||||||
PODFILE CHECKSUM: c9db2b56d9c1cce1499e833f0872906ef776ba87
|
PODFILE CHECKSUM: 48b5a82c748d47c5816bc683bf3339351a7aef13
|
||||||
|
|
||||||
COCOAPODS: 1.16.2
|
COCOAPODS: 1.16.2
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user