Syncing EKRecurrenceRules with Cloud Service RFC 2445 iCalendar specification RRULE - ios

I'm trying to create a cloud based service which stores recurring Events. I have chosen to do this using the icalendar RRULE standards (RFC2445) and use a database schema as below exposed via cloud based service.
EventID
EventName
EventDescripton
Start
End
RecurrenceRule <-- Store RFC 2445 iCalendar specification RRULE (recurrence)
Active
Deleted
DateCreated
DateLastUpdated
I beleive that the EKRecurrenceRules are RFC 2445 compliant, however by storing the string representation of the RRULE or description of the EKRecurrenceRule makes for a more cross platform compliant architecture.
I am able to create a EKRecurrenceRule on the client side easily and extract the RRULE from the EKRecurrenceRule description property. However, my question is how to convert that description property back to an EKRecurrenceRule object on the client when extracted from the cloud service? It seems stupid Apple would expose a property to extract the compliant RRULE but not provide any way to convert an RRULE to a native object.
I'd like to avoid storing individual components of the EKRecurrence rule if possible.

you might be able to use this library:
https://github.com/FabienDiTore/ios-rrule_parser
to create an EKRecurrenceRule. If you do, please let me know.

...extract the RRULE from the EKRecurrenceRule description property
This seems fraught with peril. The documentation for -[id<NSObject> description] only guarantees that it returns "a string that describes the contents of the receiver" - EKRecurrenceRule's implementation might not give a proper RRULE in the future, or might change just barely enough that "extracting" the RRULE won't work. (This is probably why Apple doesn't provide anything to convert an RRULE back to an EKRecurrenceRule - they didn't mean for you to be able to extract and work with the RRULE in the first place.)
It seems to me that a better solution would be to find or write a library or EKRecurrenceRule category that provides a proper - (NSString *)rrule accessor and perhaps a corresponding - (id)initWithRRule:(NSString *)rrule initializer. That way, you can avoid relying on undocumented behavior and be confident that you can convert between RRULEs and EKRecurrenceRule instances in the way that you want.

Related

Orleans - how to use typesafe ids or references?

I'm testing Orleans out.
I want to store grain-ids for later use. Is there a way to make the ids typesafe? I want to make it impossible to mix ids of differet types of grains.
Or maybe I should store grainreferences instead? Can grainreferences be typesafe?
One of the overrides of GrainFactory.GetGrain have this signature:
IGrain GetGrain(Type grainInterfaceType, long grainPrimaryKey, string keyExtension);
So you can save the type next to the key, and be able to recreate it later in runtime.

What are ways to store complex dynamic objects locally (iOS, swift)?

