【发布时间】:2016-02-22 15:47:11
【问题描述】:
我在我的 IO 应用程序中遇到了一个奇怪的行为,让我评论一下吧:
从 UI 调用的通用方法
func GetSensorList(){
dispatch_async(dispatch_get_global_queue(priority, 0)) {
self.sensors = Sensor.GenerateSensorList()
dispatch_async(dispatch_get_main_queue()) {
self.collectionView?.reloadData()
}
}
}
我有这个调用rest Web Service的方法:
static func GenerateSensorList() -> [Sensor]{
var sensores = [Sensor]()
let manager: AppManager = AppManager.manager
var userData: UserData? = nil
do{
userData = try manager.GetUserData()
if let userDataAux = userData {
manager.SaveSharedUserData(userDataAux)
if(userDataAux.weatherSettings!.weatherCity != nil){
var unit = "imperial"
if(userDataAux.weatherSettings!.tempFormat! == "C"){
unit = "metric"
}
let s = userDataAux.weatherSettings!.weatherCity!.stringByReplacingOccurrencesOfString(" ", withString: "@")
let weather = try manager.GetWeatherData(s, metric: unit)
let temperatureInt = Int(weather.weatherMain!.temp!)
let description = weather.weatherItem![0].description
let temp = "Temp: " + String(temperatureInt) + "°" + (userData!.weatherSettings!.tempFormat!)
let sensorAux = Sensor(image: weather.image, label1: description , label2:temp)
sensores.append(sensorAux)
}
}
let deviceData = try? manager.RetrieveDeviceDataObject()
if(deviceData != nil){
if(deviceData!?.DeviceDataItems != nil){
let deviceDataItems = deviceData!?.DeviceDataItems!
for(var i = 0; i < deviceDataItems?.count; i++){
let catId = deviceDataItems![i].CategoryId
let devId = deviceDataItems![i].DeviceItemId
switch catId!{
case 12: break
case 16:
let devItem = try manager.GetDeviceHumiditySensorItemById(devId!)
let photo1 = UIImage(named: "ic_devices")!
var humidityValue = ""
if(devItem.DeviceItemHumiditySensorHumidity != nil){
humidityValue = (devItem.DeviceItemHumiditySensorHumidity)!
}else{
humidityValue = "0"
}
let sensorAux = Sensor(image: photo1, label1: devItem.DeviceItemName , label2: ( humidityValue + "%"))
sensores.append(sensorAux)
case 17:
let devItem = try manager.GetDeviceTemperatureSensorItemById(devId!)
let photo1 = UIImage(named: "ic_devices")!
let sensorAux = Sensor(image: photo1, label1: devItem.DeviceItemName , label2: ((devItem.DeviceItemTemperatureSensorTemperature)! + "°" + (userData!.weatherSettings!.tempFormat!)))
sensores.append(sensorAux)
case 18:
let devItem = try manager.GetDeviceLightSensorItemById(devId!)
let photo1 = UIImage(named: "ic_devices")!
let sensorAux = Sensor(image: photo1, label1: devItem.DeviceItemName , label2: ((devItem.DeviceItemLightSensorLight)!))
sensores.append(sensorAux)
case 21:
let devItem = try manager.GetDevicePowerMeterItemById(devId!)
let photo1 = UIImage(named: "ic_devices")!
let sensorAux = Sensor(image: photo1, label1: devItem.DeviceItemName , label2: ((devItem.DeviceItemPowerMeterWatts)! + "Watts"))
sensores.append(sensorAux)
default: break
}
}
}
}
}
catch{
sensores = [Sensor]()
}
return sensores
}
行内:
let weather = try manager.GetWeatherData(s, metric: unit)
我面临以下问题:当我使用 iPad 模拟器时,该方法工作正常,但当我使用 iPhone 6 模拟器时,我发现数据不同并且应用程序崩溃。
我查了一下,iPhone和iPad运行的是同一个版本的IO(9.2),url完全一样,但是我得到的NSDATA对象不一样。
获取天气数据代码:
func GetWeatherData(cityName: String, metric: String) throws -> WeatherCondition{
do{
var weather = WeatherCondition()
let url = SERVICEURL + "/GetWeather/" + cityName + "/" + metric
let data = try ExecuteRequestServiceHeader(url, mmsAuth: nil, mmsAuthSig: nil, mmsSession: nil)
if let dataAux = data{
let json = try NSJSONSerialization.JSONObjectWithData(dataAux, options: .MutableLeaves) as! NSDictionary
let jsonleave = json["GetWeatherResult"] as? String
if let jsonLeaveAux = jsonleave{
weather = WeatherCondition.JsonToObject(jsonLeaveAux)
let iconVar = weather.weatherItem![0].icon
let urlIcon = SERVICEURL + "/GetWeatherIcon/"+iconVar!
let dataIcon = try ExecuteRequestService(urlIcon)
if let dataIconAux = dataIcon{
let jsonIcon = try NSJSONSerialization.JSONObjectWithData(dataIconAux, options: .MutableLeaves) as! NSDictionary
if let jsonleaveIcon = jsonIcon["GetWeatherIconResult"] as? NSArray{
var byteArray = [UInt8]()
for (var i = 0; i < jsonleaveIcon.count; i++){
byteArray.append(UInt8(String(jsonleaveIcon[i]))!)
}
let imData = NSData(bytes: byteArray, length: (byteArray.count))
let image = UIImage(data: imData)
weather.image = image
}
}else{
throw AppManagerError.ErrorAccessingService(url: "Getting Weather data")
}
}else{
throw AppManagerError.ErrorAccessingService(url: "Getting Weather data")
}
}else{
throw AppManagerError.ErrorAccessingService(url: "Getting Weather data")
}
return weather
}catch{
throw AppManagerError.ErrorAccessingService(url: "Getting Weather data")
}
}
应用程序在这一行抛出异常:
let json = try NSJSONSerialization.JSONObjectWithData(dataAux, options: .MutableLeaves) as! NSDictionary
异常跟踪:
捕获:错误域=NSCocoaErrorDomain 代码=3840“JSON 文本没有 从数组或对象和允许未设置片段的选项开始。” UserInfo={NSDebugDescription=JSON 文本不是以数组开头或 允许未设置片段的对象和选项。}
我将不胜感激这方面的任何帮助
【问题讨论】:
-
能否包含堆栈跟踪或 JSONObjectWithData 调用获得的异常文本...
-
感谢您的评论,但我在堆栈跟踪中没有遇到任何问题,例外是因为我得到的 NSDATA 对象无法序列化。这就是为什么我不明白为什么 iPhone 的数据与 iPad 的数据不同。
-
@JoseRaulPerera 请打印将在最后的
catch子句中捕获的错误。目前,您只需重新抛出错误。您的代码中还奇怪的是,尽管网络调用本质上是异步的 - 您的代码似乎采用了同步风格。这可能无法无缝运行,并且会阻塞线程。 -
@CouchDeveloper,我添加了 main 方法,对不起,我不知道如何打印异常,请给我提示,以便我可以与您分享异常描述
-
@CouchDeveloper 感谢您的评论,我添加了堆栈跟踪。