我要求从Watch Extension向日历添加新事件。 我正在创建一个与IOS App绑定的Apple Watch应用程序,监视应用程序读取通过表视图中的应用程序上下文传递给它的JSON字符串。 我需要做的是当用户点击表格单元格时,应该在手表的iPhone日历中添加新事件。
我可以使用以下代码
从应用程序成功添加事件到日历func WatchEvent(){
let eventStore = EKEventStore()
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
let date = dateFormatter.dateFromString("2016-05-28T20:20:00")
let endDate = date!.dateByAddingTimeInterval(1 * 60 * 60) // One hour
if (EKEventStore.authorizationStatusForEntityType(.Event) != EKAuthorizationStatus.Authorized) {
eventStore.requestAccessToEntityType(.Event, completion: {
granted, error in
self.createEvent(eventStore, title: "TestTitile :"+"Dr.Test", startDate: date!, endDate: endDate , alertinterval:-(24 * 60 * 60) , notes: "TestNote" , appointmentlocation: "TestLocation")
})
} else {
self.createEvent(eventStore, title: "TestTitlte :"+"Dr.Test", startDate: date!, endDate: endDate , alertinterval:-(24 * 60 * 60) , notes: "TestNote" , appointmentlocation: "TestLocation")
}
}
//==================================================================
func createEvent(eventStore: EKEventStore, title: String, startDate: NSDate, endDate: NSDate, alertinterval:NSTimeInterval , notes: String , appointmentlocation: String) {
let event = EKEvent(eventStore: eventStore)
event.title = title
event.startDate = startDate
event.endDate = endDate
event.calendar = eventStore.defaultCalendarForNewEvents
var interval = NSTimeInterval()
interval = alertinterval
//-(24 * 60 * 60) // -(30 * 60) // -(24 * 60 * 60)
let alarm = EKAlarm(relativeOffset: interval)
event.addAlarm(alarm)
event.notes = notes
event.location = appointmentlocation
do {
try eventStore.saveEvent(event, span: .ThisEvent)
// savedEventId = event.eventIdentifier
} catch {
print("Error Happened")
}
}
但我仍然坚持在Watch扩展中添加它,因为WatchOS中没有SaveEvent方法。 那么我可以做些什么来实现苹果手表呢?
答案 0 :(得分:0)
我觉得回答这个问题为时已晚,但如果对我这样的人有帮助,那将是我的荣幸:)
来自watchOS2,您无法直接从watchOS保存活动,也无法从配对设备访问钥匙串详细信息。因此,为此,您需要通过监视连接框架向配对设备发送请求,并尝试将事件保存在配对设备(iPhone)中。
在做任何事情之前,首先在iOS和watchOS类中设置监视连接,例如app delegate的didFinishLaunching
和watchOS任何视图控制器初始化方法(从你想要添加事件的位置)。
#import <WatchConnectivity/WatchConnectivity.h>
if ([WCSession isSupported]) {
WCSession *session = [WCSession defaultSession];
session.delegate = self;
[session activateSession];
}
在下一步之后移动,即保存事件的watchOS方法: -
-(void)addEventToDeviceCalendar
{
self.eventStore = [[EKEventStore alloc] init];
[self.eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (!granted) { return; }
NSMutableDictionary *eventInfoDict = [NSMutableDictionary new];
self.defaultCalendar = [self.eventStore defaultCalendarForNewEvents];
EKEvent *event = [EKEvent eventWithEventStore:self.eventStore];
event.title = title;
[eventInfoDict setObject:title forKey:@"eventTitle"];
if (eventDate)
{
NSString *dateString = eventDate;
//dateString = [NSString stringWithFormat:@"%@ %@",eventDate,@"09:00:00"];
if (eventTime) {
dateString = [NSString stringWithFormat:@"%@ %@",eventDate,eventTime];
[eventInfoDict setObject:@YES forKey:@"eventTime"];
}
[eventInfoDict setObject:dateString forKey:@"eventDate"];
NSDate *date = [[MyDataObject sharedInstance] dateFromDateString:dateString];
event.startDate = date;
}
else{
event.startDate = [NSDate date]; //today
}
event.endDate = [event.startDate dateByAddingTimeInterval:60*60]; //set 1 hour meeting
event.location = venue;
[eventInfoDict setObject:venue forKey:@"location"];
event.notes = description;
[eventInfoDict setObject:description forKey:@"notes"];
[event setCalendar:self.defaultCalendar];
NSMutableDictionary *trackDict = [[NSMutableDictionary alloc] init];
[trackDict setObject:kAppleWatchAddEvent forKey:kRequestTypeWatchKit];
[trackDict setValue:eventInfoDict forKey:kAppleWatchEvent];
// Only if using WatchOS 2 or higher
[[WCSession defaultSession] sendMessage: trackDict
replyHandler:^(NSDictionary *replyHandler) {
NSString *obj = [replyHandler valueForKey:@"reply"];
NSLog(@"%@",obj);
if ([obj isEqual:kAppleWatchAddEvent])
{
savedEventId = event.eventIdentifier;
}
}
errorHandler:^(NSError *error) {
}
];
//[self.eventStore saveEvent:event span:EKSpanThisEvent commit:YES error:&err]; ******* Watch OS does not support save or remove event ******
}];
}
之后你需要在iOS端处理回复回调函数,如下所示: -
- (void)session:(nonnull WCSession *)session didReceiveMessage:(NSDictionary<NSString *,id> *)message replyHandler:(void(^)(NSDictionary<NSString *,id> *))replyHandler {
NSString *requestType = message[kRequestTypeWatchKit];
if ([requestType isEqual:kAppleWatchAddEvent]) {
NSMutableDictionary *event = message[kAppleWatchEvent];
[self addWatchEventToDeviceCalendar:event replyHandler:^(NSDictionary *replyHandlerForWatch) {
replyHandler(replyHandlerForWatch);
}];
}
}
-(void)addWatchEventToDeviceCalendar:(NSMutableDictionary *)eventObj replyHandler:(void(^)(NSDictionary<NSString *,id> *))replyHandler
{
[self.eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (!granted) { replyHandler(@{@"reply":@"notAdded"}); }
self.defaultCalendar = [self.eventStore defaultCalendarForNewEvents];
EKEvent *event = [EKEvent eventWithEventStore:self.eventStore];
event.title = [eventObj objectForKey:@"eventTitle"];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setLocale:[NSLocale localeWithLocaleIdentifier:[APP_DELEGATE LanguageCode]]];
if (eventObj[@"eventTime"]) {
[df setDateFormat:@"EEE MMM d h:mma"];
}else{
[df setDateFormat:@"EEE MMM d"];
}
if (eventObj[@"eventDate"])
{
NSString *dateString = [eventObj objectForKey:@"eventDate"];
NSDate *date = [df dateFromString:dateString];
event.startDate = date;
}
else{
event.startDate = [NSDate date]; //today
}
event.endDate = [event.startDate dateByAddingTimeInterval:60*60]; //set 1 hour meeting
event.location = [eventObj objectForKey:@"location"];
event.notes = [eventObj objectForKey:@"notes"];
[event setCalendar:self.defaultCalendar];
NSError *err = nil;
[self.eventStore saveEvent:event span:EKSpanThisEvent commit:YES error:&err];
replyHandler(@{@"reply":kAppleWatchAddEvent});
}];
}
现在非常重要的是,请不要忘记使用WatchKit框架的这些方法来检查和保持iOS和watchOS端的连接状态
#pragma mark - Standard WatchKit Delegate
- (void)sessionDidDeactivate:(WCSession *)session
{
if(WCSession.isSupported){
WCSession* session = WCSession.defaultSession;
session.delegate = self;
[session activateSession];
}
}
-(void)sessionWatchStateDidChange:(nonnull WCSession *)session
{
if(WCSession.isSupported){
WCSession* session = WCSession.defaultSession;
session.delegate = self;
[session activateSession];
if(session.reachable){
NSLog(@"session.reachable");
}
if(session.paired){
if(session.isWatchAppInstalled){
if(session.watchDirectoryURL != nil){
}
}
}
}
}
#pragma mark - WatchKit Handlers
- (void)session:(WCSession *)session activationDidCompleteWithState:(WCSessionActivationState)activationState
error:(NSError *)error
{
NSLog(@"PHONE - activationDidCompleteWithState");
}