Commit ad955c1e authored by lmj_521aiau@163.com's avatar lmj_521aiau@163.com

log

parent 803e6511
...@@ -23,10 +23,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate { ...@@ -23,10 +23,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
}, failure: { }, failure: {
}) })
// SHUserAccountManager.shared.logCollection(with: .appStart) MobClick.event("app_start")
SHUserAccountManager.shared.logCollection(with: .appStart)
SHUserAccountManager.shared.getNovelInfo { (json) in // SHUserAccountManager.shared.getNovelInfo { (json) in
} // }
self.window = UIWindow(frame: UIScreen.main.bounds) self.window = UIWindow(frame: UIScreen.main.bounds)
......
...@@ -40,9 +40,10 @@ class SHBaseViewController: UIViewController { ...@@ -40,9 +40,10 @@ class SHBaseViewController: UIViewController {
self.navigationController?.popViewController(animated: true) self.navigationController?.popViewController(animated: true)
} }
@objc public func goGoods(){ @objc public func goGoods(_ type:String){
let goodsVC = UIStoryboard.init(name: "Goods", bundle: nil).instantiateViewController(withIdentifier: "SHGoodsViewController") as! SHGoodsViewController let goodsVC = UIStoryboard.init(name: "Goods", bundle: nil).instantiateViewController(withIdentifier: "SHGoodsViewController") as! SHGoodsViewController
goodsVC.logValue = type
let nav = SHBaseNavigationController(rootViewController: goodsVC) let nav = SHBaseNavigationController(rootViewController: goodsVC)
nav.modalPresentationStyle = .fullScreen nav.modalPresentationStyle = .fullScreen
self.present(nav, animated: true, completion: nil) self.present(nav, animated: true, completion: nil)
......
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
</constraints> </constraints>
</view> </view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="3天免费试用,之后¥498/年,随时取消" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bYQ-iK-LKQ"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="3天免费试用,之后¥498/年,随时取消" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bYQ-iK-LKQ">
<rect key="frame" x="63.333333333333329" y="139" width="248.66666666666669" height="17"/> <rect key="frame" x="63.333333333333329" y="125.66666666666663" width="248.66666666666669" height="17"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/> <fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
...@@ -142,7 +142,7 @@ ...@@ -142,7 +142,7 @@
<constraint firstItem="zdZ-po-8RK" firstAttribute="leading" secondItem="7CA-md-1C7" secondAttribute="leading" id="AbC-E6-8RL"/> <constraint firstItem="zdZ-po-8RK" firstAttribute="leading" secondItem="7CA-md-1C7" secondAttribute="leading" id="AbC-E6-8RL"/>
<constraint firstItem="97G-xL-vUR" firstAttribute="centerY" secondItem="zdZ-po-8RK" secondAttribute="centerY" id="FHh-jS-ozY"/> <constraint firstItem="97G-xL-vUR" firstAttribute="centerY" secondItem="zdZ-po-8RK" secondAttribute="centerY" id="FHh-jS-ozY"/>
<constraint firstItem="zdZ-po-8RK" firstAttribute="top" secondItem="8CH-Xu-Rvt" secondAttribute="top" id="Ire-xb-j6d"/> <constraint firstItem="zdZ-po-8RK" firstAttribute="top" secondItem="8CH-Xu-Rvt" secondAttribute="top" id="Ire-xb-j6d"/>
<constraint firstItem="bYQ-iK-LKQ" firstAttribute="centerY" secondItem="paw-ud-pJv" secondAttribute="centerY" multiplier="1.1" id="LrC-6k-V4B"/> <constraint firstItem="bYQ-iK-LKQ" firstAttribute="centerY" secondItem="paw-ud-pJv" secondAttribute="centerY" id="LrC-6k-V4B"/>
<constraint firstItem="7CA-md-1C7" firstAttribute="centerY" secondItem="paw-ud-pJv" secondAttribute="centerY" multiplier="0.5" id="P8S-Vw-F5z"/> <constraint firstItem="7CA-md-1C7" firstAttribute="centerY" secondItem="paw-ud-pJv" secondAttribute="centerY" multiplier="0.5" id="P8S-Vw-F5z"/>
<constraint firstItem="8CH-Xu-Rvt" firstAttribute="centerX" secondItem="bYQ-iK-LKQ" secondAttribute="centerX" id="PaG-1z-1ya"/> <constraint firstItem="8CH-Xu-Rvt" firstAttribute="centerX" secondItem="bYQ-iK-LKQ" secondAttribute="centerX" id="PaG-1z-1ya"/>
<constraint firstItem="97G-xL-vUR" firstAttribute="trailing" secondItem="7CA-md-1C7" secondAttribute="trailing" id="TPF-52-ghN"/> <constraint firstItem="97G-xL-vUR" firstAttribute="trailing" secondItem="7CA-md-1C7" secondAttribute="trailing" id="TPF-52-ghN"/>
......
...@@ -14,14 +14,23 @@ class SHGoodsViewController: SHBaseViewController { ...@@ -14,14 +14,23 @@ class SHGoodsViewController: SHBaseViewController {
@IBOutlet weak var yearStoreBtn: UIButton! @IBOutlet weak var yearStoreBtn: UIButton!
@IBOutlet weak var yearStoreBtnBgView: UIView! @IBOutlet weak var yearStoreBtnBgView: UIView!
@objc public var logValue: String?
let startTime: CFTimeInterval = CACurrentMediaTime()
private var pruducts: [SHAPProductModel] = [] private var pruducts: [SHAPProductModel] = []
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
setupUI() setupUI()
getDataSource()
if SHUserAccountManager.shared.isMember == true { if SHUserAccountManager.shared.isMember == true {
MBProgressHUD.showSuccess("您已成为会员", to: self.view) MBProgressHUD.showSuccess("您已成为会员", to: self.view)
} }
MobClick.event("pay_page_show", label: logValue)
let params = ["event": "guazinovel", "action": "pay_page_show", "value": logValue]
CMNetworkManager.shared.postLogRequest(withPath: .logCollection, parameters: params as [String : Any]) { (json, error) in
}
} }
override func viewWillAppear(_ animated: Bool) { override func viewWillAppear(_ animated: Bool) {
...@@ -36,8 +45,8 @@ class SHGoodsViewController: SHBaseViewController { ...@@ -36,8 +45,8 @@ class SHGoodsViewController: SHBaseViewController {
yearStoreBtnBgView.layer.cornerRadius = yearStoreBtnBgView.frame.size.height/2 yearStoreBtnBgView.layer.cornerRadius = yearStoreBtnBgView.frame.size.height/2
yearStoreBtn.layer.cornerRadius = yearStoreBtn.frame.size.height/2 yearStoreBtn.layer.cornerRadius = yearStoreBtn.frame.size.height/2
// yearStoreBtn.setTitle(SHUserAccountManager.shared.autoButtonText, for: .normal) yearStoreBtn.setTitle(SHUserAccountManager.shared.autoButtonText, for: .normal)
// yearStoreLab.text = SHUserAccountManager.shared.threeDayText yearStoreLab.text = SHUserAccountManager.shared.threeDayText
let animation = CABasicAnimation.init() let animation = CABasicAnimation.init()
animation.duration = 0.66 animation.duration = 0.66
...@@ -64,6 +73,20 @@ class SHGoodsViewController: SHBaseViewController { ...@@ -64,6 +73,20 @@ class SHGoodsViewController: SHBaseViewController {
} }
@objc @IBAction func cancelBtnClick(_ sender: UIButton){ @objc @IBAction func cancelBtnClick(_ sender: UIButton){
MobClick.event("pay_payment_close_click", label: logValue)
var params = ["event": "guazinovel", "action": "pay_payment_close_click", "value": logValue]
CMNetworkManager.shared.postLogRequest(withPath: .logCollection, parameters: params as [String : Any]) { (json, error) in
}
let endTime = CACurrentMediaTime()
let time = String(format: "%.3f", endTime - startTime)
MobClick.event("pay_page_stay", label: (logValue ?? "")+","+time)
params = ["event": "guazinovel", "action": "pay_page_stay", "value": (logValue ?? "")+","+time]
CMNetworkManager.shared.postLogRequest(withPath: .logCollection, parameters: params as [String : Any]) { (json, error) in
}
self.navigationController?.dismiss(animated: true, completion: nil) self.navigationController?.dismiss(animated: true, completion: nil)
} }
...@@ -71,7 +94,16 @@ class SHGoodsViewController: SHBaseViewController { ...@@ -71,7 +94,16 @@ class SHGoodsViewController: SHBaseViewController {
let productId = pruducts.filter({ $0.productId.contains("year") }).first?.productId ?? "com.ShorthandMaster.www.subscription.yearly" let productId = pruducts.filter({ $0.productId.contains("year") }).first?.productId ?? "com.ShorthandMaster.www.subscription.yearly"
MobClick.event("pay_year_vip_click", label: logValue)
let params = ["event": "guazinovel", "action": "pay_year_vip_click", "value": logValue]
CMNetworkManager.shared.postLogRequest(withPath: .logCollection, parameters: params as [String : Any]) { (json, error) in
}
SHStoreManager.purchaseWithProductId(productId: productId, inView: self.view, success: { SHStoreManager.purchaseWithProductId(productId: productId, inView: self.view, success: {
MobClick.event("pay_year_success", label: self.logValue)
let params = ["event": "guazinovel", "action": "pay_year_success", "value": self.logValue]
CMNetworkManager.shared.postLogRequest(withPath: .logCollection, parameters: params as [String : Any]) { (json, error) in
}
SHUserAccountManager.shared.getUserInfo({ (model) in SHUserAccountManager.shared.getUserInfo({ (model) in
self.dismiss(animated: true, completion: nil) self.dismiss(animated: true, completion: nil)
...@@ -80,6 +112,10 @@ class SHGoodsViewController: SHBaseViewController { ...@@ -80,6 +112,10 @@ class SHGoodsViewController: SHBaseViewController {
}) })
}, faliure: { errString in }, faliure: { errString in
MobClick.event("pay_year_fail", label: (self.logValue ?? "")+":"+errString)
let params = ["event": "guazinovel", "action": "pay_year_fail", "value": (self.logValue ?? "")+":"+errString]
CMNetworkManager.shared.postLogRequest(withPath: .logCollection, parameters: params as [String : Any]) { (json, error) in
}
}) })
} }
...@@ -87,8 +123,8 @@ class SHGoodsViewController: SHBaseViewController { ...@@ -87,8 +123,8 @@ class SHGoodsViewController: SHBaseViewController {
switch sender.tag { switch sender.tag {
case 100: case 100:
let webVc = SHWebViewController() let webVc = SHWebViewController()
webVc.title = "使用条款" webVc.title = "隐私政策"
webVc.url = SHUserAccountManager.shared.h5_url["user"].stringValue webVc.url = SHUserAccountManager.shared.h5_url["privacy"].stringValue
self.navigationController?.pushViewController(webVc, animated: true) self.navigationController?.pushViewController(webVc, animated: true)
break break
case 101: case 101:
...@@ -99,11 +135,17 @@ class SHGoodsViewController: SHBaseViewController { ...@@ -99,11 +135,17 @@ class SHGoodsViewController: SHBaseViewController {
self.navigationController?.dismiss(animated: true, completion: nil) self.navigationController?.dismiss(animated: true, completion: nil)
}) })
}, toView: self.view) }, toView: self.view)
MobClick.event("pay_restore_click", label: logValue)
let params = ["event": "guazinovel", "action": "pay_restore_click", "value": logValue]
CMNetworkManager.shared.postLogRequest(withPath: .logCollection, parameters: params as [String : Any]) { (json, error) in
}
break break
case 102: case 102:
let webVc = SHWebViewController() let webVc = SHWebViewController()
webVc.title = "隐私政策" webVc.title = "使用条款"
webVc.url = SHUserAccountManager.shared.h5_url["privacy"].stringValue webVc.url = SHUserAccountManager.shared.h5_url["user"].stringValue
self.navigationController?.pushViewController(webVc, animated: true) self.navigationController?.pushViewController(webVc, animated: true)
break break
default: default:
......
...@@ -20,6 +20,11 @@ ...@@ -20,6 +20,11 @@
<string>$(CURRENT_PROJECT_VERSION)</string> <string>$(CURRENT_PROJECT_VERSION)</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key> <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>App需要您开启定位权限,命名您的文件名称</string> <string>App需要您开启定位权限,命名您的文件名称</string>
<key>NSLocationAlwaysUsageDescription</key> <key>NSLocationAlwaysUsageDescription</key>
...@@ -57,5 +62,7 @@ ...@@ -57,5 +62,7 @@
<string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string> <string>UIInterfaceOrientationLandscapeRight</string>
</array> </array>
<key>UIUserInterfaceStyle</key>
<string>Light</string>
</dict> </dict>
</plist> </plist>
...@@ -24,6 +24,8 @@ typedef void(^finishBlock)(void); ...@@ -24,6 +24,8 @@ typedef void(^finishBlock)(void);
+ (void)alertControllerWithTitle:(NSString *)tilte message:(NSString *)message view:(UIView *)currentView cancelTitle:(NSString *)cancelTitle cancelBlock:(cancelBlock)cancelBlock confirm:(NSString *)confirmTitle confirmBlock:(confirmBlock)confirmBlock finishBlock:(finishBlock)finishBlock; + (void)alertControllerWithTitle:(NSString *)tilte message:(NSString *)message view:(UIView *)currentView cancelTitle:(NSString *)cancelTitle cancelBlock:(cancelBlock)cancelBlock confirm:(NSString *)confirmTitle confirmBlock:(confirmBlock)confirmBlock finishBlock:(finishBlock)finishBlock;
+ (void)alertControllerWithTitle:(NSString *)tilte message:(NSString *)message cancelTitle:(NSString *)cancelTitle cancelBlock:(cancelBlock)cancelBlock confirm:(NSString *)confirmTitle confirmTitleColor:(UIColor *)color confirmBlock:(confirmBlock)confirmBlock finishBlock:(finishBlock)finishBlock;
+ (void)alertControllerWithTitle:(NSString *)tilte message:(NSString *)message alignment:(NSTextAlignment)alignment cancelTitle:(NSString *)cancelTitle cancelBlock:(cancelBlock)cancelBlock confirm:(NSString *)confirmTitle confirmBlock:(confirmBlock)confirmBlock finishBlock:(finishBlock)finishBlock; + (void)alertControllerWithTitle:(NSString *)tilte message:(NSString *)message alignment:(NSTextAlignment)alignment cancelTitle:(NSString *)cancelTitle cancelBlock:(cancelBlock)cancelBlock confirm:(NSString *)confirmTitle confirmBlock:(confirmBlock)confirmBlock finishBlock:(finishBlock)finishBlock;
//- (void)alertControllerWithPhoto:(NSString *)imageStr finishBlock:(finishBlock)finishBlock; //- (void)alertControllerWithPhoto:(NSString *)imageStr finishBlock:(finishBlock)finishBlock;
......
...@@ -56,15 +56,20 @@ ...@@ -56,15 +56,20 @@
+ (void)alertControllerWithTitle:(NSString *)tilte message:(NSString *)message view:(UIView *)currentView cancelTitle:(NSString *)cancelTitle cancelBlock:(cancelBlock)cancelBlock confirm:(NSString *)confirmTitle confirmBlock:(confirmBlock)confirmBlock finishBlock:(finishBlock)finishBlock{ + (void)alertControllerWithTitle:(NSString *)tilte message:(NSString *)message view:(UIView *)currentView cancelTitle:(NSString *)cancelTitle cancelBlock:(cancelBlock)cancelBlock confirm:(NSString *)confirmTitle confirmBlock:(confirmBlock)confirmBlock finishBlock:(finishBlock)finishBlock{
[AlertControllerTool alertControllerWithTitle:tilte message:message view:currentView alignment:NSTextAlignmentCenter cancelTitle:cancelTitle cancelBlock:cancelBlock confirm:confirmTitle confirmBlock:confirmBlock finishBlock:finishBlock]; [AlertControllerTool alertControllerWithTitle:tilte message:message view:currentView alignment:NSTextAlignmentCenter cancelTitle:cancelTitle cancelBlock:cancelBlock confirmTitle:confirmTitle confirmTitleColor:nil confirmBlock:confirmBlock finishBlock:finishBlock];
} }
+ (void)alertControllerWithTitle:(NSString *)tilte message:(NSString *)message alignment:(NSTextAlignment)alignment cancelTitle:(NSString *)cancelTitle cancelBlock:(cancelBlock)cancelBlock confirm:(NSString *)confirmTitle confirmBlock:(confirmBlock)confirmBlock finishBlock:(finishBlock)finishBlock{ + (void)alertControllerWithTitle:(NSString *)tilte message:(NSString *)message alignment:(NSTextAlignment)alignment cancelTitle:(NSString *)cancelTitle cancelBlock:(cancelBlock)cancelBlock confirm:(NSString *)confirmTitle confirmBlock:(confirmBlock)confirmBlock finishBlock:(finishBlock)finishBlock{
[AlertControllerTool alertControllerWithTitle:tilte message:message view:nil alignment:alignment cancelTitle:cancelTitle cancelBlock:cancelBlock confirm:confirmTitle confirmBlock:confirmBlock finishBlock:finishBlock]; [AlertControllerTool alertControllerWithTitle:tilte message:message view:nil alignment:alignment cancelTitle:cancelTitle cancelBlock:cancelBlock confirmTitle:confirmTitle confirmTitleColor:nil confirmBlock:confirmBlock finishBlock:finishBlock];
} }
+ (void)alertControllerWithTitle:(NSString *)tilte message:(NSString *)message view:(UIView *)currentView alignment:(NSTextAlignment)alignment cancelTitle:(NSString *)cancelTitle cancelBlock:(cancelBlock)cancelBlock confirm:(NSString *)confirmTitle confirmBlock:(confirmBlock)confirmBlock finishBlock:(finishBlock)finishBlock{ + (void)alertControllerWithTitle:(NSString *)tilte message:(NSString *)message cancelTitle:(NSString *)cancelTitle cancelBlock:(cancelBlock)cancelBlock confirm:(NSString *)confirmTitle confirmTitleColor:(UIColor *)color confirmBlock:(confirmBlock)confirmBlock finishBlock:(finishBlock)finishBlock{
[AlertControllerTool alertControllerWithTitle:tilte message:message view:nil alignment:NSTextAlignmentCenter cancelTitle:cancelTitle cancelBlock:cancelBlock confirmTitle:confirmTitle confirmTitleColor:color confirmBlock:confirmBlock finishBlock:finishBlock];
}
+ (void)alertControllerWithTitle:(NSString *)tilte message:(NSString *)message view:(UIView *)currentView alignment:(NSTextAlignment)alignment cancelTitle:(NSString *)cancelTitle cancelBlock:(cancelBlock)cancelBlock confirmTitle:(NSString *)confirmTitle confirmTitleColor:(UIColor *)color confirmBlock:(confirmBlock)confirmBlock finishBlock:(finishBlock)finishBlock{
dispatch_async(dispatch_get_global_queue(0, 0), ^{ dispatch_async(dispatch_get_global_queue(0, 0), ^{
dispatch_sync(dispatch_get_main_queue(), ^{ dispatch_sync(dispatch_get_main_queue(), ^{
...@@ -83,6 +88,9 @@ ...@@ -83,6 +88,9 @@
confirmBlock(nil); confirmBlock(nil);
} }
}]; }];
if (color) {
[confirm setValue:color forKey:@"titleTextColor"];
}
//修改按钮文字颜色 //修改按钮文字颜色
// if ([cancel valueForKey:@"titleTextColor"]) { // if ([cancel valueForKey:@"titleTextColor"]) {
// [cancel setValue:kColorWithRGB(85,141,251) forKey:@"titleTextColor"]; // [cancel setValue:kColorWithRGB(85,141,251) forKey:@"titleTextColor"];
......
...@@ -28,8 +28,9 @@ class SHRecordListViewController: SHBaseViewController { ...@@ -28,8 +28,9 @@ class SHRecordListViewController: SHBaseViewController {
let leftImage = UIImage.init(named: "record_nav_user")?.withRenderingMode(.alwaysOriginal) let leftImage = UIImage.init(named: "record_nav_user")?.withRenderingMode(.alwaysOriginal)
self.navigationItem.leftBarButtonItem = UIBarButtonItem.init(image: leftImage, style: .plain, target: self, action: #selector(userCilck)) self.navigationItem.leftBarButtonItem = UIBarButtonItem.init(image: leftImage, style: .plain, target: self, action: #selector(userCilck))
setupUI() setupUI()
preposeMember()
// preposeMember() MobClick.event("tab_imp")
SHUserAccountManager.shared.logCollection(with: .tabImp)
/* /*
SHCloudManager.shared.cheakAccountStatus { (result) in SHCloudManager.shared.cheakAccountStatus { (result) in
...@@ -99,48 +100,54 @@ class SHRecordListViewController: SHBaseViewController { ...@@ -99,48 +100,54 @@ class SHRecordListViewController: SHBaseViewController {
func removeModel(_ indexPath: IndexPath){ func removeModel(_ indexPath: IndexPath){
var list = CRUserDefaults.recordList AlertControllerTool.alertController(withTitle: "提示", message: "确定要删除录音文件吗?", cancelTitle: "取消", cancel: {
}, confirm: "删除", confirmTitleColor: UIColor.red, confirmBlock: { message in
var list = CRUserDefaults.recordList
let deleteModel = dataSources[indexPath.row] let deleteModel = self.dataSources[indexPath.row]
for (index, dic) in list!.enumerated(){ for (index, dic) in list!.enumerated(){
if dic["pathFile"] as! String == deleteModel.pathFile{
// var subDic = dic
// subDic["delete"] = true
// subDic["deleteDate"] = Date.init()
// list![index] = subDic
list!.remove(at: index)
break
}
}
CRUserDefaults.recordList = list
let keyValueStore = NSUbiquitousKeyValueStore.default
list = keyValueStore.object(forKey: "list") as? [Dictionary<String, Any>]
if var list = list {
for (index, dic) in list.enumerated(){
if dic["pathFile"] as! String == deleteModel.pathFile{ if dic["pathFile"] as! String == deleteModel.pathFile{
// var subDic = dic // var subDic = dic
// subDic["delete"] = true // subDic["delete"] = true
// subDic["deleteDate"] = Date.init() // subDic["deleteDate"] = Date.init()
// list[index] = subDic // list![index] = subDic
list.remove(at: index) list!.remove(at: index)
break break
} }
} }
keyValueStore.set(list, forKey: "list") CRUserDefaults.recordList = list
keyValueStore.synchronize()
} let keyValueStore = NSUbiquitousKeyValueStore.default
list = keyValueStore.object(forKey: "list") as? [Dictionary<String, Any>]
dataSources.remove(at: indexPath.row)
self.tableView?.beginUpdates() if var list = list {
self.tableView?.deleteRows(at: [indexPath], with: .left) for (index, dic) in list.enumerated(){
self.tableView?.endUpdates() if dic["pathFile"] as! String == deleteModel.pathFile{
// var subDic = dic
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(333)) { // subDic["delete"] = true
self.prepareDateSource() // subDic["deleteDate"] = Date.init()
} // list[index] = subDic
list.remove(at: index)
break
}
}
keyValueStore.set(list, forKey: "list")
keyValueStore.synchronize()
}
self.dataSources.remove(at: indexPath.row)
self.tableView?.beginUpdates()
self.tableView?.deleteRows(at: [indexPath], with: .left)
self.tableView?.endUpdates()
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(333)) {
self.prepareDateSource()
}
}, finish: nil)
// let range: Range = model.pathFile.range(of: "/record.wav")! // let range: Range = model.pathFile.range(of: "/record.wav")!
// let location: Int = model.pathFile.distance(from: model.pathFile.startIndex, to: range.lowerBound) // let location: Int = model.pathFile.distance(from: model.pathFile.startIndex, to: range.lowerBound)
...@@ -165,38 +172,28 @@ class SHRecordListViewController: SHBaseViewController { ...@@ -165,38 +172,28 @@ class SHRecordListViewController: SHBaseViewController {
@objc func userCilck(){ @objc func userCilck(){
// if SHUserAccountManager.shared.isMember == false { // if SHUserAccountManager.shared.isMember == false {
self.goGoods() self.goGoods("home_pop")
MobClick.event("home_pop")
let params = ["event": "guazinovel", "action": "", "value": "home_pop"]
CMNetworkManager.shared.postLogRequest(withPath: .logCollection, parameters: params) { (json, error) in
}
// } // }
} }
@objc func preposeMember(){ @objc func preposeMember(){
if SHUserAccountManager.shared.isMember == false {
self.goGoods() SHUserAccountManager.shared.getNovelInfo { (json) in
MobClick.event("home_pay") if SHUserAccountManager.shared.isMember == false && SHUserAccountManager.shared.isStartFront == true{
let params = ["event": "guazinovel", "action": "", "value": "home_pay"] self.goGoods("home_pay")
CMNetworkManager.shared.postLogRequest(withPath: .logCollection, parameters: params) { (json, error) in
} }
} }
} }
@IBAction func goRecord(){ @IBAction func goRecord(){
if dataSources.count > 1{ if dataSources.count > 0{
if SHUserAccountManager.shared.isMember == false{ if SHUserAccountManager.shared.isMember == false{
self.goGoods() self.goGoods("home_record")
return return
} }
} }
MobClick.event("home_record")
let params = ["event": "guazinovel", "action": "", "value": "home_record"]
CMNetworkManager.shared.postLogRequest(withPath: .logCollection, parameters: params) { (json, error) in
}
let record = UIStoryboard.init(name: "Record", bundle: nil).instantiateViewController(withIdentifier: "SHRecordViewController") as! SHRecordViewController let record = UIStoryboard.init(name: "Record", bundle: nil).instantiateViewController(withIdentifier: "SHRecordViewController") as! SHRecordViewController
self.navigationController?.pushViewController(record, animated: true) self.navigationController?.pushViewController(record, animated: true)
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
import UIKit import UIKit
import AVFoundation import AVFoundation
import Speech //import Speech
import PDFGenerator import PDFGenerator
class SHRecordShowViewController: SHBaseViewController { class SHRecordShowViewController: SHBaseViewController {
...@@ -17,6 +17,7 @@ class SHRecordShowViewController: SHBaseViewController { ...@@ -17,6 +17,7 @@ class SHRecordShowViewController: SHBaseViewController {
private var playerTimeCount = 0 private var playerTimeCount = 0
private var playerTimer: SHTimer? private var playerTimer: SHTimer?
/*
// 创建语音识别器,指定语音识别的语言环境 locale ,将来会转化为什么语言,这里是使用的当前区域,那肯定就是简体汉语啦 // 创建语音识别器,指定语音识别的语言环境 locale ,将来会转化为什么语言,这里是使用的当前区域,那肯定就是简体汉语啦
// private let speechRecognizer = SFSpeechRecognizer(locale: Locale.autoupdatingCurrent) // private let speechRecognizer = SFSpeechRecognizer(locale: Locale.autoupdatingCurrent)
private let speechRecognizer = SFSpeechRecognizer(locale: Locale(identifier: "zh-CN")) private let speechRecognizer = SFSpeechRecognizer(locale: Locale(identifier: "zh-CN"))
...@@ -24,7 +25,7 @@ class SHRecordShowViewController: SHBaseViewController { ...@@ -24,7 +25,7 @@ class SHRecordShowViewController: SHBaseViewController {
private var recognitionRequest: SFSpeechURLRecognitionRequest? private var recognitionRequest: SFSpeechURLRecognitionRequest?
// 语音识别任务,可监控识别进度。通过他可以取消或终止当前的语音识别任务 // 语音识别任务,可监控识别进度。通过他可以取消或终止当前的语音识别任务
private var recognitionTask: SFSpeechRecognitionTask? private var recognitionTask: SFSpeechRecognitionTask?
*/
@IBOutlet var recordTextView: UITextView? @IBOutlet var recordTextView: UITextView?
@IBOutlet var bottomBgView: UIView! @IBOutlet var bottomBgView: UIView!
...@@ -51,20 +52,20 @@ class SHRecordShowViewController: SHBaseViewController { ...@@ -51,20 +52,20 @@ class SHRecordShowViewController: SHBaseViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
AVAudioSession.sharedInstance().requestRecordPermission { (allowed) in // AVAudioSession.sharedInstance().requestRecordPermission { (allowed) in
if !allowed { // if !allowed {
return // return
} // }
} // }
let session:AVAudioSession = AVAudioSession.sharedInstance() // let session:AVAudioSession = AVAudioSession.sharedInstance()
do { // do {
try session.setCategory(AVAudioSession.Category.playAndRecord, options: .defaultToSpeaker) // try session.setCategory(AVAudioSession.Category.playAndRecord, options: .defaultToSpeaker)
}catch{ // }catch{
print("session config failed") // print("session config failed")
} // }
//
do { try AVAudioSession.sharedInstance().setActive(true) } // do { try AVAudioSession.sharedInstance().setActive(true) }
catch { print("session active failed") } // catch { print("session active failed") }
setupUI() setupUI()
play() play()
...@@ -84,6 +85,7 @@ class SHRecordShowViewController: SHBaseViewController { ...@@ -84,6 +85,7 @@ class SHRecordShowViewController: SHBaseViewController {
confirmCilck() confirmCilck()
} }
/*
func prepareRecognition(){ func prepareRecognition(){
let documentsFile = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first)!.appending(model!.pathFile) let documentsFile = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first)!.appending(model!.pathFile)
...@@ -112,7 +114,8 @@ class SHRecordShowViewController: SHBaseViewController { ...@@ -112,7 +114,8 @@ class SHRecordShowViewController: SHBaseViewController {
// self.recordTextView?.attributedText = self.textView_text(self.model!.txt) // self.recordTextView?.attributedText = self.textView_text(self.model!.txt)
} }
}) })
} }
*/
override func setupUI(){ override func setupUI(){
...@@ -158,20 +161,20 @@ class SHRecordShowViewController: SHBaseViewController { ...@@ -158,20 +161,20 @@ class SHRecordShowViewController: SHBaseViewController {
self.model!.rename = rename self.model!.rename = rename
self.setNavTitle(self.model!.rename) self.setNavTitle(self.model!.rename)
var list = CRUserDefaults.recordList if var list = CRUserDefaults.recordList {
for (index, dic) in list.enumerated(){
for (index, dic) in list!.enumerated(){ if dic["pathFile"] as! String == self.model!.pathFile{
if dic["pathFile"] as! String == self.model!.pathFile{ var subDic = dic
var subDic = dic subDic["rename"] = rename
subDic["rename"] = rename list[index] = subDic
list![index] = subDic break
break }
} }
CRUserDefaults.recordList = list
} }
CRUserDefaults.recordList = list
let keyValueStore = NSUbiquitousKeyValueStore.default let keyValueStore = NSUbiquitousKeyValueStore.default
list = keyValueStore.object(forKey: "list") as? [Dictionary<String, Any>] let list = keyValueStore.object(forKey: "list") as? [Dictionary<String, Any>]
if var list = list { if var list = list {
for (index, dic) in list.enumerated(){ for (index, dic) in list.enumerated(){
...@@ -266,12 +269,12 @@ class SHRecordShowViewController: SHBaseViewController { ...@@ -266,12 +269,12 @@ class SHRecordShowViewController: SHBaseViewController {
} }
@objc func confirmCilck(){ @objc func confirmCilck(){
recognitionTask?.cancel() // recognitionTask?.cancel()
// if player?.isPlaying == false{ // if player?.isPlaying == false{
recordTextView?.attributedText = self.textView_text(model!.txt) recordTextView?.attributedText = self.textView_text(model!.txt)
// } // }
recognitionTask = nil // recognitionTask = nil
recognitionRequest = nil // recognitionRequest = nil
} }
@IBAction func playBtn(_ sender:UIButton){ @IBAction func playBtn(_ sender:UIButton){
...@@ -289,6 +292,12 @@ class SHRecordShowViewController: SHBaseViewController { ...@@ -289,6 +292,12 @@ class SHRecordShowViewController: SHBaseViewController {
} }
@objc fileprivate func generatePDF() { @objc fileprivate func generatePDF() {
if SHUserAccountManager.shared.isMember == false{
self.goGoods("draft_trans_pdf")
return
}
do { do {
let range: Range = model!.pathFile.range(of: "/record.mp3")! let range: Range = model!.pathFile.range(of: "/record.mp3")!
let location: Int = model!.pathFile.distance(from: model!.pathFile.startIndex, to: range.lowerBound) let location: Int = model!.pathFile.distance(from: model!.pathFile.startIndex, to: range.lowerBound)
...@@ -314,10 +323,6 @@ class SHRecordShowViewController: SHBaseViewController { ...@@ -314,10 +323,6 @@ class SHRecordShowViewController: SHBaseViewController {
activityVC.completionWithItemsHandler = { activityVC.completionWithItemsHandler = {
activity, success, items, errot in activity, success, items, errot in
// result // result
MobClick.event("draft_trans_pdf")
let params = ["event": "guazinovel", "action": "", "value": "draft_trans_pdf"]
CMNetworkManager.shared.postLogRequest(withPath: .logCollection, parameters: params) { (json, error) in
}
} }
present(activityVC, animated: true, completion: nil) present(activityVC, animated: true, completion: nil)
......
...@@ -214,7 +214,7 @@ class SHRecordViewController: SHBaseViewController{ ...@@ -214,7 +214,7 @@ class SHRecordViewController: SHBaseViewController{
if self.recognitionTaskText.count == 0 { if self.recognitionTaskText.count == 0 {
self.recordTextView.attributedText = self.textView_text(self.currentTxt ?? "") self.recordTextView.attributedText = self.textView_text(self.currentTxt ?? "")
}else{ }else{
self.recordTextView.attributedText = self.textView_text(self.recognitionTaskText.first! + "\n" + (self.currentTxt ?? "")) self.recordTextView.attributedText = self.textView_text(self.recognitionTaskText.first!)
} }
} }
...@@ -265,11 +265,7 @@ class SHRecordViewController: SHBaseViewController{ ...@@ -265,11 +265,7 @@ class SHRecordViewController: SHBaseViewController{
let alert = SHMemberUpgradeAlertView.init() let alert = SHMemberUpgradeAlertView.init()
self.view.window?.addSubview(alert) self.view.window?.addSubview(alert)
alert.callBack = { alert.callBack = {
MobClick.event("record_upgrade") self.goGoods("record_upgrade")
let params = ["event": "guazinovel", "action": "", "value": "record_upgrade"]
CMNetworkManager.shared.postLogRequest(withPath: .logCollection, parameters: params) { (json, error) in
}
self.goGoods()
} }
} }
...@@ -638,6 +634,12 @@ extension SHRecordViewController{ ...@@ -638,6 +634,12 @@ extension SHRecordViewController{
} }
private func generatePDF() { private func generatePDF() {
if SHUserAccountManager.shared.isMember == false{
self.goGoods("dialog_record_success_trans_pdf")
return
}
do { do {
let range: Range = currentModel!.pathFile.range(of: "/record.mp3")! let range: Range = currentModel!.pathFile.range(of: "/record.mp3")!
let location: Int = currentModel!.pathFile.distance(from: currentModel!.pathFile.startIndex, to: range.lowerBound) let location: Int = currentModel!.pathFile.distance(from: currentModel!.pathFile.startIndex, to: range.lowerBound)
...@@ -663,11 +665,6 @@ extension SHRecordViewController{ ...@@ -663,11 +665,6 @@ extension SHRecordViewController{
activityVC.completionWithItemsHandler = { activityVC.completionWithItemsHandler = {
activity, success, items, errot in activity, success, items, errot in
// result // result
MobClick.event("dialog_record_success_trans_pdf")
let params = ["event": "guazinovel", "action": "", "value": "dialog_record_success_trans_pdf"]
CMNetworkManager.shared.postLogRequest(withPath: .logCollection, parameters: params) { (json, error) in
}
} }
present(activityVC, animated: true, completion: nil) present(activityVC, animated: true, completion: nil)
......
...@@ -11,117 +11,185 @@ import SwiftyStoreKit ...@@ -11,117 +11,185 @@ import SwiftyStoreKit
class SHStoreManager: NSObject { class SHStoreManager: NSObject {
@objc class func purchaseWithProductId(productId: String, inView: UIView, success: @escaping(()->Void) ,faliure: @escaping((String)->Void)) { @objc class func purchaseWithProductId(productId: String, inView: UIView, success: @escaping(()->Void) ,faliure: @escaping((String)->Void)) {
let hud = MBProgressHUD.showAdded(to: inView, animated: true) let hud = MBProgressHUD.show("支付中...", view: inView)
SwiftyStoreKit.purchaseProduct(productId, quantity: 1, atomically: true) { result in SwiftyStoreKit.purchaseProduct(productId, quantity: 1, atomically: true) { result in
hud.hide(animated: true) hud?.hide(animated: true)
switch result { switch result {
case .success(let product): case .success(let product):
log("Purchase Success: \(product.productId)") log("Purchase Success: \(product.productId)")
let appleValidator = AppleReceiptValidator(service: .production, sharedSecret: "0b55ed291ec647e7867e20681fb88a41") let appleValidator = AppleReceiptValidator(service: .production, sharedSecret: "fea7fab4406346e783c9f7d966ea8041")
let hud1 = MBProgressHUD.showAdded(to: inView, animated: true) let innerHud = MBProgressHUD.show("校验中...", view: inView)
SwiftyStoreKit.verifyReceipt(using: appleValidator) { result in SwiftyStoreKit.verifyReceipt(using: appleValidator) { result in
hud1.hide(animated: true) innerHud?.hide(animated: true)
if case .success(let receipt) = result { if case .success(let receipt) = result {
let purchaseResult = SwiftyStoreKit.verifySubscription( let purchaseResult = SwiftyStoreKit.verifySubscription(
ofType: .autoRenewable, ofType: .autoRenewable,
productId: productId, productId: productId,
inReceipt: receipt) inReceipt: receipt)
switch purchaseResult {
switch purchaseResult { case .purchased(let expiryDate, _):
case .purchased(let expiryDate, _): print("Product is valid until \(expiryDate)")
print("Product is valid until \(expiryDate)") let dateFormatter = DateFormatter()
let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm" let dateStr = dateFormatter.string(from: expiryDate)
let dateStr = dateFormatter.string(from: expiryDate) CRUserDefaults.expireInTime = dateStr
CRUserDefaults.expireInTime = dateStr if product.needsFinishTransaction {
if product.needsFinishTransaction { SwiftyStoreKit.finishTransaction(product.transaction)
SwiftyStoreKit.finishTransaction(product.transaction)
}
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5) {
success()
}
case .expired(let expiryDate, _):
MBProgressHUD.showError("订阅已过期,请重新获取", to: inView)
print("Product is expired since \(expiryDate)")
case .notPurchased:
print("This product has never been purchased")
} }
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5) {
} else { success()
// receipt verification error }
case .expired(let expiryDate, _):
MBProgressHUD.showError("订阅已过期,请重新获取", to: inView)
print("Product is expired since \(expiryDate)")
case .notPurchased:
print("This product has never been purchased")
} }
} else {
// receipt verification error
} }
}
let receiptData = SwiftyStoreKit.localReceiptData
let receiptString = receiptData?.base64EncodedString(options: []) ?? ""
print("receiptString: \(receiptString)")
/*
receipt_data:不传的话 服务器根本没法校验
product_id:这个也不用解释 内购产品编号 你不传的话 服务器不知道你买的哪个订单
transaction_id:这个是交易编号
*/
// 需要验证
let dict = ["productId": product.productId, "transactionId" : (product.transaction.transactionIdentifier ?? ""), "receiptData" : receiptString]
print("productId transactionId receiptData: \(dict)")
// TODO: 服务器验证
CMNetworkManager.shared.postRequestWithBody(withPath: .iosIPAVerifyReceipt, body: dict) { (json, error) in
innerHud?.hide(animated: true)
print("success----iosIPAVerifyReceipt-----------------\(json)------")
let result: Bool = json["result"]["data"]["status"].boolValue
if result {
if product.needsFinishTransaction {
SwiftyStoreKit.finishTransaction(product.transaction)
}
print("Purchase Success: \(product.productId)")
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5) {
success()
}
} else {
faliure(error?.localizedDescription ?? "未知错误,请联系客服")
MBProgressHUD.showError("未知错误,请联系客服")
}
}
case .error(let error):
faliure(error.localizedDescription)
switch error.code {
case .unknown:
print("Unknown error. Please contact support")
MBProgressHUD.showError("无法连接到 iTunes Store, 请稍后再试")
case .paymentCancelled:
MBProgressHUD.showError("您已取消购买")
case .paymentInvalid:
MBProgressHUD.showError("无法购买, 请试试其他的")
print("The purchase identifier was invalid")
case .clientInvalid: print("Not allowed to make the payment")
case .paymentNotAllowed: print("The device is not allowed to make the payment")
case .storeProductNotAvailable: print("The product is not available in the current storefront")
case .cloudServicePermissionDenied: print("Access to cloud service information is not allowed")
case .cloudServiceNetworkConnectionFailed:
MBProgressHUD.showError("无法连接到网络")
print("Could not connect to the network")
case .cloudServiceRevoked: print("User has revoked permission to use this cloud service")
default:
print((error as NSError).localizedDescription)
MBProgressHUD.showError((error as NSError).localizedDescription)
}
}
}
}
/// 静态初始化
@objc class func launchWithSwiftyStoreKit() {
SwiftyStoreKit.completeTransactions(atomically: true) { purchases in
let sortedResults = purchases.sorted { (purchase1, purchase2) -> Bool in
if let date1 = purchase1.transaction.transactionDate, let data2 = purchase2.transaction.transactionDate {
return date1.compare(data2) == .orderedAscending
}
return false
}
print("Restore sortedResults: \(sortedResults)")
if let purchase = sortedResults.last {
switch purchase.transaction.transactionState {
case .purchased, .restored:
// Deliver content from server, then:
let receiptData = SwiftyStoreKit.localReceiptData let receiptData = SwiftyStoreKit.localReceiptData
let receiptString = receiptData?.base64EncodedString(options: []) ?? "" let receiptString = receiptData?.base64EncodedString(options: []) ?? ""
print("receiptString: \(receiptString)")
/* print("Purchase Success: \(purchase.productId.description) receiptString: \(receiptString)")
receipt_data:不传的话 服务器根本没法校验
product_id:这个也不用解释 内购产品编号 你不传的话 服务器不知道你买的哪个订单 // TODO: 服务器验证
transaction_id:这个是交易编号 // if purchase.needsFinishTransaction {
*/ // let receiptData = SwiftyStoreKit.localReceiptData
// 需要验证 // let receiptString = receiptData?.base64EncodedString(options: []) ?? ""
let dict = ["productId": product.productId, "transactionId" : (product.transaction.transactionIdentifier ?? ""), "receiptData" : receiptString] let dict = ["productId": purchase.productId, "transactionId" : (purchase.transaction.transactionIdentifier ?? ""), "receiptData" : receiptString]
print("productId transactionId receiptData: \(dict)") print("productId transactionId receiptData: \(dict)")
// TODO: 服务器验证 // TODO: 服务器验证
let innerHud = MBProgressHUD.showAdded(to: inView, animated: true)
CMNetworkManager.shared.postRequestWithBody(withPath: .iosIPAVerifyReceipt, body: dict) { (json, error) in CMNetworkManager.shared.postRequestWithBody(withPath: .iosIPAVerifyReceipt, body: dict) { (json, error) in
innerHud.hide(animated: true)
print("success----iosIPAVerifyReceipt-----------------\(json)------") print("success----iosIPAVerifyReceipt-----------------\(json)------")
let result: Bool = json["result"]["data"]["status"].boolValue let result: Bool = json["result"]["data"]["status"].boolValue
if result { if result {
if product.needsFinishTransaction { if purchase.needsFinishTransaction {
SwiftyStoreKit.finishTransaction(product.transaction) SwiftyStoreKit.finishTransaction(purchase.transaction)
}
print("Purchase Success: \(product.productId)")
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5) {
success()
} }
print("Purchase Success: \(purchase.productId)")
} else { } else {
faliure(error?.localizedDescription ?? "未知错误,请联系客服") // MBProgressHUD.showError("未知错误,请联系客服")
MBProgressHUD.showError("未知错误,请联系客服")
} }
} }
// }
case .error(let error): // Unlock content
faliure(error.localizedDescription) case .failed, .purchasing, .deferred:
hud.hide(animated: true) break // do nothing
switch error.code { @unknown default:
case .unknown: break
print("Unknown error. Please contact support")
MBProgressHUD.showError("无法连接到 iTunes Store, 请稍后再试")
case .paymentCancelled:
MBProgressHUD.showError("您已取消购买")
case .paymentInvalid:
MBProgressHUD.showError("无法购买, 请试试其他的")
print("The purchase identifier was invalid")
case .clientInvalid: print("Not allowed to make the payment")
case .paymentNotAllowed: print("The device is not allowed to make the payment")
case .storeProductNotAvailable: print("The product is not available in the current storefront")
case .cloudServicePermissionDenied: print("Access to cloud service information is not allowed")
case .cloudServiceNetworkConnectionFailed:
MBProgressHUD.showError("无法连接到网络")
print("Could not connect to the network")
case .cloudServiceRevoked: print("User has revoked permission to use this cloud service")
default:
print((error as NSError).localizedDescription)
MBProgressHUD.showError((error as NSError).localizedDescription)
}
} }
} }
} }
}
/// 静态初始化
@objc class func launchWithSwiftyStoreKit() { class func forceFetchReceipt(product: PurchaseDetails) {
SwiftyStoreKit.fetchReceipt(forceRefresh: true) { result in
SwiftyStoreKit.completeTransactions(atomically: true) { purchases in switch result {
case .success(let receiptData):
let sortedResults = purchases.sorted { (purchase1, purchase2) -> Bool in let encryptedReceipt = receiptData.base64EncodedString(options: [])
print("Fetch receipt success:\n\(encryptedReceipt)")
// fetch content from your server, then:
if product.needsFinishTransaction {
SwiftyStoreKit.finishTransaction(product.transaction)
}
case .error(let error):
print("Fetch receipt failed: \(error)")
}
}
}
// 恢复购买
@objc class func restorePurchases(success: @escaping(()->Void), toView: UIView) {
let hud = MBProgressHUD.showAdded(to: toView, animated: true)
SwiftyStoreKit.restorePurchases(atomically: true) { results in
hud.hide(animated: true);
if results.restoreFailedPurchases.count > 0 {
print("Restore Failed: \(results.restoreFailedPurchases)")
} else if results.restoredPurchases.count > 0 {
let sortedResults = results.restoredPurchases.sorted { (purchase1, purchase2) -> Bool in
if let date1 = purchase1.transaction.transactionDate, let data2 = purchase2.transaction.transactionDate { if let date1 = purchase1.transaction.transactionDate, let data2 = purchase2.transaction.transactionDate {
return date1.compare(data2) == .orderedAscending return date1.compare(data2) == .orderedAscending
} }
...@@ -129,123 +197,52 @@ class SHStoreManager: NSObject { ...@@ -129,123 +197,52 @@ class SHStoreManager: NSObject {
} }
print("Restore sortedResults: \(sortedResults)") print("Restore sortedResults: \(sortedResults)")
if let purchase = sortedResults.last { if let purchase = sortedResults.last {
switch purchase.transaction.transactionState { let appleValidator = AppleReceiptValidator(service: .production, sharedSecret: "fea7fab4406346e783c9f7d966ea8041")
case .purchased, .restored: let hud1 = MBProgressHUD.show(with: toView)
// Deliver content from server, then: SwiftyStoreKit.verifyReceipt(using: appleValidator) { result in
let receiptData = SwiftyStoreKit.localReceiptData hud1?.hide(animated: true)
let receiptString = receiptData?.base64EncodedString(options: []) ?? "" if case .success(let receipt) = result {
let purchaseResult = SwiftyStoreKit.verifySubscription(
print("Purchase Success: \(purchase.productId.description) receiptString: \(receiptString)") ofType: .autoRenewable,
productId: purchase.productId,
// TODO: 服务器验证 inReceipt: receipt)
// if purchase.needsFinishTransaction {
// let receiptData = SwiftyStoreKit.localReceiptData
// let receiptString = receiptData?.base64EncodedString(options: []) ?? ""
let dict = ["productId": purchase.productId, "transactionId" : (purchase.transaction.transactionIdentifier ?? ""), "receiptData" : receiptString]
print("productId transactionId receiptData: \(dict)")
// TODO: 服务器验证
CMNetworkManager.shared.postRequestWithBody(withPath: .iosIPAVerifyReceipt, body: dict) { (json, error) in
print("success----iosIPAVerifyReceipt-----------------\(json)------")
let result: Bool = json["result"]["data"]["status"].boolValue switch purchaseResult {
if result { case .purchased(let expiryDate, _):
print("Product is valid until \(expiryDate)")
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_CN")
dateFormatter.timeZone = TimeZone.current
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
let dateStr = dateFormatter.string(from: expiryDate)
CRUserDefaults.expireInTime = dateStr
MBProgressHUD.showSuccess("恢复成功", to: toView)
if purchase.needsFinishTransaction { if purchase.needsFinishTransaction {
SwiftyStoreKit.finishTransaction(purchase.transaction) SwiftyStoreKit.finishTransaction(purchase.transaction)
} }
print("Purchase Success: \(purchase.productId)") success()
} else { case .expired(let expiryDate, _):
// MBProgressHUD.showError("未知错误,请联系客服") print("Product is expired since \(expiryDate)")
} let dateFormatter = DateFormatter()
} dateFormatter.locale = Locale(identifier: "en_CN")
// } dateFormatter.timeZone = TimeZone.current
// Unlock content dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
case .failed, .purchasing, .deferred: let dateStr = dateFormatter.string(from: expiryDate)
break // do nothing CRUserDefaults.expireInTime = dateStr
@unknown default: MBProgressHUD.showError("订阅已过期,请重新获取", to: toView)
break case .notPurchased:
} print("This product has never been purchased")
}
}
}
class func forceFetchReceipt(product: PurchaseDetails) {
SwiftyStoreKit.fetchReceipt(forceRefresh: true) { result in
switch result {
case .success(let receiptData):
let encryptedReceipt = receiptData.base64EncodedString(options: [])
print("Fetch receipt success:\n\(encryptedReceipt)")
// fetch content from your server, then:
if product.needsFinishTransaction {
SwiftyStoreKit.finishTransaction(product.transaction)
}
case .error(let error):
print("Fetch receipt failed: \(error)")
}
}
}
// 恢复购买
@objc class func restorePurchases(success: @escaping(()->Void), toView: UIView) {
let hud = MBProgressHUD.showAdded(to: toView, animated: true)
SwiftyStoreKit.restorePurchases(atomically: true) { results in
hud.hide(animated: true);
if results.restoreFailedPurchases.count > 0 {
print("Restore Failed: \(results.restoreFailedPurchases)")
} else if results.restoredPurchases.count > 0 {
let sortedResults = results.restoredPurchases.sorted { (purchase1, purchase2) -> Bool in
if let date1 = purchase1.transaction.transactionDate, let data2 = purchase2.transaction.transactionDate {
return date1.compare(data2) == .orderedAscending
}
return false
}
print("Restore sortedResults: \(sortedResults)")
if let purchase = sortedResults.last {
let appleValidator = AppleReceiptValidator(service: .production, sharedSecret: "0b55ed291ec647e7867e20681fb88a41")
let hud1 = MBProgressHUD.show(with: toView)
SwiftyStoreKit.verifyReceipt(using: appleValidator) { result in
hud1?.hide(animated: true)
if case .success(let receipt) = result {
let purchaseResult = SwiftyStoreKit.verifySubscription(
ofType: .autoRenewable,
productId: purchase.productId,
inReceipt: receipt)
switch purchaseResult {
case .purchased(let expiryDate, _):
print("Product is valid until \(expiryDate)")
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_CN")
dateFormatter.timeZone = TimeZone.current
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
let dateStr = dateFormatter.string(from: expiryDate)
CRUserDefaults.expireInTime = dateStr
MBProgressHUD.showSuccess("恢复成功", to: toView)
if purchase.needsFinishTransaction {
SwiftyStoreKit.finishTransaction(purchase.transaction)
}
success()
case .expired(let expiryDate, _):
print("Product is expired since \(expiryDate)")
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_CN")
dateFormatter.timeZone = TimeZone.current
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
let dateStr = dateFormatter.string(from: expiryDate)
CRUserDefaults.expireInTime = dateStr
MBProgressHUD.showError("订阅已过期,请重新获取", to: toView)
case .notPurchased:
print("This product has never been purchased")
}
} else {
// receipt verification error
} }
} else {
// receipt verification error
} }
print("Restore Success: \(results.restoredPurchases)")
} }
} else { print("Restore Success: \(results.restoredPurchases)")
MBProgressHUD.showError("没有商品可恢复")
print("Nothing to Restore")
} }
} else {
MBProgressHUD.showError("没有商品可恢复")
print("Nothing to Restore")
} }
} }
}
} }
...@@ -34,7 +34,7 @@ import SwiftyJSON ...@@ -34,7 +34,7 @@ import SwiftyJSON
@objc var isMember: Bool { @objc var isMember: Bool {
return true // return true
let dateFormatter = DateFormatter() let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_CN") dateFormatter.locale = Locale(identifier: "en_CN")
......
...@@ -17,13 +17,13 @@ enum CMLogCollecAction: String { ...@@ -17,13 +17,13 @@ enum CMLogCollecAction: String {
} }
struct CMAPIManager { struct CMAPIManager {
#if DEBUG // #if DEBUG
static let baseUrl = "https://feedapitest.zhangxinhulian.com" // static let baseUrl = "https://feedapitest.zhangxinhulian.com"
static let reportUrl = "http://reporttest.zhangxinhulian.com" // static let reportUrl = "http://reporttest.zhangxinhulian.com"
#else // #else
static let baseUrl = "https://feedapi.seedsnovel.com" static let baseUrl = "http://feedapi.endpointcontent.com"
static let reportUrl = "http://report.seedsnovel.com" static let reportUrl = "http://report.endpointcontent.com"
#endif // #endif
} }
enum CMURLPath { enum CMURLPath {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment