반응형
ShakeJ
MNWorld
ShakeJ
전체 방문자
오늘
어제
  • 카테고리 N
    • Contact
    • 🤔그냥이야기
    • 📷사진이야기
    • 제주도에서 한달을 살아보았다
    • 옛글 N
      • 👇Blog
      • 공지사항
      • 이슈 N
      • 생각들
      • 👇취미
      • 건프라
      • 👇Review
      • 노래리뷰
      • 영화리뷰
      • 👇Travel Story
      • 2011 도쿄여행기
      • 2013 Google IO
      • 2013 Jeju
      • 2014 HONGKONG
      • 2014 Jeju
      • 2014 Sanfransis..
      • 2015 Lombok
      • 2016 HONGKONG
      • 2017 Saigon
      • 국내여행기
      • Photo Story
      • Growth
      • 👇Server
      • Ruby on the Rai..
      • Frontend
      • FullStack (MEAN..
      • Ubuntu
      • 👇Android
      • 안드로이드 프로그래밍
      • 번역본
      • 내어플이야기
      • 코드창고
      • 👇iOS
      • 아이폰 프로그래밍
      • 맥북 이야기
      • 👇Microsoft
      • ASP.NET
      • Silverlight
      • 윈도우 이야기
      • 👇IT Story
      • 모바일 이야기
      • 하드웨어 이야기 N
      • 네트워크 이야기
      • 프로그래밍이야기
      • Database이야기
      • 클라우드이야기
      • 프론트 이야기
      • 마케팅이야기
      • 그래픽 작업
      • 블로그 팁

블로그 메뉴

  • GuestBook

공지사항

인기 글

태그

  • 티스토리 초대장
  • 배너무료제작
  • 블로그 잡담
  • 배너교환
  • 블로그 운영
  • shakej
  • 윈도우폰7
  • 배너제작
  • 블로그 관련
  • 초대장
  • MNWorld
  • iOS 프로그래밍
  • D40 사진
  • 안드로이드 어플 추천
  • 랩
  • 블로그 운영하면서
  • 티스토리 팁
  • 블로그 시작하기
  • 블로그 만들기
  • 블로그 운영하기
  • 블로그 꾸미기
  • 블로그 팁
  • 무료배너제작
  • asp.net
  • 티스토리
  • 블로그 이야기
  • 블로그 처음
  • 풍경사진
  • 서울 출사지
  • 블로그 초보

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
ShakeJ

MNWorld

옛글/아이폰 프로그래밍

iCloud Guide (XCode iCloud 적용가이드)

2012. 7. 17. 10:14
반응형

https://docs.google.com/document/pub?id=1LrykTGpUq9jMWB7g3Ne6uHpIgIRciPWwHMJVCnFuZo0

통해서 업데이트됩니다. 


iCloud Code Review


Jung Chang Hwan
shakejj@gmail.com
mnworld.co.kr

목적 : iCloud 백업을 통해 여러 기기에 설치되어 있는 동일한 앱들 간에 Data를 주고 받는다.  (예: 게임의 Save File, 케릭터 등 파일)

- iCloud는 Document라는 다양한 파일을 저장할 수 있는 공간이 있다. (파일 형식 제한 없음)
이 Document는 MAC과 iOS 둘 다 접근이 가능하며 URL 형태로 Access하여 파일을 읽고 쓸 수 있다.













iCloud가 설정되어 있다면(설정에서 iCloud 계정 입력 및 도큐먼트 및 데이터 백업이 켜져있다면) App은 Entitlement파일(기능파일)에 적어놓은 iCloud키를 통해 Local의 iCloud Folder에 Access가 가능하다. 액세스가 성공하면 Online, Offline에 상관 없이 Sync가 되는 iCloud Folder에 파일을 지우고 쓸 수 있다(Online이 되면 자동으로 Sync). 

따라서 네트워크 상태와는 상관이 없으며, iCloud가 설정되어 있지 않다면(iCloud설정 자체가 되어 있지 않는 경우)에는 iCloud Folder가 아닌 Local Folder를 사용해야 한다. 

Sync가 이루어지는 iCloud Folder는 아래 그림을 참조한다. Mac이나 iOS 두 앱 모두 Sandbox를 적용해야 하기 때문에, 본인이 가진 Document이외에는 Access가 불가능하다. (절대경로를 통해 아래의 폴더에 Access하는 것은 바람적이지 않다) 아래 적용방법을 통해 Access한다.











- iOS iCloud 적용방법 
1) Apple Developer 에서 해당 App ID의 “iCloud”를 “Enbled” 시켜준다.
(http://developer.apple.com)

2) XCode - Project - Summary의 하단 부분에서 ‘Enable Entitlements’를 Check 한다

: Enable Entitlements를 체크한 후, “iCloud Key-Value Store” 을 체크한다. 
iCloud Key - Value Store, iCloud Containers, keychain Access Groups에는 모두 동일한 키를 넣어준다. 넣어줄 키는 TEAM_ID.Bundle Identifier의 형식으로 적어준다. 

