简体   繁体   中英

Data Model in Swift with multiple variables based on each other

I am currently stuck on a situation where I need to create a data model that will be used in a UITableView for both adding posts and retrieving them (read: showing them in a feed). Allow me to explain:

I want to create a standard data model for a post, which contains a title, a body and tags. I use a struct for this.

struct Post {
    var Title: String
    var Body: String
    var Tags: [String]
}

This works great. I can re-use this to create multiple posts simultaneously in a UITableView which is exactly what I want. However, the problem occurs now when I want to improve my system. I want to allow users to add attachments, whether they are images or videos (let's keep it at those two for this example and leave out text documents, pdfs, ...). My UITableView is set up in a way where every section is a post and every row is an item of that post. The title is defined in a UITextField in the section header and the tags are defined in the footer of the section. The body is a row. I now want to allow users to add a row to add whatever they want: plain text (a "body" row), but also image(s) or video(s). I will create three buttons: Add Text, Add Image and Add Video.

How can I improve my data model so that it can hold all this information? Should I, for example, add one variable "Attachments" for all types (image and video), or should I create separate optional variables like this:

struct Post {
    var postTitle: String
    var postBody: String
    var postTags: [String]
    var postImages: [AttachmentImage]
    var postVideos: [AttachmentVideo]
}

struct AttachmentImage {
    var imageTitle: String
    var imageReference: String
    var imageSize: Int
}

struct AttachmentVideo {
    var videoTitle: String
    var videoReference: String
    var videoSize: Int
    var videoThumbnail: String
}

This seems possible, but I would like to achieve in a certain way that I can change the variables based on another variable. Ideally I would have something like:

enum PostTypes {
    case Text, Image, Video
}

struct Post {
    var postTitle: String
    var postBody: String
    var postTags: [String]
    var postType: PostTypes
}

And then, if the type is Text, I want to keep it as-is, but if the type is Image, I want to add imageTitle, imageReference and imageSize, and the same for Video. Is there a way to achieve this, or should I go with the optionals?

First as first: If you have model named Post you don't have to name its properties like postTitle , postBody , etc. ... title or body is enough.


You can define protocol for your structs and then you can add generic constraint for your Post struct

protocol Attachment {
    var title: String { get set }
    var reference: String { get set }
    var size: Int { get set }
}

struct Post<T: Attachment> {
    var title: String
    var body: String
    var tags: [String]
    var attachments: [T]
}

struct AttachmentImage: Attachment {
    var title: String
    var reference: String
    var size: Int
}

struct AttachmentVideo: Attachment {
    var title: String
    var reference: String
    var size: Int
    var thumbnail: String
}

Example usage:

let post = Post(title: "", body: "", tags: [], attachments: [AttachmentImage(title: "", reference: "", size: 1)])
post.attachments /* type: [AttachmentImage] */

let post = Post(title: "", body: "", tags: [], attachments: [AttachmentVideo(title: "", reference: "", size: 1, thumbnail: "")])
post.attachments /* type: [AttachmentVideo] */

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM