Generic ViewModel in Swift - swift

I'm following the MVVM pattern in my app. As a result I have a bunch of classes which virtually consist of the same code: fetch some data from an SQL server, save some data to an SQL server. This does not seem to be the most efficient way to do this, so I thought I should just generalise
the code down to a single SQLViewModel class which takes in any type of data model object. Right now it looks promising, though a couple of things are still causing weird behaviour, e.g. for some reason
var json = [T]()
doesn't cause any compiler warnings, while
var json = T()
stops with an Missing argument for parameter 'from' in call. Insert 'from: <#Decoder#>' error. My real question though is this: Is this actually a good way to simplify the code or will this cause me many more issues at a later time? Would it maybe be better to stick with the one model one viewmodel pattern and for instance use an extension for each viewmodel which hosts the shared code?
Thanks for any insights!

Missing argument for parameter 'from' in call. Insert 'from: <#Decoder#>'
Seems like the compiler complains because it can't find init(from:) in T
Which means that your generic declaration is missing a constraint eg.:
class MyClass<T: Decodable> {
// ...
}
Without more details I can say much more than that

Related

Binding.scala: Get current value of a Binding

It seems it is not possible to get the current value of a Binding like we can do for a Var(using method value). I looked at the source and this method is declared as being private for Binding class, while it is public for Var or for Binding.Constant classes. Is-there any reason for making it private in the Binding case ? Do you know there is another way to achieve that for a Binding ?
Just to give a word about the context, my use-case is the following: I have a complex object within a Var and from this Var, I derive several Binding representing lists of simple objects. Then I use these Binding to render HTML tables within #dom methods. Now I would like to perform some sequential search in the data displayed in the table (without having to derive them again from the original Var object)
So, basically, I would like to get the current value of the Binding used to show my table in order to perform the search.
Currently, the only option I can think of is to use Var instead of Binding for my derived objects and then to use a watched binding expression to update the derived Var when the source Var changes. But this makes the code much less concise and I have the feeling that this would add some performance overhead. Do you have some ideas to accomplish that in a better way?
Thanks in advance for any answer!
You may need findMapM (where M is Binding, F is List or Vector) or other sequential functions in Scalaz. See Scaladoc.

Is it better to use dictionary instead of create a class

I used to do things like below:
class A {
var param1:String?
var param2:[B]?
}
class B {
var param1:String?
var param2:String?
var param3:[C]?
}
class C {
var param1:String?
var param2:String?
}
But recently I found that dictionaries are more flexible. Class A can be replaced by the following dictionary.
[
"param1":"some string",
"param2":[
"param1":"some string",
"param2":"some string",
"param3":[
"param1":"some string",
"param2":"some string"
],
[
...
...
]
],
[
...
...
],
...
]
If we want to add "param3" into class C, we need to modify a lot of associated code if using class. But if we use dictionaries, we can just use "param3" as if it already exists.
A dictionary is just like a runtime defined class. I am wondering should we use dictionaries to replace data storing classes (i.e. models in MVC pattern) in all situations.
It depends on the use you have of your model. Making small classes enables you to give each class a specific additional behavior (for example more specific isolated accessory methods or helpers).
You can also test the model more easily by using only the piece you want and mock the other.
In general splitting responsibility is better because of maintenance and testability and clear code.
If your dictionary grows out of control then it is going to be very difficult for a newcomer on your team to use and understand the giant blob of data, rather than handling a lot of small objects with relationships between themselves.
If you add a new parameter you might need to change a lot of initializers.
That is normal I would say.
Also it depends on how you manage the model initialization. Maybe you use a factory that hides this complexity for you inside the rest of your code.
Or maybe you will need just to change it in your dependency injection root.
It clearly depends on the approach and scope of the object you are creating.
But in my opinion isolated objects are more reusable than a big blob of data in a dictionary
I agree that dictionaries are more extensible, but classes are safer.
One big unsafe thing about dictionaries is that you don't know whether a key exist or not at compile time. You have to put guard let or if let statements all over the place whenever you want to access something. If you don't do this, the app will crash at runtime when the key does not exist. Sure, you can fix it after it crashed, but you wasted a lot of time running your app and making that erroneous line of code to run and crash.
The other unsafe thing is type-unsafety. Since your dictionary contains different types of stuff, It must be a [String: Any]. Normally you can do this with classes:
someAObject.param2!.first!.param3!.first!.param1
If you use dictionaries you need:
(((dict["param2"]! as! [[String: Any]]).first!["param3"] as! [[String: Any]]).first! as! [String: Any])["param1"]
Just look at how much more code that is! Also, when you want a method to accept a parameter, you can write A or B or C if you are using classes and the method will only accept the type you specify. If you are using dictionaries, all you can write is [String: Any]. There is no compile time check whether that dictionary is of the acceptable type.
The third thing is about typos. If you typed a property name wrong, Xcode will tell you that even before you run the app. If you typed a dictionary key wrong, Xcode will not tell you that. You have to run that bit of code to know. Sure, you can put keys into constants, but that is very troublesome and the trouble definitely overweighs what you call "benefits" of dictionaries.
The fourth point is that dictionaries are value types. You might want some of the features of reference types.
And last but not least, you cannot add methods to dictionaries! A very important feature of classes is that they allow you to add methods and you can call them on instances of the class. If you made good use of this, you can write very readable code.
If we want to add "param3" into class C, we need to modify a lot of associated code if using class
Not if you designed your model well. I can't think of a reason why adding a new property to a class would require you to change lots of associated code.

