MVVM implementation with RxSwift and Realm - Two way binding - swift

My implementation of the MVVM pattern with RxSwift, Realm and RxRealm looks like this:
E.g. I have a textfield that shows some editable content. I want this to be realtime saved/synched to the DB like this:
//View
textField.rx.text.subscribe(textViewModel.saveText.inputs)
viewModel.stringValue.drive(textField.rx.text)
//ViewModel:
lazy var saveText = Action<String,Void>{ newStringValue in
realm.write{
textObject.stringValue = newStringValue
}
//don't block the main thread
return Observable.just()
}
lazy var stringValue = Observable(from:textObject).map{$0.stringValue}.asDriver(onErrorJustReturn : "no string")
When typing slowly in the TextField, everything works accordingly. When typing very quickly thought, letters get "swallowed" like this:
Type "A"
write "A" to DB
Type "B"
Receive "A" from DB
-> Textfield value becomes A instead of AB.
When working with realtime synchronization this is the desired behaviour. For single text typing this seems not a good solution. How would such a 2-way binding be properly implemented and the undesired effect be avoided, especially in a scenario where the viewModel is processing the text value before write or after read from the source?

In your requirements will the Realm stored data ever be updated via another source? As in, could you ever receive a value in the string that came from another field?
If not, then you may be able to trust your input, and your writes can be eventually consistent.
The problem, though, comes down to the speed of writes and the notification returning the data; small but not nothing. Perhaps an intermediary would be beneficial.
For example, write your input field out to value that will periodically synchronise to Realm. That way your observable can have immediate access to the updated value and you can trust that eventually the value will be
Happy to explore further to see if we can solve something. :)
Edit:
Realm's guidance on conflict resolution.
A manual approach might be to hold two values; one is the value you start with, the other is the value that is being managed by the server.
If the starting value and the server value differ, you have a conflict to manage. Your strategy can be to reject one, accept one or somehow merge them, depending on the complexity of the data.

Related

Why does Data not reset its index after popFirst, and can I change that?

So, I'm doing some development in Swift, and I'm doing a small refactor to improve the internal logistics. I'm changing a class that was handling [UInt8] variables to handle Data objects instead. The problem: say I do something like this...
var data = Data()
var buffer = < an incoming Data object >
buffer.removeFirst()
buffer.removeFirst()
data = buffer[0..<32]
I get a hard EXC_BREAKPOINT error and the debugger tells me data is represented by a slice with range e.g. 2..<40 right now. I didn't have this problem with [UInt8], and it looks like .removeFirst() doesn't reset Data's index like it does for [UInt8].
I can get around this by, for example, doing buffer = Data(buffer) to get a fresh index every time, but I don't feel great about that. Neither do I want to allow this buffer's index to increment forever, as it's going to handle an indefinite stream of incoming data.
With my limited Google-fu, I was unable to find confirmation of this difference, nevermind an explanation. I'd love to understand why .removeFirst displays this difference in behaviour. I'd also love any tips, tricks etc that might come up. Originally, I was converting my incoming Data to [UInt8] and then back into Data, and I'm hoping to get rid of those seemingly excessive conversions.

Proper way to communicate with socket

Is there any design pattern or something else for the network communication using Socket.
I mean what i always do is :
I receive a message from my client or my server
I extract the type of this message (f.e : LOGIN or LOGOUT or
CHECK_TICKET etc ...)
And i test this type in a switch case statement
Then execute the suitable method for this type
this way is a little bit borring when u have a lot of type of message.
Each time i have to add a type, i have to add it in the switch case.
Plus, it take more machine operations when you have hundred or thousands type of message in your protocol (due to the switch case).
Thanks.
You could use a loop over a set of handler classes (i.e. one for each type of message supported). This is essentially the composite pattern. The Component and each Composite then become independently testable. Once written Component need never change again and the support for a new message becomes isolated to a single new class (or perhaps lambda or function pointer depending on language). Also you can add/remove/reorder Composites at runtime to the Component, if that was something you wanted from your design (alternatively if you wanted to prevent this, depending on your language you could use variadic templates). Also you could look at Chain of Responsibility.
However, if you thought that adding a case to a switch is a bit laborious, I suspect that writing a new class would be too.
P.S. I don't see a good way of avoiding steps 1 and 2.

