Sync EventKit events with remote database - swift

I would like to create an app that retrieves events (similar to calendar events) from a remote database and shows them in a View, create, edit and delete new or existing events; currently I’m using EventKit framework to access iOS calendar, I read this docs and tried SimpleEKDemo:
https://developer.apple.com/library/ios/documentation/DataManagement/Conceptual/EventKitProgGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40009765
I actually can get events from server through an HTTP POST request (a NSMutableURLRequest) with JSON response and show them in a tableView, when I tap on an event I can edit it, update the remote db entry and if I switch to iOS calendar I see the event (so writing in calendar database is successful);
the most important thing is that all events must be synchronized with remote database, so the core problem occurs when user leaves my app, opens iOS calendar and edits an event previously created through my app: in this case the synch does not occur and the data are inconsistent.
I was thinking at these possible ways:
Is there a way to hook at iOS Calendar so I can perform update in remote db, only for a subset of events?
Or can I create an event only editable through my app?
Maybe do I have to quit EventKit and create a custom calendar with custom update functions?
I read also these questions:
Create a calendar in iOS
How to identify EKEvent uniquely with Sync across the devices
Sync database on ipad with remote database
but I don't know if I'am on the right track.
Any help is appreciated, thank you.
EDIT: with "synchronized" I mean that all data on the app database must be the same as server database

At least today you cannot create a custom protocol provider for the iOS calendar, which I think is what you are asking for (you would like to feed the calendar backend with your JSON-like protocol, or some app extension translating that).
There are three options:
a) keep the remote database in sync using an application
b) write your own calendar UI
c) implement CalDAV on the server side, or in a proxy
It sounds like a) is what you are doing today. You would need to sync the EventKit database when your app starts (to pickup changes done in other EventKit apps like Calendar). Obviously the user needs to start your app once in a while to get the sync going ... (as a hack you might also be able to trigger your app using a push)
Depending on your needs b) is a lot of work and you have zero platform integration.
I think implementing CalDAV in your server, or adding a proxy which translates between your server's JSON and CalDAV is probably the best way to go. You can then just add your server as a CalDAV account to iOS. As a bonus you can use any other client doing CalDAV with your server ...

Related

Push O/R data updates to Windows Store clients

I am developing a multi-user Windows Store client app. The app's main screen displays data that can be updated by users at any time. Any changes made by a user needs to be pushed onto all clients in order to update the data displayed on the main screens of all the other users.
Would Azure's Notification Hubs apply to my scenario? The demos I've seen so far only show the pushing of "toast" notifications. In my case, I need to push notifications to client application code for programmatic processing rather than for direct display to the user.
My client app is programmed in a way that requires an object/relational mapping tool sitting between it and the database. It appears that Azure's Mobile Services includes support for Entity Framework and so can facilitate this. Is it possible to leverage Notification Hubs to achieve the goal of keeping all clients updated with the latest database changes? If so, then how would I accomplish each event in the following sequence?
Inform the mobile service that the database has changed.
Notify all the clients about the changes.
Materialize the changes on each client as objects via the O/R mapper.

EventKit Predicate Choices

The app I'm developing will write events to a calendar on the user's phone. I was thinking of preceeding my app's event with a prefix like myapp: so I can find my events in the event store to display in a tableview.
However, it seems that the only predicate available is based upon a start and end date (– predicateForEventsWithStartDate:endDate:calendars:) when I review the ios eventkit framework. Am I reading that right?
Should I just then create a calendar for just my app on the phone or is there another way to identify my events beside dates?
Thanks in advance.
One other option would be to have local storage (sqlite, coredata etc...) which indexes into the event. Each event has as event id and you can you retrieve the event from the store via eventWithIdentifier.
Not sure what your data access patterns are but that also allows you to quickly store data within your app that you can query effieciently (with a powerful predicates and sql syntax). Your local results could just return eventIds and in the the table view call backs you get the id for that row and retrieve from the events store.
Just another option ...

