Swift 4 enum codable - ios

I parse json data from an api. My struct looks like this:
struct ServiceUnit: Codable {
let description,id: String?
let group, groupDescription:String?
let name: String?
var value: MyValue?
enum CodingKeys: String, CodingKey {
case description = "Description"
case group = "Group"
case groupDescription = "GroupDescription"
case id = "Id"
case name = "Name"
case value = "Value"
}
}
enum MyValue: Codable {
case string(String)
case innerItem(InnerItem)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let string = try? container.decode(String.self) {
self = .string(string)
return
}
if let innerItem = try? container.decode(InnerItem.self) {
self = .innerItem(innerItem)
return
}
throw DecodingError.typeMismatch(MyValue.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for MyValue"))
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .string(let x):
try container.encode(x)
case .innerItem(let x):
try container.encode(x)
}
}
}
struct InnerItem: Codable {
let type, id, name: String
enum CodingKeys: String, CodingKey {
case type = "__type"
case id = "Id"
case name = "Name"
}
}
and the json data looks like this:
[
{
"Description": null,
"Group": "Beskrivning av enheten",
"GroupDescription": null,
"Id": "Description",
"Name": "Mer om enheten",
"Value": "Det finns möjlighet till parkering på gatorna runt om, men det är kantstenar och ganska branta backar för att komma upp till lekplatsen.\r\n\r\nUtanför själva lekplatsen finns en gungställning med en plan omväg in. Alla lekredskap står i sandytor, det finns många kanter. Runt hela lekplatsen går ett staket med öppningar i olika riktningar."
},
{
"Description": null,
"Group": "Bilder och film",
"GroupDescription": null,
"Id": "Image",
"Name": "Huvudbild",
"Value": {
"__type": "FileInfo",
"Id": "8871b3b1-14f4-4054-8728-636d9da21ace",
"Name": "ullerudsbacken.jpg"
}
}
]
When the data is loaded, I filter it to get only the result where id = description, and I retried the value of value like this:
let su = serviceUnit.filter{$0.id == "ShortDescription"}
let description = su[0].value
Then, my problem is that I get this error from Xcode when I want to use the value to fill a label:
Cannot assign value of type MyValue? to type String?
If I print su, I get this:
[stockholmsParks.(unknown context at 0x105c3d098).ServiceUnit(description: nil, id: Optional("ShortDescription"), group: Optional("Beskrivning av enheten"), groupDescription: nil, name: Optional("Introduktion"), value: Optional(stockholmsParks.(unknown context at 0x105c3d0e8).MyValue.string("Regnbågen på höjden. Den här lekplatsen ligger på ett högt berg i naturmark, omgiven av höghus. Det finns en instängslad bollplan och olika lekredskap står placerade efter varandra. Utanför själva lekplatsen finns en gungställning. Det finns också bänkbord i sol och grillplats.")))]
What am I missing???

You need to get the associated value from your enum.
let value = su[0].value
switch value {
case .string(let description)?:
yourLabel.text = description
default:
break
}

Related

Fatal error: Failed to decode productsTest.json from app bundle

