2012-12-26 1 views
2

이 문제를 해결할 때 이미 두통이 있습니다. 현재 응용 프로그램에서 iCloud를 사용하여 내 문서를 저장하고 있지만 데이터에 UIDocument 기반 저장소를 사용할 수 없습니다. . 그래서 내 접근 방식은 WWDC 2012 기사 237 (고급 iCloud 문서 저장)을 따르고 신발 상자 앱과 같이 내 문서를 처리하는 것이 었습니다.문제 처리 NSMetadataQueryDidUpdateNotification 비 UIDocument 기반 iCloud 파일

NSMetadataQuery를 빌드하여 iCloud 문서 폴더의 변경 사항을 모니터링하여 파일 변경 사항을주의 할 때 실제 문제가 발생합니다. 쿼리를 설정하고 NSMetadataQueryDidFinishGatheringNotification에 대한 옵저버로 시작하고 쿼리가 업데이트 될 때 NSMetadataQueryDidUpdateNotification에 대한 옵저버를 설정합니다. 후자는 한 파일 변경에 대해 한 번만 작동하며 동일한 파일이나 다른 파일의 후속 변경에 대해 반복적으로 실행하는 방법을 찾지 못했습니다. 다음은 일부 코드 부분입니다.

- (void)startMonitoringDocumentsFolder: (id)sender 
{ 
    if (self.queryDocs != nil) 
     return; 

    NSLog(@"startMonitoringDocumentsFolder:"); 

    self.queryDocs = [[NSMetadataQuery alloc] init]; 
    [queryDocs setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]]; 

    NSPredicate* pred = [NSPredicate predicateWithFormat:@"%K like '*.nwa' or %K like '*.NWA'", NSMetadataItemFSNameKey, NSMetadataItemFSNameKey]; 

    [self.queryDocs setPredicate:pred]; 

    NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; 
    NSOperationQueue*  mainQueue = [NSOperationQueue mainQueue]; 

    // I'm using the blocks version because I'm planning to setup observers for the same tracking name... 
    self.observeGatherDocs = [center addObserverForName: NSMetadataQueryDidFinishGatheringNotification 
               object: self.queryDocs 
                queue: mainQueue 
              usingBlock: ^(NSNotification* note) 
    { 
     [self queryDidFinishGathering:note]; 
    }]; 
    [self.queryDocs startQuery]; 
} 

- (void)queryDidFinishGathering:(NSNotification *)notification 
{ 
    NSLog(@"queryDidFinishGathering:"); 
    NSMetadataQuery* query = [notification object]; 

    if (query == queryDocs) 
    { 
     NSLog(@"--> for queryDocs"); 
     NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; 
     NSOperationQueue*  mainQueue = [NSOperationQueue mainQueue]; 

     [center removeObserver: observeGatherDocs]; 
     self.observeGatherDocs = nil; 
     self.observeUpdateDocs = [center addObserverForName: NSMetadataQueryDidUpdateNotification 
                object: query 
                 queue: mainQueue 
               usingBlock: ^(NSNotification* note) 
     { 
      [self queryDidUpdateDocumentsFolder:note]; 
     }]; 

     [query enableUpdates]; 
    } 
} 

- (void)queryDidUpdateDocumentsFolder:(NSNotification *)notification 
{ 
    NSLog(@"queryDidUpdateDocumentsFolder:"); 
    NSMetadataQuery* query = [notification object]; 

    [query disableUpdates]; 

    for (NSMetadataItem* item in [query results]) 
    { 
     // find and handle file changes here w/out any command calls to the query itself 
     ... 
    } 

    if (self.needDownload) 
     [self triggerDownloadThread]; 

    // ---- BEGIN code part added to solve the problem ---- // 
    // re-create the observer 
    NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; 
    NSOperationQueue*  mainQueue = [NSOperationQueue mainQueue]; 

    [center removeObserver: observeUpdateDocs]; 
    self.observeUpdateDocs = [center addObserverForName: NSMetadataQueryDidUpdateNotification 
               object: query 
                queue: mainQueue 
              usingBlock: ^(NSNotification* note) 
    { 
     [self queryDidUpdateDocumentsFolder:note]; 
    }]; 
    // ---- END code part added to solve the problem ---- // 

    [query enableUpdates]; 
    // that's all with the query, am I missing something? 
} 

여기에있는 조언은 정말 감사하겠습니다.

정말 무엇을 :

  1. 나는 아이 클라우드 문서 컨테이너 내에서 파일을 수정

    직접 (덮어 쓰기) - 아무것도 쿼리가 발생하지 않습니다.

  2. 시퀀스를 통해 파일을 수정할 때 : 아니오, setUbiquitous : YES로 설정하면 로컬 파일에 쓸 수 있습니다. 예 : 쿼리가 한 번 실행되면 변경 사항을 감지하고 동일한 파일을 다시 변경하면 쿼리가 리콜되지 않습니다. 핸들러.

내가 1 위 또한 필요한 수정 기존 파일 것 같다 NEW 파일에 적용됩니다 같은 방법은 iCloud에 파일을 쓸 수있는 애플의 문서에서 발견 한 지금에도 불구하고.

하지만 어쨌든 쿼리 메커니즘을 반복적으로 실행하려면 어떻게해야합니까?

건배 ...

답변

3

더 많은 노력으로 조사한 결과 주목할만한 해결책을 찾았습니다. (ARC를 사용하는 경우 또는 강한)

  1. 관찰자 인스턴스 변수가 참조를 유지으로 유지해야 업데이트가 활성화되기 전에 관찰자를 다시해야
  2. : 다른 사람이 나에 걸림돌 경우 그래서 그냥 내 경험을 공유하고있어 -만들어진.

모든 것으로 보입니다. 지금 당장은 효과가있는 것 같습니다.

+0

# 2로 무엇을 의미합니까? – SpaceDog

+0

내가 기억하는 한 : 코드 줄 "[query enableUpdates];" 이전에 게시 한 목록의 "addObserverForName : ..."에 대한 NSNotificationCenter 호출이 있어야합니다. – konran

+0

NSMetadataQuery 인스턴스에 대한 강력한 바인딩을 주셔서 감사합니다 ... 견과류를 몰고 왔습니다. –