我对编程很陌生。我已经学习 Swift 几个月了。我正在尝试制作一个应用程序来扫描一维或二维条形码,获取字符串,并将其发送到 API 端点,该端点将返回一些信息。例如产品编号和批次号。
对于条形码部分,我使用来自 GitHub 的非常好的软件 BarcodeScanner。它运行没有任何问题,我可以从它读取的条形码中获取字符串。
一旦我有了字符串,我就可以将其发送到 API 端点,但随后它就卡在那里了。
如果我在操场上运行相同的代码,它就可以正常工作。它发出请求,我可以从服务器看到 JSON 格式的答案。如果我在 iPhone 上运行代码,就会卡住。当然,我在游乐场时不能使用扫描部分。我用它来测试网络部分以及与 API 的通信。
这是我的 Networking.swift 文件。它有一些用于调试的
print()
:
import Foundation
import UIKit
protocol NetworkManagerDelegate: class {
func didUpdatePharmo(pharmo: PharmoModel)
func didUpdateBarcode(barcode: BarcodeModel)
}
public struct NetworkManager {
var delegate: NetworkManagerDelegate?
let pharmoURL = "https://someurl.com/api"
let pharmoEndpoint = "https://someendpoint.com/api"
func fetchData(productNumber: String) {
let urlString = "\(pharmoURL)&number=\(productNumber)"
performRequestProductInfo(urlString: urlString)
print(urlString)
}
func fetchEndpoint(dataMatrix: String) {
let urlString = "\(pharmoEndpoint)&datamatrix=\(dataMatrix)"
performRequestEndpoint(urlString: urlString)
print(urlString)
}
func performRequestEndpoint(urlString: String) {
if let url = URL(string: urlString) {
let session = URLSession(configuration: .default)
var request = URLRequest(url: url)
request.httpMethod = "GET"
let task = session.dataTask(with: request) { (data, response, error) in
if error != nil {
print(error!)
return
}
if let response = response as? HTTPURLResponse {
print("EndPoint HTTP Status code: \(response.statusCode)")
}
if let safeData = data {
if let barcode = self.parseJSONEndpoint(endPointData: safeData) {
self.delegate?.didUpdateBarcode(barcode: barcode)
}
}
}
task.resume()
}
}
func parseJSONEndpoint(endPointData: Data) -> BarcodeModel? {
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode(BarcodeData.self, from: endPointData)
let productNumber = decodedData.product_number
let batchNumber = decodedData.batchnumber
let barcode = BarcodeModel(productNumber: productNumber, batchNumber: batchNumber)
print(batchNumber)
return barcode
} catch {
print(error)
return nil
}
}
func performRequestProductInfo(urlString: String) {
if let url = URL(string: urlString) {
let session = URLSession(configuration: .default)
var request = URLRequest(url: url)
request.httpMethod = "GET"
let task = session.dataTask(with: request) { (data, response, error) in
if error != nil {
print(error!)
return
}
if let response = response as? HTTPURLResponse {
print("ProductInfo HTTP Status code: \(response.statusCode)")
}
if let safeData = data {
if let pharmo = self.parseJSONProductInfo(pharmoData: safeData) {
self.delegate?.didUpdatePharmo(pharmo: pharmo)
}
}
}
task.resume()
}
}
func parseJSONProductInfo(pharmoData: Data) -> PharmoModel? {
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode(PharmoData.self, from: pharmoData)
let id = decodedData.id
let number = decodedData.number
let name = decodedData.name
let atcCode = decodedData.atc_code
let imagePath = decodedData.image_path
let displayImage = decodedData.display_image
let storageGroupId = decodedData.storage_group_id
let animalGroupId = decodedData.animal_group_id
let udlevbest = decodedData.udlevbest
let packageSizeText = decodedData.package_size_text
let packageSizeNum = decodedData.package_size_num
let unitCode = decodedData.unit_code
let strengthText = decodedData.strength_text
let prodPrice = decodedData.prod_price
let aupPrice = decodedData.aup_price
let aupInstPrice = decodedData.aup_inst_price
let animalGroups = decodedData.animal_groups
let udleveringsbestemmelse = decodedData.udleveringsbestemmelse
let animalGroup = decodedData.animal_group
let storageGroup = decodedData.storage_group
let species = decodedData.species
let indications = decodedData.indications
let substances = decodedData.substances
let manufacturer = decodedData.manufacturer
let pharmo = PharmoModel(id: id, number: number, name: name, atc_code: atcCode, image_path: imagePath, display_image: displayImage, storage_group_id: storageGroupId, animal_group_id: animalGroupId, udlevbest: udlevbest, package_size_text: packageSizeText, package_size_num: packageSizeNum, unit_code: unitCode, strength_text: strengthText, prod_price: prodPrice, aup_price: aupPrice, aup_inst_price: aupInstPrice, animal_groups: animalGroups, udleveringsbestemmelse: udleveringsbestemmelse, animal_group: animalGroup, storage_group: storageGroup, species: species, indications: indications, substances: substances, manufacturer: manufacturer)
print(name)
return pharmo
} catch {
print(error)
return nil
}
}
}
从运行条形码扫描仪的 ViewController.swift 中,我调用该函数
fetchEndpoint(dataMatrix: String)
。
extension ViewController: BarcodeScannerCodeDelegate {
func scanner(_ controller: BarcodeScannerViewController, didCaptureCode code: String, type: String) {
print("Barcode Data: \(code)")
print("Symbology Type: \(type)")
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
networkManager.fetchEndpoint(dataMatrix: code)
}
}
}
从控制台输出中我可以看到 ViewController.swift 中的这两个
print()
语句:
print("Barcode Data: \(code)")
print("Symbology Type: \(type)")
我还可以看到来自 Networking.swift 的
print()
声明:
print(urlString)
但此后什么也没有发生。同样,如果我在操场上运行相同的代码,它就可以正常工作。我还使用 Postman 发出请求,因此我可以查看 JSON 文件并确保 urlstring 正常工作。
有人知道我做错了什么吗?
我能够找到问题所在。从扫描仪读取的字符串包含非 ASCII 字符。
在任何时候,XCode 都会说出有关非 ASCII 字符的任何内容,我必须将字符串复制到 Playground 中,然后收到此错误:
Unprintable ASCII character found in source file
我将字符串复制到终端 shell 中,并且能够看到该字符。
datamatrix=^]01036611030467831722113010RXT0711GC
我会尝试使用
URLComponents
或percent encoding