2015-06-03 15 views
19

Mein Ziel ist es, einige Gäste zu einem EKEvent hinzuzufügen. Ich habe andere Fragen wie diese wie this one untersucht, aber alle sagen, dass es im Wesentlichen unmöglich ist, EKParticipant s zu einem EKEvent programmgesteuert hinzuzufügen. Ich sehe, dass die attendees Eigenschaft schreibgeschützt ist, aber ich sehe andere Dienste wie Sunrise in ihrer mobilen App verwenden.Ändern von EKParticipants (Teilnehmer) in EventKit wie Sunrise

Ich bin zuversichtlich, dass sie ein System verwenden, das zumindest teilweise in EventKit integriert ist, weil sie Kalender aus der iCal App des Benutzers ziehen. Einladungen, die beispielsweise von einem hinzugefügten Exchange-Konto gesendet werden, werden auch eindeutig vom Exchange-Dienst gesendet, im Gegensatz zu Sunrise's eigener Einladung (entweder wenn das Ereignis direkt an Exchange gesendet oder an iCal gesendet wird).

Jede Umgehung dieser Einschränkung wäre sehr hilfreich - vielleicht ein Endpunkt in Exchange, der zum Hinzufügen/Entfernen von Eingeladenen aufgerufen werden kann? Ein Workaround innerhalb von EventKit? Solange es keine private Apple API ist, wäre ich mehr als glücklich, es auszuprobieren.

Danke!

+0

Aus meiner Erfahrung war es nicht möglich, 'EKParticipant' Objekte hinzuzufügen, selbst mit privaten API. Speichern würde immer fehlschlagen. Könnte sein, dass ich nicht hart genug gegraben habe, aber mein Gefühl ist, dass sie nur Leute wollen, die Teilnehmer mit EventKitUI hinzufügen (vielleicht aus Datenschutzgründen). Ich wäre überrascht, wenn eine beliebte Anwendung wie Sunrise private API verwenden würde, um Ereignisse zu bearbeiten. –

+0

Wenn Sie an privaten API interessiert sind, lassen Sie es mich wissen, und ich werde noch einmal eine Chance geben. –

+0

@LeoNatan Vielen Dank für Ihre Antwort. Leider muss ich mich an öffentliche APIs halten, um den App Store-Richtlinien zu entsprechen. Wäre es möglich, Teilnehmer nachträglich über einen REST-Aufruf mit einer von EventKit erhaltenen Kalender-ID hinzuzufügen? – rebello95

Antwort

11

Ich habe es herausgefunden!

Im Wesentlichen muss man in die EKAttendee Klasse gehen, die von EKParticipant erbt. Ich habe dies getan, indem ich eine generische Instanz dieser Klasse mit der Methode NSClassFromString() erstellt habe. Wenn Sie einen Teilnehmer haben, können Sie die Eigenschaften mithilfe der Funktion setValue:ForKey: festlegen.

Schließlich kompilieren Sie Ihre EKAttendee Instanzen in ein Array und setzen Sie das auf die attendees Eigenschaft.

Ich testete dies mit einem Exchange-Konto auf meinem Gerät, und es funktionierte wie ein Charme - Einladung gesendet und alles!

Der Code unten ist, was ich jetzt verwende, um die Teilnehmer der Ereignisse einzustellen. Mein Beispiel ist zum Erstellen neuer Ereignisse, aber dies kann sehr einfach für bestehende Ereignisse durchgeführt werden, indem eine Kopie der attendees Liste auf EKEvent gemacht wird, dann diese geändert und neu eingestellt wird.

//Create generic event info 
EKEvent *event = [EKEvent eventWithEventStore:database]; 
event.title = @"TEST EVENT"; 
event.location = @"Test location"; 
event.notes = @"Example notes"; 
event.startDate = [NSDate date]; 
event.endDate = [[NSDate date] dateByAddingTimeInterval:(60 * 60)]; 
event.calendar = exchange; 

