본문 바로가기

Windows Phone 7

Windows Phone 7 에서의 IsolatedStorageSettings 활용

안녕하세요.
오늘은 격리된 저장소에 앱관련 설정파일을 생성하고 활용하는 방벙에 대해서 알아 보도록 하겠습니다.
격리된 저장소는 WP7에서 앱관련 파일들의 샌드박스내에서 저장하고 읽을 수 있는 앱을 위한 저장공간인데요.
아래와 같은 구조로 이루어져 있습니다.
파일/폴더를 저장할 수 있을 뿐더러, 어플리케이션의 설정을 보관하는 Local Settings 라는 것이 존재합니다.
이 것을 이용하여 격리된 저장소의 관리할 수 있을 뿐만 아니라, 어플리케이션에서 사용하는 설정값들을 저장하고 불러올 수 있는 기능을 제공합니다.

이제부터는 격리된 저장소에 존재하는 Local Settings 를 활용하는 방법에 대해서 알아보도록 하겠습니다.
사용자 이름이나, 외부와의 통신을 위한 계정이나 주소등을 어플리케이션이 시작될때 마다 사용자에게 직접 입력받아야 한다면, 사용자로썬 불편해서 사용하질 못하겠죠?
이런 부분들은 격리된 저장소에 따로 파일로 저장하여 사용해도 되지만, System.IO.IsolatedStorage.IsolatedStorageSettings 클래스를 이용하면 아주 쉽게 관리하실 수 있습니다.

설정값 저장하기 (기본활용)

우선은 간단한 설정 값을 저장하는 방법에 대해서 알아보도록 하겠습니다.
IsolatedStorageSettings 클래스에 보면 정적 속성으로 ApplicationSettings 속성이 존재합니다.
이 ApplicationSettings 속성을 이용하여 우리가 저장하고자 하는 설정값을 Key/Value 쌍으로 저장이 가능합니다.

새로운 설정값을 추가하고자 한다면
IsolatedStorageSettings.ApplicationSettings.Add("키", 값); 와 같이 추가해주면 되는 것입니다.

사용자 이름을 추가하는 경우라면

IsolatedStorageSettings.ApplicationSettings.Add("userName", "Hong, Gildong");

와 같이 사용 하면 되는 것이죠.

Add메서드는 시그니쳐는 아래와 같습니다.

Add메서드의 시그니쳐를 잘 보면 key는 string 형식이며, value는 object 형식을 받고 있음을 알 수 있습니다.
Value에 해당하는 설정 값이 꼭 문자열일 필요가 없으며, int, DateTime 등의 기본형식외에도 우리가 직접 생성한 클래스의 객체들도 들어 갈 수 있다는 것입니다.

public class User

{

    public string Name { get; set; }

    public string UserID { get; set; }

    public string Password { get; set; }

}


와 같은 클래스가 존재한다고 했을때, 이 클래스에 생성된 객체를 아래처럼 설정값으로 저장할 수도 있다는 의미죠.

User user = new User { Name = "Hong, Gildong", UserID = "Hong", Password = "Gildong1!" };

IsolatedStorageSettings.ApplicationSettings.Add("user", user);


클래스의 인스턴스를 저장할 수 있으므로, 하나의 키에 여러가지 정보를 저장하고 가져올 수 있게 되는 것입니다.

그렇다면, 이미 추가되어 있는 키를 새로 추가하고자 한다면 키가 중복되므로 예외가 발생하겠죠.
기존에 존재하는 키에 대해서 값을 변경할 때는 아래와 같이 ApplicationSettings[] 인덱서를 이용하여 직접 값을 할당 하면 됩니다.

IsolatedStorageSettings.ApplicationSettings["user"] = user;


그리고, 설정이 추가되거나 변경되었을때는 꼭 Save 메서드를 호출 하여 변경분을 Local Settings에 저장하여야 합니다.

IsolatedStorageSettings.ApplicationSettings.Save();


기본적인 저장코드를 전체를 본다면 아래와 같이 되겠죠.

User user = new User { Name = "Hong, Gildong", UserID = "Hong", Password = "Gildong1!" };

 

if (IsolatedStorageSettings.ApplicationSettings.Contains("user"))

{

    IsolatedStorageSettings.ApplicationSettings["user"] = user;

}

else

{

    IsolatedStorageSettings.ApplicationSettings.Add("user", user);

}

 

IsolatedStorageSettings.ApplicationSettings.Save();


ApplicationSettings의 Contains 메서드를 이용하여 현재 설정파일에 user 라는 키값이 존재하는지 확인한후 추가하거나 변경하고, 저장하는 형태를 가지게 됩니다.

설정값 불러오기

설정을 저장하였다면, 값을 불러와야겠죠?
값을 불러 올때는 아래와 같이 사용해도 됩니다.


User user = IsolatedStorageSettings.ApplicationSettings["user"] as User;


User user = (User)IsolatedStorageSettings.ApplicationSettings["user"];


ApplicationSettings 컬렉션은 값을 object 형식으로 가지기 때문에 등록했던 형식으로의 캐스팅이 필요하므로,
두 방법 모두 object 형식을 등록하였던 형식으로 캐스팅을 하고 있습니다.

하지만, 위 방법을 이용하실 때 만일 설정파일에 지정한 키값(user)가 존재하지 않는다면, 예외가 발생합니다.
설정 키값이 존재하는지에 관계없이 설정 값을 가져오는 방법으로 TryGetValue<T>(string key, out object value) 제네릭 메서드가 있습니다.
시그니쳐를 보면