Swift: Prevent gameplayer address tracking

I'm developing a simple game in swift, but using GamePlayer (on Cydia, a cheat-enginelike), I am able to locate, track and modify my score.
I was wondering how can I prevent this kind of cheats... I tried to create a new instance of the element whenever it changes, example:
score = Int(score + 1)
I also tried to reset the var to nil and re-assign it:
let tmp = score + 1
score = nil
score = tmp
But it is not working...
My first question is: Is it possible to change a variable's address in swift ? And will it prevent address tracking?
My second question is: Another thing that can work, encoding my score, but is it worth the work ?
You can put your score variable in a struct and use copy-on-write. Then, when you change a value, you get a fresh copy of the score. The possibilities and how copy-on-write works, is described here with examples: copy-on-write
Compared to the solution, were you actually encrypt the number it has advantages and disadvantages. Just some of them from the top of my head (I'm curious what your points are)
encryption needs more cpu power and therefore more battery. Whereas the copy-on-write is implemented deep on iOS level, where we can assume, that it is very well optimised.
The copy-on-write solution is less secure, as one might find the right address just at the beginning and can track it (now, that I think about it, not really...)
The copy-on-write adds more complexity to your source code as you need to trigger it on every change.

Non-RESTful backend with backbone.js

I'm evaluating backbone.js as a potential javascript library for use in an application which will have a few different backends: WebSocket, REST, and 3rd party library producing JSON. I've read some opinions that backbone.js works beautifully with RESTful backends so long as the api is 'by the book' and follows the appropriate http verbage. Can someone elaborate on what this means?
Also, how much trouble is it to get backbone.js to connect to WebSockets? Lastly, are there any issues with integrating a backbone.js model with a function which returns JSON - in other words does the data model always need to be served via REST?
Backbone's power is that it has an incredibly flexible and modular structure. It means that any part of Backbone you can use, extend, take out, or modify. This includes the AJAX functionality.
Backbone doesn't "care" where do you get the data for your collections or models. It will help you out by providing an out of the box RESTful "ajax" solution, but it won't be mad if you want to use something else!
This allows you to find (or write) any plugin you want to handle the server interaction. Just look on backplug.io, Google, and Github.
Specifically for Sockets there is backbone.iobind.
Can't find a plugin, no worries. I can tell you exactly how to write one (it's 100x easier than it sounds).
The first thing that you need to understand is that overwriting behavior is SUPER easy. There are 2 main ways:
Globally:
Backbone.Collection.prototype.sync = function() {
//screw you Backbone!!! You're completely useless I am doing my own thing
}
Per instance
var MySpecialCollection = Backbone.Collection.extend({
sync: function() {
//I like what you're doing with the ajax thing... Clever clever ;)
// But for a few collections I wanna do it my way. That cool?
});
And the only other thing you need to know is what happens when you call "fetch" on a collection. This is the "by the book"/"out of the box behavior" behavior:
collection#fetch is triggered by user (YOU). fetch will delegate the ACTUAL fetching (ajax, sockets, local storage, or even a function that instantly returns json) to some other function (collection#sync). Whatever function is in collection.sync has to has to take 3 arguments:
action: create (for creating), action: read (for fetching), delete (for deleting), or update (for updating) = CRUD.
context (this variable) - if you don't know what this does it, don't worry about it, not important for now
options - where da magic is. We only care about 1 option though
success: a callback that gets called when the data is "ready". THIS is the callback that collection#fetch is interested in because that's when it takes over and does it's thing. The only requirements is that sync passes it the following 1st argument
response: the actual data it got back
Now
has to return a success callback in it's options that gets executed when it's done getting the data. That function what it's responsible for is
Whenever collection#sync is done doing it's thing, collection#fetch takes back over (with that callback in passed in to success) and does the following nifty steps:
Calls set or reset (for these purposes they're roughly the same).
When set finishes, it triggers a sync event on the collection broadcasting to the world "yo I'm ready!!"
So what happens in set. Well bunch of stuff (deduping, parsing, sorting, parsing, removing, creating models, propagating changesand general maintenance). Don't worry about it. It works ;) What you need to worry about is how you can hook in to different parts of this process. The only two you should worry about (if your wraps data in weird ways) are
collection#parse for parsing a collection. Should accept raw JSON (or whatever format) that comes from the server/ajax/websocket/function/worker/whoknowwhat and turn it into an ARRAY of objects. Takes in for 1st argument resp (the JSON) and should spit out a mutated response for return. Easy peasy.
model#parse. Same as collection but it takes in the raw objects (i.e. imagine you iterate over the output of collection#parse) and splits out an "unwrapped" object.
Get off your computer and go to the beach because you finished your work in 1/100th the time you thought it would take.
That's all you need to know in order to implement whatever server system you want in place of the vanilla "ajax requests".

Form-related problems

I am new to Lift and I am thinking whether I should investigate it more closely and start using it as my main platform for the web development. However I have few "fears" which I would be happy to be dispelled first.
Security
Assume that I have the following snippet that generates a form. There are several fields and the user is allowed to edit just some of them.
def form(in : NodeSeq): NodeSeq = {
val data = Data.get(...)
<lift:children>
Element 1: { textIf(data.el1, data.el1(_), isEditable("el1")) }<br />
Element 2: { textIf(data.el2, data.el2(_), isEditable("el2")) }<br />
Element 3: { textIf(data.el3, data.el3(_), isEditable("el3")) }<br />
{ button("Save", () => data.save) }
</lift:children>
}
def textIf(label: String, handler: String => Any, editable: Boolean): NodeSeq =
if (editable) text(label, handler) else Text(label)
Am I right that there is no vulnerability that would allow a user to change a value of some field even though the isEditable method assigned to that field evaluates to false?
Performance
What is the best approach to form processing in Lift? I really like the way of defining anonymous functions as handlers for every field - however how does it scale? I guess that for every handler a function is added to the session with its closure and it stays there until the form is posted back. Doesn't it introduce some potential performance issue when it comes to a service under high loads (let's say 200 requests per second)? And when do these handlers get freed (if the form isn't resubmitted and the user either closes the browser or navigate to another page)?
Thank you!
With regards to security, you are correct. When an input is created, a handler function is generated and stored server-side using a GUID identifier. The function is session specific, and closed over by your code - so it is not accessible by other users and would be hard to replay. In the case of your example, since no input is ever displayed - no function is ever generated, and therefore it would not be possible to change the value if isEditable is false.
As for performance, on a single machine, Lift performs incredibly well. It does however require session-aware load balancing to scale horizontally, since the handler functions do not easily serialize across machines. One thing to remember is that Lift is incredibly flexible, and you can also create stateless form processing if you need to (albeit, it will not be as secure). I have never seen too much of a memory hit with the applications we have created and deployed. I don't have too many hard stats available, but in this thread, David Pollak mentioned that demo.liftweb.net at the time had 214 open sessions consuming about 100MB of ram (500K/session).
Also, here is a link to the Lift book's chapter on Scalability, which also has some more info on security.
The closure and all the stuff is surely cleaned at sessionShutdown. Earlier -- I don't know. Anyway, it's not really a theoretical question -- it highly depends on how users use web forms in practice. So, for a broader answer, I'd ask the question on the main channel of liftweb -- https://groups.google.com/forum/#!forum/liftweb
Also, you can use a "statical" form if you want to. But AFAIK there are no problems with memory and everybody is using the main approach to forms.
If you don't create the handler xml/html -- the user won't be able to change the data, that's for sure. In your code, if I understood it correctly (I'm not sure), you don't create "text(label,handler)" when it's not needed, so everything's secure.