WiFiQRCodeKit
在 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.swift 和 httpswift/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的工作流程如下:
- 通过QR码阅读库获取Wi-Fi QR码内容
- WiFiQRCodeKit为Wi-Fi设置创建配置文件
- WiFiQRCodeKit启动一个本地HTTP服务器,用于提供配置文件
- WiFiQRCodeKit使用本地HTTP服务器的URL打开Safari
- Safari向用户确认配置文件的设置
- 连接到Wi-Fi
参考
许可
MIT许可(MIT)