Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Apple iCloud在uwp应用程序中访问联系人_C#_.net_Uwp_Icloud - Fatal编程技术网

C# Apple iCloud在uwp应用程序中访问联系人

C# Apple iCloud在uwp应用程序中访问联系人,c#,.net,uwp,icloud,C#,.net,Uwp,Icloud,我正在尝试在我的UWP应用程序中访问我的iCloud联系人。 我知道我可以通过访问我的Gmail联系人,也可以通过Microsoft的或访问我的Outlook联系人 苹果是否提供了一个API(Rest或其他),可以用来获取、更新、添加和删除联系人?如果是,是否有教程介绍如何设置access iCloud api?在花了很多天的时间试图解决这个问题之后,我想我已经开始破解这个问题了。我不确定(可能是我)苹果是否有意让这件事变得困难,但这比它应该做的更困难。 以下是我必须做的事情,甚至可以获取联系人

我正在尝试在我的UWP应用程序中访问我的iCloud联系人。 我知道我可以通过访问我的Gmail联系人,也可以通过Microsoft的或访问我的Outlook联系人


苹果是否提供了一个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>