내보내기(0) 인쇄
모두 확장
정보
요청한 주제가 아래에 표시됩니다. 그러나 이 주제는 이 라이브러리에 포함되지 않습니다.

Windows Phone 8의 기본 사용자 지정 연락처 저장소 작업을 수행하는 방법

2014-06-18

적용 대상: Windows Phone 8 및 Windows Phone Silverlight 8.1만

이 항목에서는 앱에 사용자 지정 연락처 저장소를 만드는 방법과 연락처를 추가, 업데이트하고 삭제하는 등의 기본적인 작업을 수행하는 방법에 대해 설명합니다.

이 항목에는 다음 단원이 포함되어 있습니다.

참고참고:

사용자 지정 연락처 저장소 API의 경우 앱에서 만들어진 연락처에만 액세스할 수 있습니다. 앱에 휴대폰의 연락처 저장소나 일정에 대한 읽기 액세스 권한이 필요한 경우에는 다른 API를 사용해야 합니다. 자세한 내용은 Windows Phone 8의 연락처 및 일정에 대한 읽기 전용 액세스를 참조하세요.

각각의 Windows Phone 앱에서는 하나의 연락처 저장소를 사용할 수 있습니다. CreateOrOpenAsync를 호출하여 이 저장소를 엽니다. 이 저장소가 아직 없는 경우 이 메서드를 호출하면 만들어집니다. 오버로드된 이 메서드 버전은 ContactStoreSystemAccessMode 열거형 멤버와 ContactStoreApplicationAccessMode 열거형 멤버를 허용하는데, 이는 시스템 및 기타 앱에서 연락처 저장소에 제공하는 액세스 권한에 따라 지정됩니다. ContactStoreSystemAccessMode.ReadOnly는 사용 중인 앱에서만 연락처를 수정할 수 있음을 뜻합니다. ContactStoreSystemAccessMode.ReadWrite는 기본 제공되는 휴대폰의 연락처 환경에서 연락처를 수정할 수 있음을 뜻합니다. ContactStoreApplicationAccessMode.LimitedReadOnly는 다른 앱에서 연락처의 표시 이름과 프로필 사진만 읽을 수 있음을 뜻합니다. ContactStoreApplicationAccessMode.ReadOnly는 다른 앱에서 연락처의 모든 속성을 읽을 수 있음을 뜻합니다. 기본 설정은 ContactStoreSystemAccessMode.ReadOnlyContactStoreApplicationAccessMode.LimitedReadOnly입니다.

연락처 저장소를 연 후에는 StoredContact 생성자를 호출하고 저장소에 참조를 전달하여 새 연락처를 만듭니다. StoredContact 개체에는 지정된 이름 및 성 같은 일부 공통된 연락처 데이터에 기본 제공되는 속성이 포함되어 있습니다. 각 연락처에는 운영 체제에서 동적으로 할당하는 로컬 ID가 포함된 필드와, 앱으로 설정할 수 있는 원격 ID를 저장하는 필드도 있습니다. 원격 ID와 로컬 ID를 사용하여 휴대폰의 앱 연락처 저장소에 있는 연락처를 클라우드의 원격 연락처 저장소에 연결할 수 있습니다.

주의주의:

앱이 ContactStore API를 사용하고 StoredContact.RemoteId 속성을 사용하여 휴대폰에 저장된 연락처를 원격으로 저장된 연락처와 연결하는 경우 RemoteId 속성에 대한 값은 안정적이고 고유해야 합니다. 즉, 원격 ID는 단일 사용자 계정을 일관되게 식별하고 다른 앱이 소유한 연락처를 포함하여 휴대폰에 있는 다른 연락처의 원격 ID와 충돌되지 않도록 하는 고유한 태그를 포함해야 합니다. RemoteId 속성에 대한 고유한 값이 없는 StoredContact를 저장하려고 하면 저장 작업이 실패할 수 있습니다.

앱에서 사용하는 원격 ID가 안정적이고 고유하지 않으면 이 항목의 뒷부분에 나오는 RemoteIdHelper 클래스를 사용하여 모든 원격 ID에 고유한 태그를 추가한 후 시스템에 추가할 수 있습니다. 또는 RemoteId 속성을 사용하지 않는 대신 연락처에 대한 원격 ID를 저장하는 사용자 지정 확장 속성을 만들 수 있습니다.

StoredContact 개체에서 제공하는 필드 외에, GetExtendedPropertiesAsync를 호출하여 속성을 추가할 수 있습니다. 이렇게 하면 연락처 데이터로 채울 수 있는 키 값 쌍의 사전이 반환됩니다. 필드가 휴대폰의 내부 연락처 속성 이름과 일치되게 하려면 키 값의 KnownContactProperties 클래스 필드를 사용할 수 있습니다. 또는 임의의 문자열을 키로 지정할 수 있습니다. 연락처에 속성을 설정한 후에 SaveAsync를 호출하여 저장소에 저장합니다.