I have iOS app that takes data from the server as json and then serializes them into objects of different types. Types can be complicated, can contain subtypes, can inherit, so there is no any limitations. Another thing that makes everything even more complicated is some of types are stored as AnyObject? and only in run time they are being serialized into real types accordingly to the specific rules. Something like that:
class A {
var typeName: String?
var b: AnyObject?
}
Then when it's serialized it can be done something like that:
if let someClass = NSClassFromString(typeName) as? SomeGenericType.Type{
b = someClass.init()
}
Also querying should be done on all the data. Currently I'm trying to store all of them locally, then load into memory and query there from the code. I'm using User defaults, but they have some limitations, also I needed to provide custom coding to make it work, and each time when I add a new field it turned out that I missed something in coding and nothing works. So it's pain.
Ideally I would just do some magic command and all the objects are sent to local storage no matter how complicated they are. The same to extract them from this storage. Also, user change data so I can't just store primary Json. And I don't want to covert objects back to Jason as for it's pain too.
Any suggestions?
If you want to use sqlite then You can store whole object in one row! I means you can create table with 2 columns one is id and second is your dataobject(it's data type should be blob). Then convert your whole object into data. Then store in sqlite table and retrieve it as data then convert it to object when want to use. By this way your object will remains in same format as you asked
Firebase while meant for online synching and storage can also cache everything locally in case you are offline and perform query's against the local cache. It uses JSON.
CouchDB also has a mobile version for iOS.
Both of those are over kill if your dataset is small; you can just store it as a text file and read the JSON back in. See performance characteristics here. The graph is for a 7MB file so if you are significantly less than that your load time may be minimal.
NSKeyedArchiver.archivedData(withRootObject:) is great for storing custom objects as Data objects. The only thing you need to do to be able to use this is to make your custom objects conform to NSCoding. A great example can be found here:
Save custom objects into NSUserDefaults
Once you have the Data version of the object, it can easily be stored in UserDefaults, as a property in CoreData, or even in the app's keychain entries. Depending on your use case, sensitivity of data, and how much data you intend to store, you might want to use any number of storage methods. NSKeyedArchiver.archivedData(withRootObject:) allows you to pretty much use any of them.

How to convert an event in string format into DDay.iCal Event?

I have an event string like so:
BEGIN:VEVENT
CREATED;
VALUE=DATE:00010101
DTSTAMP:20150527T074655Z
DTSTART;VALUE=DATE:00010101
EFFECTIVEDATETIME:2015-05-27T07:46:55.3203522+00:00
RRULE:FREQ=DAILY;BYHOUR=12;BYMINUTE=0
SEQUENCE:0
SUMMARY:BLAH
UID:0622249b-7161-4e31-9517-f51dddaa4cd8
END:VEVENT
How do I Deserialize this into DDay.iCal event?
You can't deserialize that, because you have invented things that aren't part of the icalendar spec, and aren't supported by ical.net (dday.ical is now ical.net). These things are malformed, or don't exist:
CREATED;
VALUE=DATE:00010101
EFFECTIVEDATETIME:2015-05-27T07:46:55.3203522+00:00
Have a look at the VEVENT documentation for valid VEVENT blocks:
http://www.kanzaki.com/docs/ical/vevent.html
Your question speaks to a weakness of the ical.net API: you can't deserialize icalendar components in a piecemeal fashion. In a perfect world, you would be able to pass your string to the Event constructor, and it would do the right thing.
I have an open ticket to re-evaluate ical.net's parsing and serialization which will cover this use case. Getting there will take some time.
https://github.com/rianjs/ical.net/issues/22

CoreData and the "Allows External Storage" option

I'm doing a tutorial on CoreData and they talked about the "Allows External Storage" option. The documentation says "When enabled, Core Data heuristically decides on a per-value basis if it should save the data directly in the database or store a URI to a separate file which it manages for you. You cannot query based on the contents of a binary data property if you use this option." I understand the first part but I don't understand what they mean by "You cannot query based on the contents of a binary data property if you use this option". I feel this is important stuff, but I can't understand it. "You cannot query based on the contents of a binary data", what does that mean? I don't if it's my bad english or something but I can't figure it out.
The tutorial is "Core Data by Tutorials" from the Ray Wenderlich's tutorial book series. I highly recommend!
image the NSData you store is jpeg data with an exif header.
if you store the data inside the DB, you can use a predicate matching said exif data: e.g. something like (pseudo) "jpgedData CONTAINS author: dominik"
if you store it as a separate file, that query wouldn't work as the data isn't really inside the database
[note that this was explanatory pseudo code and I can't really think of a practical / useful example]
All that means is that if you enable that option for a property, you can't use that property in an NSPredicate when fetching objects. A fetch request is a query, and when you use a predicate you're fetching objects based on whether they match the predicate. That doesn't work if external storage is allowed for the property.
Ok I think I got it. Basically you can't use the image's raw meta data to look for a specific image, because you don't have access to the raw data. You only have access to the URI. Sounds logical and fair to me, since you could just extract the meta data, and store it in your CoreData model before saving the image as a transformable (if need be).

Apache Taste String Id

Is it possible to use an id which isn't an integer using taste?
My model may have preferences for remote products. To differentiate these we use a string identifier which is "locationId:itemId".
I can't see support for this however.
Is there any other way to get around this?
Yes, though it's going to slow things down. Look at IDMigrator and implementations and usages in the framework. This is how you can get some help in translating to/from integer IDs automatically.
There is no support for this in the distributed version.
Yes. Look at the answers to this question. Basically you can extend FileDataModel, overriding readItemIDFromString(String stringID), and perhaps use an IDMigrator to do the conversion.
userId and itemId can be string, so this is the CustomFileDataModel which will convert your string into integer and will keep the map (String,Id) in memory; after recommendations you can get string from id.

Resources