我正在尝试在UWP应用程序中访问我的iCloud联系人。 我知道我可以通过Google's People API访问我的Gmail联系人,并可以通过Microsoft的Graph api或Outook people api访问Outlook联系人。
Apple是否提供可用于获取,更新,添加,删除联系人的API(Rest或其他方式)?如果是,是否有一个教程可以逐步介绍如何设置访问iCloud api?
答案 0 :(得分:0)
花了很多天试图弄清楚这一点之后,我认为我开始对此进行破解。我不确定(也许是)苹果是否有意使这一过程变得困难,但这比原本应该的困难。 这是我什至需要获取联系人的方法(根本不知道如何添加,更新或删除它们):
步骤1>使用Apple ID和密码请求令牌。如果激活了2FA,则在响应标头中将不会收到auth令牌和auth用户cookie。但这没关系,我们将在下一步中解决。请注意,最有可能暂时无法提取AUTH-TOKEN和AUTH-USER。另外,我们将在以后的回复中接收语言环境信息和联系链接。
public sealed partial class MainPage : Page
{
String contactLink = "";
String authToken = "";
String authUser = "";
public MainPage()
{
this.InitializeComponent();
}
private async void IcloudBtn_Click(object sender, RoutedEventArgs e)
{
HttpResponseHeaderCollection respHeaders = await ContactApple();
ContactsBlock.Text += "CONTACT LINK: " + contactLink + "\n";
ContactsBlock.Text += authToken + "\n";
ContactsBlock.Text += authUser + "\n";
}
private async void GetToken_Click(object sender, RoutedEventArgs e)
{
HttpResponseHeaderCollection respHeaders = await ContactApple(AuthenticationCode.Text);
ContactsBlock.Text += "CONTACT LINK: " + contactLink + "\n";
ContactsBlock.Text += authToken + "\n";
ContactsBlock.Text += authUser + "\n";
}
private async void GetContacts_Click(object sender, RoutedEventArgs e)
{
Uri contactUri = new Uri(contactLink + "/co/startup?locale=en_US&order=last%2Cfirst");
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Origin", "https://www.icloud.com");
client.DefaultRequestHeaders.Add("Cookie", authToken + ";" + authUser + ";");
HttpResponseMessage hrm = await client.GetAsync(contactUri);
JObject contactJson = JObject.Parse(await hrm.Content.ReadAsStringAsync());
ContactsBlock.Text += contactJson["contacts"];
}
private async Task<HttpResponseHeaderCollection> ContactApple(String authentication = "")
{
// The apple id and the password
String appleId = "AppleID";
String password = "Password" + authentication;
// https://stackoverflow.com/questions/31457068/get-icloud-contact-list-in-c-sharp?noredirect=1&lq=1
// Post request will have this in the content
String data = "{\"apple_id\":" + appleId + ", \"password\":" + password + ", \"extended_login\":true}";
HttpStringContent content = new HttpStringContent(data, UnicodeEncoding.Utf8);
// The URI to get the tokens from:
Uri requestUri = new Uri("https://setup.icloud.com/setup/ws/1/accountLogin");
// Create an instance of the HttpClient (Windows.Web.Http)
HttpClient client = new HttpClient();
// Add Origin = https://www.icloud.com in the header.
client.DefaultRequestHeaders.Add("Origin", "https://www.icloud.com");
// Post request and read response as JSON object (NewtonSoft)
HttpResponseMessage hrm = await client.PostAsync(requestUri, content);
JObject resp = JObject.Parse(await hrm.Content.ReadAsStringAsync());
// Get the URL to the contacts
contactLink = (String)resp["webservices"]["contacts"]["url"];
// Read the headers for AUTH-TOKEN and AUTH-USER Cookies,
HttpResponseHeaderCollection headers = hrm.Headers;
if (headers.ContainsKey("Set-Cookie"))
{
String cookie = headers["Set-Cookie"];
char[] separators = { ';', ',' };
String[] tokens = cookie.Split(separators);
foreach (String token in tokens)
{
int length = token.Length;
if (token.Contains("X-APPLE-WEBAUTH-TOKEN"))
{
authToken = token;
}
if (token.Contains("X-APPLE-WEBAUTH-USER"))
{
authUser = token;
}
}
}
return headers;
}
}
第2步>如果2FA已激活,您将在Apple设备上收到请求以授权登录并使用提供的代码进行登录。获得代码后,请重复上述步骤,仅附加通过在授权码文本字段中提供密码来输入密码。
请注意,您将需要输入授权码。
第3步>希望您现在已收到获取联系人所需的令牌。现在,您可以通过使用在响应正文中获得的联系链接来获取联系人,同时获取令牌并附加“ / co / startup?locale = XXXXX&order = last%2Cfirst”
请注意,您将必须使用适合您需要的语言环境。我需要使用“ en_US”,因为这就是我在响应中所使用的语言环境。您将需要使用请求中返回的语言环境。
XAML:
<Page
x:Class="AddressBook.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AddressBook"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel x:Name="MainStack">
<Button x:Name="IcloudBtn" Content="Request Code" Click="IcloudBtn_Click"/>
<TextBox x:Name="AuthenticationCode" Text="Authentication Code here." TextWrapping="Wrap"/>
<Button x:Name="GetToken" Content="Get Token" Click="GetToken_Click"/>
<Button x:Name="GetContacts" Content="Get Contacts" Click="GetContacts_Click"/>
<TextBox x:Name="ContactsBlock" TextWrapping="Wrap"/>
</StackPanel>
</Page>
但是,我仍然不知道如何实际操作联系人列表。我想如果我发现了,我会在这里更新。
答案 1 :(得分:0)
因此,如果您只想获取联系人(并以JSON格式),则我以前的答案可能是解决方法。 但是,由于我希望能够对Apple帐户执行CRUD操作,因此更好的方法是使用icloud / apple支持的CARDDAV协议。
- 通过在here上发出带有请求内容的PROPFIND请求,以使用基本身份验证获取主要用户(此基本身份验证中使用的密码必须作为应用程序密码https://contacts.icloud.com生成):< / li>
<propfind
xmlns="DAV:">
<prop>
<current-user-principal/>
</prop>
</propfind>
- 上一步将使您可以检索格式为/ 1437425399 / principal /的原理。现在,您可以在链接https://contacts.icloud.com/1437425399/principal上使用以下请求内容来触发对此用户的家庭设置的PROPFIND查询:
<propfind
xmlns="DAV:"
xmlns:c="urn:ietf:params:xml:ns:carddav">
<prop>
<c:addressbook-home-set/>
</prop>
</propfind>
- 从上一个请求中,您将获得格式为https://p48-contacts.icloud.com:443/1437425399/carddavhome/的家庭链接。您可以在首页链接上使用以下PROPFIND请求查询用户的vcard的位置:
<propfind
xmlns="DAV:">
<prop>
<resourcetype/>
</prop>
</propfind>
- 您将收到放置所有卡的位置(例如/ 1437425399 / carddavhome / card /)。使用地址簿查询,现在您可以在上一个链接中收到的端点上发起REPORT请求:
<c:addressbook-query
xmlns="DAV:"
xmlns:c="urn:ietf:params:xml:ns:carddav">
<prop>
</prop>
</c:addressbook-query>
- 这将为您提供标签中的所有卡片。然后,您可以使用地址簿多报告请求来获取多张卡片:
<c:addressbook-multiget
xmlns="DAV:"
xmlns:c="urn:ietf:params:xml:ns:carddav">
<prop>
<getetag />
<c:address-data />
</prop>
<href>/1437425399/carddavhome/card/somecard.vcf</href>
<href>/1437425399/carddavhome/card/anothercard.vcf</href>
</c:addressbook-multiget>
对于更新,创建和删除卡,您可以使用我们先前在将Content-Type设置为“ text / vcard”之后讨论的基本身份验证,在“ /1437425399/carddavhome/card/cardtobemanipulated.vcf”端点上触发PUT请求。并发送内容中的VCard以进行更新和创建请求。