Are Umbraco dictionary items cached? - umbraco

Firstly, are Umbraco dictionary Items cached? If they are, how do you change the cache settings?
Secondly, is there any way in which we can regenerate list of existing dictionary items with a new prefix?
For example, if I have dictionary items with the following names
Dic_one
Dic_two
Dic_three
Dic_four
Now I need to add a prefix, such as UK_, and I need to copy the respective Umbraco dictionary items without losing their previous values:
UK_Dic_one
UK_Dic_two
UK_Dic_three
UK_Dic_four
How could I add this prefix, while still keeping the rest of the values in the dictionary?

Dictionary items by itself are not cached, though they are part of either a macro or a template which can cached (on the macro itself, or via IIS caching).
The existing dictionary items are stored in the table cmsDictionary, which you can get with the following SQL
SELECT [pk]
,[id]
,[parent]
,[key]
FROM [dbo].[cmsDictionary]
From there it is just a matter of updating the existing "key" value with a prefix.
As far as the "UK" prefix goes, this is a bit strange as dictionary keys can have different languages assigned to them. Having a dictionary item UK_Dic_One with a Dutch value would be a bit confusing, that would better be solved by adding different languages and using nested dictionary items (dictionary items can be nested in version 6).
If you can add new dictionary items, I would recommend the Dictionary Dashboard that allows you to export/import and edit an XML file with dictionary items which then can be imported afterwards.

I had the same issue. As #astuanax mentioned they are cached on template level. I was able to clear the "cache" by touching the web.config and restart the apppool.

Related

Remove or Add an attribute to CoreData at runtime programmatically

I have to create and remove attributes based on an api response in Objective C.
For example, Now my api response contains fields "facebook", "whatsapp" and "viber". But in future the reponse can add "youtube". Based on this response, I have to remove all the attributes and values of an entity "Social", and create Four attributes now and set values.
How to do that programmatically? Because the default *.xcdatamodeld file cant help me here, right?
Note: My project is in objective C.
The data model is mutable when the app starts-- you can completely build the model in code, and not use the model editor, for example. But as soon as you load a persistent store file, you must treat the model as fixed. Any changes after loading a persistent store will cause crashes. That means any changes would have to happen before calling either loadPersistentStores(completionHandler:) or addPersistentStore(with:completionHandler:).
Alexander's suggestion of optional attributes is a good one. If you need the model to be more dynamic, you would need to create a new related entity which would store the service name plus whatever information you need to save about the service. If you did this, your Social entity would have a to-many relationship to a new entity called something like Service. Service would have a string property called name that would have values like twitter, facebook, youtube, etc. It would also have whatever other attributes you need to save about the service.
You can create all 4 fields in advance and just make them optional and fill them depending on the server response. But you cannot add new attributes in runtime. Your *.xcdatamodeld file compiles into *.momd and it contains all the data to create tables in the DB since Core Data by default works with SQLite under the hood and it's a relational database management system.
To make attributes optional you should check that.
And then newly created objects contain nil as default values of object properties. So, in your case your "youtube" property of Social object will be just nil.

efficient way to remove superfluous data from core data

I read data from one of more remote files into coredata. If a remote file is changed the data in core data needs to be updated. For instance, assume one file is filled with departments, the other with employees.
As the company is restructured, one department is renamed and a second department without employees is deleted in the file. The employees file is not changed, so I only want to reread the file with departments. In my code I read the file, fetch the department from coredata and updates its name property. But since the second department is no longer in the file, I want to delete it from core data.
My pseudocode solution is as follows:
the department entity gets a hasChanged attribute
before reading from the file, all hasChanged attributes are set to false
if a department is present in the file, its hasChanged attribute is set to true
after the file is read, all departments with hasChanged attribute set to false are fetched and deleted
Somehow the seems not very efficient. Deleting all departments and building them a new seems also not very efficient, because core data will delete all employees with the departments and now I have to reread the employees (and probably all other files) also.
Is there a better way to approach this problem of data becoming superfluous? If you answer with code, swift is preferable.
First the delete rule should not be cascade - change it to nullify.
When you get new data from the server follow these steps:
fetch all of the entities that are effected. If you are updating departments - then fetch all the departments
store the results in a dictionary where the ID is the key.
Also store all the results in a mutable set called objectsToDelete
now iterate through all the data that you got from the server. lookup the department using the dictionary you made in step #2. If you find the object, then update it and remove it from the set you created in step #3. If you don't find the object then create it.
If there are any objects left in objectsToDelete then delete them
save the context.
It is the same principle for the employees. You match up the ones you already have using a dictionary, and delete the ones that don't get matched up.

Changing a global identifier of a Core Data object with Ensembles

