我从包含阿拉伯文和英文文本的服务器返回了一个很长的JSON。我可以从同一段JSON创建C#对象,但无法反序列化JSON包含Swift对象。我收到错误无法读取数据,因为它的格式不正确。
我正在尝试通过使用以下代码将其转换为Swift对象:
let decoder = JSONDecoder()
do {
let people = try decoder.decode([DataClass].self, from: response.data!
)
print(people)
}
catch
{
print(error.localizedDescription)
}
}
这里是数据类:
import Foundation
// MARK: - MainData
struct MainData: Codable {
let data: DataClass
let error: Int
let msg: String
}
// MARK: - DataClass
struct DataClass: Codable {
let subCategories: [SubCategory]
let mainCategories: [MainCategory]
let trainers: [Trainer]
let appVideo: String
let videoDerivation: VideoDerivation
enum CodingKeys: String, CodingKey {
case subCategories = "sub_categories"
case mainCategories = "main_categories"
case trainers
case appVideo = "app_video"
case videoDerivation = "video_derivation"
}
}
// MARK: - MainCategory
struct MainCategory: Codable {
let id: Int
let name: String
let nameEn: NameEn
let arrange, status, addedBy: Int
let image, video, faIcon, color: String
let cssClass, unicode, seo: String
let videoDerivation: VideoDerivation
let courses: [Course]
let subCategories: [SubCategory]
enum CodingKeys: String, CodingKey {
case id, name
case nameEn = "name_en"
case arrange, status
case addedBy = "added_by"
case image, video
case faIcon = "fa_icon"
case color
case cssClass = "css_class"
case unicode, seo
case videoDerivation = "video_derivation"
case courses
case subCategories = "sub_categories"
}
}
// MARK: - Course
struct Course: Codable {
let id: Int
let name: String
let code: Code
let template: NameEn
let createDate, updated: String
let status, listed: Int
let lastApproved: String
let courseCategory: Int
let price, oldPrice: Double
let textPrice: TextPrice
let coverImage, mobileCoverImage: String
let hours: Int
let duration: String
let trainer, repeatCount, level, passMark: Int
let isOrdering: Int
let youtube: JSONNull?
let courseDescription: String
let lang: Lang
let video: String
let isStar, templateID, showSummary: Int
let summaryVideo: String
let ranking: Int
let seo: String
let itemsCount, isBasket, isInterested, isRegister: Int
let lessonCount, examCount: Int
let trainerName: String
let studentsCount: Int
let levelName: LevelName
let levelNameEn: LevelNameEn
let stdRatingCount: Int
let videoDerivation: VideoDerivation
let averageRate: Double
enum CodingKeys: String, CodingKey {
case id, name, code, template
case createDate = "create_date"
case updated, status, listed
case lastApproved = "last_approved"
case courseCategory = "course_category"
case price
case oldPrice = "old_price"
case textPrice = "text_price"
case coverImage = "cover_image"
case mobileCoverImage = "mobile_cover_image"
case hours, duration, trainer
case repeatCount = "repeat_count"
case level
case passMark = "pass_mark"
case isOrdering = "is_ordering"
case youtube
case courseDescription = "description"
case lang, video
case isStar = "is_star"
case templateID = "template_id"
case showSummary = "show_summary"
case summaryVideo = "summary_video"
case ranking, seo
case itemsCount = "items_count"
case isBasket = "is_basket"
case isInterested = "is_interested"
case isRegister = "is_register"
case lessonCount = "lesson_count"
case examCount = "exam_count"
case trainerName = "trainer_name"
case studentsCount = "students_count"
case levelName = "level_name"
case levelNameEn = "level_name_en"
case stdRatingCount = "std_rating_count"
case videoDerivation = "video_derivation"
case averageRate = "average_rate"
}
}
enum Code: Codable {
case integer(Int)
case string(String)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let x = try? container.decode(Int.self) {
self = .integer(x)
return
}
if let x = try? container.decode(String.self) {
self = .string(x)
return
}
throw DecodingError.typeMismatch(Code.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for Code"))
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .integer(let x):
try container.encode(x)
case .string(let x):
try container.encode(x)
}
}
}
enum Lang: String, Codable {
case ar = "ar"
case en = "en"
case langAr = "Ar"
}
enum LevelName: String, Codable {
case مبتدئ = "مبتدئ"
case متوسط = "متوسط"
}
enum LevelNameEn: String, Codable {
case junior = "Junior"
case medium = "Medium"
}
enum NameEn: String, Codable {
case interactiveCourses = "Interactive Courses"
case masterClass = "Master Class"
case worldwideDubbedCourses = "Worldwide Dubbed Courses"
}
enum TextPrice: String, Codable {
case empty = ""
case خصم = "خصم"
}
// MARK: - VideoDerivation
struct VideoDerivation: Codable {
let duration: Int
let gif, thump, q240, q360: String
let q480, q720, q1080: String?
let dubbings: Dubbings
let subtitles: Subtitles
enum CodingKeys: String, CodingKey {
case duration, gif, thump
case q240 = "q_240"
case q360 = "q_360"
case q480 = "q_480"
case q720 = "q_720"
case q1080 = "q_1080"
case dubbings, subtitles
}
}
// MARK: - Dubbings
struct Dubbings: Codable {
let ar, en, tu, or: JSONNull?
let fr, arVideoDerivation, enVideoDerivation, tuVideoDerivation: JSONNull?
let orVideoDerivation, frVideoDerivation: JSONNull?
enum CodingKeys: String, CodingKey {
case ar, en, tu, or, fr
case arVideoDerivation = "ar_video_derivation"
case enVideoDerivation = "en_video_derivation"
case tuVideoDerivation = "tu_video_derivation"
case orVideoDerivation = "or_video_derivation"
case frVideoDerivation = "fr_video_derivation"
}
}
// MARK: - Subtitles
struct Subtitles: Codable {
let ar, en, tu, or: JSONNull?
let fr: JSONNull?
}
// MARK: - SubCategory
struct SubCategory: Codable {
let id: Int
let name, nameEn: String
let arrange, status: Int
let addedBy: Int?
let image: String?
let faIcon, unicode, seo: String
enum CodingKeys: String, CodingKey {
case id, name
case nameEn = "name_en"
case arrange, status
case addedBy = "added_by"
case image
case faIcon = "fa_icon"
case unicode, seo
}
}
// MARK: - Trainer
struct Trainer: Codable {
let id: Int
let name: String
let lang: Lang
let email: String
let gender: Int
let nationality: Int?
let qualifications: JSONNull?
let residence: Int?
let foundation: JSONNull?
let trainerDescription: String?
let image: String
let family: Int
let phone: Phone?
let experience: JSONNull?
enum CodingKeys: String, CodingKey {
case id, name, lang, email, gender, nationality, qualifications, residence, foundation
case trainerDescription = "description"
case image, family, phone, experience
}
}
enum Phone: String, Codable {
case empty = "."
case the00971551532040 = "00971551532040"
case the97144202912 = "+9714 420 2912"
}
// 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 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()
}
}
下面是一些JSON:
{
"data": {
"sub_categories": [
{
"id": 104,
"name": "إعلام",
"name_en": "Media",
"arrange": 5,
"status": 1,
"added_by": null,
"image": "0A5F2D1D-1979-4672-ACC2-477A0E2627D0.png",
"fa_icon": "fal fa-camcorder",
"unicode": "f8a8",
"seo": ""
},
{
"id": 106,
"name": "القيادة",
"name_en": "Leadership",
"arrange": 7,
"status": 1,
"added_by": null,
"image": "09FB9067-D2ED-4C36-B01A-67E10B5370D2.png",
"fa_icon": "fal fa-users",
"unicode": "f0c0",
"seo": ""
},
{
"id": 108,
"name": "إدارة الأعمال",
"name_en": "Business Management",
"arrange": 9,
"status": 1,
"added_by": null,
"image": "42EA485A-1438-4FF4-BDD5-220E71149260.png",
"fa_icon": "fal fa-user-tie",
"unicode": "f508",
"seo": ""
},
{
"id": 114,
"name": "الإبداع والابتكار",
"name_en": "Creativity and Innovation",
"arrange": 15,
"status": 1,
"added_by": 3,
"image": null,
"fa_icon": "fal fa-atom",
"unicode": "f5d2",
"seo": ""
}
],
"main_categories": [
{
"id": 115,
"name": "ماستر كلاس",
"name_en": "Master Class",
"arrange": 1,
"status": 1,
"added_by": 3,
"image": "25A595C3-8638-4CC2-872A-09C064468986.png",
"video": "1588683016371-1f5280bac-ddb1-4d3b-bf3f-d700c267f02a.mp4",
"fa_icon": "fal fa-object-ungroup",
"color": "#00d6ff",
"css_class": "MasterClass",
"unicode": "f51c",
"seo": "{\"description\":\"master class\"}",
"video_derivation": {
"duration": 103,
"gif": "1588683016371-1f5280bac-ddb1-4d3b-bf3f-d700c267f02a.gif",
"thump": "1588683016371-1f5280bac-ddb1-4d3b-bf3f-d700c267f02a.jpg",
"q_240": "1588683016371-1f5280bac-ddb1-4d3b-bf3f-d700c267f02a_240.mp4",
"q_360": "1588683016371-1f5280bac-ddb1-4d3b-bf3f-d700c267f02a_360.mp4",
"q_480": "1588683016371-1f5280bac-ddb1-4d3b-bf3f-d700c267f02a_480.mp4",
"dubbings": {
"ar": null,
"en": null,
"tu": null,
"or": null,
"fr": null,
"ar_video_derivation": null,
"en_video_derivation": null,
"tu_video_derivation": null,
"or_video_derivation": null,
"fr_video_derivation": null
},
"subtitles": {
"ar": null,
"en": null,
"tu": null,
"or": null,
"fr": null
}
},
"courses": [
{
"id": 151,
"name": "ماستر كلاس إعداد الممثل",
"code": "actor01",
"template": "Master Class",
"create_date": "2020-03-21 08:13:35",
"updated": "2020-05-11 13:37:48",
"status": 1,
"listed": 1,
"last_approved": "69d9fbbe4e8ad49bfb99147c84e13cb9",
"course_category": 114,
"price": 199.99,
"old_price": 399.99,
"text_price": "",
"cover_image": "646ACE6A-08E7-4D4D-9CBA-531816AFCF1D.jpg",
"mobile_cover_image": "D16F41B3-C85D-46A9-B4BB-F86AE2EE1824.jpg",
"hours": 10,
"duration": "2:0",
"trainer": 332,
"repeat_count": 0,
"level": 1,
"pass_mark": 0,
"is_ordering": 1,
"youtube": null,
"description": "التحديات في مهنة التمثيل كثيرة ومتنوعة يحتاج خوضها إلى مهارة مصقولة وقدرة كبيرة على تأدية مختلف الأدوار في مختلف الظروف وبالقدر الذي يكون الممثل على معرفة بما بحتاجه من أدوات ومدركاً لمختلف التقنيات التي تتطلبها مهنة التمثيل بقدر ما يحظى الحصول على شخصية مميزة قادرة على القيام بأعمال التمثيل مهما كانت مستوياتها ودرجة صعوبتها.منصة كن المنصة الرائدة في العالم العربي في تقديم الدورات الأونلاين تقدم دورة ماستر كلاس إعداد الممثل يقدمها النجم جمال سليمان بما يحمله من خبرة طويلة في مجال الفن وتجربته الرائدة في في أكاديمة الفنون في دمشق والتي درب من خلالها العديد من الأسماء التي برزت في سماء الفن، والتي ستتيح لك الفرصة لإبراز شخصيتك التمثيلية واحتراف مهنة التمثيل من خلال ما تقدمه من إرشادات وتطبيقات حيث ستتعرف على الأفعال وأقسامها وأهميتها بالنسبة للممثل وكيف يطبقها وستتعرف على منهج تكوين الممثل وعلى الشخصية وكيف يتعايش معها الممثل.وتحديات المكان وكيفة التصرف بمختلف الظروف التي يفرضها.وستتعرف على تقنية التواصل البصري ووضعية الجسد والمعاني التي يمكن أن يقدمها استخدام الجسد بوضع معين إضافة إلى التعبير اللفظي والجسدي.وستتعرف على المشكلة في عالم التمثيل وماهية التصرف لمواجهة هذه المشكلة وستتعرف على التركيز وكيف تنمي قدرتك على التركيز من خلال التمرين وكيف تسخر قوة خيالك للتعايش مع الشخصية. والكثير من المعلومات والتقنيات التي تقدمها هذه الدورة من خلال جلسات تدريبية لمختلف المشاهد والأدوار.\nكن نجماً مع كن أكاديمي",
"lang": "ar",
"video": "1587921590843-0243f8871-7b8d-4142-945d-7f06449fe159.mp4",
"is_star": 0,
"template_id": 115,
"show_summary": 0,
"summary_video": "1584896037975-0c0bf4791-846f-48df-b33a-0f02903aabe9.mp4",
"ranking": 5,
"seo": "{\"title\":\"ماستر كلاس إعداد ممثل اونلاين ، مع جمال سليمان على أكاديمية كُن\",\"description\":\"دورة ماستر كلاس إعداد الممثل يقدمها النجم جمال على منصة أكاديمية كُن سليمان فرصة لاحتراف مهنة التمثيل وإبراز شخصيتك التمثيلية،\\n تعرف على منهج تكوين الممثل وتأدية الشخصية التي يتعايش معها الممثل، قاوم تحديات المكان وطبق تقنية التواصل البصري ووضعية الجسد،ا\\nلتعبير اللفظي ، التعبير الجسدي استخدم التركيز في مواجهة المشكلة، وسخر قوة الخيال لتأدية الدور، فرصتك لتكن ممثلا مع جمال سليمان. نجم مسلسل: حرملك، حرملك ٢، التغريبة الفلسطينية، مسلسل صلاح الدين، مسلسل صفر قريش\",\"keywords\":\"التمثيل ،السايكولوجيا ،الفعل المقصود، الفعل غير المقصود،\\nكتاب إعداد الممثل ،منهج ، تكوين الممثل، أنواع الأفعال، التعايش، الشخصية، تطوير المشهد،العملية السيكولوجية ،الذاكرة الانفعالية،الأفعال اللفظية، تأثير المكان ،الممثل ، مراعاة المجتمع، التعبير الجسدي\\nالتركيز ،الحركة، قوة الخيال، الأفعال النفسية والحركية، دوائر التركيز ،مهمة الممثل، Straight Acting، Character Acting \\nتحضير النص ،الحفظ ، اللغة ، دورات اونلاين ، أكاديمية كُن ، كُن أكاديمي، online courses، حرملك، حرملك ٢، التغريبة الفلسطينية، مسلسل صلاح الدين، مسلسل صفر قريش ، جمال سليمان ، تدريب عن بعد\"}",
"items_count": 4,
"is_basket": 0,
"is_interested": 0,
"is_register": 0,
"lesson_count": 4,
"exam_count": 0,
"trainer_name": "جمال سليمان",
"students_count": 13,
"level_name": "مبتدئ",
"level_name_en": "Junior",
"std_rating_count": 1,
"video_derivation": {
"duration": 29,
"gif": "1587921590843-0243f8871-7b8d-4142-945d-7f06449fe159.gif",
"thump": "1587921590843-0243f8871-7b8d-4142-945d-7f06449fe159.jpg",
"q_240": "1587921590843-0243f8871-7b8d-4142-945d-7f06449fe159_240.mp4",
"q_360": "1587921590843-0243f8871-7b8d-4142-945d-7f06449fe159_360.mp4",
"q_480": "1587921590843-0243f8871-7b8d-4142-945d-7f06449fe159_480.mp4",
"q_720": "1587921590843-0243f8871-7b8d-4142-945d-7f06449fe159_720.mp4",
"q_1080": "1587921590843-0243f8871-7b8d-4142-945d-7f06449fe159_1080.mp4",
"dubbings": {
"ar": null,
"en": null,
"tu": null,
"or": null,
"fr": null,
"ar_video_derivation": null,
"en_video_derivation": null,
"tu_video_derivation": null,
"or_video_derivation": null,
"fr_video_derivation": null
},
"subtitles": {
"ar": null,
"en": null,
"tu": null,
"or": null,
"fr": null
}
},
"average_rate": 3
},
{
"id": 179,
"name": "ماستر كلاس كتابة البرامج الساخرة",
"code": "bassemMa",
"template": "Master Class",
"create_date": "2020-03-31 02:10:47",
"updated": "2020-05-11 12:02:57",
"status": 1,
"listed": 1,
"last_approved": "5872ea6dbf8819aae85ccf0d236e30e1",
"course_category": 104,
"price": 199.99,
"old_price": 399.99,
"text_price": "",
"cover_image": "7B99C4A6-1E45-4D95-BF2B-E1BCEFFFD579.jpg",
"mobile_cover_image": "A0CBCE37-6026-4B8A-8DA4-2E1225CCF513.jpg",
"hours": 10,
"duration": "2:40",
"trainer": 376,
"repeat_count": 0,
"level": 1,
"pass_mark": 0,
"is_ordering": 1,
"youtube": null,
"description": "مما لاشك فيه أن البرامج الساخرة فتحت آفاقا جديدة في عالمنا وإعلامنا العربي في السنوات الأخيرة وأصبحت محط اهتمام ومتابعة الرأي العام الذي أقبل بشغف على هذا الوافد الجديد إلى الساحة الإعلامية. ومما لاشك فيه أيضا أن هذا النوع من البرامج وفي ظل المنافسة الحثيثة مع برامج مشابهة أو برامج أخرى ومن أجل الاستمرار والتميز أيضا. لابد من إعداد جيد وأسس متينة يبنى عليها.\nمنصة كن المنصة الرائدة في العالم العربي في تقديم الدورات الأونلاين تقدم بأسلوب تفاعلي مميز ماستر كلاس كتابة البرامج الساخرة مع الدكتور باسم يوسف الاسم الأبرز في عالمنا العربي في مجال تقديم البرامج الساخرة والذي يقدم خلاصة تجربته في هذا المجال من بداية احترافه هذا الفن مرورا بمختلف المراحل وما تحمله من تحديات وصولا إلى مراحل الشهرة وما يترتب عليها من تبعات ، تجربة فريدة ستتيح لك الفرصة لتحظى بالدعم الكافي لتقديم برنامج ساخر احترافي من البداية إلى النهاية حيث ستحظى بمعرفة شاملة لأهم الأسس التي تقوم عليها هذه البرامج وشروط الكتابة لها وأهيمة خلق محتوى جيد وكيف تبني الخريطة العقلية الخاصة بك وماهي الوصايا العشرة في الكوميديا ومواصفات وإعداد المقال الساخر وحدود الكتابة في الكوميديا وكيف تتمكن من تحويل موقف حزين إلى كوميديا .والكثير الكثير من الأشياء في هذا المجال الواسع ..\nكن مختلفا مع كن أكاديمي",
"lang": "ar",
"video": "1586005691291-1b268e4a4-bc7f-4056-aa12-c84358cfd2e4.mp4",
"is_star": 0,
"template_id": 115,
"show_summary": 0,
"summary_video": "",
"ranking": 5,
"seo": "{\"title\":\"ماستر كلاس كتابة البرامج الساخرة اونلاين\\nمع باسم يوسف Bassem Youssef ، أكاديمية كُن\",\"description\":\"ماستر كلاس كتابة البرامج الساخرة مع باسم يوسف \\n ماستر كلاس كتابة البرامج الساخرة تجربة فريدة ستتيح لك الفرصة لتحظى بالدعم الكافي لتقديم برنامج ساخر احترافي من \\nالبداية إلى النهاية حيث ستحظى في ماستر كلاس كتابة البرامج الساخرة على أكاديمية كُن بمعرفة شاملة لأهم الأسس التي تقوم عليها هذه \\nالبرامج وشروط الكتابة لها وأهيمة خلق محتوى جيد وكيف تبني الخريطة العقلية الخاصة بك وماهي الوصايا العشرة في الكوميديا \\nومواصفات وإعداد المقال الساخر وحدود الكتابة في الكوميديا وكيف تتمكن من تحويل موقف حزين إلى كوميديا .والكثير الكثير من \\nالأشياء في هذا المجال الواسع تجدها في ماستر كلاس كتابة البرامج الساخرة على منصة كُن..\",\"keywords\":\"الكتابة، الساخرة ، الكوميديا ،الخريطة العقلية،\\nالوصايا العشرة،المقال الساخر،الموضوع- تحضير الجمهور،الشخصية،الموقف. Online courses, دورات اونلاين، أاكاديمية كن، كن اكاديمي ،اسم يوسف، Bassem Youssef\",\"keykeywords\":\" \"}",
"items_count": 3,
"is_basket": 0,
"is_interested": 0,
"is_register": 0,
"lesson_count": 3,
"exam_count": 0,
"trainer_name": "باسم يوسف",
"students_count": 7,
"level_name": "مبتدئ",
"level_name_en": "Junior",
"std_rating_count": 0,
"video_derivation": {
"duration": 82,
"gif": "1586005691291-1b268e4a4-bc7f-4056-aa12-c84358cfd2e4.gif",
"thump": "1586005691291-1b268e4a4-bc7f-4056-aa12-c84358cfd2e4.jpg",
"q_240": "1586005691291-1b268e4a4-bc7f-4056-aa12-c84358cfd2e4_240.mp4",
"q_360": "1586005691291-1b268e4a4-bc7f-4056-aa12-c84358cfd2e4_360.mp4",
"q_480": "1586005691291-1b268e4a4-bc7f-4056-aa12-c84358cfd2e4_480.mp4",
"q_720": "1586005691291-1b268e4a4-bc7f-4056-aa12-c84358cfd2e4_720.mp4",
"dubbings": {
"ar": null,
"en": null,
"tu": null,
"or": null,
"fr": null,
"ar_video_derivation": null,
"en_video_derivation": null,
"tu_video_derivation": null,
"or_video_derivation": null,
"fr_video_derivation": null
},
"subtitles": {
"ar": null,
"en": null,
"tu": null,
"or": null,
"fr": null
}
},
"average_rate": 3
},
{
"id": 159,
"name": "ماستر كلاس تقديم البرامج المنوعة",
"code": "raya12",
"template": "Master Class",
"create_date": "2020-03-24 11:50:37",
"updated": "2020-05-11 12:27:56",
"status": 3,
"listed": 1,
"last_approved": "65e2b7045170afd86891fd733348776e",
"course_category": 104,
"price": 199.99,
"old_price": 399.99,
"text_price": "",
"cover_image": "DD3FF14C-9B07-405F-A4B9-F61F23E22BFA.jpg",
"mobile_cover_image": "84B5DC6F-8381-45BE-BCA4-AA4532869D32.jpg",
我在上面的代码中有问题。我根据模型类将let people = try decoder.decode([DataClass].self, from: response.data!
更改为let people = try decoder.decode(DataClass.self, from: response.data!
,并且工作正常。