【问题标题】:Calling web service error in iPhone 6在 iPhone 6 中调用 Web 服务错误
【发布时间】: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 感谢您的评论,我添加了堆栈跟踪。

标签: ios iphone swift ipad


【解决方案1】:

这在评论中写起来变得很复杂,所以我将把它放在答案中。

首先,我对你的这部分代码有点困惑:

 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

您看起来是在尝试基于尝试序列化 dataAux 不是数据来创建 dataAux 变量。我假设您想对数据调用 JSONObjectWithData 方法。不知道为什么您会在不同平台上看到差异,但这可能是问题的一部分。

此外,值得使用 .AllowFragments 调用 JSONObjectWithData 方法,看看这是否有帮助。我还建议在尝试序列化数据之前先做这样的事情来查看数据的实际样子。至少它可以帮助您解决两个平台之间的差异。

print(NSString(data: data, encoding: NSUTF8StringEncoding))

【讨论】:

  • 非常感谢,我会按照你的建议去做,我会通知你的。
  • spottedrabbit 我发现一个错误,当我使用 iPhone 时,Web 服务以 html 格式返回“运行时错误”,这就是我在尝试解析为 JSON 时遇到异常的原因。但奇怪的是,当我使用 iPad 时,它可以正常工作。
  • 没有问题。格兰德我让你指出了正确的方向。祝你好运解决 Web 服务的根本问题。
猜你喜欢
  • 1970-01-01
  • 2017-05-26
  • 1970-01-01
  • 1970-01-01
  • 2012-10-28
  • 1970-01-01
  • 1970-01-01
  • 2015-11-18
  • 1970-01-01
相关资源
最近更新 更多