Removing Objects From The Calendar Store. - objective-c

I was wondering how you actually remove objects from the Calendar Store, I've looked at the documentation and it only mentions how to add objects but nothing about removing.
How would I remove an object from the calendar store?

How would I remove an object from the calender store?
Buy out their stock!
Serious answer: The CalCalendarStore object responds to two messages that remove a calendar item: one for events, the other for tasks. Use whichever one is appropriate to the item you want to remove.

As Peter points out in his comment; it isn't enough to identify a CalTask just by it's title.
So, how do you uniquely identify a task?
If you look at the documentation for CalTask you will see that it is a sub-class. The super-class has a property which you can use to uniquely identify objects of that super-class, and because CalTask is a sub-class, it too has that property.
Have a look at the code that you used to create those tasks in iCal. When you create each task you can inspect its properties for that property and store it in your model. Then, when you come to delete the tasks from iCal, you can use that property to uniquely identify the task that is to be deleted.
I make no apologies for not being more specific in this answer. You'll need to read the documentation and try and write this for yourself. You'll need to make changes in more than one place in your app:
Change the model so that you can store this unique identifier for the tasks you create.
Change the method that you use to create and add task to the Calendar Store so that you get this identifier and store it in your model.
Make use of this identifier when you are trying to identify the tasks in the Calendar store that you want to delete.

Related

How do you get the ID of a row in a Core Data entity, such that you can reference it later?

Small question!
With Ruby on Rails (which I appreciate talks to a "real" database), with each record I add to a table, I can extract the ID of that record, send it somewhere, do something with it, and return data which can be associated with the original record.
I can't (for the life of me) seem to find the way to do it in Core Data.
If I have a Messages Entity with rows of messages. I want to be able to extract the ID of the message (row ID?), and send it to my server, and have a response change the same record by looking up it's ID.
The closest I can get is [message objectID]. However, I have no idea what this really returns, and I can't seem to encode it in a JSON request anyway.
Sigh.
Any help would be appreciated as I really don't know where to start with this one.
Edit:
Looking at other websites, and finally drilling it down, I've decided to use my own Unique ID. Apple can change the structure of URIRepresentation and, objectID can change if you change the structure of core data. So, it's best to stick with what I know.
objectID is a unique id for an object in CoreData. Quoted from Apple
An NSManagedObjectID object is a compact, universal identifier for a
managed object. This forms the basis for uniquing in the Core Data
Framework. A managed object ID uniquely identifies the same managed
object both between managed object contexts in a single application,
and in multiple applications (as in distributed systems). Identifiers
contain the information needed to exactly describe an object in a
persistent store (like the primary key in the database), although the
detailed information is not exposed. The framework completely
encapsulates the “external” information and presents a clean object
oriented interface.
you might consider reading the documentation here and here
You can get an URIRepresentation which might help you with JSON representation.
Looking at other websites, and finally drilling it down, I've decided to use my own Unique ID. Apple can change the structure of URIRepresentation and, objectID can change if you change the structure of core data. So, it's best to stick with what I know.

Can you restrict the access on a custom field type?

I want to create a custom field type (MyCompLookup) that will be used in lists that all users will have access to. However, the field type will be fairly complicated / confusing to a regular user who is creating a simple list in their department's site. Is there a way to restrict certain users from selecting the custom field when they are creating columns for their lists?
I'm afraid you can't set ACL on field types.
A few things you can do to achieve some kind of workaround:
Add a custom logic in SPField OnAdded method that removes the field immediately after it was added by a regular user. This method might be very confusing for users, so at least you should give a descriptive name to your field. You can find a similar solution here, where I add extra fields to the list in this method.
You can add a custom editor control (see a simple sample here) to your field, that interactsts with other controls on the add new field page, for example disables the OK button.
Hope it helps.

How to associate calculated values to an object

