2014-12-21 1 views
3

iOS 앱의 저장된 CLLocation 객체를 확장 프로그램 (이 경우 Apple Watch 확장 프로그램)으로 다시 전달하려고합니다.CLLocation 객체를 iOS 앱 확장자에 다시 전달하려고 할 때 사전이 0이됩니다.

확장 코드에서 WKInterfaceController 클래스의 권장 openParentApplication(userInfo: [NSObject : AnyObject]!, reply: (([NSObject : AnyObject]!, NSError!) -> Void)!) -> Bool 함수를 사용하고 있습니다. 내 응용 프로그램 대리인의 application(application: UIApplication!, handleWatchKitExtensionRequest userInfo: [NSObject : AnyObject]!, reply: (([NSObject : AnyObject]!) -> Void)!) 기능을 통해 내 IOS 응용 프로그램에서 요청을 성공적으로 수신하고 있습니다.

var results = [NSObject: AnyObject]() 
    if let loc = getLastKnownLocation() { 
     results["hasLoc"] = "yes" 
     results["locStr"] = "\(loc)" 
     results["results"] = loc // at this point, loc is actually a valid CLLocation object 
    } 
    reply(results) 

이 모든 코드는 iOS 앱의 컨텍스트에서 실행되는 모든 것이 잘 작동된다

지금, 나는이 코드를 사용하여 앱 정보를 다시 데이터를 전달하기 위해 노력하고있어. 그러나 reply 함수가 확장 프로그램의 컨텍스트에서 호출되면 해당 사전은 궁극적으로 nil이됩니다.

이 라인을 주석
   results["results"] = loc 

는 확장이 성공적으로 문자열로 두 첫번째 항목 ("hasLoc""locStr") 가득 사전을 가져옵니다

InterfaceController.openParentApplication(parentValues, reply: {(values, error) -> Void in 
     NSLog("\(values) (err: \(error))") // echoed back to the console: "nil (err: nil)" 
    }) 

나는 결함이있는 라인이 하나라는 것을 깨달았다 :

[locStr: Optional(<+37.33756323,-122.04115699> +/- 10.00m (speed 5.00 mps/course 272.00) @ 21/12/2014 19:20:05 heure normale d’Europe centrale), hasLoc: yes] (err: nil) 

그래서 그것은 모두가 실패하고,237,453 될 수 있습니다 내 사전에 CLLocation 객체를 삽입하는 것 같아,하지만 이유를 이해할 수 없습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?

도움 주셔서 감사합니다.

편집 :

class func getLastKnownLocation() -> CLLocation? { 
    return NSKeyedUnarchiver.unarchiveObjectWithData(NSUserDefaults(suiteName: AppHelper.appGroupName)!.dataForKey("UserLastLocation")!) as CLLocation? 
} 
+0

@ 매트, 내 질문에 업데이트를 참조하십시오. – Romain

+0

'locStr'은'loc' 변수의 문자열 표현입니다. 여러분이 아시다시피 선택적인'CLLocation? '입니다. – Romain

+0

이제 확인하겠습니다. 하지만'CLLocation으로 '를'CLLocation'으로, 함수 서명을'CLLocation' 대신'CLLocation'으로 변경했습니다.문제를 해결하지는 못했지만 이제는'locStr'가 더 이상''Optional ''로 나타나지 않습니다. – Romain

답변

4

내가의 문서를 읽기로 : 매트의 요청 @ 여기 getLastKnownLocation()에 대한 코드의 당 "사전의 내용은 속성 목록 파일로 직렬화해야합니다." 그러나 CLLocation은 이런 식으로 직렬화 할 수 없습니다. 아마도 장벽을 통과하기 위해 사전에 붙여 넣기 전에 NSData에 다시 포장해야합니다.

+0

행운이 세 번째? ... 이걸 시도해보십시오. – matt

+0

그래, 너는 옳은 길이야! 이제는 바이트를 확장으로 가져올 수 있지만 현재는 'CLLocation' 객체로 다시 변환 할 수 없습니다. 'NSKeyedArchiver'와'NSKeyedUnarchiver'를 사용하고 있지만 다시 변환하지 않습니다 ... – Romain

+0

마음에 들지 않습니다 ... 나는'CLLocation' 모든 사전 항목을'String's조차도 캐스팅했습니다 ... 이제 작동합니다 , NSData에서 캐스팅하고 리턴하는 것이 그리 편리하지는 않지만 적어도 작동합니다! @matt에게 감사합니다! – Romain

2

The Apple documentation "사전의 내용은 속성 목록 파일과 직렬 가능해야합니다." CLLocation은 이런 식으로 직렬화 할 수 없습니다. 이 컨텍스트에서 반환되는 NSDictionary에 포함 시키려면 NSData 객체로 마무리해야합니다. 이것은 간단합니다. CLLocation은 NSSecureCoding을 지원하며,이 같은 NSKeyedArchiver를 사용

CLLocation *myLocationToStore = ...; // (a CLLocation object) 
NSData *locationData = [NSKeyedArchiver archivedDataWithRootObject:myLocationToStore]; 

이 다음 NSKeyedUnarchiver와 마찬가지로 단순히 다른 쪽 끝에서 앱 정보를 전달의 NSDictionary에 추가하고 디코딩 할 수 있습니다

Swift equivalent functions

CLLocation *myStoredLocation = (CLLocation *)[NSKeyedUnarchiver unarchiveObjectWithData:locationData]; 
은 다음과 같습니다

class func archivedDataWithRootObject(_ rootObject: AnyObject) -> NSData] 
class func unarchiveObjectWithData(_ data: NSData) -> AnyObject? 
관련 문제