3

I need 4 file objects to upload. Few files have date, few files have image. What is the data structure should I use?

I tried to create an enum

enum File: String, CaseIterable {
    case a = "A"
    case b = "B"
    case c = "C"
    case d = "D"
    var size: String//enum cannot contain stored properties
}

I tried to create a struct

struct File {
    var name: String//for 4 files
    var size: String//only for A and B
    var image: UIImage// only for C and D
}
arun siva
  • 809
  • 1
  • 7
  • 18
  • Possible duplicate of [Why do enums have computed properties but not stored properties in Swift?](https://stackoverflow.com/questions/32278305/why-do-enums-have-computed-properties-but-not-stored-properties-in-swift) – A.Munzer Jun 20 '19 at 08:10

4 Answers4

2

This could help you-

    enum File: String, CaseIterable {
    case a = "A"
    case b = "B"
    case c = "C"
    case d = "D"

    static let sizeMapper: [File: String] = [
        .a: "Size A",
        .b: "Size B"
        ]
    static let nameMapper: [File: String] = [
        .a: "Name A",
        .b: "Name B",
        .c: "Name C",
        .d: "Name D"
        ]
    static let imageMapper: [File: UIImage] = [
        .c: UIImage(),
        .d: UIImage()
        ]

    var size: String {
        return File.sizeMapper[self] ?? ""
    }
    var name: String {
        return File.nameMapper[self] ?? ""
    }
    var image: UIImage {
        return File.imageMapper[self] ?? UIImage()
    }
}

call it like this-

        let size = File.a.size
        print(size)
        let name = File.a.name
        print(name)
        let image = File.c.image
        print(image)
Anupam Mishra
  • 3,408
  • 5
  • 35
  • 63
1

The error says it all:

enum cannot contain stored properties

Ideally you're the one to provide values to your enum's properties. Meaning they should be read-only. You can however make a new instance of your enum.

Here's an example:

enum File: String, CaseIterable {
    case a = "A"
    case b = "B"
    case c = "C"
    case d = "D"

    var size: String {
        switch self {
        case .a: return "Some size for A"
        case .b: return "Some size for B"
        case .c: return "Some size for C"
        case .d: return "Some size for D"
        }
    }
}

let fileA = File(rawValue: "A")
let fileB = File(rawValue: "B")

let size = fileA.size //Some size for A
let size = fileB.size //Some size for B
Glenn Posadas
  • 12,555
  • 6
  • 54
  • 95
  • But I want 2 cases should have size property and another 2 cases should have image property. How to do that? – arun siva Jun 20 '19 at 08:16
1

If you answer is "How to create an enum with extra properties", then you can write something like this:

enum File {
   case containingDate(fileName: String, date: Date)
   case containingImage(fileName: String, image: UIImage)
}

Also, note that enum with raw types (in your case it is String) can't contain extra parameters.

PS: to be honest, I don't see any advantages of using enums in your situation

vdmzz
  • 261
  • 1
  • 4
1

You should use both enum and struct here:

// Enum with associated values for differences
enum FileType {
    case withDate(date: Date)
    case withImage(image: UIImage)
}

// Struct to bind common
struct File {
    var name: String
    var fileType: FileType
}

And then you can have your files defined:

extension File {
    // Files with date
    static let a = File(name: "a", fileType: .withDate(date: Date()))
    static let b = File(name: "b", fileType: .withDate(date: Date()))

    // Files with image
    static let c = File(name: "c", fileType: .withImage(image: UIImage()))
    static let d = File(name: "d", fileType: .withImage(image: UIImage()))
}

And for simple way to access date and image you can declare those handy extensions:

extension FileType {
    var date: Date? {
        if case let .withDate(date) = self {
            return date
        } else {
            return nil
        }
    }

    var image: UIImage? {
        if case let .withImage(image) = self {
            return image
        } else {
            return nil
        }
    }
}

extension File {
    var date: Date? {
        return fileType.date
    }

    var image: UIImage? {
        return fileType.image
    }
}

And then use it like this:

let date = File.a.date
user28434'mstep
  • 6,290
  • 2
  • 20
  • 35