What's the best way to do one-way synching from a server-side database to iPhone?

I've got a database on my server which is about 3mb big. I'd like to ship that with my iphone application.
The most important thing is that I'd like to promote changes to the database (insert, updates, deletes) to the iphone. What's the best way of doing that? I mean - what is necessary on
- the server
- the client (= iphone)
- between; how to transfer this data?
I'm pretty free in using technologies serverside; right now, I've got an sqlite-database on the server filled with the data I'd like to sync to the iphones.
How often do you need the database to be updated, and how urgent are the changes?
If the database updates are infrequent and non-urgent, I'd have the app check for a new version of the database on startup, and if it has changed, download the entire new file.
The app would always download a small metadata file from a known URL on startup. The metadata file contains an version identifier for the latest version and a location where that version of the database can be downloaded. If the version identifier has changed from the version the app already has, will download the new version. If the version identifier has not changed, or if it can't check, the app can keep using the version it has.
Pro tip: if you want to show a progress bar for the download, include the size of the database in the metadata file. Cell networks often have transparent proxies that strip out the Content-Length header from HTTP responses.
Try using web hooks.
The concept of a WebHook is simple. A
WebHook is an HTTP callback: an HTTP
POST that occurs when something
happens; a simple event-notification
via HTTP POST.
A web application implementing
WebHooks will POST a message to a URL
when certain things happen. When a web
application enables users to register
their own URLs, the users can then
extend, customize, and integrate that
application with their own custom
extensions or even with other
applications around the web. For the
user, WebHooks are a way to receive
valuable information when it happens,
rather than continually polling for
that data and receiving nothing
valuable most of the time. WebHooks
have enormous potential and are
limited only by your imagination! (No,
it can't wash the dishes. Yet.)
You can find out more on Webhooks here:
http://www.webhooks.org/ and http://webhooks.pbworks.com/
Wonder if you have considered using a Sync Framework to manage the synchronization. If that interests you can take a look at the open source project, OpenMobster's Sync service. You can do the following sync operations
two-way
one-way client
one-way device
bootup
Besides that, all modifications are automatically tracked and synced with the Cloud. You can have your app offline when network connection is down. It will track any changes and automatically in the background synchronize it with the cloud when the connection returns. It also provides synchronization like iCloud across multiple devices
Also, modifications in the Cloud are synched using Push notifications, so the data is always current even if it is stored locally.
Here is a link to the open source project: http://openmobster.googlecode.com
Here is a link to iPhone App Sync: http://code.google.com/p/openmobster/wiki/iPhoneSyncApp

iPhone offline application with synchronization

I'm looking into building an application which works just as well offline as it does online. Since the application cannot communicate with the server while in offline, there is some level of synchronization which needs to take place.
What are some good tools to read about and start thinking about when planning offline operations with synchronization for your iPhone?
What tools would I have to create on my own, versus tools that apple already provides to help with this particular issue?
I've been working on an app that handles this exact behavior for the last 2 months or so. It has a small subset of functions which are online only and a large set of functionality that is offline/online.
I'm using sqlite for local storage as suggested here with a modified version of the sqlitepersistentobjects library. The base version of sqlitepersistentobjects is not thread safe so watch out if you are using it. (check out objectiverecord in: objectivesync for a thread safe alternative but be prepared to dig into the code). If you are willing to develop for the 3.0 sdk then core data is another possibility for a sqlite library.
The overall architecture is simple enough I have modeled local storage using sqlite and remote interaction using objective resource against a rails app and REST api. It can use either xml or json for data serialization.
When an object is modified locally the change is first saved to the sqlite database record for that object and then added to a queue which is serialized and stored in the local sqlite db as well. (The queue can then be processed at any time)
If there is a connection available any queued local changes are deserialized and added to an NSOperationQueue which then processes them in the background.
In order to make this all work I've subclassed NSOperation so that it can support several types of remote queue operations - create, update, delete essentially using objective resource to make the remote requests.
The nice thing about using NSOperationQueue and NSOperation is that they handle the background threading for you so I'd highly recommend having a look at the apple docs for those classes and also at the apple threading guide.
When the application loads there is a bit of remote checking done and processed in the background to pull down the latest data - although to be honest I am still changing the way this behaves a bit.
That's a quick overview of what I've had to deal with so far...hope it helps a little.
there are plenty of application on the app store which rely on both online as well as offline data
what you should really be doing is on start of your app, run a background thread (which runs silently so your user never sees any delay). this thread downloads the latest data from your server and pushes it into your local database (sqlite is the best choice)
make sure you implement some kind of data versioning so that your app only downloads data which is actually changed since last download - else you would unnecessarily be downloading the entire dataset which can be quite huge (depending upon your app requirements)
also make sure to test for internet connectivity when doing this. if no internet is available, alert the user for sure
this way you get the best of both worlds. users when away from internet can still use your app with their local sqlite data
in iphone os 3.0 apple has introduced push services - where you can simply "PUSH" your data instead of doing a "PULL" however this is not available in the current iPhone OS (2.x.x)
Push is probably not a viable option here, since the amount of data you can push is miniscule, and basically comes back to "tell my app to make a server call". We use an online/offline model in Satchel. Whenever we have to communicate with the server, we bundle that communication (a URL and possibly some POST data) and store it to a database. If we're online, we pull it right back out, send it, and when we get a valid response back, we remove the record from the database. If we're offline, those rows build up, and the next time we ARE online, they get sent out. This is not a workable model in all situations, but can be adapted to most.
In 3.0, you've got access to CoreData, which is a great data management tool. Other than that, the NSURLXXX family is your friend.
I would store all the information I gather while offline in a SQLite database. Then, on user 's request, you can SYNC all the stored information with a server using HTTP or a custom TCP/IP protocol you can come up with.
I have been using this approach on Palm OS applications for almost 10 years now, and they do work very effectively.
As far as I know, the only "tool" you will have to accomplish this is plain old OBJECTIVE-C with Cocoa Touch. Although you could use some TCP/IP C++ libraries that will make your life easier if you decide to implement your own protocol.
Wonder if you have considered using a Sync Framework to manage the synchronization. If that interests you can take a look at the open source project, OpenMobster's Sync service. You can do the following sync operations
two-way
one-way client
one-way device
bootup
Besides that, all modifications are automatically tracked and synced with the Cloud. You can have your app offline when network connection is down. It will track any changes and automatically in the background synchronize it with the cloud when the connection returns. It also provides synchronization like iCloud across multiple devices
Also, modifications in the Cloud are synched using Push notifications, so the data is always current even if it is stored locally.
Here is a link to the open source project: http://openmobster.googlecode.com
Here is a link to iPhone App Sync: http://code.google.com/p/openmobster/wiki/iPhoneSyncApp

Overwrite database or update (iPhone)?

I have a content based, read-only iPhone app. Users can select favorite topics, which I need to track. Some topics I'd like to make available between app updates through the App Store. I'll need to track if users have downloaded these particular topics or not until the App Store update is available. This approach will consist of two tables for user tracking. All other tables contain mainly static content, save any new downloaded entries.
Before I began tracking user content, I'd always deploy the database on app updates. An overwrite - simple. But now I need to track certain user configurations. Rather than trying to keep track of which app version a user has and running through a list of sql scripts in the correct order, so the user is at the right database version, I'm thiking to use two databases. One contains static content and the other user data. The static content database is always overwritten. That keeps things simple. The database currently is 250kb. It will grow very slowly.
I have plans to use SDK 3.0 push notification and peer-to-peer as well, which will store any user config data in the user database.
Any one see problems with this approach?
This sounds alright to me. If you're using SQLite, you may want to look into the ATTACH DATABASE command, which lets you keep two databases open on the same connection.