다음 코드에서는 간단한 연락처 추가 방법을 보여 줍니다.


async public void AddContact(string remoteId, string givenName, string familyName, string email, string codeName)
{
    ContactStore store = await ContactStore.CreateOrOpenAsync();

    StoredContact contact = new StoredContact(store);
    contact.RemoteId = remoteId;
    contact.GivenName = givenName;
    contact.FamilyName = familyName;

    IDictionary<string, object> props = await contact.GetExtendedPropertiesAsync();
    props.Add(KnownContactProperties.Email, email);
    props.Add("Codename", codeName);

    await contact.SaveAsync();

}


저장소에서 연락처를 검색하고 속성을 수정한 후 다시 저장해서 연락처를 업데이트할 수 있습니다. 다음 코드 예제에서는 FindContactByRemoteIdAsync를 사용하여 원격 ID로 연락처를 검색합니다. FindContactByLocalIdAsync를 호출하여 로컬 ID별로 연락처를 검색할 수도 있습니다. 그러면 연락처의 속성이 수정되고 SaveAsync가 호출되어 연락처가 다시 저장소에 저장됩니다.


async private void UpdateContact(string remoteId, string givenName, string familyName, string email, string codeName)
{
    ContactStore store = await ContactStore.CreateOrOpenAsync();
    StoredContact contact = await store.FindContactByRemoteIdAsync(remoteId);

    if (contact != null)
    {
        contact.GivenName = givenName;
        contact.FamilyName = familyName;

        IDictionary<string, object> props = await contact.GetExtendedPropertiesAsync();
        props[KnownContactProperties.Email] = email;
        props["Codename"] = codeName;

        await contact.SaveAsync();
    }
}


DeleteContactAsync를 호출하고 삭제할 연락처의 로컬 ID를 전달하여 연락처를 삭제합니다. 원격 ID를 기반으로 연락처를 삭제하려면 FindContactByRemoteIdAsync를 호출한 다음 Id 속성의 값을 사용하여 DeleteContactAsync를 호출합니다.


async private void DeleteContact(string localID)
{
    ContactStore store = await ContactStore.CreateOrOpenAsync();
    await store.DeleteContactAsync(localID);   
}


CreateContactQuery를 호출하여 저장소에 있는 모든 연락처를 쿼리할 수 있습니다. 인수가 없는 메서드 버전은 각 연락처의 기본 필드 집합을 반환하고 기본 순서를 사용합니다. 반환된 연락처 목록을 검색하려면 반환된 ContactQueryResult 개체에서 GetContactsAsync를 호출합니다.


async private void DefaultQuery()
{
    ContactStore store = await ContactStore.CreateOrOpenAsync();
    ContactQueryResult result = store.CreateContactQuery();
    IReadOnlyList<StoredContact> contacts = await result.GetContactsAsync();

    Dispatcher.BeginInvoke(() => { ContactListBox.DataContext = contacts; });
}


액세스해야 하는 KnownContactProperties의 하위 집합이 있는 경우 새 ContactQueryOptions를 만들고 속성 이름을 DesiredFields 벡터에 추가하여 쿼리할 때 가져오도록 지정할 수 있습니다. 필드 값에 액세스하려면 GetPropertiesAsync를 호출해야 하지만 데이터베이스에 대한 추가 쿼리는 필요하지 않으므로 원하는 필드를 지정하여 성능을 최적화할 수 있습니다.

또한 OrderBy를 설정하여 결과 순서를 지정하는 데 사용되는 필드를 변경할 수도 있지만, 여러 앱에서 일관된 사용자 환경을 손쉽게 제공할 수 있도록 기본 순서를 사용하는 것이 좋습니다.


async private void QueryWithExtendedProperties()
{
    ContactStore store = await ContactStore.CreateOrOpenAsync();

    ContactQueryOptions options = new ContactQueryOptions();
    options.DesiredFields.Add(KnownContactProperties.Email);
    options.DesiredFields.Add("Codename");

    ContactQueryResult result = store.CreateContactQuery(options);
    IReadOnlyList<StoredContact> contacts = await result.GetContactsAsync();

    Dispatcher.BeginInvoke(() => { ContactListBox.DataContext = contacts; });
}


