Reputation:
In Java we can use constructors in order to pass initial values into a class. Is this possible in swift?
For example, in the line below I am trying to add an object, which should include all the values you can see in the function that is within it, into an array called arrayOfMedia.
self.arrayOfMedia.append(Media().getUsersMedia(image: image!, postNum: anyPosts.key, userID: user))
I cannot do this however and get the error below.
Cannot convert value of type '()' to expected argument type 'Media'
Upvotes: 1
Views: 4094
Reputation: 7756
For what it's worth, in this case I would use enums to wrap your media types.
enum MediaType {
case image(UIImage)
case video(Data)
}
Then you have Type safe access without requiring optionals:
struct Media {
let postKey: Int
let userId: Int
let mediaType: MediaType
}
let video = Media(postKey: 1, userId: 2, mediaType: .video(dataVariable))
let image = Media(postKey: 2, userId: 3, mediaType: .image(imageVariable))
Upvotes: 1
Reputation: 347314
I do not want to have to initialize the class as the values going into it vary (sometimes a video and sometimes a image)
Okay, so that makes no sense, you have a class
which is a container for some data, some of which is optional (either you have an image or a video), why not supply two different initialisers for the two different use cases ... just like you would in Java?
There's a few ways you "might" achieve this, this is just one...
class Media {
var image: UIImage?
var video: Data?
let postKey: Int
let userId: Int
internal required init(postKey: Int, userId: Int) {
self.postKey = postKey
self.userId = userId
}
convenience init(image: UIImage, postKey: Int, userId: Int) {
self.init(postKey: postKey, userId: userId)
self.image = image
}
convenience init(video: Data, postKey: Int, userId: Int) {
self.init(postKey: postKey, userId: userId)
self.video = video
}
}
Also, note, you could have simply provided a single initialiser, something like...
init(image: UIImage? = nil, video: Data? = nil, postKey: Int, userId: Int) {...}
but this doesn't constraint the user to one or the other type (they can still pass nil
for both values)
Another approach might be to make use of a protocol
to describe the basic/common properties of Media
and then implement the different requirements (directly as struct
s or class
s or indirectly as additional protocols
)
For example...
protocol Media {
var postKey: Int { get }
var userId: Int { get }
}
struct VideoMedia: Media {
let postKey: Int
let userId: Int
let video: Data
}
struct ImageMedia: Media {
let postKey: Int
let userId: Int
let image: UIImage
}
Upvotes: 3