123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- import Cocoa
- import WebKit
- protocol AdsWebViewDelegate: AnyObject {
- func kmAdViewClicked(_ adView: KMAdsWebView)
- func kmAdViewClose(_ adView: KMAdsWebView)
- }
- enum KMADViewDirections: Int {
- case up
- case down
- }
- // Banner Ads Width,Height
- let kAD_View_Width = 728.0
- let kAD_View_Height = 90.0
- // Banner Ads refresh rate in second, 新广告会自动刷新,所以时间延长
- let kAD_Refresh_Rate = 6000.0
- class KMAdsWebView: NSView, WKNavigationDelegate, CAAnimationDelegate {
- weak var adDelegate: AdsWebViewDelegate?
- private var closeButton: NSButton!
- var clickButton: NSButton!
- private var timer: Timer?
- private var currentPage: Int = 0
- private var completionHandler: ((Int) -> Void)?
- var adsImageView: NSImageView!
- var adsInfo: KMAdsInfo!
- var adPosY: CGFloat = 30.0
- override init(frame frameRect: NSRect) {
- super.init(frame: frameRect)
-
- wantsLayer = true
- self.frame = NSRect(x: 0, y: 0, width: kAD_View_Width, height: kAD_View_Height)
- autoresizingMask = [.minXMargin, .maxXMargin]
- adsImageView = NSImageView.init(frame: self.bounds)
- adsImageView.autoresizingMask = [.width, .height]
- adsImageView.imageScaling = .scaleAxesIndependently
- addSubview(adsImageView)
- adPosY = 30.0
-
- clickButton = NSButton.init(frame: self.bounds)
- clickButton.isHidden = false
- clickButton.autoresizingMask = [.width, .height]
- clickButton.isBordered = false
- clickButton.title = ""
- clickButton.target = self
- clickButton.action = #selector(buttonItemClicked(_:))
- addSubview(clickButton)
-
- closeButton = NSButton.init(frame: NSRect(x: frameRect.size.width - 30, y: frameRect.size.height - 30, width: 30, height: 30))
- closeButton.isHidden = false
- closeButton.imagePosition = .imageOnly
- closeButton.imageScaling = .scaleProportionallyUpOrDown
- closeButton.autoresizingMask = [.maxXMargin, .minYMargin]
- closeButton.image = NSImage(named: "ad_cancel_button00")
- closeButton.isBordered = false
- closeButton.target = self
- closeButton.action = #selector(buttonItemClicked_Close(_:))
- addSubview(closeButton)
- NotificationCenter.default.addObserver(self, selector: #selector(handleUserHaveClickRateUsNotification(_:)), name: NSNotification.Name("kUserHaveClickRateUsNotification"), object: nil)
- NotificationCenter.default.addObserver(self, selector: #selector(adsWebView_Switch), name: NSNotification.Name("KMFirebaseRemateConfigRequestIsSuccessful"), object: nil)
- NotificationCenter.default.addObserver(self, selector: #selector(recommondInfoUpdateNoti), name: NSNotification.Name("KMRecommondInfoUpdateNoti"), object: nil)
-
- }
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
- deinit {
- adDelegate = nil
-
- timer?.invalidate()
- timer = nil
- completionHandler = nil
- NotificationCenter.default.removeObserver(self)
- }
- var adsData: [String] {
- get {
- var data: [String] = []
- #if VERSION_DMG
- if !UserDefaults.standard.bool(forKey: "kUserHaveClickRateUsKey") {
- data = ["https://test.sitemaji.com/native/pdfreaderpro.html?s=PDFReaderPro_Mac_DMG_HouseAD_728x90"]
- } else {
- data = ["https://test.sitemaji.com/native/pdfreaderpro.html?s=PDFReaderPro_Mac_DMG_728x90"]
- }
- #else
- if !UserDefaults.standard.bool(forKey: "kUserHaveClickRateUsKey") {
- data = ["https://test.sitemaji.com/native/pdfreaderpro.html?s=PDFReaderPro_Mac_Store_HouseAD_728x90"]
- } else {
- data = ["https://test.sitemaji.com/native/pdfreaderpro.html?s=PDFReaderPro_Mac_Store_728x90"]
- }
- #endif
- if !UserDefaults.standard.bool(forKey: "kUserHaveClickRateUsKey") {
- data = [KMKdanRemoteConfig.remoteConfig.displayHouseAdsUrl()]
- } else {
- data = [KMKdanRemoteConfig.remoteConfig.displayAdsUrl()]
- }
- #if DEBUG
- #if VERSION_DMG
- data = ["http://test-pdf-pro.kdan.cn:3021/native?s=PDFReaderPro_Mac_DMG_HouseAD_728x90&testflag=on"]
- #else
- data = ["https://test.sitemaji.com/native/pdfreaderpro.html?s=PDFReaderPro_Mac_Store_728x90"]
- #endif
- #endif
- return data
- }
-
- set {
-
- }
- }
- func restoreDefaultAdPosY() {
- adPosY = 30.0
- }
- func sortAdsData() {
- return
-
- let tLength = self.adsData.count
-
- for _ in 0..<24 {
- let tIndex0 = Int(arc4random()) % tLength
- var tIndex1 = Int(arc4random()) % tLength
-
- if tIndex0 == tIndex1 {
- tIndex1 = (tIndex1 + 1) % tLength
- }
-
- self.adsData.swapAt(tIndex0, tIndex1)
- }
- }
- func startAdsDataRequest() {
- if adsData.count > 0 {
- KMAdsManager.defaultManager.refreshLoadingDate()
- }
- }
-
- func reloadData() {
- DispatchQueue.main.async {
- self.adsImageView.image = self.adsInfo.adsImage
- }
- }
- func stopLoading() {
- if timer != nil {
- timer?.invalidate()
- timer = nil
- }
- }
- func resizeWithOldSuperviewSize(oldSize: NSSize) {
- var width = kAD_View_Width
- var height = kAD_View_Height
- if superview?.frame.size.width ?? 0 < width {
- let newWidth = (superview?.frame.size.width ?? 0) - 20
- height = height / width * newWidth
- width = newWidth
- }
-
- self.frame = NSRect(x: (superview?.frame.size.width ?? 0 - width) / 2.0, y: frame.origin.y, width: width, height: height)
- }
- func beginSheetModalForView(view: NSView, directions: KMADViewDirections, animated: Bool, completionHandler handler: ((Int) -> Void)?) {
- self.completionHandler = handler
- if adPosY < 0 {
- restoreDefaultAdPosY()
- }
- let tWidth = frame.size.width
- let tHeight = frame.size.height
- view.addSubview(self)
- if animated {
- switch directions {
- case .up:
- frame = NSRect(x: (view.frame.size.width - tWidth) / 2.0, y: view.frame.size.height, width: tWidth, height: tHeight)
- animator().frame = NSRect(x: frame.origin.x, y: view.frame.size.height - tHeight - adPosY, width: tWidth, height: tHeight)
- case .down:
- frame = NSRect(x: (view.frame.size.width - tWidth) / 2.0, y: -tHeight, width: tWidth, height: tHeight)
- animator().frame = NSRect(x: frame.origin.x, y: adPosY, width: tWidth, height: tHeight)
- default:
- frame = NSRect(x: 0, y: 0, width: tWidth, height: tHeight)
- }
- } else {
- switch directions {
- case .up:
- frame = NSRect(x: (view.frame.size.width - tWidth) / 2.0, y: view.frame.size.height - tHeight - adPosY, width: tWidth, height: tHeight)
- case .down:
- frame = NSRect(x: (view.frame.size.width - tWidth) / 2.0, y: adPosY, width: tWidth, height: tHeight)
- default:
- frame = NSRect(x: 0, y: 0, width: tWidth, height: tHeight)
- }
- }
- adsImageView.frame = bounds
- closeButton.frame = NSRect(x: self.bounds.size.width - 30, y: self.bounds.size.height - 30, width: 30, height: 30)
- currentPage = 0
- startAdsDataRequest()
- if timer != nil {
- timer?.invalidate()
- timer = nil
- }
- var interval = 0
- if !UserDefaults.standard.bool(forKey: "kUserHaveClickRateUsKey") {
- interval = KMKdanRemoteConfig.remoteConfig.refreshAdsDate()
- } else {
- interval = KMKdanRemoteConfig.remoteConfig.refreshAdsDateEvaluateAfter()
- }
- timer = Timer.scheduledTimer(timeInterval: TimeInterval(interval), target: self, selector: #selector(adsWebView_Switch), userInfo: nil, repeats: true
- )
- RunLoop.current.add(timer!, forMode: .common)
- }
- @objc func adsWebView_Switch() {
- DispatchQueue.main.async {
- if !KMKdanRemoteConfig.remoteConfig.isDisplayAds() || !KMAdsManager.defaultManager.checkTheDate() || !KMAdsManager.defaultManager.isValidLastShowAds() {
- self.removeFromSuperview()
- return
- }
- let transition = CATransition()
- transition.type = .moveIn
- let tRandomData = arc4random() % 100
- if tRandomData > 50 {
- transition.subtype = .fromBottom
- } else {
- transition.subtype = .fromTop
- }
- transition.duration = 0.6
- transition.delegate = self
- self.layer?.add(transition, forKey: "KMTransitionAnimation")
- self.currentPage += 1
- if self.currentPage >= self.adsData.count {
- self.currentPage = 0
- }
- let url = URL(string: self.adsData[self.currentPage])
-
- KMAdsManager.defaultManager.refreshLoadingDate()
- }
- }
-
- @objc func recommondInfoUpdateNoti() {
- DispatchQueue.main.async {
-
- self.reloadData()
- }
- }
- @objc func buttonItemClicked_Open(_ sender: Any) {
- guard let newURL = (sender as? NSURL) else {
- return
- }
- NSWorkspace.shared.open(newURL as URL)
- adDelegate?.kmAdViewClicked(self)
- if let completionHandler = self.completionHandler {
- completionHandler(currentPage + 1)
- }
- removeFromSuperview()
- }
-
- @objc func buttonItemClicked(_ sender: Any) {
-
- guard let string = self.adsInfo?.adsURLLink else {
- return
- }
-
- let newURL = NSURL(string: string)
- NSWorkspace.shared.open(newURL! as URL)
- if let completionHandler = self.completionHandler {
- completionHandler(currentPage + 1)
- }
-
- adDelegate?.kmAdViewClicked(self)
- }
-
- @objc func buttonItemClicked_Close(_ sender: Any) {
- adDelegate?.kmAdViewClose(self)
- if let completionHandler = self.completionHandler {
- completionHandler(0)
- }
- removeFromSuperview()
- }
- func animationDidStart(_ anim: CAAnimation) {
- if timer != nil {
- timer?.invalidate()
- }
- }
- func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
- if !flag {
- return
- }
- if timer != nil {
- timer?.invalidate()
- }
- var interval = 0
- if !UserDefaults.standard.bool(forKey: "kUserHaveClickRateUsKey") {
- interval = KMKdanRemoteConfig.remoteConfig.refreshAdsDate()
- } else {
- interval = KMKdanRemoteConfig.remoteConfig.refreshAdsDateEvaluateAfter()
- }
- timer = Timer.scheduledTimer(timeInterval: TimeInterval(interval), target: self, selector: #selector(adsWebView_Switch), userInfo: nil, repeats: true)
- RunLoop.current.add(timer!, forMode: .common)
- closeButton.alphaValue = 1.0
- adsImageView.frame = bounds
- }
- // MARK: - WKNavigationDelegate
-
- @objc func handleUserHaveClickRateUsNotification(_ notification: Notification) {
- adsWebView_Switch()
- }
- }
|