* Team_ID을 알아내기 위해서는 XCode - Window - Orgranizor - [Devices Tab] - 왼쪽의 메뉴 중 Provisioning Profiles를 클릭하면, 사용하고자 하는 프로필의 App Identifier을 적어주면 된다. 
10자리의 고유한 형태로 이루어져 있다. (EX: M23JF1JEZK)
* Bundle Identifier은 Project - Summary에서 알 수 있다. 


위와 같이 Bundle Identifier에 있는 값을 넣어준다 (EX: com.회사이름.AppID)

iCloud Key - Value Store, iCloud Containers, keychain Access Groups 모두 예를 들면 (M23JF1JEZK.com.회사이름.AppID)을 넣어준다.

!주의 : 위와 같이 설정 후 Device를 통해 Run 을 했을 때 (Simulator는 iCloud에 Access할 수 없음) 정상적으로 실행되지 않고 Entitlement오류가 난다면, Developer 계정에서 Provisioning File을 Recreate한 후 XCode의 Profile들을 지운 후 Refresh 한다. 

3) 정상적으로 실행 된다면, iCloud를 사용하기 위한 환경설정은 완료된 것 이다.

iCloud에 정상적으로 접근하여 파일을 저장하고 지우기 위해서는 다음 코드를 참고한다. 


Path 가 아닌 containerID를 통해 (Entitlement에 기록된, Summary에서 설정을 해놓은) URL로 접근해서 파일을 쓰고 지울 수 있다. 
(NSURL이 아닌 Query를 통해 iCloud에 저장되어 있는 파일을 로컬로 저장하는 등의 방법도 가능하다) 

// 파일 삭제 시 
NSURL *url = [self getiCloudURLFor:filename containerID:nil]; //leaving nil so it is auto filled from entitlements
   if (url) {     //정상적으로 iCloud 에 Access가 되었다면...

        NSError *error;

        if (![[NSFileManager defaultManager] removeItemAtURL:url error:&error]) {

            NSLog(@"Error downloading/syncing %@ (%@)",[url path],[error description]);                

        }else{

            NSLog(@"Started syncing %@",[url path]);              

        }        

    }

   

NSArray *conflicts = [NSFileVersion unresolvedConflictVersionsOfItemAtURL:url];

 for (NSFileVersion *conflict in conflicts) {
       NSLog(@"Conflicting %@ at %@ by %@ from %@",[url path],[conflict URL],[conflict localizedNameOfSavingComputer],[conflict modificationDate]);  

    }

//==================iCloud OSX & iOS =====================

- (NSURL*)getiCloudURLFor:(NSString*)fileName containerID:(NSString*)containerID

{  

 NSFileManager *fm = [NSFileManager defaultManager];  
NSURL *rootURL = [fm URLForUbiquityContainerIdentifier:containerID];    

   

    if (rootURL) {

    NSURL *directoryURL = [rootURL URLByAppendingPathComponent:@"Documents"];
                   //dirURL은 mobileDocuments

       

 if (![fm fileExistsAtPath:[directoryURL path]]) { 
                    //filemanager경로를 MobileDocument로 변경
 [fm createDirectoryAtURL:directoryURL withIntermediateDirectories:NO attributes:nil error:NULL];

 }

NSURL *cloudURL = [directoryURL URLByAppendingPathComponent:fileName]; 
                    //CloudUrl은 MoibleDoucment의 Image파일

       

  if (![fm isUbiquitousItemAtURL:cloudURL]){

                     //filemager가 ImageFile을 쓴다.

       NSLog(@"!NO Cloud ");

}

  //this only runs once per filename when it is first added to iCloud

       return cloudURL;

  }else{

       return [[[fm URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] objectAtIndex:0] URLByAppendingPathComponent:fileName]; //no cloud

    }    

 return nil;

}

// 파일 추가 시 
 NSURL *url = [self getiCloudURLFor:filename containerID:nil];

    if (url) {

      NSError *error;

 if (![[NSFileManager defaultManager] startDownloadingUbiquitousItemAtURL:url error:&error]) 
//startDownloadingUbiQuitousItemAtURL 파일 저장

{

        NSLog(@"Error downloading/syncing %@ (%@)",[url path],[error description]);                

    }else{

        NSLog(@"Started downloading/syncing %@",[url path]);              

       }        

}

   NSArray *conflicts = [NSFileVersion unresolvedConflictVersionsOfItemAtURL:url];

   for (NSFileVersion *conflict in conflicts) {

      NSLog(@"Conflicting %@ at %@ by %@ from %@",[url path],[conflict URL],[conflict localizedNameOfSavingComputer],[conflict modificationDate]);  

   }

   [self goToScene:SCENE_LOCKER];

}


//========iCloud OSX & iOS===========//

- (NSURL*)getiCloudURLFor:(NSString*)fileName containerID:(NSString*)containerID

