ios 怎么去掉字典json的null

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ios 怎么去掉字典json的null相关的知识,希望对你有一定的参考价值。

参考技术A 通过[x isKindOfClass:[NSNull class]]判断就可以了如果是null就改成@""
- (NSArray *)checkNSArrayWithChangeUseful:(NSArray *)checkArray



if([checkArray isKindOfClass:[NSArray class]])



NSMutableArray *usefulArr = [NSMutableArray arrayWithArray:checkArray];

[usefulArr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop)

if([obj isKindOfClass:[NSNull class]] )



[usefulArr replaceObjectAtIndex:idx withObject:@""];

else if([obj isKindOfClass:[NSNumber class]] || [obj isKindOfClass:[NSValue class]])



[usefulArr replaceObjectAtIndex:idx withObject:[NSString stringWithFormat:@"%@",obj]];

else if([obj isKindOfClass:[NSDictionary class]])



[usefulArr replaceObjectAtIndex:idx withObject:[self checkNSDictinaryWithChangeUseful:obj]];

else if([obj isKindOfClass:[NSArray class]])



[usefulArr replaceObjectAtIndex:idx withObject:[self checkNSArrayWithChangeUseful:obj]];



];

return [NSArray arrayWithArray:usefulArr];



return checkArray;



- (NSDictionary *)checkNSDictinaryWithChangeUseful:(NSDictionary *)checkDictioary



if([checkDictioary isKindOfClass:[NSDictionary class]])



NSMutableDictionary *usefulDic = [NSMutableDictionary dictionaryWithDictionary:checkDictioary];

[usefulDic enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop)

if(ISNULL(obj) || ISNil(obj))



usefulDic[key] = @"";

else if([obj isKindOfClass:[NSNumber class]] || [obj isKindOfClass:[NSValue class]])



usefulDic[key] = [NSString stringWithFormat:@"%@",obj];

else if([obj isKindOfClass:[NSDictionary class]])



usefulDic[key] = [self checkNSDictinaryWithChangeUseful: obj];

else if([obj isKindOfClass:[NSArray class]])



usefulDic[key] = [self checkNSArrayWithChangeUseful:obj];



];

return [NSDictionary dictionaryWithDictionary:usefulDic];



return checkDictioary;

在字典中解码字典 - JSON/Swift

【中文标题】在字典中解码字典 - JSON/Swift【英文标题】:Decoding a Dictionary Inside a Dictionary - JSON/Swift 【发布时间】:2020-09-25 00:23:59 【问题描述】:

我有一个结构如下的 JSON 文件:

"forecast": [
    
      "altimeter": "",
      "clouds": [
        
          "repr": "OVC025",
          "type": "OVC",
          "altitude": 25,
          "modifier": null,
          "direction": null
        
      ],
      "flight_rules": "MVFR",
      "other": [],
      "sanitized": "0318/0424 34017G26KT P6SM -RA OVC025",
      "visibility": 
        "repr": "P6",
        "value": null,
        "spoken": "greater than six"
      ,
      "wind_direction": 
        "repr": "340",
        "value": 340,
        "spoken": "three four zero"
      

And so on....

我正在尝试使用 DispatchQueue 访问信息并更新 UI,但无法弄清楚如何从内部预测中提取数据:clouds: repr(或任何其他类似的嵌套)。我可以成功提取数据,例如:预测:原始。我尝试使用未嵌套在第一个中的结构,但它不起作用(正如预期的那样,数据是内部的另一个索引)。

我的解码文件是:

//
//  TAFData.swift
//  AvWx Pro
//
//  Created by Grayson Bertaina on 9/24/20.
//

import Foundation

struct TAFDatas: Codable 
   
    
    let flight_rules: String?
    let time: TimeTAF?
    let station: String?
    let raw: String?
    let forecast: [ForecastTAF?]
    let end_time: ?
    let wind_gust: ?


struct ForecastTAF: Codable 
    let raw: String?
    struct CloudsTAF: Codable 
        let type: String
        let altitude: Int
    
    struct endTimeTAF: Codable 
        let repr: String
    

    struct WindSpeedTAF: Codable 
        let value: Int
    

    struct WindGustTAF: Codable 
        let value: Int
    

    struct WindDirectionTAF: Codable 
        let repr: String
    

    struct VisibilityTAF: Codable 
        let repr: String
    

    struct WxcodesTAF: Codable 
        let value: String
    

    struct StartTimeTAF: Codable 
        let repr: String
    

    struct EndTimeTAF: Codable 
        let repr: String
    


    


struct TimeTAF: Codable 
    let repr: String


我的解析文件是:

//
//  TAFManager.swift
//  AvWx Pro
//
//  Created by Grayson Bertaina on 9/24/20.
//

import Foundation

protocol TAFManagerDelegate : class 
    func didUpdateTAF(_ weatherManager: TAFManager, weatherTAF: TAFModel)
    func didFailWithErrorTAF(error: Error)




struct TAFManager 
    let TAFURL = "https://avwx.rest/api/taf/"
    
    weak var delegate : TAFManagerDelegate?

    func fetchWeatherTAF (stationICAO: String) 
        let TAFurlString = "\(TAFURL)\(stationICAO)?token=OVi45FiTDo1LmyodShfOfoizNe5m9wyuO6Mkc95AN-c"
        performRequestTAF(with: TAFurlString)
    
    
    func performRequestTAF (with TAFurlString: String) 
        if let TAFurl = URL(string: TAFurlString) 
            let session = URLSession(configuration: .default)
                
            
            let taskTAF = session.dataTask(with: TAFurl)  (data, response, error) in
                if error != nil 
                    self.delegate?.didFailWithErrorTAF(error: error!)
                    return
                
                
                if let safeDataTAF = data 
                    if let weatherTAF = self.parseJSONTAF(safeDataTAF) 
                        self.delegate?.didUpdateTAF(self, weatherTAF: weatherTAF)
                    
                
            
            
            taskTAF.resume()
            print(TAFurlString)
            
            
            
        
    
   
    func parseJSONTAF(_ TAFData: Data) -> TAFModel? 
        
        
        do 
            let decoderTAF = JSONDecoder()
            let decodedDataTAF = try decoderTAF.decode(TAFDatas.self, from: TAFData)
            
            
            
            let cloudsTAF = decodedDataTAF.clouds
            let wxcodesTAF = decodedDataTAF.wx_codes
            let forecastTAF = decodedDataTAF.forecast
            let lowCloudsTypeTAF = (cloudsTAF.count > 0 ? cloudsTAF[0]?.type : nil) ?? "N/A"
            let midCloudsTypeTAF = (cloudsTAF.count > 1 ? cloudsTAF[1]?.type : nil) ?? "N/A"
            let highCloudsTypeTAF = (cloudsTAF.count > 2 ? cloudsTAF[2]?.type : nil) ?? "N/A"
            let lowCloudsAltTAF = (cloudsTAF.count > 0 ? cloudsTAF[0]?.altitude : nil) ?? 0
            let midCloudsAltTAF = (cloudsTAF.count > 1 ? cloudsTAF[1]?.altitude : nil) ?? 0
            let highCloudsAltTAF = (cloudsTAF.count > 2 ? cloudsTAF[2]?.altitude : nil) ?? 0
            let reportingStationVarTAF = decodedDataTAF.station ?? "N/A"
            let windGustValueTAF = decodedDataTAF.wind_gust?.value ?? 0
            let windSpeedValueTAF = decodedDataTAF.wind_speed?.value ?? 0
            let windDirectionValueTAF = decodedDataTAF.wind_direction?.repr ?? "N/A"
            let visibilityValueTAF = decodedDataTAF.visibility?.repr ?? "N/A"
            let flightRulesValueTAF = decodedDataTAF.flight_rules ?? "N/A"
            let timeReportedTAF = decodedDataTAF.time?.repr ?? "N/A"
            let firstWxCode1TAF = (wxcodesTAF.count > 0 ? wxcodesTAF[0]?.value : "N/A") ?? "N/A"
            let startTimeTaf = decodedDataTAF.start_time?.repr ?? "N/A"
            let endTimeTaf = (forecastTAF.count > 0 ? forecastTAF[0]? : nil) ?? "N/A"
            let rawTAFData = (forecastTAF.count > 0 ? forecastTAF[0]?.raw : nil) ?? "N/A"
            
            
            let weatherTAF = TAFModel(lowestCloudsTypeTAF: lowCloudsTypeTAF , lowestCloudsAltTAF: lowCloudsAltTAF, middleCloudsTypeTAF: midCloudsTypeTAF , middleCloudsAltTAF: midCloudsAltTAF, highestCloudsTypeTAF: highCloudsTypeTAF , highestCloudsAltTAF: highCloudsAltTAF, reportingStationTAF: reportingStationVarTAF, windGustTAF: windGustValueTAF, windSpeedTAF: windSpeedValueTAF, windDirectionTAF: windDirectionValueTAF, visibilityTAF: visibilityValueTAF, flightRulesTAF: flightRulesValueTAF, timeTAF: timeReportedTAF, startTimeTAF: startTimeTaf, endTimeTAF: endTimeTaf, firstWxCodeTAF: firstWxCode1TAF, rawTAF: rawTAFData)
            
            delegate?.didUpdateTAF(self, weatherTAF: weatherTAF)
            return weatherTAF
            
         catch 
            delegate?.didFailWithErrorTAF(error: error)
            return nil
        
    
    
    


    

我的模型文件是:

//
//  WeatherModel.swift
//  AvWx Pro
//
//  Created by Grayson Bertaina on 9/22/20.
//

import Foundation

struct WeatherModel 
    
    
    let lowestCloudsType: String
    let lowestCloudsAlt: Int
    let middleCloudsType: String
    let middleCloudsAlt: Int
    let highestCloudsType: String
    let highestCloudsAlt: Int
    let reportingStation: String
    let windGust: Int
    let windSpeed: Int
    let windDirection: String
    let visibility: String
    let flightRules: String
    let time: String
    let remarks: String
    let altimeter: Double
    let temperature: String
    let dewpoint: String
    let firstWxCode: String
    
    var altToString1: String 
        return String(format: "%u" + "00 ft", lowestCloudsAlt)
    
    
    var altToString2: String 
        return String(format: "%u" + "00 ft", middleCloudsAlt)
    
    
    var altToString3: String 
        return String(format: "%u" + "00 ft", highestCloudsAlt)
    
    
    var windGustString: String 
        return String(format: "%u" + "kt", windGust)
    
    
    
    var windSpeedString: String 
        return String(format: "%u" + "kt", windSpeed)
    
    
    var altimeterString: String 
        return String(format: "%.2f" + " inHg", altimeter as CVarArg)
    
    
    var visUnits: String 
        return visibility + " SM"
    
    
    var degUnits: String 
        return windDirection + "°"
    
    
    var tempUnits: String 
        return temperature + "°C"
    
    
    var dewUnits: String 
        return dewpoint + "°C"
    

    
    var flightConditions: String 
        switch flightRules 
        case "VFR":
            return "green"
        case "MVFR":
            return "blue"
        case "IFR":
            return "red"
        case "LIFR":
            return "purple"
        default:
            return "gray"
        
        
    

我认为主要的问题是获取这些数据键。一旦我在那里,希望其余的都会到位。非常感谢提前提供的帮助,祝您有美好的一天!

加上评论,我的新 JSON

// MARK: - TAFData
struct TAFData: Codable 
    let meta: MetaTAF?
    let raw, station: String?
    let time: TimeTAF?
    let remarks: String?
    let forecast: [ForecastTAF?]
    let startTime, endTime: TimeTAF?
    let maxTemp, minTemp: String?
    let alts, temps: JSONNull?

    enum CodingKeys: String, CodingKey 
        case meta, raw, station, time, remarks, forecast
        case startTime = "start_time"
        case endTime = "end_time"
        case maxTemp = "max_temp"
        case minTemp = "min_temp"
        case alts, temps, units
    


// MARK: - Time
struct TimeTAF: Codable 
    let repr, dt: String


// MARK: - Forecast
struct ForecastTAF: Codable 
    let altimeter: String
    let clouds: [CloudTAF]
    let flightRules: String
    let other: [JSONAny]
    let sanitized: String
    let visibility, windDirection: VisibilityTAF
    let windGust: VisibilityTAF?
    let windSpeed: VisibilityTAF
    let wxCodes: [WxCodeTAF]
    let endTime: TimeTAF
    let icing: [JSONAny]
    let probability: JSONNull?
    let raw: String
    let startTime: TimeTAF
    let turbulence: [JSONAny]
    let type: String
    let windShear: JSONNull?
    let summary: String

    enum CodingKeys: String, CodingKey 
        case altimeter, clouds
        case flightRules = "flight_rules"
        case other, sanitized, visibility
        case windDirection = "wind_direction"
        case windGust = "wind_gust"
        case windSpeed = "wind_speed"
        case wxCodes = "wx_codes"
        case endTime = "end_time"
        case icing, probability, raw
        case startTime = "start_time"
        case turbulence, type
        case windShear = "wind_shear"
        case summary
    


// MARK: - Cloud
struct CloudTAF: Codable 
    let repr, type: String
    let altitude: Int
    let modifier, direction: JSONNull?


// MARK: - Visibility
struct VisibilityTAF: Codable 
    let repr: String
    let value: Int?
    let spoken: String


// MARK: - WxCode
struct WxCodeTAF: Codable 
    let repr, value: String


// MARK: - Meta
struct MetaTAF: Codable 
    let timestamp: String


// MARK: - Units
struct UnitsTAF: Codable 
    let altimeter, altitude, temperature, visibility: String
    let windSpeed: String

    enum CodingKeys: String, CodingKey 
        case altimeter, altitude, temperature, visibility
        case windSpeed = "wind_speed"
    


// MARK: - Encode/decode helpers

class JSONNull: Codable, Hashable 

    public static func == (lhs: JSONNull, rhs: JSONNull) -> Bool 
        return true
    

    public var hashValue: Int 
        return 0
    

    public func hash(into hasher: inout Hasher) 
        // No-op
    

    public init() 

    public required init(from decoder: Decoder) throws 
        let container = try decoder.singleValueContainer()
        if !container.decodeNil() 
            throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
        
    

    public func encode(to encoder: Encoder) throws 
        var container = encoder.singleValueContainer()
        try container.encodeNil()
    


class JSONCodingKey: CodingKey 
    let key: String

    required init?(intValue: Int) 
        return nil
    

    required init?(stringValue: String) 
        key = stringValue
    

    var intValue: Int? 
        return nil
    

    var stringValue: String 
        return key
    


class JSONAny: Codable 

    let value: Any

    static func decodingError(forCodingPath codingPath: [CodingKey]) -> DecodingError 
        let context = DecodingError.Context(codingPath: codingPath, debugDescription: "Cannot decode JSONAny")
        return DecodingError.typeMismatch(JSONAny.self, context)
    

    static func encodingError(forValue value: Any, codingPath: [CodingKey]) -> EncodingError 
        let context = EncodingError.Context(codingPath: codingPath, debugDescription: "Cannot encode JSONAny")
        return EncodingError.invalidValue(value, context)
    

    static func decode(from container: SingleValueDecodingContainer) throws -> Any 
        if let value = try? container.decode(Bool.self) 
            return value
        
        if let value = try? container.decode(Int64.self) 
            return value
        
        if let value = try? container.decode(Double.self) 
            return value
        
        if let value = try? container.decode(String.self) 
            return value
        
        if container.decodeNil() 
            return JSONNull()
        
        throw decodingError(forCodingPath: container.codingPath)
    

    static func decode(from container: inout UnkeyedDecodingContainer) throws -> Any 
        if let value = try? container.decode(Bool.self) 
            return value
        
        if let value = try? container.decode(Int64.self) 
            return value
        
        if let value = try? container.decode(Double.self) 
            return value
        
        if let value = try? container.decode(String.self) 
            return value
        
        if let value = try? container.decodeNil() 
            if value 
                return JSONNull()
            
        
        if var container = try? container.nestedUnkeyedContainer() 
            return try decodeArray(from: &container)
        
        if var container = try? container.nestedContainer(keyedBy: JSONCodingKey.self) 
            return try decodeDictionary(from: &container)
        
        throw decodingError(forCodingPath: container.codingPath)
    

    static func decode(from container: inout KeyedDecodingContainer<JSONCodingKey>, forKey key: JSONCodingKey) throws -> Any 
        if let value = try? container.decode(Bool.self, forKey: key) 
            return value
        
        if let value = try? container.decode(Int64.self, forKey: key) 
            return value
        
        if let value = try? container.decode(Double.self, forKey: key) 
            return value
        
        if let value = try? container.decode(String.self, forKey: key) 
            return value
        
        if let value = try? container.decodeNil(forKey: key) 
            if value 
                return JSONNull()
            
        
        if var container = try? container.nestedUnkeyedContainer(forKey: key) 
            return try decodeArray(from: &container)
        
        if var container = try? container.nestedContainer(keyedBy: JSONCodingKey.self, forKey: key) 
            return try decodeDictionary(from: &container)
        
        throw decodingError(forCodingPath: container.codingPath)
    

    static func decodeArray(from container: inout UnkeyedDecodingContainer) throws -> [Any] 
        var arr: [Any] = []
        while !container.isAtEnd 
            let value = try decode(from: &container)
            arr.append(value)
        
        return arr
    

    static func decodeDictionary(from container: inout KeyedDecodingContainer<JSONCodingKey>) throws -> [String: Any] 
        var dict = [String: Any]()
        for key in container.allKeys 
            let value = try decode(from: &container, forKey: key)
            dict[key.stringValue] = value
        
        return dict
    

    static func encode(to container: inout UnkeyedEncodingContainer, array: [Any]) throws 
        for value in array 
            if let value = value as? Bool 
                try container.encode(value)
             else if let value = value as? Int64 
                try container.encode(value)
             else if let value = value as? Double 
                try container.encode(value)
             else if let value = value as? String 
                try container.encode(value)
             else if value is JSONNull 
                try container.encodeNil()
             else if let value = value as? [Any] 
                var container = container.nestedUnkeyedContainer()
                try encode(to: &container, array: value)
             else if let value = value as? [String: Any] 
                var container = container.nestedContainer(keyedBy: JSONCodingKey.self)
                try encode(to: &container, dictionary: value)
             else 
                throw encodingError(forValue: value, codingPath: container.codingPath)
            
        
    

    static func encode(to container: inout KeyedEncodingContainer<JSONCodingKey>, dictionary: [String: Any]) throws 
        for (key, value) in dictionary 
            let key = JSONCodingKey(stringValue: key)!
            if let value = value as? Bool 
                try container.encode(value, forKey: key)
             else if let value = value as? Int64 
                try container.encode(value, forKey: key)
             else if let value = value as? Double 
                try container.encode(value, forKey: key)
             else if let value = value as? String 
                try container.encode(value, forKey: key)
             else if value is JSONNull 
                try container.encodeNil(forKey: key)
             else if let value = value as? [Any] 
                var container = container.nestedUnkeyedContainer(forKey: key)
                try encode(to: &container, array: value)
             else if let value = value as? [String: Any] 
                var container = container.nestedContainer(keyedBy: JSONCodingKey.self, forKey: key)
                try encode(to: &container, dictionary: value)
             else 
                throw encodingError(forValue: value, codingPath: container.codingPath)
            
        
    

    static func encode(to container: inout SingleValueEncodingContainer, value: Any) throws 
        if let value = value as? Bool 
            try container.encode(value)
         else if let value = value as? Int64 
            try container.encode(value)
         else if let value = value as? Double 
            try container.encode(value)
         else if let value = value as? String 
            try container.encode(value)
         else if value is JSONNull 
            try container.encodeNil()
         else 
            throw encodingError(forValue: value, codingPath: container.codingPath)
        
    

    public required init(from decoder: Decoder) throws 
        if var arrayContainer = try? decoder.unkeyedContainer() 
            self.value = try JSONAny.decodeArray(from: &arrayContainer)
         else if var container = try? decoder.container(keyedBy: JSONCodingKey.self) 
            self.value = try JSONAny.decodeDictionary(from: &container)
         else 
            let container = try decoder.singleValueContainer()
            self.value = try JSONAny.decode(from: container)
        
    

    public func encode(to encoder: Encoder) throws 
        if let arr = self.value as? [Any] 
            var container = encoder.unkeyedContainer()
            try JSONAny.encode(to: &container, array: arr)
         else if let dict = self.value as? [String: Any] 
            var container = encoder.container(keyedBy: JSONCodingKey.self)
            try JSONAny.encode(to: &container, dictionary: dict)
         else 
            var container = encoder.singleValueContainer()
            try JSONAny.encode(to: &container, value: self.value)
        
    

【问题讨论】:

【参考方案1】:

我可能会使用不同的模型,因为您当前的模型不支持与 JSON 相同的格式:


struct Forecast: Codable 
    let altimeter: String
    let clouds: [Cloud]
    let flightRules: String
    let other: [JSONAny]
    let sanitized: String
    let visibility, windDirection: Visibility

    enum CodingKeys: String, CodingKey 
        case altimeter, clouds
        case flightRules = "flight_rules"
        case other, sanitized, visibility
        case windDirection = "wind_direction"
    


// MARK: - Cloud
struct Cloud: Codable 
    let repr, type: String
    let altitude: Int


// MARK: - Visibility
struct Visibility: Codable 
    let repr: String
    let value: Int?
    let spoken: String

这样你就可以使用了:

if let cloud = forecast.clouds.first() 
    let repr = cloud.repr
    .. Your logic 

我的模型中可能缺少一些东西,但你应该知道

【讨论】:

我正在轮询的数据有多个预测部分——即预测:[forecast1 with all that data、forecast two with all that data等]。该逻辑是否允许我创建所有数据的多个实例?感谢您的回答,我正在努力尝试! 这些是我的 JSON 数据:avwx.docs.apiary.io/#reference/0/parse-metar/get-taf-report 这仅适用于您在问题中发送的 JSON,如果您有很多多个来源,您可以使用此工具帮助您对所有内容进行建模:app.quicktype.io 这是一个很棒的工具。感谢分享!我将新的 JSON 放在我的问题帖子的底部。在 TAFManager 上,我如何访问预测 > 云 > 类型中的内容? 我试过了:给定let forecastTAF = decodedDataTAF.forecast forecastTAF.CloudsTAF[0].typeforecastTAF.clouds[0].type 和其他一些。

以上是关于ios 怎么去掉字典json的null的主要内容,如果未能解决你的问题,请参考以下文章

alibaba的JSON.toString会把值为null的字段去掉,谨记

iOS NSDictionary 转Json 去掉换行去掉空格

Android开发 解析JSON数据格式 如何去掉JSON数

android button边框怎么去掉

PHP怎么生成去掉中括号的JSON

Android的json中怎么去掉第三方符号