T 는 저장한 값의 형식(여기서는 User 클래스 형식)이며, 설정값을 가져오는데 성공했는지 여부를 bool 형식으로 반환합니다.
그리고, value 는 out 파라미터를 이용합니다. 그러므로 호출시 out 키워드를 꼭 붙어야 합니다.

값을 가져오는 기본적인 코드를 보자면 아래와 같이 될 겁니다.

User user;

IsolatedStorageSettings.ApplicationSettings.TryGetValue<User>("user", out user);

 

if (user != null)

{

    // Do something

}


물론 TryGetValue 메서드는 지정한 키값을 가져오는데 성공했는지 여부를 반환하므로 아래와 같이 사용해도 됩니다.

User user;

if (IsolatedStorageSettings.ApplicationSettings.TryGetValue<User>("user", out user))

{

    // Do something

}


여기 까지만 한다면, 간단한 설정값을 저장하고 불러오는데는 아무런 문제가 없을 것입니다.

설정값 저장하기 (고급활용)

그렇다면, 아래와 같은 클래스를 설정파일로 저장한다고 생각해보죠.

public class Comics

{

    public string FileName { get; set; }

    public string LocalPath { get; set; }

    public DateTime Created { get; set; }

    public long FileSize { get; set; }

    public string ThumnailPath { get; set; }

    public BitmapImage Thumnail { get; set; }

}


List<Comics> comicsList = GetCurrentComics();

 

if (IsolatedStorageSettings.ApplicationSettings.Contains("comics"))

{

    IsolatedStorageSettings.ApplicationSettings["comics"] = comicsList;

}

else

{

    IsolatedStorageSettings.ApplicationSettings.Add("comics", comicsList);

}

 

IsolatedStorageSettings.ApplicationSettings.Save();


위와 같이 하나의 객체만 설정파일에 저장할 수 있는것이 아닌 배열이나, List<T>와 같은 집합형태의 객체도 충분이 설정파일에 저장이 가능합니다.
다수의 리스트를 어플리케이션 설정에 저장해야 할 경우에는 위와 같은 방식을 이용하시면 됩니다.

하지만, 위의 Comics 클래스는 다소 억지스러운 면이 있는 클래스입니다. 뭔가 위화감이 느껴지시나요?
만일, comicsList가 10개의 항목을 가지고 있고, Thumnail 속성의 BitmapImage 객체가 평균적으로 1MB의 크기를 가진다고 가정했을 때, 설정파일의 크기가 최소 크기가 10MB나 될 겁니다.
이렇게 되면 배보다 배꼽이 더 큰 형상이 되겠죠?

앞에서 IsolatedStorageSettings 항목은 값으로 object 형식을 가진다고 하였습니다.
그리고, 이 항목은 XML 형식으로 격리된 저장소에 저장되게되죠. XML은 문자열로 이뤄짐을 모두 잘 알고 계실것입니다.
그렇다면 어떻게 객체가 어떻게 문자열로 저장이 될까요?
바로 객체를 직렬화하여 문자열로 변경하여 저장하게 되는 것입니다.

.NET 3.5 이상에서는 직렬화를 위하여 DataContractAttribute 특성과 DataMemberAttribute 특성을 이용하여 객체의 직렬화를 제어할 수 있습니다.

위 Comics 클래스를 아래와 같이 고쳐보겠습니다.
우선 직렬화를 사용하기 위해서 System.Runtime.Serialization 어셈블리를 프로젝트에 참조로 추가하여 주십시오.
클래스가 존재하는 파일의 using 절에  System.Runtime.Serialization 네임스페이스를 추가하여 주시구요.

[DataContract]

public class Comics

{

    [DataMember]

    public string FileName { get; set; }

    [DataMember]

    public string LocalPath { get; set; }

    [DataMember]

    public DateTime Created { get; set; }

    [DataMember]

    public long FileSize { get; set; }

    [DataMember]

    public string ThumnailPath { get; set; }

    [IgnoreDataMember]

    public BitmapImage Thumnail { get; set; }

}

 


클래스를 위와 같이 수정하였습니다. 클래스에는 DataContractAttribute 특성이 추가되었고, 직렬화할 멤버들에 대해서는 DataMemberAttribute 특성을 추가하였습니다.
그리고, 마지막으로 직렬화에 추가하지 않을 Thumnail 속성에서는 IgnoreDataMemberAttribute 를 추가하여 명시적으로 직렬화에서 제외하였습니다.
참고로 DataContractAttribute를 이용한 직렬화에서는 DataMemberAttribute가 지정되지 않은 멤버들은 모두 직렬화에서 제외됩니다.

List<Comics> comicsList = GetCurrentComics();

 

if (IsolatedStorageSettings.ApplicationSettings.Contains("comics"))

{

    IsolatedStorageSettings.ApplicationSettings["comics"] = comicsList;

}

else

{

    IsolatedStorageSettings.ApplicationSettings.Add("comics", comicsList);

}

 

IsolatedStorageSettings.ApplicationSettings.Save();


와 같이 설정파일에 저장하면, Thumnail 속성을 제외한 객체가 직렬화되어 설정파일에 저장됩니다.

위와 같은 방법을 이용하여 설정파일만을 위한 새로운 클래스를 생성할 필요없이 기존에 사용하던 클래스에서 불필요한 멤버들을 제외하고 설정파일로 저장하는 것이 가능해 지는 것입니다.

오늘은 여기까지 마치도록 하겠습니다.
혹시, 궁금하거나 잘못된 사항이 있으시면 댓글 부탁드리겠습니다.

그럼 즐거운 하루 되십시오.