I have some basic objects like Customer, Portfolio and ... with some association to other objects. I can easily display the required information in the web page by reading object values. The problem is that what do I do when the value associated with the object is calculated and returned by a method, a value that makes sense only in certain context and cannot be attached to the object as an instance variable? In this case if I have a list of say Users I have to pass the username of each user to the method to get the calculated value. This causes problem to keep the association while displaying the values in the page.
An example to make this clear:
An application provides the functionality for users to keep track of each others activities by letting them add whoever they want to a list. If this user performs a search on users there's the option to follow each returned user. I want to make sure this option is disabled for those user's that are already being followed. This functionality is provided by a method like isFollowed(String follower, String followee) which returnes a boolean. How can I associate this boolean values to each user in search result?
Solutions:
One thing I can think of is to add a followed instance variable to User class. But I don't think it's a good approach because this variable only makes sense in a certain context. It's not a part of User class in the domain.
The other way I can think of is to use Decoration or Wrappers in a way to extend the User class and add the attribute in the child class. But again what if I have several objects that need to be in the same context. In that case I have to extend all of them with the same boolean attribute in all classes.
I hope I could make it clear.
In principle, I don't see anything wrong with instance method on User: bool IsFollowedBy(User user).
Of course, this could lead to performance issues. If that is the case, you can create separate object for presentation purposes which bundles data from User and whether he is being followed by the user performing search. Then you can build query which retrieves all necessary data for such object in a single roundtrip to DB.
One solution is to avoid querying Entities (as in DDD/ORM) and query directly using subquery/join or even using some denormalized database. This is something CQRS pattern suggests.
Other solution is to do computations on application layer (how many Users can you show on the same page anyway), which is expensive but you can implement some caching techniques to make things easier.

How can I set up a newly created relationship in Core Data on iOS?

So I'm using Core Data in an existing iPhone app, and I've set up two entities: Person and Item. The root view of my app's navigation (currently) shows a list of people, and you drill down from there to items. In short, the hierarchy looks like this:
Person -> Item
I want to add a new entity above Person in the hierarchy, called List:
List -> Person -> Item
Additionally, I want the user's first List to be created for them on startup, and for any People the user's already added to be assigned to that list.
I'm familiar with Core Data's lightweight migration & versioning feature, so I think I know how to add the new entity and relationship, but I'm not sure how to:
Create a List record on app start if they've never had the Lists feature before
Set all existing People records to belong to that new list.
One quick and dirty way would be to add some code to my app delegate's applicationDidFinishLaunching method that performs the migration by (1) checking to see if there are any Lists, (2) if not, creating the default one, (3) fetching all existing People from my data store, (4) setting each Person's list attribute to the newly created default list, and finally (5) saving those changes.
My question is: is there any faster or easier way to do all of that?
That's pretty much what you'd want to do. Use an NSFetchRequest to see if any Listss exist. If not, create one. Then do another request to get all the Persons. Here, instead of assigning the list property of each Person, I'd create an NSSet containing all your Persons and assign that to the List's people property. You did create an inverse property, right?
This is actually a pretty lightweight operation, all tolled, so I wouldn't worry too much about performance. Unless you've got hundreds or thousands of Person objects, your user will probably won't even notice.

Data Mapper API - unsure about organisation

Let's say we have "User" and a "Hotel" model classes. I'd use a User_Mapper and Hotel_Mapper to load/save/delete etc. I want to then have the user be able to mark their "favourite" hotels. In the database I have my user_favourite_hotels table which is a simple link table along with say a field for subscribing to hotel updates.
When listing out the user's favourite hotels, how would you expect this to work from an API point of view? A part of me thinks that this should be a "findFavouritesByUserId" method on the Hotel_Mapper, but other than saying it "feels" right - however a colleague suggests that the "favourites" is owned by the user and should therefore be on the User_Mapper.
Perhaps I should have a User_Hotel_Favourites_Mapper? I was thinking of incorporating the "favourites" data in to the User object so it's saved and loaded whenever the User object is. I'm not sure whether it'd be better to split it out in to it's own object and mapper however.
I'd appreciate any advice on how best to setup the API for the above and any pros/cons/experiences.
Thanks very much,
James.
This (admittedly retired) patterns&practices guide to designing data tier components suggests that you put the method in the mapper of the type of object that you're getting back from the call.
If you have methods that return a particular type of business entity, place these methods in the Data Access Logic Component for that type. For example, if you are retrieving all orders for a customer, implement that function in the Order Data Access Logic Component because your return value is of the type Order. Conversely, if you are retrieving all customers that have ordered a specific product, implement that function in the Customer Data Access Logic Component.
So, in your example, it would go in the Hotel Mapper as it is returning Hotels.
If you want to store favorite hotels for the user, you are using the UserMapper, which notices that domain object for User has changes favorites, and updates both tables for users and for user_favorite_hotels ( you just need the hotel IDs ).
When you are retrieving favorite hotels of some user, you use HotelMapper and set filter to be based on User, because you will be working with instances of Hotel.
Considering that this was asked more than 2 years ago, I'm not sure if an answer matters to you now. But here's what I think anyway.
If User could have multiple types of favourites (including Hotels), it may make sense to have a UserFavourites abstraction to cover all possible types of favourites. UserFavourites could expose a getItems() method to get the underlying Favourites.
This could be managed with the help of a manager class to return the appropriate Favourites object(FavouriteHotels for example) on which the getItems() method can be called.