Swift: confused about nullable/optional types

I'm new to Swift and iOS coding and have been working on writing my first app. While my programming background is pretty significant, I come from a Python and C# background where pretty much anything can be None or null and it's up to the user to check at runtime for a null. I'm finding this whole concept of "nullable vs. non-nullable types" or "optional types" in Swift to be confusing.
I understand that the core concept is that a variable declared as a type like myObject cannot be set to nil. However, if I define it as type myObject? then the value can be set to nil.
The problem is that, when I look at my code designs, it feels like everything will have to be "nullable" in my code. It feels like this either means I'm not thinking correctly with how my code should run, or that I'm missing some crucial piece of understanding.
Let's take the simplest example of something I am confused about. Suppose I have two classes - one that stores and manages some sort of data, and another that provides access to that data. (An example of this might be something like a database connection, or a file handle, or something similar.) Let's call the class containing data myData and the class that works with that data myObject.
myObject will need a class-level reference to myData because many of its methods depend on a local reference to the class. So, the first thing the constructor does is to generate a data connection and then store it in the local variable dataConnection. The variable needs to be defined at the class level so other methods can access it, but it will be assigned to in the constructor. Failure to obtain the connection will result in some sort of exception that will interfere with the very creation of the class.
I know that Swift has two ways to define a variable: var and let, with let being analogous to some languages' const directive. Since the data connection will persist throughout the entire life of the class, let seems an obvious choice. However, I do not know how to define a class-level variable via let which will be assigned at runtime. Therefore, I use something like
var dataConnection: myData?
in the class outside any functions.
But now I have to deal with the nullable data type, and do explicit unwrapping every time I use it anywhere. It is frustrating to say the least and quite confusing.
func dealWithData() {
self.dataConnection.someFunctionToGetData() <- results in an unwrapping error.
self.dataConnection!.someFunctionToGetData() <- works.
let someOtherObjectUsingData: otherObject = self.getOtherObject() <- may result in error unless type includes ?
someOtherObjectUsingData.someMethod(self.dataConnection) <- unwrap error if type included ?
var myData = self.dataConnection!
someOtherObjectUsingData.someMethod(myData) <- works
}
func somethingNeedingDataObject(dataObject: myData?) {
// now have to explicitly unwrap
let myDataUnwrapped = myData!
...
}
This just seems to be an extremely verbose way to deal with the issue. If an object is nil, won't the explicit unwrap in and of itself cause a runtime error (which could be caught and handled)? This tends to be a nightmare when stringing things together. I've had to do something like:
self.dataConnection!.somethingReturningAnObject!.thatObjectsVariable!.someMethod()
var myData? = self.dataConnection
var anotherObject? = myData!.somethingReturningAnObject
...
The way I'm used to doing this is that you simply define a variable, and if it is set to null and you try to do something with it, an exception (that you can catch and handle) is thrown. Is this simply not the way things work anymore in Swift? This has confused me sufficiently that just about every time I try to compile an app, I get tons of errors about this (and I just let Xcode fix them). But this can't be the best way to deal with it.
Do I have to consistently deal with wrapping and unwrapping variables - even those which are expected to never be null in the first place but simply can't be assigned at compile time?
However, I do not know how to define a class-level variable via let which will be assigned at runtime.
This part is easy. Just use let instead of var. With Swift 1.2 and later, you can delay the actual assignment of a let. The compiler is smart enough to do flow analysis and make sure it's assigned once, and only once, in all paths. So in the case of a class-wide let, the assignment can also happen in the constructor.
But now I have to deal with the nullable data type, and do explicit unwrapping every time I use it anywhere.
But this is what implicitly unwrapped Optionals are for. For example, StoryBoard defines all #IBOutlets as implicitly unwrapped, because the semantics are very clear: upon entrance to viewDidLoad() and everywhere after, unwrapping is safe. If you can prove clear semantics to yourself, you can do the same.
So you have roughly 4 choices:
A) declare at class level as implicitly unwrapped:
let dataConnection: MyData!
And be forced to initialize it in the constructor:
init() {
let whateverObj = someInitialCalculation()
dataConnection = whateverObj.someWayOfGettingTheConnection()
}
And from then on you don't need the '!'; it should be clear that implicit unwrap is always safe.
B) Initialize it right in its declaration if its initialization is reliable and sensible at that point, allowing you to forgo the entire concept of Optionals:
let dataConnection = SomeClass.someStaticMethod()
C) Declare at class level as a var, as implicit optional:
var dataConnection: MyData!
You won't have to init it in the constructor; let it be nil until its value can/should be computed. You still need some flow analysis to prove after a certain point, as in the case of #IBOutlets, accessing it will always be valid
D) The most 'unpredictable' case. Declare it as an explicit optional, because throughout the lifecycle of the class, the data connection will come and go:
var dataConnection: MyData?
func someMethodThatHandlesData() {
if let dC = dataConnection {
dc.handleSomeData()
}
else {
alert("Sorry, no data connection at the moment. Try again later.")
}
}
I think you're imagining that Swift always forces you down path D).
As far as your spaghetti-string code, you want to look into Optional Chaining, and only need to check the end result for nil.