위에서 설명한 대로 사용자 지정 연락처의 RemoteId 필드를 사용하려면 휴대폰의 모든 앱에서 ID 값이 고유하도록 해야 합니다. 클라우드 기반 연락처 저장소에서 고유하다고 보장할 수 있는 ID를 사용하지 않으면 저장소에 연락처를 저장하기 전에 ID에 고유한 태그를 추가하는 데 도움이 되는 다음 클래스를 프로젝트에 추가할 수 있습니다. 저장소에서 검색한 후 ID에서 고유한 태그를 제거하여 원래의 원격 ID를 다시 가져오도록 할 수도 있습니다. 다음 예제에서는 RemoteIdHelper 클래스의 정의를 보여 줍니다.


class RemoteIdHelper
{
    private const string ContactStoreLocalInstanceIdKey = "LocalInstanceId";

    public async Task SetRemoteIdGuid(ContactStore store)
    {
        IDictionary<string, object> properties;
        properties = await store.LoadExtendedPropertiesAsync().AsTask<IDictionary<string, object>>();
        if (!properties.ContainsKey(ContactStoreLocalInstanceIdKey))
        {
            // the given store does not have a local instance id so set one against store extended properties
            Guid guid = Guid.NewGuid();
            properties.Add(ContactStoreLocalInstanceIdKey, guid.ToString());
            System.Collections.ObjectModel.ReadOnlyDictionary<string, object> readonlyProperties = new System.Collections.ObjectModel.ReadOnlyDictionary<string, object>(properties);
            await store.SaveExtendedPropertiesAsync(readonlyProperties).AsTask();
        }
    }

    public async Task<string> GetTaggedRemoteId(ContactStore store, string remoteId)
    {
        string taggedRemoteId = string.Empty;

        System.Collections.Generic.IDictionary<string, object> properties;
        properties = await store.LoadExtendedPropertiesAsync().AsTask<System.Collections.Generic.IDictionary<string, object>>();
        if (properties.ContainsKey(ContactStoreLocalInstanceIdKey))
        {
            taggedRemoteId = string.Format("{0}_{1}", properties[ContactStoreLocalInstanceIdKey], remoteId);
        }
        else
        {
            // handle error condition
        }

        return taggedRemoteId;
    }

    public async Task<string> GetUntaggedRemoteId(ContactStore store, string taggedRemoteId)
    {
        string remoteId = string.Empty;

        System.Collections.Generic.IDictionary<string, object> properties;
        properties = await store.LoadExtendedPropertiesAsync().AsTask<System.Collections.Generic.IDictionary<string, object>>();
        if (properties.ContainsKey(ContactStoreLocalInstanceIdKey))
        {
            string localInstanceId = properties[ContactStoreLocalInstanceIdKey] as string;
            if (taggedRemoteId.Length > localInstanceId.Length + 1)
            {
                remoteId = taggedRemoteId.Substring(localInstanceId.Length + 1);
            }
        }
        else
        {
            // handle error condition
        }

        return remoteId;
    }

}


연락처를 저장소에 저장하기 전에 새 RemoteIdHelper를 만들고 SetRemoteIdGuid를 호출합니다. 그러면 앱에 대한 GUID가 만들어져 연락처 저장소의 확장 속성에 저장됩니다. 이 메서드는 두 번 이상 호출할 수도 있습니다. GUID가 이미 있는 경우에도 재정의되지 않습니다.

원격 ID로 작업을 수행해야 할 때마다 먼저 해당 ID를 GetTaggedRemoteId에 전달하여 앱의 GUID가 추가된 ID의 복사본을 검색합니다.

연락처 저장소에 저장된 원격 ID에서 원본 원격 ID를 가져와야 하는 경우 고유한 태그를 제거하고 원본 ID를 반환하는 GetUntaggedRemoteId를 호출합니다.

vCard는 전자 명함에 사용되는 표준 파일 형식입니다. ContactInformation 클래스는 지정된 URI에서 vCard를 비동기적으로 구문 분석하는 ParseVcardAsnc 메서드를 표시한 다음, 채워진 ContactInformation 개체를 반환합니다. 이 클래스와 연락처 저장소에 대한 참조를 StoredContact 생성자로 전달한 다음 SaveAsync를 호출하여 연락처를 저장합니다.

다음 샘플 코드에서는 vCard의 연락처를 사용자 지정 연락처 저장소에 저장하는 방법을 보여 줍니다.

task<StoredContact^> SaveFromVcard(ContactStore^ store, String^ uriToVcard)
{
    // Invoke the parser on the passed-in URI.
    return create_task(ContactInformation::ParseVcardAsync(ref new Uri(uriToVcard)))
    .then([=] (ContactInformation^ info) -> StoredContact^
    {
        // When that's done, wrap a stored contact around it, save.
        auto contact = ref new StoredContact(store, info);
        create_task(contact->SaveAsync()).get();

        return contact;
    });
}

표시:
© 2014 Microsoft