3

Since I upgraded my app to Xcode 9 and iOS 11, I've been experiencing some inconsistencies with EventKit.

  • For example, when creating a new event, the event.eventIdentifier is returning nil, when the property is declared as String!. Before iOS11, it returned an empty string
  • Another issue is that one of my users is getting also a nil title on an event when the property is also defined as String!.
  • I'm getting another report that my app os crashing when using the standard EventKitUI editor when editing a particular task.

I'm asking if anyone else is experiencing similar issues. I've already filed a bug report a while ago when it was still in beta.

Update: Apple has flagged my bug report as a duplicate of: 34134523

the Reverend
  • 12,305
  • 10
  • 66
  • 121
  • Seeing device only iOS 11 bugs myself. Just verified on 10 sim, 11 sim, and a 10 device. Bug only repros on 11 device. Events, yay – Stephen J Nov 20 '17 at 19:12

2 Answers2

1

I'm experiencing something similar. It seems to be because it's not able to retrieve the default calendar. I'm seeing this in my unit tests. I haven't yet been able to figure out why the default calendar is failing.

[EventKit] Error getting default calendar for new events: Error Domain=EKCADErrorDomain Code=1019 "(null)"

Paul Bruneau
  • 1,026
  • 1
  • 9
  • 15
0

Well, if it is String! (an implicitly unwrapped Optional) it can return nil. (just to be clear: if nil wouldn't be a possible return value, it would be just String, which provides exactly that guarantee.)

This is likely why you are now crashing on the 3rd point. If an API returns an optional, you need to check for nil (though they should make it a regular Optional [maybe they did when compiling in Swift 4?]). It could be something as simple as event.title ?? 'no title'.

The first two changes also seem reasonable to me.

The first is a fix in the API, returning an empty string for eventIdentifier is plain wrong. It has to return nil (meaning no identifier assigned).

The second also makes sense. The title is not a required field in iCalendar (SUMMARY property), so the API now properly reflects a missing title (vs an empty title).

Assuming they didn't change the API (which I think is not the case for 3.2), all this seems fine. Your code didn't properly check for nil values.

hnh
  • 13,957
  • 6
  • 30
  • 40
  • Why should I check for a nil value if its an implicitly unwrapped optional ? Isn't that the point of it? I think you are right, its better to get a nil value for a new event, but they need to reflect this new behavior in their event kit api. – the Reverend Oct 10 '17 at 19:04
  • "Why should I check for a nil value if its an implicitly unwrapped optional ? Isn't that the point of it?" No, that would be the point of a *non*-Optional type. Implicitly unwrapped optionals are mostly a convenience for the situation where the optional is *usually* non-nil. It is not a guarantee though, in this case one wouldn't use either Optional type in the first place. " they need to reflect this new behavior in their event kit api" The API didn't change. It was allowed to return nil values before. – hnh Oct 10 '17 at 19:12
  • I agree that it should be a regular Optional. And maybe it is in Swift 4 (would be worth checking). The whole point of Swift 3.2 is that the API (the interface) does not change and source code compiles as-is. – hnh Oct 10 '17 at 19:14
  • That is not what my testing is showing, previous SDK's did returned an empty string in the eventIdentifier. This is not a swift issue. Also from the swift docs about implicity unwrapped optionals: "Sometimes it’s clear from a program’s structure that an optional will always have a value" and "it can be safely assumed to have a value all of the time." It is not used for usually non-nil. – the Reverend Oct 10 '17 at 22:55
  • I understand that you don't like the change and you can argue circles around it, but this is what the API was saying before: `String!`. Which explicitly says that you can receive a `nil` from such a function (otherwise it would be `String`). – hnh Oct 10 '17 at 23:00
  • 1
    Neither, It should be declared as "String?" Since the EventKit is not written in swift, String! is an automatic swift interpretation when they haven't added nonnull or nullable type annotations to their api. Here is how is currently defined: @property(null_unspecified, nonatomic, readonly) NSString *eventIdentifier; Which is plainly wrong because in their comments say "This may be nil for events that have not been saved". This is clearly a nullable type "String?" There is a big difference, because the compiler will warn you if you don't check a String? – the Reverend Oct 11 '17 at 14:54
  • > "Implicitly unwrapped optionals are mostly a convenience for the situation where the optional is usually non-nil." -- I don't think that's what they are. You had better be more than "usually" if you are using implicitly unwrapped optionals. It should be a severe fail case that nil appears in one. – Paul Bruneau Oct 09 '18 at 17:48