如何将事件推送到iPhone日历

7

我正在尝试将我的应用程序(Windows桌面应用程序和Web应用程序)与移动日历集成。

我的应用程序应该:

  • 向移动日历推送新事件
  • 从移动日历获取事件

到目前为止,我已经成功地与Google日历集成(非常容易,使用简单库 + OAuth)。

现在我想用iCloud日历做同样的事情,但这并不容易。

  • 在iCloud设置中,我可以将日历设为公共。 然后我可以获取事件(作为iCalendar文件),但无法推送事件。
  • 找不到任何认真的iCloud日历集成库。 我尝试过CalDav.Client,但需要提供CalDAV服务器网址,根据文献,应该长这样"https://pXX-caldav.icloud.com/USER_ID/calendars/CALENDAR_ID"。 我不知道USER_IDCALENDAR_ID是什么,也不知道在哪里找到它们。

有什么想法吗?

PS

有一个变通方法。 我可以要求用户创建一个Google帐户以及一个日历,并将其用作代理。 将iPhone与Google日历集成,然后从另一侧将我的应用程序与Google日历集成。 它有效,但对于用户来说配置有点繁琐。

编辑

我尝试了@hnh的指示,通过以下方式发现了CalDAV:

PROPFIND https://p42-caldav.icloud.com/ HTTP/1.1
Depth: 0
Prefer: return-minimal
Content-Type: application/xml; charset=utf-8
Host: p42-caldav.icloud.com
Content-Length: 102

<d:propfind xmlns:d="DAV:">
  <d:prop>
     <d:current-user-principal />
  </d:prop>
</d:propfind>

结果是401:

HTTP/1.1 401 Unauthorized
Content-Type: text/html;charset=utf-8
WWW-Authenticate: x-mobileme-authtoken realm="MMCalDav"
WWW-Authenticate: basic realm="MMCalDav"
Server: iCloudCalendarServer 15G33
Date: Tue, 26 Jan 2016 12:46:14 GMT
X-Responding-Server: mr26p42ic-ztdg05101801 17 a63660a6f7d1a25b5a7ed66dab0da843
X-Transaction-Id: c8dc19d4-c42a-11e5-8381-008cfaeb448c
Content-Length: 141
Strict-Transport-Security: max-age=31536000; includeSubDomains

<html><head><title>Unauthorized</title></head><body><h1>Unauthorized</h1><p>You are not authorized to access this resource.</p></body></html>

编辑 2

按照进一步的说明,我成功进行了身份验证,但仍然在文章中的请求方面遇到问题:

对于:

<d:propfind xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/">
  <d:prop>
     <d:displayname />
     <cs:getctag />
  </d:prop>
</d:propfind>

我得到的是:(未找到ctag,并且displayName的值为“tmp”-我不认识)
<?xml version='1.0' encoding='UTF-8'?>
<multistatus xmlns='DAV:'>
  <response>
    <href>/</href>
    <propstat>
      <prop>
        <displayname>tmp</displayname>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
    <propstat>
      <prop>
        <getctag xmlns='http://calendarserver.org/ns/'/>
      </prop>
      <status>HTTP/1.1 404 Not Found</status>
    </propstat>
  </response>
</multistatus>

而对于这个:

<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
    <d:prop>
        <d:getetag />
        <c:calendar-data />
    </d:prop>
    <c:filter>
        <c:comp-filter name="VCALENDAR" />
    </c:filter>
</c:calendar-query>

我收到了400错误请求。

“你的应用程序”是什么?它是iOS应用程序还是Web服务? - hnh
1
@hnh 这是一个Windows桌面应用程序,或者是一个Web应用程序(最好是桌面应用程序,但Web也可以)。 - Andrzej Gis
编辑2:URL很可能是错误的。请仔细(重新)阅读构建CalDAV客户端 - hnh
@gisek,你写过一段能够成功连接到icloud日历的代码吗? - Beetlejuice
@Beetlejuice 不,但说实话我很快就放弃了。 - Andrzej Gis
1个回答

3
这是一篇很好的介绍:构建CalDAV客户端,它还描述了日历发现过程的工作原理(如何找到日历homeset URL)。
许多CalDAV服务器不支持OAuth,通常需要要求用户提供登录名和密码。
似乎没有针对CalDAV的.NET库。您可以在这里找到实现列表:http://caldav.calconnect.org/implementations/librariestools.html
总结:可能不像您使用Google那样容易,但也不是非常困难。一旦拥有它,您就可以连接到许多不同的服务器,因为CalDAV是一个标准...(包括Google,您也可以使用CalDAV连接到它)。
问题编辑后的更新:
401是通用的HTTP响应,意味着您需要提供凭据以继续请求。客户端通常会提示用户输入登录名和密码,然后重新运行请求。基本认证在Wikipedia上的Basic auth文章中有很好的描述。
另一个错误是使用作为入口点URL。请使用,因为您不知道用户所在的分区。您需要像构建CalDAV客户端中描述的那样使用发现过程来找到实际托管用户日历的URL。

这部分怎么样?“我需要提供给CalDAV服务器URL,根据这个应该是这样的”https://pXX-caldav.icloud.com/USER_ID/calendars/CALENDAR_ID。“我在哪里可以找到USER_ID和CALENDAR_ID的值?” - Andrzej Gis
发现过程无法使用iCloud。它需要授权。我甚至不确定是否命中了正确的URL。请查看编辑。 - Andrzej Gis
链接是通用的,因为CalDAV是通用的。iCloud是一个CalDAV服务器,您需要实现它以可靠地连接到它。例如,您必须实现Discovery,因为URL结构可能会更改,并且过去确实发生了这种情况。 - hnh
iCloud在我发布的链接中所描述的完全有效。除非您提供凭据,否则无法发现用户的主页URL。 401是通用HTTP的一部分,并在[RFC2616](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2)中指定。我提到了您需要哪个:基本。响应中也这样说(WWW-Authenticate:basic)。 - hnh
谢谢。这让我进一步了解了一些,但还不够。您能否请看一下EDIT2? - Andrzej Gis
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接