I am reading the Ensembles documentation where global identifiers should never change in an object life time. However, I have a Tag object which only consists with a name attribute (a string). According to the Ensembles documentation as well, the tag name can be returned as the global identifier, which is actually even better than returning a UUID for obvious reasons.
My question is, since the user is allowed to rename tags in my app, should I delete the tag object from the database and re-create it, or renaming the tag object is considered safe? (renaming the tag object will cause the app to return the new tag name as the global identifier, which seems to conflict with the warning of not changing global identifier in object's entire life cycle)
Thanks.
You should not change the global id, so the tag objects should be considered immutable. You can delete them, or insert new ones, even ones also created on other devices. But don't ever change the global id.
My advice is to create a new tag object when the user renames. Depending on your model, that may mean changing relationships from one tag object to another, but that should work well.
The nice thing about global ids is that Ensembles can merge the relationship even if you create the same tag on two devices at once.

Realm over CoreData should I use NSFetchedResultController or a Dictionary?

I'm working on an app using Core Data and NSFetchedResultController but for many reasons I would like to switch it to use Realm.
I saw that there is a "Realm version" of the NSFetchedResultController on github but It wouldn't be compatible with my current code using Core Data.
The view controller is displaying a list of People from the same school, like an address book.
This list is a sublist of a people who studied in the same city.
So I was thinking to make 1 unique request to the database to retrieve the list of all people and then filter locally this list within 1 Dictionary per school [String: AnyObject] with String as Section name within the tableView and AnyObject an array of people.
first solution, make a NSFetchedResultController for each school with a predicate filtering the location. Then all delete actions etc.. are handled by the delegates -> this is not compatible with Realm
Create those dictionaries and update them for each actions... -> this works with Realm but it's very annoying to code.
Any better solution?
EDIT:
I need to clarify my request:
I'd like to write a class that inherit UITableViewController.
This class has a list of people sorted in the alphabetical order
The tableview has section with the first letter of their firstname
The tableview controller needs to handle updates of the data model (insert, update, delete)
As we might move from CoreData to Realm, I'd like to write code that is compatible with both so that I don't need to modify it again later. The only "smart" way I found to do it so far is to forget about the NSFetchedResultController and the RBQFetchedResultsController, because they are respectively linked to CoreData and Realm, and then use data structure like Dictionaries.
Just to clarify, you're creating a UITableView with multiple sections; 1 per school, and you want to sort a flat list of people in a Realm database into the table based on their school, correct?
If that Realm fetched results controller you mentioned (I'm guessing it's RBQFetchedResultsController) doesn't fit your app's architecture, then yeah, dictionaries would be the way to go, but it shouldn't hopefully be as 'manual' as you'd think.
The good thing about Realm Results objects are that they are 'live' in the sense that if a new item is added to Realm after the Results query was made, it'll be retroactively updated to include the new item. That being the case, as long as you're managing a dictionary of Results objects that each relate to fetching the people for each specific school, the only manual aspect would be managing the table sections themselves.
The only thing to be aware of is you'll need a mechanism to be notified when a new person has been added to a specific school (in order to know to refresh that section of the table view), but for now, it would be best if you did that in your own logic (Either through a callback block, or a delegate call).
On a sidenote, we're in the middle of adding a set of new APIs to make implementing native fetched results controller behaviour possible in Realm (i.e., automating the need to post a notification when a new object is added). We haven't got a proper release date confirmed yet, but it should be within the first quarter of 2016! :)

How can a user add a new field to a table by creating a new attribute

I'm new to Core Data and I got stuck at this part of my xCode project.
I have created a core data entity "Person" and this entity has the following attributes:
name;
age;
birthday;
address;
and this attributes are getting displayed in a tableview. So far so good.
My problem is that I want the table to have an "Add Field" or "Add Row" cell so when the user wants to add more information in addition to these already created attributes he just clicks the cell and chooses the field name and type.
For example if he wants the person's "phone number" in the detail view of the table he names the new field "phone number" and chooses its type "number". Then he has an extra field where he can add the person's phone number.
How can I do this in core data? Is there a way for a user to manually add a new attribute to an entity and choosing its format? What is the best approach? Thanks.
You can't do exactly what you want with Core Data. Core Data can't change structure except if you make a new version of your design, but you do that in xcode.
But you can easily add another table called f.ex. information, which links to the person single connection and has the person linking back many to the information table.
This way, you can add as many fields and values as you want, of course all the extra fields you add would follow the same person, so if you want to use cellPhone field, you must add that to all.
I would recommend that you use direct SQL, and don't use Core Data. Core Data is not a database, it is an object store, and when you get better at iOS development, you will understand the difference, it is much bigger than you might think at first.
There is an excellent high level library for SQLite, called FMDB, you can find it on github here : https://github.com/ccgus/fmdb
Here you can do direct SQL queries like "Alter Table" and more on the fly, though what you are after isn't very simple, it could be real fun project to do.
Good luck with this.
I don't think this is directly possible in Core Data because its purpose is object persistence and you can't add new properties to objects dynamically. It could be faked to some degree using a to-many relationship to an "extra property" entity that had name, value (as string), and data type fields.
I believe your best option would be using SQLite in order to modify the table structure on the fly. (http://www.sqlite.org/lang_altertable.html)
My last company did something like this, but its not trivial. I don't have access to the code so this is more or less going to be from memory.
you provide transformable property in your entity (which will be a dictionary)
the model object has to provide the getter and setter for this that in turn drive the primitive methods to set/get an attribute
you provide a getter/setter along the lines of -objectForKey and -setObject forKey, which read and write values
when you are told to 'fault', you update the dictionary in the entity
In summary, maintain a dictionary of key value pairs. Perhaps you maintain a shadow dictionary that gets initialized and updated as needed. Its been around 4 years since I last saw this code so a little fuzzy on it. But you should get the idea. It was like magic - you can arbitrarily set any key/value pair (assuming string keys and NSCoding compliant values), and can always ask for the keys by asking the dictionary for its current set of keys.

Resources