如何在Swift中生成限时二维码
如何在Swift中生成限时有效的二维码
首先得明确一个关键点:二维码本身只是纯粹的数据载体,没有内置的过期或失效机制。要实现“限时可扫描”的效果,核心思路是把「原始文本+过期时间」打包后编码进二维码,然后在扫描验证环节检查当前时间是否超过过期时间。
下面分生成和验证两个环节给你具体的实现方案:
一、生成带过期信息的二维码
我们可以先定义一个结构体来封装原始内容和过期时间,然后把这个结构体序列化为JSON数据,再传给二维码生成器。这样二维码里就包含了判断是否过期的关键信息。
1. 定义内容结构体
首先创建一个遵循Codable的结构体,方便序列化和反序列化:
import Foundation struct TimedQRContent: Codable { let originalText: String // 用户输入的原始文本 let expirationTimestamp: TimeInterval // 过期时间的时间戳(自1970年以来的秒数) }
2. 修改生成二维码的代码
更新你原来的generateCodePressed方法,把用户输入的文本和过期时间打包成JSON,再生成二维码:
@IBOutlet weak var myImageView: UIImageView! @IBOutlet weak var myTextField: UITextField! var filter: CIFilter! @IBAction func generateCodePressed(_ sender: UIButton){ guard let inputText = myTextField.text, !inputText.isEmpty else { // 处理空输入的情况,比如提示用户输入内容 return } // 计算一周后的时间戳(7天 = 7*24*3600秒) let oneWeekInSeconds: TimeInterval = 7 * 24 * 3600 let expirationTimestamp = Date().addingTimeInterval(oneWeekInSeconds).timeIntervalSince1970 // 创建带过期信息的内容对象 let qrContent = TimedQRContent(originalText: inputText, expirationTimestamp: expirationTimestamp) // 把结构体序列化为JSON数据 guard let jsonData = try? JSONEncoder().encode(qrContent) else { print("Failed to encode QR content") return } // 生成二维码 filter = CIFilter(name: "CIQRCodeGenerator") filter.setValue(jsonData, forKey: "inputMessage") filter.setValue("H", forKey: "inputCorrectionLevel") // 设置高纠错级别,提升扫描容错率 if let outputImage = filter.outputImage { // 缩放二维码,避免模糊 let scaleTransform = CGAffineTransform(scaleX: 10, y: 10) let scaledImage = outputImage.transformed(by: scaleTransform) myImageView.image = UIImage(ciImage: scaledImage) } }
这里有个小优化:把原来的.ascii编码换成JSON的UTF-8编码,这样可以支持中文等非英文字符,兼容性更好。
二、扫描时验证二维码是否过期
当用户扫描二维码后,需要解析出里面的JSON数据,然后对比当前时间和过期时间,判断二维码是否有效:
// 假设扫描得到的二维码数据是scannedData: Data func validateTimedQRCode(scannedData: Data) -> String? { // 反序列化JSON为TimedQRContent对象 guard let qrContent = try? JSONDecoder().decode(TimedQRContent.self, from: scannedData) else { // 二维码数据格式错误,直接判定无效 return nil } // 获取当前时间的时间戳 let currentTimestamp = Date().timeIntervalSince1970 // 检查是否过期 if currentTimestamp <= qrContent.expirationTimestamp { // 未过期,返回原始文本 return qrContent.originalText } else { // 已过期,返回nil或者提示用户 return nil } }
三、进阶:提升安全性(防止篡改)
上面的方案是客户端本地验证,如果用户修改设备系统时间,可能会绕过过期检查。如果需要更高的安全性,建议结合后端验证:
- 生成二维码时,把原始文本和过期时间发送给后端,后端生成一个基于这些信息的签名(比如HMAC-SHA256)。
- 把「原始文本+过期时间+签名」一起编码进二维码。
- 扫描后,把这些数据发送给后端,由后端验证签名的合法性和是否过期,返回验证结果。
示例结构体可以改成:
struct SecureTimedQRContent: Codable { let originalText: String let expirationTimestamp: TimeInterval let signature: String // 后端生成的签名 }
总结一下:二维码本身不会自动失效,必须通过在数据中嵌入过期信息,再配合扫描时的时间校验来实现限时功能。如果对安全性要求高,一定要结合后端验证哦。
内容的提问来源于stack exchange,提问作者muradbay
相关产品推荐
相关产品推荐

