FanpowerPackage 0.0.50

FanpowerPackage 0.0.50

Luke Wyatt 维护。



 
依赖关系
Alamofire~> 5.6.1
RxSwift~> 6.5.0
RxCocoa~> 6.5.0
 

  • FanPower

FanpowerPackage

Swift 包以显示 Fanpower 小部件

将 Fanpower Swift 包添加到您的项目中

Swift 包管理器

Swift 包管理器 是一个用于自动分发 Swift 代码的工具,并集成到 swift 编译器中。

一旦您设置了您的 Swift 包,将 FanPower Swift 包作为依赖项添加,就像将它添加到 Package.swift 中的 dependencies 值一样简单。

dependencies: [
    .package(url: "https://github.com/RocketFarm/fanpower-swift-package.git", .exact(version: "0.0.49"))
]

CocoaPods

# Podfile
source 'https://github.com/CocoaPods/Specs.git'

target 'YOUR_TARGET_NAME' do
  pod 'FanpowerPackage', '0.0.49
end

替换YOUR_TARGET_NAME,然后,在Podfile目录中输入

$ pod install

示例用法

初始化小部件

import UIKit
import FanpowerPackage

class ViewController: UIViewController {
    @IBOutlet weak var fanPowerView: FanPowerView!
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        fanPowerView.setup(
            tokenForJwtRequest: "your-tokenForJwtRequest",
            publisherToken: "your-publisherToken",
            publisherId: "your-publisherId",
            shareUrl: "your-shareUrl",
            propIds: ["00001", "00002"] //Optional parameter, replace with your list of prop IDs.  Can be a list of a single ID.
        ) {
            //self.fanPowerView has completed initialization and is ready to be displayed
            self.fanPowerView.isHidden = false
        }
    }
}

tokenForJwtRequestpublisherTokenpublisherId 应由 FanPower 提供。shareUrl 是当用户使用小部件的分享功能时将要分享的 URL。它也用于创建推荐 URL。如果不使用 propIds 参数,小部件将使用您账户中的所有活动属性。

清除用户会话(注销)

import FanpowerPackage

...

FanPower.logout()

大多数应用程序会将此添加到现有的注销流程中。

添加服装字体

在将FanpowerPackage添加到您的项目后,将字体文件从Sources/FanpowerPackage/Resources/Fonts/Outfit-VariableFont_wght.ttf复制到您的项目,并按照https://developer.apple.com/documentation/uikit/text_display_and_fonts/adding_a_custom_font_to_your_app中的说明添加字体

添加不锈钢字体

如果您的应用程序使用不锈钢字体,在将FanpowerPackage添加到您的项目后,将字体文件从Sources/FanpowerPackage/Resources/Fonts/Stainless-Black.otfSources/FanpowerPackage/Resources/Fonts/Stainless-Bold.otfSources/FanpowerPackage/Resources/Fonts/Stainless-Regular.otf中复制到您的项目,并按照https://developer.apple.com/documentation/uikit/text_display_and_fonts/adding_a_custom_font_to_your_app中的说明添加字体


使用ScrollableFanPowerView

先决条件

在网页视图上放置一个 ScrollableFanPowerView。应将 ScrollableFanPowerView 限制在网页视图的边缘。 ScrollableFanPowerView 应具有清晰的颜色背景。

ScrollableFanPowerView 的示例视图控制器

import UIKit
import FanpowerPackage
import WebKit