{  

   NSFileManager *fm = [NSFileManager defaultManager];  

   

     NSURL *rootURL = [fm URLForUbiquityContainerIdentifier:containerID];

if (rootURL) {

NSURL *directoryURL = [rootURL URLByAppendingPathComponent:@"Documents"];

  if (![fm fileExistsAtPath:[directoryURL path]]) [fm createDirectoryAtURL:directoryURL withIntermediateDirectories:NO attributes:nil error:NULL];

 NSURL *cloudURL = [directoryURL URLByAppendingPathComponent:fileName];

 if (![fm isUbiquitousItemAtURL:cloudURL]) [self makeUbiquitousItemAtURL:cloudURL];

//this only runs once per filename when it is first added to iCloud

 return cloudURL;

    }else{

 return [[[fm URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] objectAtIndex:0] URLByAppendingPathComponent:fileName]; //no cloud

}    

   return nil;

}

- (void)makeUbiquitousItemAtURL:(NSURL*)cloudURL

{

 NSFileManager *fm = [NSFileManager defaultManager];

   

NSURL *localURL = [[[fm URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] objectAtIndex:0] URLByAppendingPathComponent:[cloudURL lastPathComponent]];

   

 if (![fm fileExistsAtPath:[localURL path]]) [fm createFileAtPath:[localURL path] contents:nil attributes:nil];

 

   NSError *error;            

 if(![fm setUbiquitous:YES itemAtURL:localURL destinationURL:cloudURL error:&error])  {

       

NSLog(@"Error making %@ ubiquituous at %@ (%@)",[localURL path],[cloudURL path],[error description]);

  }else{

NSLog(@"Made %@ ubiquituous at %@",[localURL lastPathComponent],[cloudURL path]);              

  }      

}

파일 탐색 시에도 URL 을 통해 탐색이 가능하며, NSPred Query를 통해 탐색하는 방법과 NSUrl 을 통해 탐색하는 방법이 있다. (아래는 NSUrl 을 통해 탐색하는 방식)

  NSFileManager* kFileManager = [NSFileManager defaultManager];

 NSURL *rootURL = [kFileManager URLForUbiquityContainerIdentifier:nil];

 NSURL *directoryURL = [rootURL URLByAppendingPathComponent:@"Documents"];

 NSLog(@"directoryURL is %@", directoryURL); //DirectoryURL은 iCloud의 Document폴더

   

 if ( directoryURL != nil ) {

NSLog(@"iCloud Folder URL Access");

NSArray* kSavedFile =  [kFileManager contentsOfDirectoryAtURL:directoryURL includingPropertiesForKeys:nil options:NSDirectoryEnumerationSkipsHiddenFiles error:nil];

NSLog(@"This kSavedFile is %@", kSavedFile);

       

for (NSURL* kUrl in kSavedFile)      {

NSError *error;           
// 파일 탐색 후 탐색 된 파일들을 다운로드 받는 예제

  if (![[NSFileManager defaultManager] startDownloadingUbiquitousItemAtURL:kUrl error:&error])     {                

NSLog(@"Error downloading/syncing %@ (%@)",[kUrl path],[error description]);                            

   }else{                

NSLog(@"Started downloading/syncing %@",[kUrl path]);              

 }      

 NSString *kFile = kUrl.path;  
           //URL 을 String 으로 바꾸어서 원하는 대로 사용이 가능함 (Path를 통해)

 NSLog(@"File Path  : %@", kFile);

 NSString* filePath = kFile;

  }

}


- MAC iCloud 적용 방법

MAC의 경우에도 코드는 iOS와 같은 방식으로 적용하며, 설정방법도 동일하다.

아래 그림과 같이 “Code Sign Application” Check, 
“Enable Entitlement” Check,
iCloud Key-store Value Check 한 후,

만약 iOS 와 같은 iCloud Container를 사용하고 싶다면, iOS에서 설정해준,

 TEAMID.BundleIdentifier을 입력하면 동일한 iCloud Document에 접근이 가능하다.


-  Reference

http://icloudintegration.blogspot.kr/

http://stackoverflow.com/questions/7795629/icloud-basics-and-code-sample

http://samvermette.com/312

https://daw.apple.com/cgi-bin/WebObjects/DSAuthWeb.woa/wa/login?appIdKey=4a75046cda87eab6386a9eae8caabb9824e328b9abc988119b39296495ec184c&path=/login.jspa#565586

http://stackoverflow.com/questions/9032901/nsdocument-sync-with-icloud-where-is-there-a-sample-code

http://www.raywenderlich.com/6015/beginning-icloud-in-ios-5-tutorial-part-1


반응형
저작자표시 비영리 변경금지

'옛글 > 아이폰 프로그래밍' 카테고리의 다른 글

Code signing is required for product type 'Application' in SDK 'iOS5.1' 에러처리  (0) 2012.07.23
iOS에서 나인패치(배경리사이즈) 적용하기  (0) 2012.07.20
xCode iCloud iOS/MAC App에 적용하기 Part1  (0) 2012.07.06
[iOS프로그래밍] NSString Split(Token 으로 자르기)  (0) 2012.07.06
[iOS프로그래밍] NSRunLoop로 잠시 Timer걸기  (0) 2012.07.06
    추천글👇
    • [📷사진이야기] 붉은 호치민의 노을
    ShakeJ
    ShakeJ

    티스토리툴바