PlatformHostApiImpl.swift
4.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import Foundation
import AuthenticationServices
import StoreKit
import UIKit
import WebKit
/**
* PlatformApi iOS implementation.
*
* 组装完整 User-Agent,格式与 Android 端保持一致:
* `{systemWebViewUA} doublefeel/{versionCode}({versionName})(Apple##Apple##{model}; iOS{osVersion}; {height}x{width})(huawei)`
*/
final class PlatformHostApiImpl: PlatformHostApi {
func requestAppleProductInfo(productId: String, completion: @escaping (Result<AppleProductInfo?, any Error>) -> Void) {
Task {
do {
let product = try await ApplePayment.shared.requestProducts(productId)
let isTrialPeriod = await ApplePayment.shared.isFreeTrail(product: product)
let originPrice = product.price
var displayPrice = product.displayPrice
var price = originPrice
if let introductoryOffer = product.subscription?.introductoryOffer, introductoryOffer.price > 0{
price = introductoryOffer.price
displayPrice = introductoryOffer.displayPrice
}else if let offer = product.subscription?.promotionalOffers.first(where: { $0.id == product.id }){
price = offer.price
displayPrice = offer.displayPrice
}
let productInfo = AppleProductInfo(
productId: product.id,
originPriceDescription: product.displayPrice,
priceDescription: displayPrice,
originPrice: NSDecimalNumber(decimal: originPrice).doubleValue,
price: NSDecimalNumber(decimal: price).doubleValue,
isTrialPeriod: isTrialPeriod
)
print("[PlatformHostApiImpl.requestAppleProductInfo] return: \(productInfo)")
completion(.success(productInfo))
} catch StoreKitError.productNotFound {
print("[PlatformHostApiImpl.requestAppleProductInfo] return: nil")
completion(.success(nil))
} catch {
print("[PlatformHostApiImpl.requestAppleProductInfo] error: \(error.localizedDescription)")
completion(.failure(error))
}
}
}
func performApplePayment(productId: String, uuid: String, completion: @escaping (Result<AppleProductPaymentResult?, any Error>) -> Void) {
Task {
let result = await ApplePayment.shared.purchase(productId, uuidString: uuid)
print("[PlatformHostApiImpl.performApplePayment] return: \(result)")
completion(.success(result))
}
}
private var appleSignInCoordinator: AppleSignInCoordinator?
func requestAppleSignIn(completion: @escaping (Result<AppleSignInModel?, any Error>) -> Void) {
DispatchQueue.main.async { [weak self] in
guard let self else {
print("[PlatformHostApiImpl.requestAppleSignIn] error: \(PlatformHostApiError.deallocated.localizedDescription)")
completion(.failure(PlatformHostApiError.deallocated))
return
}
let provider = ASAuthorizationAppleIDProvider()
let request = provider.createRequest()
request.requestedScopes = [.fullName, .email]
guard let presentationAnchor = AppleSignInCoordinator.currentPresentationAnchor() else {
print("[PlatformHostApiImpl.requestAppleSignIn] error: \(PlatformHostApiError.missingPresentationAnchor.localizedDescription)")
completion(.failure(PlatformHostApiError.missingPresentationAnchor))
return
}
let coordinator = AppleSignInCoordinator(presentationAnchor: presentationAnchor) { [weak self] result in
self?.appleSignInCoordinator = nil
switch result {
case .success(let model):
print("[PlatformHostApiImpl.requestAppleSignIn] return: \(String(describing: model))")
case .failure(let error):
print("[PlatformHostApiImpl.requestAppleSignIn] error: \(error.localizedDescription)")
}
completion(result)
}
appleSignInCoordinator = coordinator
let controller = ASAuthorizationController(authorizationRequests: [request])
controller.delegate = coordinator
controller.presentationContextProvider = coordinator
controller.performRequests()
}
}
func getFullUserAgent() throws -> String {
let userAgent = UserAgent.share.finalUA
print("[PlatformHostApiImpl.getFullUserAgent] return: \(userAgent)")
return userAgent
}
}