It stated "Build Succeeded".
However, on the canvas, it stated "Could not view this file - crashed". And the app crashed as well.
Problem from JSONDecoder.swift
Thread 1: Fatal error: Failed to decode productsTest.json from app bundle.
Content View (file name: ContentView.swift)
struct ContentView: View {
let menu = Bundle.main.decode([ProductSection].self, from: "productsTest.json")
var body: some View {
NavigationView{
VStack{
List {
ForEach(menu) { section in
Text(section.category)
}
}
}.navigationTitle("Products")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Codeable extension to decode json (file name: JSONDecoder.swift)
extension Bundle {
func decode<x: Decodable>(_ type: x.Type, from filename: String) -> x {
guard let json = url(forResource: filename, withExtension: nil) else {
fatalError("Failed to locate \(filename) in app bundle.")
}
guard let jsonData = try? Data(contentsOf: json) else {
fatalError("Failed to load \(filename) from app bundle.")
}
let decoder = JSONDecoder()
guard let result = try? decoder.decode(x.self, from: jsonData) else {
fatalError("Failed to decode \(filename) from app bundle.")
}
return result
}
}
Swift file to guide reading JSON (file name: ProductsTest.swift)
struct ProductSection: Codable, Identifiable {
var id: UUID
var category: String
var items: [ItemList]
}
struct ItemList: Codable, Equatable, Identifiable {
var id: UUID
var status: String
var quantity: Int
var name: String
var price: Double
var image: String
var moreImage: [String]
var productCode: String
var UPCCode: String
var servingSize: String
var servingPerContainer: String
var amountPerServing: [String]
var percentageDailyValue: String
var description: [String]
var suggestedUse: String
var otherIngredients: [String]
var warning: [String]
#if DEBUG
static let example = ItemList(
id: UUID(),
status: "in-stock",
quantity: 10,
name: "Doctor's Best, Vitamin D3, 25 mcg (1,000 IU), 180 Softgels",
price: 4.98,
image: "753950002098.front",
moreImage: ["753950002098.back"],
productCode: "DRB-00209",
UPCCode: "753950002098",
servingSize: "1 Softgel",
servingPerContainer: "180 servings",
amountPerServing: ["Vitamin D3: 25 mcg (1000 IU)"],
percentageDailyValue: "125%",
description: ["Empty, Empty"],
suggestedUse: "Adult Use: Take 1 softgel daily with food, or as recommended by a nutritionally-informed physician.",
otherIngredients: ["Extra virgin olive oil; softgel capsule (bovine gelatin; glycerin; purified water)"],
warning: ["Store in a cool dry place."]
)
#endif
}
JSON file (validated) (file name: productsTest.json)
[
{
"id": "EF1CC5BB-4785-4D8E-AB98-5FA4E00B6A66",
"category": "SUPPLEMENT",
"items": [
{
"id": "EDCD038C-036F-4C40-826F-61C88CD84DDD",
"status" : "in-stock",
"quantity" : 10,
"name": "Doctor's Best, Vitamin D3, 25 mcg (1,000 IU), 180 Softgels",
"price" : 4.98,
"image" : "753950002098.front",
"moreImage": ["753950002098.back"],
"productCode" : "DRB-00209",
"UPCCode" : "753950002098",
"servingSize" : "1 Softgel",
"servingPerContainer" : "180 servings",
"amountPerServing" : ["Vitamin D3: 25 mcg (1000 IU)"],
"percentageDailyValue" : "125%",
"description" : ["Empty, Empty"],
"suggestedUse" : "Adult Use: Take 1 softgel daily with food, or as recommended by a nutritionally-informed physician.",
"otherIngredients" : ["Extra virgin olive oil; softgel capsule (bovine gelatin; glycerin; purified water)"],
"warning" : ["Store in a cool dry place."]
},
{
"id": "36A7CC40-18C1-48E5-BCD8-3B42D43BEAEE",
"status" : "in-stock",
"quantity" : 5,
"name": "Now Foods, High Potency Vitamin D-3, 50 mcg (2000 IU), 120 Softgels",
"price" : 4.26,
"image" : "733739003676.front",
"moreImage": ["733739003676.back"],
"productCode" : "NOW-00367",
"UPCCode" : "753950002098",
"servingSize" : "1 Softgel",
"servingPerContainer" : "120 servings",
"amountPerServing" : ["Vitamin D4: 50 mcg (2000 IU)"],
"percentageDailyValue" : "250%",
"description" : ["Empty, Empty"],
"suggestedUse" : "Take 1 softgel daily with a meal.",
"otherIngredients" : ["Extra virgin olive oil and softgel capsule (bovine gelatin; water; glycerin)., Not manufactured with yeast; wheat; gluten; soy; corn; milk; egg; fish or shellfish ingredients. Produced in a GMP facility that processes other ingredients containing these allergens."],
"warning" : ["For adults only, Consult physician if pregnant/nursing; taking medication; or have a medical condition. Keep out of reach of children, Natural color variation may occur in this product, Store in a cool, dry place after opening."]
}
]
},
{
"id": "3D97FAB4-50AC-40FC-9BF0-3F46BB6A92F5",
"category": "ELECTRONICS",
"items": [
{
"id": "empty",
"status" : "empty",
"quantity" : 0,
"name": "empty",
"price" : 0.00,
"image" : "empty",
"moreImage": ["empty"],
"productCode" : "empty",
"UPCCode" : "empty",
"servingSize" : "empty",
"servingPerContainer" : "empty",
"amountPerServing" : ["empty"],
"percentageDailyValue" : "empty",
"description" : ["empty"],
"suggestedUse" : "empty",
"otherIngredients" : ["empty"],
"warning" : ["empty"]
}
]
}
]
Crash Console Report
...
Exception Type: EXC_BAD_INSTRUCTION (SIGILL)
Exception Codes: 0x0000000000000001, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Signal: Illegal instruction: 4
Termination Reason: Namespace SIGNAL, Code 0x4
Terminating Process: exc handler [4837]
Application Specific Information:
JOCO/DecodeJson.swift:23: Fatal error: Failed to decode products.json from app bundle.
...
You should pretty much never use try? - It simply discards errors. You should, at the very least, catch and print the error if you can't handle it in a better way; Then at least you know what is going wrong.
Changing your JSON decoding to:
extension Bundle {
func decode<x: Decodable>(_ type: x.Type, from filename: String) -> x? {
guard let json = url(forResource: filename, withExtension: nil) else {
print("Failed to locate \(filename) in app bundle.")
return nil
}
do {
let jsonData = try Data(contentsOf: json)
let decoder = JSONDecoder()
let result = try decoder.decode(x.self, from: jsonData)
return result
} catch {
print("Failed to load and decode JSON \(error)")
return nil
}
}
}
gives you the error
Failed to load and decode JSON dataCorrupted(Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 1", intValue: 1), CodingKeys(stringValue: "items", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "id", intValue: nil)], debugDescription: "Attempted to decode UUID from invalid UUID string.", underlyingError: nil))
which points you straight to the problem - The first item (Index 0) in the second element of the outer array (Index 1) has an invalid id - And sure enough, it has an id of "empty" - Which cannot be converted to a UUID. So, either fix the data or perhaps change the type of id to String.

How do I convert raw data of type 'Any' into a concrete type?

Scenario: I've created a data-source engine that returns data of
various formats (depending on context) using Any as the return
type.
Here's the subscriber from remoteDataPublisher:
remoteDataPublisher
.eraseToAnyPublisher()
.sink(receiveCompletion: { completion in
switch completion {
case .finished:
print("Publisher Finished")
case let .failure(anError):
Swift.print("\nReceived error: ", anError)
}
}, receiveValue: { [self] someValue in
DataSource.shared.rawData = someValue
}).store(in: &cancellables)
Here's the receiving DataSource:
final class DataSource {
...
static let shared = DataSource()
...
var rawData: Any?
...
}
Being that the data comes from many sources, depending of the context, the type is Any.
In this case, the data type is:
struct AppleSubRegions: Codable {
let country, subregion: String
let data: [AppleDatum]
}
(lldb) po DataSource.shared.rawData!
▿ AppleSubRegions
- country : "Canada"
▿ subregions : 20 elements
- 0 : "Alberta"
- 1 : "Calgary"
- 2 : "Edmonton"
- 3 : "British Columbia"
- 4 : "Vancouver"
- 5 : "Manitoba"
- 6 : "New Brunswick"
- 7 : "Newfoundland and Labrador"
- 8 : "Northwest Territories"
- 9 : "Halifax"
- 10 : "Nova Scotia"
- 11 : "Ontario"
- 12 : "Ottawa"
- 13 : "Toronto"
- 14 : "Prince Edward Island"
- 15 : "Montreal"
- 16 : "Quebec"
- 17 : "Saskatchewan"
- 18 : "All"
- 19 : "Yukon Territory"
Goal: I want convert this 'Any' data type back into a the usable 'AppleSubRegions' type; ditto with other respective types {e.g., '[String]', etc.); depending on the context,
Here's the raw output on console:
{"country":"Canada","subregions":["Alberta","Calgary","Edmonton","British Columbia","Vancouver","Manitoba","New Brunswick","Newfoundland and Labrador","Northwest Territories","Halifax","Nova Scotia","Ontario","Ottawa","Toronto","Prince Edward Island","Montreal","Quebec","Saskatchewan","All","Yukon Territory"]}
(lldb) po type(of: DataSource.shared.rawData)
Swift.Optional<Any>
I've tried to cast the 'Any' back into the Struct and failed:
(lldb) po DataSource.shared.rawData as AppleSubRegions
Fatal error: Unexpectedly found nil while unwrapping an Optional value: file __lldb_expr_50/<EXPR>, line 6
2020-11-05 12:21:44.108408-0800 Covid19[68513:2486483] Fatal error: Unexpectedly found nil while unwrapping an Optional value: file __lldb_expr_50/<EXPR>, line 6
Question: How can I get the iOS objects back in their native types?
Per feedback - Using Generics vs datatype 'Any':
protocol GenericProtocol {
associatedtype T : Decodable
var rawData: T {get set}
}
class SomeClass<T: Decodable> {
var isHistorical: Bool = false
var continent: String?
var countryName: String?
var subRegion: String?
var rawData: T?
}
// =======================================================
struct AppleSubRegions: Codable {
let country, subregion: String
let data: [AppleDatum]
}
struct AppleDatum: Codable {
let subRegion, subregionAndCity, geoType, date: String
let driving, transit, walking: Int
enum CodingKeys: String, CodingKey {
case subRegion = "sub-region"
case subregionAndCity = "subregion_and_city"
case geoType = "geo_type"
case date, driving, transit, walking
}
}
// ---------------------------------------------------------------------------
// 1) String ----
let stringClass = SomeClass<String>()
stringClass.rawData = "Ric"
print("String Type: ", stringClass.rawData! as String)
// 2) Int ----
let intClass = SomeClass<Int>()
intClass.rawData = 123
print("Int Type: ", intClass.rawData! as Int)
// 3) Apple SubRegions ---
let appleDatum = AppleDatum(subRegion: "Ontario", subregionAndCity: "Ontario", geoType: "sub-region", date: "2020-11-05", driving: 1, transit: 2, walking: 3)
let appleSubRegion = AppleSubRegions(country: "Canada", subregion: "Ontario", data: [appleDatum])
let appleClass = SomeClass<AppleSubRegions>()
appleClass.rawData = appleSubRegion
print("Apple SubRegion Type: ", appleClass.rawData!)
let appleData = appleClass.rawData
let country = appleData?.country
print("Country: \(country!)")
print("The End")
Output:
String Type: Ric
Int Type: 123
Apple SubRegion Type: AppleSubRegions(country: "Canada", subregion: "Ontario", data: [__lldb_expr_25.AppleDatum(subRegion: "Ontario", subregionAndCity: "Ontario", geoType: "sub-region", date: "2020-11-05", driving: 1, transit: 2, walking: 3)])
Country: Canada
The End

Create a comparison in an array

I working on an app to show some information about cities
In an array I have two parameters
1- languages (I don't know how many there are)
2- the number of people that speak on that language
I get this data from an server
here is this two paramter in JSon
"language": "French",
"number": "12321",
these data among other data is saved in an array
I Just want to get the most used language with the pecentage
for example French with 35%
how can I do it in swift?
Your help will be appreciated.
import Foundation
let serverOutput = Data("""
[
{
"language": "French",
"number": "12"
},
{
"language": "English",
"number": "10"
}
]
""".utf8)
struct LangueUsers: Codable {
let language: String
let number: Int
enum CodingKeys: CodingKey {
case language
case number
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
language = try container.decode(String.self, forKey: .language)
let rawNumber = try container.decode(String.self, forKey: .number)
guard let number = Int(rawNumber) else {
throw DecodingError.typeMismatch(Int.self, DecodingError.Context(codingPath: [CodingKeys.number], debugDescription: "\(rawNumber) can't be convert to Int"))
}
self.number = number
}
}
struct LangueUsersPercent: CustomStringConvertible {
let language: String
let share: Double
init(language: String, number: Int, all: Int) {
self.language = language
self.share = Double(number) / Double(all)
}
var description: String {
return String(format: "%# - %0.1f%%", language, share * 100)
}
}
let decoder = JSONDecoder()
//1
var output = try decoder.decode([LangueUsers].self, from: serverOutput)
//2
let allUser = output.reduce(0) { (reult, languageUsers) -> Int in
reult + Int(languageUsers.number)
}
//3
output.sort { (lhs, rhs) -> Bool in
lhs.number > rhs.number
}
//4
let response = output.map {
LangueUsersPercent(language: $0.language, number: $0.number, all: allUser)
}
print(response[0])
The code assumes that the output from a server is in serverOutput variable. So steps need to achieve your task:
decode your JSON to swift structure (called LangueUsers) using swift codable. Keep in mind that by default it won't convert string values to int, so I have to create a custom init(from decoder: Decoder) initializer
count the sum of all users (you can do it using for loop or reduce like in my example)
sort your list, so the language with the most users will be first
this step is optional, but I've added a separate structure that will help us generate output and in this step, we are rewriting our input structures to output ones
Hope this is clear for you. Let me know if you have any questions.
The simplest way is:
// Example JSON
const exampleJSON = {
"people": [
{
"language": "French",
"number": 12321,
},
{
"language": "English",
"number": 7000,
}
]
};
// Parse it
const parsed = JSON.parse(JSON.stringify(exampleJSON));
const speakers = [...parsed.people];
// Count number of all speakers and let it be as 100%
let sumAllSpeakers = 0;
parsed.people.reduce((previous, current) => {
sumAllSpeakers = previous.number + current.number;
return previous;
});
// Compare fucntion
const compareSpeakers = (speaker1, speaker2) => {
if (speaker1.number > speaker2.number) {
return -1;
}
if (speaker1.number < speaker2.number) {
return 1;
}
return 0;
}
// Create new array with statistic sorted from max number
const statisticsOfSpeakersInPersent = speakers
.sort((speaker1, speaker2) => compareSpeakers(speaker1, speaker2))
.map(speaker => {
return {...speaker, ...{inPersent: speaker.number * 100 / sumAllSpeakers + '%'}}
});
I hope this example helps you.
Out:
[ { language: 'French',
number: 12321,
inPersent: '63.76999120128358%' }, { language: 'English',
number: 7000,
inPersent: '36.23000879871642%' } ]

What's the appropriate way to access an enum from Swift Decodables?

I have a really weird case where I took JSON and thought I would be able to substring all the way to the data I want to access, however, it's not working as expected.
Using QuickType, I was able to convert this JSON: https://kidsuper.fodalabs.com/wp-json/wp/v2/art
To the below.
When trying to access, it seems like I should be able to do .acf.gallery.id however once I get to acf.gallery, it says .id does not exist. This is strange but here's what it returns when I try
let temp = imageArray[indexPath.row].acf.gallery.id
Value of type 'GalleryUnion?' has no member 'id'
Just for fun I tried this one and had no luck as well:
let temp = imageArray[indexPath.row].acf.GalleryUnion.galleryElementArray
Error
: Value of type 'Acf' has no member 'GalleryUnion'
The return when I print .acf.gallery starts like this:
Acf(company: "Season #3",
gallery: Optional(weddingszn.GalleryUnion.galleryElementArray([weddingszn.GalleryElement(
id: 135, galleryID: 135, title: "1-791x1024",
filename: "1-791x1024.jpg", url: "https://kidsuper.fodalabs.com/wp-content/up
Full code is below for what I'm trying to parse. Any ideas?
struct Acf: Codable {
let company: String
let gallery: GalleryUnion?
let tagline: String
let featuredImg: Bool?
enum CodingKeys: String, CodingKey {
case company, gallery, tagline
case featuredImg = "featured_img"
}
}
enum GalleryUnion: Codable {
case bool(Bool)
case galleryElementArray([GalleryElement])
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let x = try? container.decode(Bool.self) {
self = .bool(x)
return
}
if let x = try? container.decode([GalleryElement].self) {
self = .galleryElementArray(x)
return
}
throw DecodingError.typeMismatch(GalleryUnion.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for GalleryUnion"))
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .bool(let x):
try container.encode(x)
case .galleryElementArray(let x):
try container.encode(x)
}
}
}
struct GalleryElement: Codable {
let id, galleryID: Int
let title, filename: String
let url: String
let alt, author, description, caption: String
let name, date, modified: String
let mimeType: MIMEType
let type: TypeEnum
let icon: String
let width, height: Int
let sizes: Sizes
enum CodingKeys: String, CodingKey {
case id = "ID"
case galleryID = "id"
case title, filename, url, alt, author, description, caption, name, date, modified
case mimeType = "mime_type"
case type, icon, width, height, sizes
}
}
You have to use if case, guard case or switch case to unpack the enum before you drill down into the array.
if case .galleryElementArray(let x) = imageArray[indexPath.row].acf.gallery {
print(x.first!.id)
}
however once I get to acf.gallery, it says .id does not exist. This is strange
No it isn't. According to your code, .gallery should be a GalleryUnion. Well, a GalleryUnion has no .id. It has no properties at all. A GalleryElement has an .id, but a GalleryUnion is not a GalleryElement. So I don't see where your surprise comes from; there is no surprise here.
A GalleryUnion has cases. You need to check which case this is. If it's . galleryElementArray you need to extract the associated value. Even then you won't have any .id, because what you will now have is still not a GalleryElement; it's an array of GalleryElements.
You could make this a lot easier on yourself by defining GalleryUnion with an extra calculated property that fetches the associated value for you:
enum GalleryUnion : Codable {
case bool(Bool)
case galleryElementArray([GalleryElement])
var galleryElements : [GalleryElement]? {
switch self {
case .bool : return nil
case let .galleryElementArray(arr): return arr
}
}
// ... and so on
}
That would allow you, at least, to say:
act.gallery.galleryElements?.map {$0.id}
...or whatever it is you have in mind.
So, GalleryUnion can one of two things. It can either both .bool(_) or galleryElementArray(_). When you want access the actual underlying value, you need to determine which state it's in.
To do this in Swift, you can use a switch statement. You can then use it to gain access to the internally contained values. Maybe something similar to:
if let gallery = acf.gallery {
switch gallery {
case .galleryElementArray(let values):
values.forEach {
print($0.id)
}
case .bool(_):
break
}
}
You might like to have a read of Enumerations, look for the "Associated Values" sections

Received json data is in form of 531 bytes and giving curruptedData error in swift 4.1 and Xcode 9.2

I am trying to get response from server which is in form of JSON with Swift 4.1 and Xcode 9.2. But the received JSON data by JSONDecoder is printing 531 bytes and giving error
dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.})))
my request task is
let itemUrl = URL(string: mainUrl.MainUrl + "viewallstore")
let foodUrl = URLRequest(url: itemUrl!)
URLSession.shared.dataTask(with: foodUrl) { (data, response, error) in
print(data ?? "Errrrr")
if data != nil {
do {
let storeDetails = try JSONDecoder().decode(AllStores.self, from: data!)
for store in storeDetails.StoreDetails {
self.foods.append(FoodCourt(storeId: store.str_id, storeNo: store.str_number, storeName: store.str_name, storePhone: store.str_phone, storeParking: store.str_parking, storeOpenTime: store.str_open_time, storeCloseTime: store.str_close_tie, storeStartdate: store.str_open_date, storeCloseDate: store.str_close_date, storeLogoPath: store.str_logo_path, storeLogoFileName: store.str_logo_file_name, storeStatus: store.status, storeCategory: store.str_cat, createdAt: store.create_at, storeZone: store.str_zone, storeAvailability: store.str_availability, storeMulCategory: store.str_multiple_cat))
}
}catch let error {
self.toastNeck(message: "\(error)")
print(error)
DispatchQueue.main.async{
myActivityIndicator.stopAnimating()
myActivityIndicator.hidesWhenStopped = true
}
}
DispatchQueue.main.async {
self.collectionViewFoodCourt.reloadData()
}
}
}.resume()
}
and my struct is
struct AllStores: Decodable{
let StoreDetails: [StoreDetail]
}
struct StoreDetail: Decodable {
let str_id: String
let str_number: String
//let tid : String? //tid
let str_name: String
let str_phone: String
let str_parking: String
let str_open_time: String
let str_close_tie: String
let str_open_date: String
let str_close_date: String
let str_logo_path: String
let str_logo_file_name: String
let status: String
let str_cat: String
let create_at: String
let str_zone: String
let str_availability: String
let str_multiple_cat: String
enum CodingKey: String {
case str_id = "str_id"
case str_number = "str_number"
//case tid = "tid"
case str_name = "str_name"
case str_phone = "str_phone"
case str_parking = "str_parking"
case str_open_time = "str_open_time"
case str_close_tie = "str_close_tie"
case str_open_date = "str_open_date"
case str_close_date = "str_close_date"
case str_logo_path = "str_logo_path"
case str_logo_file_name = "str_logo_file_name"
case status = "status"
case str_cat = "str_cat"
case create_at = "create_at"
case str_zone = "str_zone"
case str_availability = "str_availability"
case str_multiple_cat = "str_multiple_cat"
}
}
and my json file on server is
{
"StoreDetails": [
{
"str_id": "1",
"str_number": "0",
"tid": "",
"str_name": "Moti mahal",
"str_des": "",
"str_phone": "9540011581",
"str_add": "",
"str_parking": "Ground Floor",
"str_short_dis": "Moti Mahal",
"str_open_time": "10:00:00",
"str_close_tie": "23:00:00",
"str_open_date": "2017-01-29",
"str_close_date": "2018-01-28",
"str_logo_path": "",
"str_logo_file_name": "Moti mahal.png",
"status": "Y",
"str_cat": "1",
"company_id": "0",
"str_lat": "0",
"str_lon": "0",
"create_at": "2017-02-11 19:45:28",
"create_by": "0",
"str_zone": "1",
"str_floor": "0",
"str_availability": "1",
"str_multiple_cat": "1"
},
{
"str_id": "2",
"str_number": "0",
"tid": "",
"str_name": "Ever Green",
"str_des": "",
"str_phone": "9953487923",
"str_add": "",
"str_parking": "Green Floor",
"str_short_dis": "Snakes",
"str_open_time": "10:00:00",
"str_close_tie": "22:00:00",
"str_open_date": "2017-02-05",
"str_close_date": "2017-12-31",
"str_logo_path": "",
"str_logo_file_name": "Ever Green.jpg",
"status": "N",
"str_cat": "1",
"company_id": "0",
"str_lat": "0",
"str_lon": "0",
"create_at": "2018-01-15 22:20:11",
"create_by": "0",
"str_zone": "1",
"str_floor": "0",
"str_availability": "1",
"str_multiple_cat": "1"
}
]
}
the same json file is working fine in android but not working in iOS. I am stuck here from a very long time.
All the other questions on StackOverflow is stating that my JSON file is not valid but it's working elsewhere.
Note. Feel free to edit my question if there any issues.
I have gone through all the similar questions but none of them is working in my scenario.
solved the issue, just needed to add POST request to the URL
foodUrl.httpMethod = "POST"

Resources