Reputation: 197
I have one base view controller and some child view controllers. I am having difficulty to pass the view model created in children view controller (CommentViewController) to it's parent view controller (FeedBaseViewController) to access.
class BaseViewController: UIViewController {
...
}
class FeedBaseViewController: BaseViewController {
var viewModel1 = FeedBaseViewModel<BaseObject>()
...
}
class CommentViewController: FeedBaseViewController {
var viewModel2: CommentViewModel<CommentObject>
init() {
viewModel2 = CommentViewModel()
/* This is where I have issue, and I tried a few approaches. And here are the 2 of them.*/
// Method 1:
// viewModel1 = viewModel2
// Error: Cannot assign value of type 'CommentViewModel<CommentObject>' to type 'FeedBaseViewModel<BaseObject>'
// Method 2:
// viewModel1 = viewModel2 as FeedBaseViewModel<BaseObject>
// Error: Cannot convert value of type 'CommentViewModel<CommentObject>' to type 'FeedBaseViewModel<BaseObject>' in coercion
...
}
...
}
My view models for the View Controller
class FeedBaseViewModel<Item: BaseObject> {
}
class CommentViewModel<T: CommentObject>: FeedBaseViewModel<CommentObject> {
}
Here are the object classes, the BaseObject class is the only Objective-C class here, and a CommentObject swift class which inherit from BaseObject.
@interface BaseObject : NSObject <NSCoding>
@end
class CommentObject: BaseObject {
}
I am not sure if it is possible to do, or it is only syntax issue. Please advice, thank you!
Edited(2017-09-11):
I think I could provide more information of what I would like to achieve, and hope it helps.
FeedBaseViewModel
stores and manipulate an array of items with type BaseObject.
FeedBaseViewController
have UI handling actions such as "filtering", "sorting", and ask FeedBaseViewModel
to do the job.
For the Comment part, I will have a CommentObject
array with basic manipulation and some specific manipulation. This is why CommentViewModel
comes in, CommentViewModel
inherit FeedBaseViewModel
so that basic manipulation can be handled by the parent, and it will do the specific manipulation itself.
Similar in the view controller part, CommentViewController
will inherit FeedBaseViewController
, so FeedBaseViewController
can do the basic handling while CommentViewController
itself can provide additional functions.
Upvotes: 2
Views: 940
Reputation: 57124
I do not think that is possible.
Your problem boils down to:
let m = FeedBaseViewModel<CommentObject>()
let k : FeedBaseViewModel<BaseObject> = m
That is not allowed. As to why: assume that FeedBaseViewModel
contains a member of its generic type and offers a set
function for that member. If you now would be allowed to write the second line, then call set
using a BasObject
instance that would violate the generic constraint of m
because they are still the same object instance with different generic constraints, a BaseObject
instance is not necessarily an instance of CommentObject
.
A solution in your case should be to move the generics up a little bit more:
class FeedBaseViewController<T : BaseObject>: BaseViewController {
var viewModel1: FeedBaseViewModel<T>
required init?(coder aDecoder: NSCoder) {
viewModel1 = FeedBaseViewModel<T>()
super.init(coder: aDecoder)
}
}
class CommentViewController: FeedBaseViewController<CommentObject> {
var viewModel2: CommentViewModel<CommentObject>
required init?(coder aDecoder: NSCoder) {
viewModel2 = CommentViewModel<CommentObject>()
super.init(coder: aDecoder)
viewModel1 = viewModel2
// now this assignment is allowed because viewModel1 and viewModel2 have the super type FeedBaseViewModel<CommentObject>
}
}
Not sure if that solution works in your situation though.
Upvotes: 2