Intersystems Cache - Correct syntax for %ListOfObjects

The documentation says this is allowed:
ClassMethod GetContacts() As %ListOfObjects(ELEMENTTYPE="ContactDB.Contact")
[WebMethod]
I want to do this:
Property Permissions As %ListOfObjects(ELEMENTTYPE="MyPackage.MyClass");
I get an error:
ERROR #5480: Property parameter not declared:
MyPackage.Myclass:ELEMENTTYPE
So, do I really have to create a new class and set the ELEMENTTYPE parameter in it for each list I need?
Correct syntax for %ListOfObjects in properties is this one
Property Permissions As list of MyPackage.MyClass;
Yes, a property does sometimes work differently than a method when it comes to types. That is an issue here, in that you can set a class parameter of the return value of a method declaration in a straightforward way, but that doesn't always work for class parameters on the class of a property.
I don't think the way it does work is documented completely, but here are some of my observations:
You can put in class parameters on a property if the type of the property is a data-type (which are often treated differently than objects).
If you look at the %XML.Adaptor class it has the keyword assignment statement
PropertyClass = %XML.PropertyParameters
This appears to add its parameters to all the properties of the class that declares it as its PropertyClass. This appears to be an example of Intersystems wanting to implement something (an XML adaptor) and realizing the implementation of objects didn't provide it cleanly, so they hacked something new into the class compiler. I can't really find much documentation so it isn't clear if its considered a usable API or an implementation detail subject to breakage.
You might be able to hack something this way - I've never tried anything similar.
A possibly simpler work around might be to initialize the Permissions property in %OnNew and %OnOpen. You will probably want a zero element array at that point anyway, rather than a null.
If you look at the implementation of %ListOfObjects you can see that the class parameter which you are trying to set simply provides a default value for the ElementType property. So after you create an instance of %ListOfObjects you could just set it's ElementType property to the proper element type.
This is a bit annoying, because you have to remember to do it every time by hand, and you might forget. Or a maintainer down the road might not now to do it.
You might hope to maybe make it a little less annoying by creating a generator method that initializes all your properties that need it. This would be easy if Intersystems had some decent system of annotating properties with arbitrary values (so you could know what ElementType to use for each property). But they don't, so you would have to do something like roll your own annotations using an XData block or a class method. This probably isn't worth it unless you have more use cases for annotations than just this one, so I would just do it by hand until that happens, if it ever does.

morphia annotation

I am using mongodb with java and also morphia.
For my usecase i get collection name at run time. So i have a enum of collection names and based on some value i get the corresponding collection name from enum. My entity annotation is as follows
#entity(EnumName.getCollectionName())
But i get the following error
"The value for annotation attribute Entity.value must be a constant expression"
I am actually returning a constant expression only. Could anyone let me know what the issue is.
You can't use some something dynamic within annotations as those are "compile" time features which can't be changed afterwards. So you can only handle constants which you declared there, Enums and Classes. For this a smart compiler may be able to find out that you handle something which may never change, but most wont and will simply error as soon as they see that you're trying asign some function value to an annotation property.
I don't really understand what you're trying to do, but it somehow looks like you try to use one "generic" entity class for several concrete entities. I think this is really bad design.
If you can tell more details, we may be able to give you a proper solution for your problem.
If you simply don't know what Class you have to operate with at runtime, try this.
Declare your concrete entities and fill your enum with those Classes. At Runtime you can do Datastore.find(Enum.YOURCLASS) and morphia will query your appropriate class.