class ViewController: UIViewController {
    @IBOutlet weak var fanpowerView: ScrollableFanPowerView!
    @IBOutlet weak var webView: WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        webView.scrollView.delegate = self
        webView.navigationDelegate = self
        webView.loadHTMLString("<html><head><meta name='viewport' content='initial-scale=1, user-scalable=no, width=device-width' /></head><body style=\"-webkit-text-size-adjust:none;color:black;\"><p>This weekend, NASCAR&#8217;s premier series returns to Nashville Superspeedway for just the second time.</p><p>The Cup Series heads back to the 1.33-mile concrete oval in Lebanon, Tennessee, for the Ally 400 on Sunday (5 p.m. ET, NBC/NBC Sports App, MRN, SiriusXM NASCAR Radio) after the series&#8217; off weekend.</p>   <div style=\"height:750px;\" id=\"pu-prop-embed\" class=\\\"pu-prop-embed\\\" data-pickup-prop-id=\\\"25452\\\"><section><a href=\\\"https://playpickup.com/news/Array / surez-vs-chastain-who-wins-in-nashville - 25452\\\" rel=\\\"follow\\\" title=\\\"Suárez vs. Chastain: Who wins in Nashville? - Powered By PickUp\\\">Suárez vs. Chastain: Who wins in Nashville? - Powered By PickUp</a></section></div>   <p>[Repeated content] This weekend, NASCAR&#8217;s premier series returns to Nashville Superspeedway for just the second time.</p><p>The Cup Series heads back to the 1.33-mile concrete oval in Lebanon, Tennessee, for the Ally 400 on Sunday (5 p.m. ET, NBC/NBC Sports App, MRN, SiriusXM NASCAR Radio) after the series&#8217; off weekend.</p></body></html>", baseURL: nil)
    }
    
    func positionOfElement(withId elementID: String) {
        let js = "function f(){ var r = document.getElementById('%@').getBoundingClientRect(); return r.top+''; } f();"
        webView?.evaluateJavaScript(String(format: js, elementID)) { object, error  in
            if let object = object {
                let stringY = String(describing: object)
                self.fanpowerView.setup(heightConstant: 750, //This value could be calculated the same way topMarginConstant is
                                        topMarginConstant: CGFloat(truncating: NumberFormatter().number(from: stringY)!) 
                                                            * self.webView.scrollView.zoomScale,
                                        bottomMarginConstant: 1500, //This value could be calculated the same way topMarginConstant is
                                        tokenForJwtRequest: "your-tokenForJwtRequest",
                                        publisherToken: "your-publisherToken",
                                        publisherId: "your-publisherId",
                                        shareUrl: "your-shareUrl",
                                        referenceFrame: self.webView.frame, //Passing nil for this param will make the scrollview full-screen
                                        propIds: ["00001", "00002"] ) {  //Optional parameter, replace with your list of prop IDs.  Can be a list of a single ID.
                    self.fanpowerView.isHidden = false
                    self.fanpowerView.setCollectionViewLayout() //This line allows the widget to update its UI layout after it has been moved
                }
            }
        }
    }
}

extension ViewController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        fanpowerView.setContentOffset(offset: webView.scrollView.contentOffset)
    }
}

extension ViewController: WKNavigationDelegate {
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        positionOfElement(withId: "pu-prop-embed")
    }
}

使用嵌入推文时使用 ScrollableFanPowerView

先决条件

在网页视图上放置一个 ScrollableFanPowerView。应将 ScrollableFanPowerView 限制在网页视图的边缘。 ScrollableFanPowerView 应具有清晰的颜色背景。网页视图的 HTML 将包括一个嵌入的推文。

ScrollableFanPowerView 的示例视图控制器

import UIKit
import FanpowerPackage
import WebKit

