WiFiQRCodeKit 1.1.1

WiFiQRCodeKit 1.1.1

Kuniwak 维护。



  • ——
  • Kuniwak

WiFiQRCodeKit

Swift Compatible CocoaPods Status Carhthage Compatible Build Status

在 iOS 11 中,我们可以通过读取 Wi-Fi 的二维码轻松配置 Wi-Fi 网络。但是,有些合理的情况可能会保留 iOS 版本低于 iOS 11。

WiFiQRCodeKit 通过二维码为这些情况提供了 Wi-Fi 配置功能。它适用于 iOS 8.0+。

安装

Carthage

github "Kuniwak/WiFiQRCodeKit" >= 1.0

CocoaPods

pod 'WiFiQRCodeKit', '~> 1.0'

要求

  • iOS 8.0+

并且 WiFiQRCodeKit 需要 2 个其他库

  • 一个二维码阅读器库
  • 本地HTTP服务器库

这意味着您可以使用您想要的任何库。

用法

简单示例

这是一个使用 yannickl/QRCodeReader.swifthttpswift/swifter 的简单示例。

// AppDelegate.swift
import QRCodeReader
import WiFiQRCodeKit


class AppDelegate: UIResponder, UIApplicationDelegate {

    // ...

    private let installer = WiFIQRCodeKit.MobileConfig.Installer(
        distributingBy: SwifterMobileConfigDistributionServer(listeningOn: 8989)
    )

    private var qrCodeReaderWindow: UIWindow?
    private var originalWindow: UIWindow?

    // ...

    func applicationDidEnterBackground(_ application: UIApplication) {
        // This method MUST be called in the method.
        self.installer.keepDistributionServerForBackground(for: application)
    }


    // Open a QR code reader.
    func readQRCode() {
        let qrCodeReaderBuilder = QRCodeReaderViewControllerBuilder()
        qrCodeReaderBuilder.reader = QRCodeReader(
            metadataObjectTypes: [.qr],
            captureDevicePosition: .back
        )

        let qrCodeReaderViewController = QRCodeReaderViewController(builder: qrCodeReaderBuilder)
        qrCodeReaderViewController.completionBlock = { [weak self] result in
            guard let `self` = self else { return }

            if let result = result {
                self.install(qrCodeContent: result.value)
            }

            self.qrCodeReaderWindow = nil
            self.originalWindow.makeKeyAndVisible()
        }

        self.originalWindow = UIApplication.shared.keyWindow

        let qrCodeReaderWindow = UIWindow()
        qrCodeReaderWindow.rootViewController = qrCodeReaderViewController
        qrCodeReaderWindow.makeKeyAndVisible()

        self.qrCodeReaderWindow = window
    }


    // Install the Wi-Fi settings.
    private func install(qrCodeContent: String) {
        switch WiFiQRCodeKit.parse(text: qrCodeContent) {
        case .success(let wiFiQRCode):
            var mobileConfig = WiFiQRCodeKit.MobileConfig.from(
                wiFiQRCode: wiFiQRCode,
                organization: .init(organizationName: "Example, Inc.")

                // Also you can specify the following optional items:
                //
                //   identifier: .init(identifier: "com.example.WiFiSettings"),
                //   description: "Joining the Wi-Fi network that managed by Example, Inc.",
                //   displayName: .init(displayName: "Wi-Fi settings for Example, Inc."),
                //   consentText: .init(consentTextsForEachLanguages: [
                //       .default: "Would you join the Wi-Fi network that manged by Example, Inc.?",
                //       .en: "Would you join the Wi-Fi network that manged by Example, Inc.?",
                //       .jp: "Example, Inc. の Wi-Fi ネットワークへ接続しますか?",
                //   ])
            )

            // You can modify other items such as the expiration option of the configuration profile.
            // Configurable items are listed on "Configuration Profile Reference".
            // See https://developer.apple.com/library/content/featuredarticles/iPhoneConfigurationProfileRef/

            // It open the configuration profile on Safari.
            self.installer.install(mobileConfig: mobileConfig)

        case .failed(because: let reason):
            dump(reason)
        }
    }
}
// SwifterMobileConfigDistributionServer.swift
import Swifter
import WiFiQRCodeKit


class SwifterMobileConfigDistributionServer: WiFiQRCodeKit.MobileConfig.DistributionServer {
    let distributionURL: URL
    private let server: Swifter.HttpServer
    private let port: UInt16
    private var mobileConfig: (data: Data, mimeType: String)?


    init(listeningOn port: UInt16) {
        let mobileConfigPath = "/WiFi.mobileConfig"

        self.distributionURL = URL(string: "http://127.0.0.1:\(port)\(mobileConfigPath)")!
        self.port = port
        self.server = Swifter.HttpServer()

        self.server[mobileConfigPath] = { [weak self] (_: Swifter.HttpRequest) -> Swifter.HttpResponse in
            guard let `self` = self, let mobileConfig = self.mobileConfig else {
                return .notFound
            }

            let statusCode = 20
            let statusText = "OK"
            let headers = ["Content-Type": mobileConfig.mimeType]

            return .raw(
                statusCode,
                statusText,
                headers,
                { (writer: Swifter.HttpResponseBodyWriter) throws in
                    try writer.write(mobileConfig.data)
                }
            )
        }
    }


    func start() -> WiFiQRCodeKit.MobileConfig.DistributionServerState {
        do {
            try self.server.start(self.port)
            return .successfullyStarted
        }
        catch {
            return .failed(because: "\(error)")
        }
    }


    func update(mobileConfigData: Data, mimeType: String) {
        self.mobileConfig = (data: mobileConfigData, mimeType: mimeType)
    }
}

完整示例

请参阅 Kuniwak/WiFiQRCodeKitExampleApp

实现细节

WiFiQRCodeKit的工作流程如下:

  1. 通过QR码阅读库获取Wi-Fi QR码内容
  2. WiFiQRCodeKit为Wi-Fi设置创建配置文件
  3. WiFiQRCodeKit启动一个本地HTTP服务器,用于提供配置文件
  4. WiFiQRCodeKit使用本地HTTP服务器的URL打开Safari
  5. Safari向用户确认配置文件的设置
  6. 连接到Wi-Fi

参考

许可

MIT许可(MIT)