//Do our super clever hack 
NSMutableArray *attendees = [NSMutableArray new]; 
for (int i = 0; i < 5; i++) { 

    //Initialize a EKAttendee object, which is not accessible and inherits from EKParticipant 
    Class className = NSClassFromString(@"EKAttendee"); 
    id attendee = [className new]; 

    //Set the properties of this attendee using setValue:forKey: 
    [attendee setValue:@"Invitee" forKey:@"firstName"]; 
    [attendee setValue:[NSString stringWithFormat:@"#%i", i + 1] forKey:@"lastName"]; 
    [attendee setValue:@"[email protected]" forKey:@"emailAddress"]; 

    //Add this attendee to a list so we can assign it to the event 
    [attendees addObject:attendee]; 
} 

//Finally, add the invitees to the event 
[event setValue:attendees forKey:@"attendees"]; 

//Save the event! 
NSError *error = nil; 
[database saveEvent:event span:EKSpanThisEvent error:&error]; 
if (error) { 
    NSLog(@"Save failed with error: %@", error); 
} else { 
    NSLog(@"Success!"); 
} 
+0

Eigentlich habe ich diese Methode ausprobiert und habe Probleme in der Vergangenheit gesehen. Stellen Sie sicher, dass Sie mehr als nur den Simulator testen. –

+0

@LeoNatan Ja, ich habe auf echten Geräten getestet und hatte noch kein Problem. Schätze, wir werden sehen ... – rebello95

+0

@LeoNatan welche Art von Problemen hast du in der Vergangenheit gesehen? –

6

Schnelle Version von rebello95 Lösung. Ich kann bestätigen, dass es wie ein Charme funktioniert! Ich spielte mit den firstName und lastName Eigenschaften herum, aber sie scheinen überhaupt keine Rolle zu spielen, also habe ich sie aus meinem Beispiel gestrichen. Nur die emailAddress zählt, die mit Ihrer Kontaktliste verglichen wird, um einen vollständigen Namen in beispielsweise der nativen Kalender-App anzuzeigen.

private func createEventWithAttendees() { 
    let eventStore = EKEventStore() 

    let calendars = eventStore.calendarsForEntityType(.Event) 

    let event = EKEvent(eventStore: eventStore) 
    event.title = "TEST EVENT" 
    event.startDate = NSDate() 
    event.endDate = NSDate().dateByAddingTimeInterval(60 * 60) 
    event.calendar = calendars[0] 

    var attendees = [EKParticipant]() 
    for i in 0 ..< 5 { 
     if let attendee = createParticipant(email: "test\(i)@email.com") { 
      attendees.append(attendee) 
     } 
    } 
    event.setValue(attendees, forKey: "attendees") 

    try! eventStore.saveEvent(event, span: .ThisEvent) 
} 

private func createParticipant(email email: String) -> EKParticipant? { 
    let clazz: AnyClass? = NSClassFromString("EKAttendee") 
    if let type = clazz as? NSObject.Type { 
     let attendee = type.init() 
     attendee.setValue(email, forKey: "emailAddress") 
     return attendee as? EKParticipant 
    } 
    return nil 
} 
+0

Dies wurde mit Swift 3.1 und iOS 10.x versucht - der 'eventStore.saveEvent (...) 'Fehler mit der Fehlermeldung' Fehler Domain = EKErrorDomain Code = 35 'Teilnehmer können nicht geändert werden.'' – leviathan

+0

(Getestet auf Xcode 9.1 beta und iPhone X Simulator) Ich bin in der Lage, Personen einzuladen und anzuhängen (Änderungen an bestehenden Array zu machen) als Organisator, aber nicht in der Lage, als Eingeladener anzuhängen. Außerdem kann ich keine Einladung annehmen. In allen fehlgeschlagenen Fällen lautet der Fehler "Teilnehmer können nicht geändert werden". Irgendeine Hilfe? –