从WatchExtension

时间:2016-04-22 09:07:22

标签: ios iphone swift calendar watchkit

我要求从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方法。 那么我可以做些什么来实现苹果手表呢?

1 个答案:

答案 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");
}