class ViewController: UIViewController {
    @IBOutlet weak var fanpowerView: ScrollableFanPowerView!
    @IBOutlet weak var webView: WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        webView.scrollView.delegate = self
        //navigation delegate is not needed for this implementation
        let tweet = "<blockquote id=\"tweet\" class=\"twitter-tweet\"><p lang=\"en\" dir=\"ltr\">Sunsets don&#39;t get much better than this one over <a href=\"https://twitter.com/GrandTetonNPS?ref_src=twsrc%5Etfw\">@GrandTetonNPS</a>. <a href=\"https://twitter.com/hashtag/nature?src=hash&amp;ref_src=twsrc%5Etfw\">#nature</a> <a href=\"https://twitter.com/hashtag/sunset?src=hash&amp;ref_src=twsrc%5Etfw\">#sunset</a> <a href=\"https://#/YuKy2rcjyU\">pic.twitter.com/YuKy2rcjyU</a></p>&mdash; US Department of the Interior (@Interior) <a href=\"https://twitter.com/Interior/status/463440424141459456?ref_src=twsrc%5Etfw\">May 5, 2014</a></blockquote> <script async src=\"https://platform.twitter.com/widgets.js\" charset=\"utf-8\"></script>"
        webView.loadHTMLString("<html><head><meta name='viewport' content='initial-scale=1, user-scalable=no, width=device-width' /></head><body style=\"-webkit-text-size-adjust:none;color:black;\">"+tweet+"<p>This weekend, NASCAR&#8217;s premier series returns to Nashville Superspeedway for just the second time.</p><p>The Cup Series heads back to the 1.33-mile concrete oval in Lebanon, Tennessee, for the Ally 400 on Sunday (5 p.m. ET, NBC/NBC Sports App, MRN, SiriusXM NASCAR Radio) after the series&#8217; off weekend.</p>   <div style=\"height:750px;\" id=\"pu-prop-embed\" class=\\\"pu-prop-embed\\\" data-pickup-prop-id=\\\"25452\\\"><section><a href=\\\"https://playpickup.com/news/Array / surez-vs-chastain-who-wins-in-nashville - 25452\\\" rel=\\\"follow\\\" title=\\\"Suárez vs. Chastain: Who wins in Nashville? - Powered By PickUp\\\">Suárez vs. Chastain: Who wins in Nashville? - Powered By PickUp</a></section></div>   <p>[Repeated content] This weekend, NASCAR&#8217;s premier series returns to Nashville Superspeedway for just the second time.</p><p>The Cup Series heads back to the 1.33-mile concrete oval in Lebanon, Tennessee, for the Ally 400 on Sunday (5 p.m. ET, NBC/NBC Sports App, MRN, SiriusXM NASCAR Radio) after the series&#8217; off weekend.</p></body></html>", baseURL: nil)

        twitterHeightTest()
    }
    
    func twitterHeightTest() {
        var isTallEnough = false
        let tooShortHeight = 10 //value to be determined by the developer
        let heightTestInterval = 0.5 //code checks for twitter load every 0.5 seconds
        DispatchQueue.main.asyncAfter(deadline: .now() + heightTestInterval) { [weak self] in
            let js = "function f(){ var r = document.getElementsByClassName('%@')[0].getBoundingClientRect(); return r.height+''; } f();"
            self?.webView?.evaluateJavaScript(String(format: js, "twitter-tweet")) { object, error  in
                if let object = object {
                    let stringY = String(describing: object)
                    print("tweet height is \(stringY)")
                    let intHeight = Int(stringY) ?? 0
                    if intHeight > tooShortHeight {
                        isTallEnough = true
                    }
                }
                if !isTallEnough {
                    self?.twitterHeightTest() //repeat the test until it succeeds or the nav controller is deallocated
                } else {
                    self?.positionOfElement(withId: "pu-prop-embed")
                }
            }
        }
    }
    
    func positionOfElement(withId elementID: String) {
        let js = "function f(){ var r = document.getElementById('%@').getBoundingClientRect(); return r.top+''; } f();"
        webView?.evaluateJavaScript(String(format: js, elementID)) { object, error  in
            if let object = object {
                let stringY = String(describing: object)
                self.fanpowerView.setup(heightConstant: 750, //This value could be calculated the same way topMarginConstant is
                                        topMarginConstant: CGFloat(truncating: NumberFormatter().number(from: stringY)!) 
                                                            * self.webView.scrollView.zoomScale,
                                        bottomMarginConstant: 1500, //This value could be calculated the same way topMarginConstant is
                                        tokenForJwtRequest: "your-tokenForJwtRequest",
                                        publisherToken: "your-publisherToken",
                                        publisherId: "your-publisherId",
                                        shareUrl: "your-shareUrl",
                                        referenceFrame: self.webView.frame, //Passing nil for this param will make the scrollview full-screen
                                        propIds: ["00001", "00002"] ) {  //Optional parameter, replace with your list of prop IDs.  Can be a list of a single ID.
                    self.fanpowerView.isHidden = false
                    self.fanpowerView.setCollectionViewLayout() //This line allows the widget to update its UI layout after it has been moved
                }
            }
        }
    }
}

extension ViewController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        fanpowerView.setContentOffset(offset: webView.scrollView.contentOffset)
    }
}