Using different delegates for NSXmlParser - iphone

I am trying to figure out the best way to design something. I am writing an iPhone App and for the most part I am using async calls to a web service. This means that I cam setting up a URLConnection, calling start and letting it call me back when the data is available or an exception occurs. This works well and I think is the correct way to handle things.
For example:
I request a list of people from a web service. The resulting list is Xml Person elements which will be translated into an objective-c "Person" object by my XmlDelegate.
When I call the function to get the person, I pass in a "PersonResultDelegate", which is a protocol with a single function called "PersonReceived:(Person *)p". So, each time I get a complete Person object, I call that method and all is well. So, my detail view (or search result view) just receives the elements as they are available.
The problem comes when I need to obtain more then one specific object. In my specific case, I need to get the first and last appointment for a person. So, I need to make two API calls to obtain these two single Appointment objects. Each Appointment object will result in a call to the registered AppointmentResultDelegate, but how will I know which is the first and which is the last? I also need to somehow handle the case when there is no "first" or "last" Appointments and the Delegate will never get called.
What would be the correct way design wise to handle this? Should I add some additional context information to the initial request which is passed back to the handle in the delegate? An opaque piece of data which only makes sense to the person who made the initial call? What are my other options?
Solution
What I actually ended up doing is just passing an opaque piece of data along with the Appointment to the delegate. So, when I request an appointment object I have a method like:
getNextAppointment withDelegate:self withContext:#"next"
getPrevAppointment withDelegate:self withContext:#"prev"
This way when the delegate gets called I know what appointment is being delivered.

"Each Appointment object will result in a call to the registered AppointmentResultDelegate, but how will I know which is the first and which is the last?"
By looking at the order in which you receive these callbacks. Or by looking at some value in that xml data. Like a sequence or data. I don't know your data of course.

Related

Pass ID or Object which has irrelavant details as RequestBody in Rest Call?

Approach 1:
#PostMapping("/api/{id}")
String getSomeObj(int id){
//make another rest call with id and get CustomObj
// then do some logic and return something
//Here response time will be more as it has again another rest calls
}
Approach 2:
#PostMapping("/api/{id}")
String getSomeObj(#PathParam("id") int id, #RequestBody CustomObj obj){
//directly do logic with the provided obj and return something
//Here Response time would be less as we are directly getting the actual Object from Request Body
//BUT is this a good practise to pass an object in which we need only few details?
}
Q1) All I am asking is to whether to pass just id or Object? If id is passed, another Rest call has to be made unnecessarily. If Object is passed, we can avoid making another rest call, BUT the problem is: this custom object may contain some irrelavant details too.. So, is this correct?
Q2) If passed with id, response time will be more when comparing with just passing object.. So, I am not understanding which approach should follow..
A1) This is all up to you and there is no "one correct" way. I would say if it's a small object pass the object and respond fast. If its a big object pass the id. How do you define big and small objects? if object has hashmaps or lists in it that's a big object. Also you can ignore serialization of internals; check https://www.baeldung.com/jackson-ignore-properties-on-serialization
A2) Pass the id and enjoy your REST service. After all REST is very fast. Don't worry about the speed of calls. If your back end function is fast and if you put a "loading" gif to front end; users will wait for the response.

GWT MVP updating Activity state on Place change

