Json 使用swift 4获取数据

Json 使用swift 4获取数据,json,swift4,Json,Swift4,我正在尝试从swift 4获取数据,我得到了nil作为响应 1-我有这段代码,我有错误“类型'JobSeekerDataAPI'不符合协议'Decodable' import UIKit import SwiftyJSON struct JobSeekerDataAPI : Decodable { let job_seeker_id: String? let job_seeker_name: String? let linkedin_id: String? let first_name: S

我正在尝试从swift 4获取数据,我得到了nil作为响应

1-我有这段代码,我有错误“类型'JobSeekerDataAPI'不符合协议'Decodable'

import UIKit
import SwiftyJSON

struct JobSeekerDataAPI : Decodable {

let job_seeker_id: String?
let job_seeker_name: String?
let linkedin_id: String?
let first_name: String?
let last_name: String?
let user_id: String?
let profile_pic_file: String?
let personal_job_title: String?
let about: String?
let interest: String?
let most_recent_work_history_id: String?
let most_recent_education_id: String?
let rel_work_exp_year: String?
let most_recent_salary: String?
let salary_expectation_high: String?
let salary_expectation_low: String?
let is_salary_on_public_profile: String?
let education_level_id: String?
let location_country_id: String?
let location_timezone_id: String?
let work_eligibility_id: String?
let public_seeking_status_id: String?
let search_seeking_status_id: String?
let days_before_begin_new_job: String?
let disc_self_d: String?
let disc_self_i: String?
let disc_self_s: String?
let disc_self_c: String?
let location_postal_code: String?
let will_relocate: String?
let is_default: String?
let is_military: String?
let website_url: String?
let contact_email: String?
let contact_mobile: String?
let contact_alt_phone: String?
let sort_order: String?
let disc_adj_nd_id: String?
let disc_adj_ni_id: String?
let disc_adj_ns_id: String?
let disc_adj_nc_id: String?
let disc_adj_lw_id: String?
let talent_filter_01: String?
let talent_filter_02: String?
let talent_filter_03: String?
let talent_filter_04: String?
let talent_filter_05: String?
let talent_filter_10: String?
let talent_filter_11: String?
let talent_filter_12: String?
let talent_filter_13: String?
let talent_filter_14: String?
let talent_filter_15: String?
let talent_filter_16: String?
let talent_filter_17: String?
let talent_filter_18: String?
let talent_filter_19: String?
let profileSlug: String?
let mostRecentWorkHistory: [String:String]?
let priorWorkHistories: [WorkHistory]?
let mostRecentEducationHistory: [EducationHistory]?
let priorEducationHistories: [EducationHistory]?
let topQualifications: [TopQualifications]?
let seekingLocations: String?
let education_level: EducationLevel?
let location_country: LocationCountry?
let location_timezone: LocationTimeZone?
let work_eligibility: WorkEligibility?
let public_seeking_status: SeekingStatus?
let search_seeking_status: SeekingStatus?
let most_recent_work_history: WorkHistory?
let most_recent_education: EducationHistory?
let disc_adj_nd: DiscAdjData?
let disc_adj_ni: DiscAdjData?
let disc_adj_ns: DiscAdjData?
let disc_adj_nc: DiscAdjData?
let disc_adj_lw: DiscAdjData?
let js_employer_excludes: [String]?
let js_media: [String]?
let js_occupations: [JSOccupation]?
let js_search_places: [JSSearchPlaces]?
let js_work_types: [JSWorkTypes]?
let userCoWorkers: [String]?

enum CodingKeys: String, CodingKey {

    case jobSeekerID = "job_seeker_id"
    case jobseekerName = "job_seeker_name"
    case linkedInId = "linkedin_id"
    case firstName = "first_name"
    case lastName = "last_name"
    case userID = "user_id"
    case profilePicture = "profile_pic_file"
    case personalJobTitle = "personal_job_title"
    case aboutUser = "about"
    case userInterest = "interest"
    case mostRecentWorkHistoryId = "most_recent_work_history_id"
    case mostRecentEducationId = "most_recent_education_id"
    case workExperienceYear = "rel_work_exp_year"
    case mostRecentSalary = "most_recent_salary"
    case salaryExpectationHigh = "salary_expectation_high"
    case salaryExpectationLow = "salary_expectation_low"
    case salaryVisiblePublicProf = "is_salary_on_public_profile"
    case educationLevelID = "education_level_id"
    case locationCountryID = "location_country_id"
    case locationTimezoneID = "location_timezone_id"
    case workEligibilityID = "work_eligibility_id"
    case publicSeekingStatusID = "public_seeking_status_id"
    case searchSeekingStatusID = "search_seeking_status_id"
    case daysBeforeBeguinJob = "days_before_begin_new_job"
    case discSelfD = "disc_self_d"
    case discSelfI = "disc_self_i"
    case discSelfS = "disc_self_s"
    case discSelfC = "disc_self_c"
    case locationPostalCode = "location_postal_code"
    case willRelocate = "will_relocate"
    case isDefault = "is_default"
    case isMilitary = "is_military"
    case websiteURL = "website_url"
    case contactEmail = "contact_email"
    case contactMobile = "contact_mobile"
    case contactAlternativePhone = "contact_alt_phone"
    case sortOrder = "sort_order"
    case discAdjNDID = "disc_adj_nd_id"
    case discAdjNIID = "disc_adj_ni_id"
    case discAdjNSID = "disc_adj_ns_id"
    case discAdjNCID = "disc_adj_nc_id"
    case discAdjLWID = "disc_adj_lw_id"
    //probably bool value
    case talentFilter01 = "talent_filter_01"
    case talentFilter02 = "talent_filter_02"
    case talentFilter03 = "talent_filter_03"
    case talentFilter04 = "talent_filter_04"
    case talentFilter05 = "talent_filter_05"
    case talentFilter10 = "talent_filter_10"
    case talentFilter11 = "talent_filter_11"
    case talentFilter12 = "talent_filter_12"
    case talentFilter13 = "talent_filter_13"
    case talentFilter14 = "talent_filter_14"
    case talentFilter15 = "talent_filter_15"
    case talentFilter16 = "talent_filter_16"
    case talentFilter17 = "talent_filter_17"
    case talentFilter18 = "talent_filter_18"
    case talentFilter19 = "talent_filter_19"
    case profileSlug = "profile_slug"
    case mostRecentWorkHistoryArray = "mostRecentWorkHistory"
    case priorWorkHistoriesArray = "priorWorkHistories"
    case mostRecentEducationHistoryArray = "mostRecentEducationHistory"
    case priorEducationHistoryArray = "priorEducationHistories"
    case topQUalificationsArray = "topQualifications"
    case seekingLocations = "seekingLocations"
    case educationLevel = "education_level"
    case locationCountry = "location_country"
    case locationTimeZone = "location_timezone"
    case workEligibility = "WorkEligibility"
    case publicSeekingStatus = "public_seeking_status"
    case searchSeekingStatus = "search_seeking_status"
    case discAdjND = "disc_adj_nd"
    case discAdjNI = "disc_adj_ni"
    case discAdjNS = "disc_adj_ns"
    case discAdjNC = "disc_adj_nc"
    case discAdjLW = "disc_adj_lw"
    case jobSeekerEmployerExcludes = "js_employer_excludes"
    case jobSeekerMedia = "js_media"
    case jobSeekerOccupationsArray = "js_occupations"
    case jobSeekerSearchPlacesArray = "js_search_places"
    case jobSeekerWorkTypes = "js_work_types"
    case userCoWorkers = "user_coworkers"

}
}

struct WorkHistory: Decodable{

let work_history_id : String?
let job_seeker_id: String?
let position: String?
let employer: String?
let work_history_name: String?
let work_type_id: String?
let responsibilities: String?
let reason_for_leaving: String?
let is_current_position: String?
let start_month: String?
let start_year: String?
let end_month: String?
let end_year: String?
let sort_order: String?

//    enum CodingKeys: String, CodingKey {
//
//        case workHistoryID = "work_history_id"
//        case jobSeekerID = "job_seeker_id"
//        case position = "position"
//        case employer = "employer"
//        case workHistoryName = "work_history_name"
//        case workTypeId = "work_type_id"
//        case responsabilities = "responsibilities"
//        case reasonForLeaving = "reason_for_leaving"
//        case isCurrentPosition = "is_current_position"
//        case startMonth = "start_month"
//        case startYear = "start_year"
//        case finishMonth = "end_month"
//        case finishYear = "end_year"
//        case sortOrder = "sort_order"
//    }
}

struct EducationHistory: Decodable {

let education_history_id: String?
let job_seeker_id: String?
let education_level: String?
let start_month: String?
let start_year: String?
let end_month: String?
let end_year: String?
let educational_institution: String?
let program_major: String?
let education_history_name: String?
let cumulative_gpa: String?
let major_gpa: String?
let currently_attending: String?
let sort_order: String?

//    enum CodingKeys: String, CodingKey {
//
//        case educationID = "education_history_id"
//        case jobSeekerID = "job_seeker_id"
//        case educationLevel = "education_level"
//        case startMonth = "start_month"
//        case startYear = "start_year"
//        case endMonth = "end_month"
//        case endYear = "end_year"
//        case educationalInstitution = "educational_institution"
//        case programMajor = "program_major"
//        case educationalHistoryName = "education_history_name"
//        case cumulativeGPA = "cumulative_gpa"
//        case majorGPA = "major_gpa"
//        case currentlyAttending = "currently_attending"
//        case sortEducationOrder = "sort_order"
//    }
}

struct TopQualifications: Decodable {

let requirement_id: String?
let requirement_name: String?
let requirement_descr: String?
let req_category_id: String?
let req_type_id: String?
let for_all_occupations: String?

//    enum CodingKeys: String, CodingKey {
//
//        case requirementID = "requirement_id"
//        case requirementName = "requirement_name"
//        case requirementDescription = "requirement_descr"
//        case requirementCategoryID = "req_category_id"
//        case requirementTypeID = "req_type_id"
//        case forAllOccupations = "for_all_occupations"
//    }
}

struct EducationLevel: Decodable {

let education_level_id: String?
let education_level_name: String?
let education_level_code: String?
let sort_order: String?

//    enum CodingKeys: String, CodingKey {
//
//        case educationLevelID = "education_level_id"
//        case edcationLevelName = "education_level_name"
//        case educationLevelCode = "education_level_code"
//        case sortOrder = "sort_order"
//    }
}

struct LocationCountry: Decodable {

let location_country_id: String?
let location_country_name: String?
let location_country_code: String?
let sort_order: String?

//    enum CodingKeys: String, CodingKey {
//
//        case locationCountryID = "location_country_id"
//        case locationCountryName = "location_country_name"
//        case locationCountruyCode = "location_country_code"
//        case sortOrder = "sort_order"
//    }
}

struct LocationTimeZone: Decodable {

let location_timezone_id: String?
let location_timezone_name: String?
let location_timezone_code: String?
let sort_order: String?

//    enum CodingKeys: String, CodingKey {
//        case locationTimeZoneID = "location_timezone_id"
//        case locationTimezoneName = "location_timezone_name"
//        case locationTimezoneCode = "location_timezone_code"
//        case sortOrder = "sort_order"
//    }
}

struct WorkEligibility: Decodable {

let work_eligibility_id: String?
let work_eligibility_name: String?
let work_eligibility_code: String?
let sort_order: String?

//    enum CodingKeys: String, CodingKey {
//        case workEligibilityID = "work_eligibility_id"
//        case workEligibilityName = "work_eligibility_name"
//        case workEligibilityCode = "work_eligibility_code"
//        case sortOrder = "sort_order"
//    }
}

struct SeekingStatus: Decodable {

let seeking_status_id: String?
let seeking_status_name: String?
let seeking_status_code: String?
let sort_order: String?

//    enum CodingKeys: String, CodingKey {
//
//        case seekingStatusID = "seeking_status_id"
//        case seekingStatusName = "seeking_status_name"
//        case seekingStatusCode = "seeking_status_code"
//        case sortOrder = "sort_order"
//    }
}

struct DiscAdjData: Decodable {

let disc_adj_id: String?
let disc_adj_name: String?
let disc_adj_code: String?

//    enum CodingKeys: String, CodingKey {
//
//        case discAdjID = "disc_adj_id"
//        case discAdjName = "disc_adj_name"
//        case discAdjCode = "disc_adj_code"
//    }
}

struct JSOccupation: Decodable {

let occupation_id: String?
let occupation_name: String?
let occupation_code: String?
let job_family_id: String?
let soc_coverage: String?
let description: String?
let education_level_id: String?

//    enum CodingKeys: String, CodingKey {
//        case occupationID = "occupation_id"
//        case occupationName = "occupation_name"
//        case occupationCode = "occupation_code"
//        case jobFamilyID = "job_family_id"
//        case socCoverage = "soc_coverage"
//        case description = "description"
//        case educationLevelID = "education_level_id"
//    }

}

struct JSSearchPlaces: Decodable {

let geo_place_id: String?
let country_code: String?
let geo_place_code: String?
let geo_place_name: String?

//    enum CodingKeys: String, CodingKey {
//
//        case geoPlaceId = "geo_place_id"
//        case countryCode = "country_code"
//        case geoPlaceCode = "geo_place_code"
//        case geoPlaceName = "geo_place_name"
//    }
}

struct JSWorkTypes: Decodable {
let work_type_id: String?
let work_type_name: String?

  //    enum CodingKeys: String, CodingKey {
  //
  //        case workTypeID = "work_type_id"
  //        case workTypeName = "work_type_name"
  //    }
  }
之后,我提出了以下要求:

class JobSeekerJsonRequests: NSObject{

class func jobSeekerRequest(completion: @escaping(_ error: Error?, _ jobSeekerData : JobSeekerDataAPI?) ->Void) {

    let jsonURLString = URLs.jobSeeker

    guard let url = URL(string: jsonURLString) else { return }

    URLSession.shared.dataTask(with: url) { (data, response, error) in

        guard let data = data else { return }

        do {
            let jobSeekerData = try
                JSONDecoder().decode(JobSeekerDataAPI.self, from: data)
            print(jobSeekerData)

        }catch let jsonError {
            print("Error serializing json: ", jsonError)
        }

    }.resume()
}
然后:

 func  userData(){

    JobSeekerJsonRequests.jobSeekerRequest { (error: Error?, jobSeekerData: JobSeekerDataAPI?) in

        if let jobSeekerData = jobSeekerData {

            self.myProfileJobTitle.text = jobSeekerData.most_recent_work_history?.position
            self.menuProfileName.text = jobSeekerData.job_seeker_name
            self.userNameLabel.text = jobSeekerData.first_name
            self.userNameJobPositionLabel.text = jobSeekerData.most_recent_work_history?.position
            self.userLocationLabel.text = jobSeekerData.location_country?.location_country_name
            self.infoAboutLabel.text = jobSeekerData.about
            self.userJobTitleLabel.text = jobSeekerData.most_recent_work_history?.position

        }
    }
我在理解API请求时遇到了一些问题,因为我一直在研究这个问题,但我没有得到任何答案。我在过去5个月自学了swift,我一直在学习这个问题。很抱歉,如果这个问题看起来很愚蠢,但这是像我这样的新手如何陷入困境并需要帮助的问题


谢谢大家!

你们忘了在
枚举编码键:字符串,编码键中为下面添加编码键

let most_recent_work_history: WorkHistory?
let most_recent_education: EducationHistory?

您忘记在
enum CodingKeys:String,CodingKey

let most_recent_work_history: WorkHistory?
let most_recent_education: EducationHistory?

您使用
编码键枚举的方式不正确

如苹果文档中所述:

枚举案例的名称应与您给定的名称匹配 到类型中相应的属性

如果序列化数据格式中使用的键与 从数据类型中选择属性名称,通过 将字符串指定为编码键的原始值类型 枚举。用作每个枚举的原始值的字符串 case是编码和解码期间使用的密钥名

简言之:

  • 案例名称属性名称完全相同
  • 特定大小写的rawValue是要使用的自定义键名
  • 你所做的与需要做的完全相反

    示例:

    struct JobSeekerDataAPI : Decodable
    {
        let job_seeker_id: String?
        let job_seeker_name: String?
        //Other properties
    
        enum CodingKeys: String, CodingKey
        {
            case job_seeker_id = "jobSeekerID" //case name is same as property name
            case job_seeker_name = "jobseekerName"
            //Other cases
        }
    }
    
    有关更多说明,请参阅:

    您需要对所有要进行
    解码的
    结构执行相同的操作

    这肯定会解决你的问题

    Edit:解码json响应数据后得到nil

    如果您得到的是
    nil
    ,请检查您的API在响应中返回了什么。我已经包含了一个代码片段,说明您的API响应应该是什么样子,以及您将获得什么结果:

    class JobSeekerJsonRequests: NSObject
    {
        class func jobSeekerRequest(completion: @escaping(_ error: Error?, _ jobSeekerData : JobSeekerDataAPI?) ->Void)
        {
            let jsonResponseString = "{\"jobSeekerID\":\"1234\",\"jobseekerName\":\"abcd\"}" //Something like this must be the format of your JSON response. Check the key names that are used here.
            guard let data = jsonResponseString.data(using: .utf8) else { 
                return 
            }
    
            do
            {
                let jobSeekerData = try
                JSONDecoder().decode(JobSeekerDataAPI.self, from: data)
                print(jobSeekerData)
            }
            catch let jsonError
            {
                print("Error serializing json: ", jsonError)
            }
        }
    
        func userData()
        {
            //Your code
        }
    }
    
    输出执行
    打印(jobSeekerData)
    语句后,您将得到:

    JobSeekerDataAPI(job_seeker_id: Optional("1234"), job_seeker_name: Optional("abcd"))
    
    只需确保使用了正确的键名,因为您的结果完全取决于它

    注意:首先在
    struct
    中使用较少的属性测试代码,这样调试就容易了。添加更多的代码会使调试问题变得困难。因此,从小的开始,然后最终将其变大


    如果您仍然面临任何问题,请告诉我。

    您使用
    编码键枚举的方式不正确

    如苹果文档中所述:

    枚举案例的名称应与您给定的名称匹配 到类型中相应的属性

    如果序列化数据格式中使用的键与 从数据类型中选择属性名称,通过 将字符串指定为编码键的原始值类型 枚举。用作每个枚举的原始值的字符串 case是编码和解码期间使用的密钥名

    简言之:

  • 案例名称属性名称完全相同
  • 特定大小写的rawValue是要使用的自定义键名
  • 你所做的与需要做的完全相反

    示例:

    struct JobSeekerDataAPI : Decodable
    {
        let job_seeker_id: String?
        let job_seeker_name: String?
        //Other properties
    
        enum CodingKeys: String, CodingKey
        {
            case job_seeker_id = "jobSeekerID" //case name is same as property name
            case job_seeker_name = "jobseekerName"
            //Other cases
        }
    }
    
    有关更多说明,请参阅:

    您需要对所有要进行
    解码的
    结构执行相同的操作

    这肯定会解决你的问题

    Edit:解码json响应数据后得到nil

    如果您得到的是
    nil
    ,请检查您的API在响应中返回了什么。我已经包含了一个代码片段,说明您的API响应应该是什么样子,以及您将获得什么结果:

    class JobSeekerJsonRequests: NSObject
    {
        class func jobSeekerRequest(completion: @escaping(_ error: Error?, _ jobSeekerData : JobSeekerDataAPI?) ->Void)
        {
            let jsonResponseString = "{\"jobSeekerID\":\"1234\",\"jobseekerName\":\"abcd\"}" //Something like this must be the format of your JSON response. Check the key names that are used here.
            guard let data = jsonResponseString.data(using: .utf8) else { 
                return 
            }
    
            do
            {
                let jobSeekerData = try
                JSONDecoder().decode(JobSeekerDataAPI.self, from: data)
                print(jobSeekerData)
            }
            catch let jsonError
            {
                print("Error serializing json: ", jsonError)
            }
        }
    
        func userData()
        {
            //Your code
        }
    }
    
    输出执行
    打印(jobSeekerData)
    语句后,您将得到:

    JobSeekerDataAPI(job_seeker_id: Optional("1234"), job_seeker_name: Optional("abcd"))
    
    只需确保使用了正确的键名,因为您的结果完全取决于它

    注意:首先在
    struct
    中使用较少的属性测试代码,这样调试就容易了。添加更多的代码会使调试问题变得困难。因此,从小的开始,然后最终将其变大


    如果您仍然面临任何问题,请告诉我。

    Ah。注释是因为我试图手动读取。在修复问题之前,请尝试键入较少的代码,否则5个月将是5年,而您仍然是stuckAh。注释是因为我试图手动读取。在修复问题之前,请尝试键入较少的代码或5个月可能是5年,你仍然是stuckI注意到名称与你提到的不一样。我不理解的是,它仍然返回nil,并且在结构中出现相同的错误。我喜欢:结构名称:Decodable{let varName(exatcly等于api键):String()enum CodingKeys:String,CodingKey{case varName=“api键“}}我确实遵循了苹果文档中的步骤。太棒了!我在这里测试一下。谢谢答案:)我注意到这个名字和你提到的不一样。我不理解的是,它仍然返回nil和结构中的相同错误。我喜欢:struct Name:Decodable{let varName(完全等于api键):String()enum CodingKeys:String,CodingKey{case varName=“api key”}}我确实遵循了苹果文档中的步骤。太棒了!我在这里测试一下。谢谢DSure..Up投票并接受答案,如果你让它工作起来….:)