C# Apple iCloud在uwp应用程序中访问联系人
我正在尝试在我的UWP应用程序中访问我的iCloud联系人。 我知道我可以通过访问我的Gmail联系人,也可以通过Microsoft的或访问我的Outlook联系人C# Apple iCloud在uwp应用程序中访问联系人,c#,.net,uwp,icloud,C#,.net,Uwp,Icloud,我正在尝试在我的UWP应用程序中访问我的iCloud联系人。 我知道我可以通过访问我的Gmail联系人,也可以通过Microsoft的或访问我的Outlook联系人 苹果是否提供了一个API(Rest或其他),可以用来获取、更新、添加和删除联系人?如果是,是否有教程介绍如何设置access iCloud api?在花了很多天的时间试图解决这个问题之后,我想我已经开始破解这个问题了。我不确定(可能是我)苹果是否有意让这件事变得困难,但这比它应该做的更困难。 以下是我必须做的事情,甚至可以获取联系人
苹果是否提供了一个API(Rest或其他),可以用来获取、更新、添加和删除联系人?如果是,是否有教程介绍如何设置access iCloud api?在花了很多天的时间试图解决这个问题之后,我想我已经开始破解这个问题了。我不确定(可能是我)苹果是否有意让这件事变得困难,但这比它应该做的更困难。 以下是我必须做的事情,甚至可以获取联系人(根本不知道如何添加、更新和删除联系人): 步骤1>使用apple id和密码请求令牌。如果2FA被激活,您将不会在响应标头中收到身份验证令牌和身份验证用户cookie。但没关系,我们将在下一步实现这一点。请注意,现在提取AUTH-TOKEN和AUTH-USER很可能会失败。此外,我们将在响应中接收区域设置信息和联系人链接,稍后我们将需要这些信息
公共密封部分类主页面:第页
{
字符串contactLink=“”;
字符串authToken=“”;
字符串authUser=“”;
公共主页()
{
this.InitializeComponent();
}
私有异步无效IcloudBtn\u单击(对象发送方,路由目标)
{
HttpResponseHeaderCollection respHeaders=等待联系Apple();
ContactsBlock.Text+=“联系人链接:”+contactLink+“\n”;
ContactsBlock.Text+=authToken+“\n”;
ContactsBlock.Text+=authUser+“\n”;
}
私有异步void GetToken\u单击(对象发送方,RoutedEventArgs e)
{
HttpResponseHeaderCollection respHeaders=等待联系Apple(AuthenticationCode.Text);
ContactsBlock.Text+=“联系人链接:”+contactLink+“\n”;
ContactsBlock.Text+=authToken+“\n”;
ContactsBlock.Text+=authUser+“\n”;
}
私有异步void GetContacts\u单击(对象发送方,路由目标)
{
Uri contactUri=新Uri(contactLink+“/co/startup?locale=en_US&order=last%2Cfirst”);
HttpClient=新的HttpClient();
client.DefaultRequestHeaders.Add(“Origin”https://www.icloud.com");
client.DefaultRequestHeaders.Add(“Cookie”,authToken+”;“+authUser+”;”);
HttpResponseMessage hrm=wait client.GetAsync(contactUri);
JObject contactJson=JObject.Parse(等待hrm.Content.ReadAsStringAsync());
ContactsBlock.Text+=contactJson[“contacts”];
}
专用异步任务ContactApple(字符串身份验证=“”)
{
//苹果id和密码
字符串appleId=“appleId”;
字符串password=“password”+身份验证;
// https://stackoverflow.com/questions/31457068/get-icloud-contact-list-in-c-sharp?noredirect=1&lq=1
//Post请求将在内容中包含此内容
字符串数据=“{\'apple\u id\”:“+appleId+”,“password\”:“+password+”,“extended\u login\”:true}”;
HttpStringContent内容=新的HttpStringContent(数据,UnicodeEncoding.Utf8);
//要从中获取令牌的URI:
Uri requestUri=新Uri(“https://setup.icloud.com/setup/ws/1/accountLogin");
//创建HttpClient的实例(Windows.Web.Http)
HttpClient=新的HttpClient();
//添加原点=https://www.icloud.com 在标题中。
client.DefaultRequestHeaders.Add(“Origin”https://www.icloud.com");
//作为JSON对象发布请求和读取响应(NewtonSoft)
HttpResponseMessage hrm=wait client.PostAsync(请求URI,内容);
JObject resp=JObject.Parse(等待hrm.Content.ReadAsStringAsync());
//获取联系人的URL
contactLink=(字符串)resp[“Web服务”][“联系人”][“url”];
//读取AUTH-TOKEN和AUTH-USER cookie的标题,
HttpResponseHeaderCollection headers=hrm.headers;
if(headers.ContainsKey(“设置Cookie”))
{
字符串cookie=标题[“设置cookie”];
字符[]分隔符={';',','};
String[]tokens=cookie.Split(分隔符);
foreach(令牌中的字符串令牌)
{
int length=token.length;
if(token.Contains(“X-APPLE-WEBAUTH-token”))
{
authToken=令牌;
}
if(token.Contains(“X-APPLE-WEBAUTH-USER”))
{
authUser=token;
}
}
}
返回标题;
}
}
步骤2>如果2FA被激活,您将在Apple设备上收到一个请求,以授权登录并使用提供的代码登录。获得代码后,重复上述相同步骤,仅通过在授权代码文本字段中提供将代码附加到密码中
请注意,您需要输入授权代码
步骤3>希望您现在已经收到获取联系人所需的令牌。现在,您可以在获取令牌并附加“/co/startup?locale=XXXXX&order=last%2Cfirst”时,使用响应正文中获得的联系人链接获取联系人
请注意,您必须使用适合您需要的区域设置。我需要使用“en_US”,因为这是我在响应中使用的语言环境。您需要使用请求中返回的区域设置
XAML:
但是,我仍然不知道如何实际操作联系人列表。我想如果我发现了,我会在这里更新。因此,如果你只想获取联系人(以及JSON格式),我之前的答案可能是正确的。 然而,由于我希望能够在Apple帐户上执行CRUD操作,更好的方法是使用CARDDAV协议th
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;
}
}
<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>
<propfind
xmlns="DAV:">
<prop>
<current-user-principal/>
</prop>
</propfind>
<propfind
xmlns="DAV:"
xmlns:c="urn:ietf:params:xml:ns:carddav">
<prop>
<c:addressbook-home-set/>
</prop>
</propfind>
<propfind
xmlns="DAV:">
<prop>
<resourcetype/>
</prop>
</propfind>
<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>