2017-10-04 3 views
1

J'essaie d'extraire des données de swift 4 et je n'ai aucune réponse.Récupération de données à l'aide de swift 4

1- J'ai ce morceau de code et je l'erreur « Type « JobSeekerDataAPI » ne sont pas conformes au protocole « décodables »

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" 
    // } 
    } 

Après cela, je fait la demande:

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() 
} 

Et puis:

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 

     } 
    } 

J'ai un problème pour comprendre les demandes de l'API becuase que je travaille sur ce et je n'ai eu aucune réponse de cela. J'apprends vite par moi-même ces 5 derniers mois et je suis coincé là-dessus. Désolé Si cela ressemble à une question stupide, mais c'est comme ça que les nouveaux mecs m'aiment et ont besoin d'aide.

Merci les gars!

+0

Ah. Le commenté est parce que j'essayais de le faire lire manuellement. – Khromos

+0

Avant de résoudre le problème, essayez de taper moins de code ou les 5 mois seraient 5 ans et vous êtes toujours coincé – zombie

Répondre

0

La façon dont vous utilisez CodingKeys enum est incorrect.

Comme indiqué dans docs d'Apple:

Les noms des cas d'énumération doivent correspondre aux noms que vous avez donné aux propriétés correspondantes dans votre type.

Si les clés utilisées dans le format de données sérialisé ne correspondent pas aux noms de propriétés de votre type de données, fournir des clés alternatives en spécifiant chaîne comme type valeur brute pour les CodingKeys d'énumération . La chaîne que vous utilisez comme valeur brute pour chaque énumération est le nom de clé utilisé lors du codage et du décodage.

En bref:

  1. nom de cas est exactement le même que le nom de la propriété
  2. rawValue d'un cas particulier est le nom clé personnalisée que vous souhaitez utiliser .

Vous faites exactement le contraire de ce qui doit être fait.

Exemple:

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 
    } 
} 

Pour plus de précisions, consultez: https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types

Vous devez faire la même chose pour tous les structs que vous voulez être Decodable.

Cela va sûrement résoudre votre problème.

Edit: Obtenir zéro après le décodage des données de réponse JSON

Je vous obtenez nil, vérifiez que votre API retourne en réponse. J'ai inclus un extrait de code de ce que vous la réponse API devrait ressembler et ce que vous obtiendrez comme résultat:

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 
    } 
} 

sortie vous obtiendrez après print(jobSeekerData) instruction est exécutée:

JobSeekerDataAPI(job_seeker_id: Optional("1234"), job_seeker_name: Optional("abcd")) 

Juste assurez-vous que vous utilisez les noms de clés correctes, puisque votre résultat en dépend complètement.

Remarque: Commencez par tester votre code avec moins de propriétés dans struct afin que le débogage soit facile. L'ajout de plus de code rend difficile le débogage du problème. Alors, commencez avec petit et puis finalement le rendre grand. Informez-moi si vous rencontrez toujours un problème.

+0

J'ai remarqué que le nom n'est pas le même que vous avez mentionné. Ce que je ne comprends pas, c'est parce qu'il retourne toujours zéro et la même erreur dans la structure. J'ai aimé: struct Nom: décodable { laisser nomVar (exatcly égale à la clé api): String() ENUM CodingKeys: String, CodingKey { cas nomVar = "API KEY" } } Je ne suis les étapes de la documentation Apple. – Khromos

+0

J'ai mis à jour ma réponse. – PGDev

+0

Super! Je vais le tester ici. Je vous remercie! : D – Khromos

0

Vous avez oublié d'ajouter CodingKeys ci-dessous pour enum CodingKeys: String, CodingKey

let most_recent_work_history: WorkHistory? 
let most_recent_education: EducationHistory?