What is the best practise to update Activity state on Place change? Imagine you have an activity with view that displays list of categories and list of items in the category. If different category is selected then app goes to new place with category ID. I want then to only refresh items and not to create new activity that also re-reads category list.
My current approach is like this:
public class AppActivityMapper implements ActivityMapper {
private ItemListActivity itemListActivity;
...
public Activity getActivity(final Place place) {
final Activity activity;
if (place instanceof ItemListPlace) {
if (itemListActivity == null) {
itemListActivity = new ItemListActivity((ItemListPlace) place, clientFactory);
} else {
itemListActivity.refresh((ItemListPlace) place);
}
activity = itemListActivity;
} else {
itemListActivity = null;
}
...
return activity;
}
...
Alternatives are:
listen to PlaceChangeEvents from within the activity (you can then use a FilteredActivityMapper and CachingActivityMapper for the caching of the activity in your ActivityMapper, so that it's reduced to only create a new activity when asked). †
have some component listen to PlaceChangeEvents and translate them to business-oriented events, the activity then listens to those events rather than PlaceChangeEvents, otherwise the same as above.
decouple the activity from the "screen", make the "screen" a singleton with a reset() method and call that method from the activity's start (possibly passing the category ID as an argument in this case). The "screen" being a singleton could then make sure to load the categories list only once.
in your case, you could also simply put the categories list in a shared cache, so that you don't have to reuse your activity by can create a new one, the categories list will be retrieved once and put in the cache, subsequent activity instances will just use what's in the cache. This is similar to the above, but simpler, and the cache could be used by other parts of the application.
I'd personally rather go with your approach though (with a small exception, see below), as it's the simplest/easiest. Decoupling the activity from the "screen" is also an option; the GWT Team started exploring this approach in the Expenses sample (decoupling the activity responsibility from the presenter responsibility with using MVP) without ever finishing it unfortunately.
Other than that, I don't think any best practice has really emerged for now.
†. I don't like coupling my activities with the places they're used with (I don't quite like the coupling for the goTo calls either, but haven't yet found a clean and simple alternative), so I'd rather not go with this option; and similarly, I'd not pass the place to the activity constructor and refresh method like you did, but rather extract the information out of the place and pass it to the activity (e.g. in your case, only give the category ID to the activity, not the ItemListPlace instance; I would then simply call setCategory in all cases, and not even pass the category ID to the constructor).
In my opinion,
The role of the ActivityMapper is to give you back an Activity from a Place.
The role of the ActivityManager is to start the Activity given back from the ActivityMapper and to stop the current one if different. In your case you would like to "update/refresh" the current Activity.
So I would modify the ActivityMapper so as it will allways give me back the same instance of Activity for a given type of Place. A good way to do so could be to use GIN and use the singleton scope ...in(Singleton.class) to inject your Activity.
If you do that, when changing the url, if the place stays the same (meaning your url has the same word after # and before :) so that the Type of your place stays the same, the ActivityMapper will give you back the same instance of Activity so the ActivityManager will do nothing on the Activity. Check l.126 of ActivityManager
if (currentActivity.equals(nextActivity)) {
return;
}
For me you have 2 options there. The first one, as Thomas said , is to listen to PlaceChangeEvent in your Activity. The new Place you will receive can have new parameters inside based on the new url given and you can "update/refresh" your Activity.
The second one, that I find more in line with the Activity/Place pattern is to modify the ActivityManager so that it calls an update(Place) method on the Activity when the Activity given back by the ActivityMapper is the same that the current Activity.
I haven't tried any of these solutions yet but I will soon ... I might be able to update that post at that time.
You can find more information in this article I wrote on my blog on that topic
Here is a little schema I made to help me understand the pattern, hope it will help :
I would not do any logic in my ActiviyMapper except returning an activity, by creating a new one or giving a previous one (or null). According to me, the mapper doesn't have to know about refresh() or what activities do.
If that, then the logic of 'refresh()' would be given to the activy through the place which holds a token. That token should be holding the information about either what is the state of the request (a new page, reload, an id, etc).
In the activity, first, it asks for the View, the one related to this activity (tip : a singleton given by a 'ClientFactory' is good practice), then it creates a presenter for that view, and bind them together.
Lastly, the activity will use the token from the place to provide any information about state to the presenter. And then, it adds the view in the page.
It's good to know by default, with places and activies, going to the same place doesn't do anything (no reload). But you can take care of it with token and activity-mapper easily.
Hope you'll find an adapted solution for you case. Goodluck.

Doctrine 2, Need to execute code pre-persist/post-persist

I am using Doctrine 2 entities. We have some entities which have to update related items when they are saved to the database. For example, when a user record is modified, we save it as a new record, with the "inactive" field set to 'false'. However, we have to set the the 'inactive' field for all previous record for that user to 'true'. This is done to keep an audit history. It is a Legacy database, so changing the structure is not an option.
Since Doctrine saves objects by passing them to a persister object (persist::($thisObj)), rather than the object having a save method ($thisObj->save()), we can't just extend a 'save' method from a parent object. The only option I see here is to try to extend the 'persist' object, but that sounds like a goose gaggle, just waiting to happen.
I found some information on events, but do not see how to add them to make events fire a particular function when a particular entity is persisted.
How do I add pre-save/post-save functionality to some of my entities ?
So, you probably already know http://www.doctrine-project.org/docs/orm/2.1/en/reference/events.html right?
You add an annotation that the entity contains callbacks and then create specific functions (which need to be public) on that entity and also annotate them with #PrePersist or #PostPersist or whatever.
The other way is creating an event subscriber, register that one with the doctrine event manager and implement methods called prePersist, postPersist etc. They get passed an EventArguments object which contains the entity relevant for the occurred event.
I know this is a very general answer to your question, but you need to be a bit more specific where your problem lies.
Please dont exend the entity manager and overwrite the persist method, there are way cleaner methods for doing what you need as far as I can tell.
It's actually quite simple to do what you want to do. It does not require dorking with the event manager, or anything complex like that. You use something called "Lifecycle callbacks". These are functions that Doctrine automatically runs during the "lifecycle" of the entity, ie: prePersist, postPersist, preUpdate, postUpdate, etc. You can find the complete list here: http://www.doctrine-project.org/docs/orm/2.0/en/reference/events.html
The process of adding this functionality to your entities is very simple.
In the Annotations section of your entity, include the following tag: "#HasLifecycleCallbacks". This tells Doctrine that it should search the entity for functions to run upon various events
Write a public function in your entity that you would like to fire upon a specific event.
Put an annotation above the function indicating which event it should be used to handle.
For example, look at the following code:
/** #PostPersist */
public function doSPostPersist() {
$this->tester = 'Value changed by post-persist';
}
I have found that sometimes the events simply refuse to fire, and I don't yet know why. But when they do fire, they will fire reliably.
Don't forget to enable Lifecycle Callbacks in your class annotation :
/**
* Report\MainBundle\Entity\Serveur
* #ORM\HasLifecycleCallbacks
*/
class Serveur {

GWT - Where should i use code splitting while using places/activities/mappers?

"core" refers to the initial piece of the application that is loaded.
In order to bind url to places, GWT uses PlaceTokenizer<P extends Place>. When loading the application from the url, it calls the method P getPlace(String token) to retrieve a new instance of the place to call.
due to the asynchronous nature of code splitting, I can't create the place inside a runAsync in this method. So I have to put all the places of my app in the core.
To link places to activity, GWT callsActivity getActivity(Place place) (from com.google.gwt.activity.shared.ActivityMapper) to retrieve a new instance of the activity.
Once again, i have to put all my activities in the core.
Here's what I want to try: Write a custom com.google.gwt.place.shared.Delegate that
bind itself on PlaceChangeRequestEvent. If the AppPiece corresponding to the requestedPlace isn't loaded, it calls event.setWarning(NEED_TO_LOAD_MODULE)
in the confirm(String message) method, always return false when the message equals NEED_TO_LOAD_MODULE (so it doesn't bother the user), and load the module via RunAsync.
Once the module is loaded, call goTo(requestedPlace)
Each AppPiece of my application contains a bunch of activies and the corresponding views. Since the mappers are only called when PlaceChangeEventis fired, i could generate a new instance of my activity via AppPiece.getSomeActivityInstance().
I'm pretty sure this will work, but what bother me is that
Finding wich AppPiece to load depending on the requestedPlace will force me to write code that will be very similar to my mappers
I would like to have my places inside the corresponding AppPiece
Overriding Delegate for this purpose is tricky, and I'm looking for a better solution
You don't have to put all your activities in the core (as you call it): while an Activity instance is retrieved synchronously, it's allowed to start asynchronously. This is where you'd put your GWT.runAsync call.
See http://code.google.com/p/google-web-toolkit/issues/detail?id=5129 and https://groups.google.com/d/topic/google-web-toolkit/8_P_d4aT-0E/discussion

Business Logic when Saving in Entity Framework

If I want to perform some action when an entity is saved, I can do something as described here.
However, suppose I retrieve an object from the database. This object has a list of items within it. If I instantiate a new item and add it to this list and then save all changes, the item in the list is not part of the "GetObjectStateEntries".
The problem for my situation, I believe, has been resolved. There appears to be a bug, in my opinion, in the ObjectContext.SaveChanges(SaveOptions) method. Even though this method will call DetectChanges (depending on the saveOptions), the OnSavingChanges method is called FIRST. This, I think, is a problem.
The solution to this is to call ObjectContext.DetectChanges() prior to calling SaveChanges().