2013-05-27 26 views
7

Tôi đang sử dụng XPC ở một trong các ứng dụng của mình trên 10.8. Nó có các thiết lập tiêu chuẩn với các giao thức được xác định cho giao diện xuất khẩu và giao diện từ xa. Vấn đề tôi gặp phải là với một trong các phương pháp của tôi trên giao diện được xuất.XPC không đăng ký chính xác các lớp học cho bộ sưu tập

Tôi có một lớp mô hình, chỉ cần gọi nó là Foo. Lớp này phù hợp với NSSecureCoding, triển khai +supportsSecureCoding và mã hóa/giải mã các thuộc tính bên trong một cách chính xác bằng cách sử dụng các phương pháp mã hóa an toàn. Khi truyền đối tượng này thông qua một phương thức trên giao diện xuất khẩu của tôi mà chỉ liên quan đến một cá thể duy nhất, nó hoạt động tốt.

Sự cố xảy ra khi tôi muốn chuyển một bộ sưu tập các đối tượng này hoặc NSArray của các đối tượng Foo. Dưới đây là một ví dụ về những gì các chữ ký trên giao diện xuất khẩu trông giống như:

- (void)grabSomethingWithCompletion:(void (^)(NSArray *foos))completion; 

Và tôi đã whitelisted lớp Foo, như đã nêu trong tài liệu hướng dẫn:

NSSet *classes = [NSSet setWithObject:Foo.class]; 
[exportedInterface setClasses:classes forSelector:@selector(grabSomethingWithCompletion:) argumentIndex:0 ofReply:YES]; 

Bây giờ điều này sẽ làm cho nó để mảng này có thể được sao chép một cách an toàn trên toàn bộ quá trình và giải mã ở phía bên kia. Thật không may điều này dường như không hoạt động như mong đợi.

Khi gọi phương thức trên giao thức xuất khẩu, tôi nhận được một ngoại lệ:

Cảnh báo: Exception bắt trong giải mã nhận được trả lời nhắn 'grabSomethingWithCompletion:', thả tin nhắn gửi đến và gọi khối thất bại.

Ngoại lệ: ngoại lệ khi giải mã lập luận 1 trong tổng số gọi: giá trị trả về: {v} trống mục tiêu: {@}? 0x0 (block) lập luận 1: {@} 0x0

Ngoại lệ: giá trị cho khóa ' NS.objects 'là lớp học bất ngờ ' Foo '. lớp cho phép là '{( NSNumber, NSArray, NSDictionary, NSString, NSDate, NSData)}'.

Điều này dường như thậm chí không đăng ký danh sách trắng mà tôi đã thực hiện trước đó. Có suy nghĩ gì không?

+0

Trông như thể nó cũng cần phải làm 'NSPropertyListSerialization'. Dường như [bạn không đơn độc] (https://gist.github.com/AlanQuatermain/3209230) – CodaFi

Trả lời

11

CHỈNH SỬA 2: Tùy thuộc vào nơi bạn đã ghi danh sách trắng Foo. Nó cần phải được đưa vào danh sách trắng từ bên trong bất cứ điều gì đang gọi grabSomethingWithCompletion:.Ví dụ, nếu bạn có một dịch vụ triển khai và cho thấy:

- (void)takeThese:(NSArray *)bars reply:(void (^)(NSArray *foos))completion;

Sau đó, bạn cần phía dịch vụ vào danh sách trắng Bar cho kết nối đến:

// Bar and whatever Bar contains. 
NSSet *incomingClasses = [NSSet setWithObjects:[Bar class], [NSString class], nil]; 
NSXPCInterface *exposedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(InYourFaceInterface)]; 
[exposedInterface setClasses:incomingClasses forSelector:@selector(takeThese:reply:) argumentIndex:0 ofReply:NO]; 

// The next line doesn't do anything. 
[exposedInterface setClasses:incomingClasses forSelector:@selector(takeThese:reply:) argumentIndex:0 ofReply:YES]; 
xpcConnection.exposedInterface = exposedInterface; 

Đó phần thứ hai phải đi về đầu kia của kết nối, bất cứ điều gì đang nói chuyện với dịch vụ của bạn:

NSSet *incomingClasses = [NSSet setWithObjects:[Foo class], [NSNumber class], nil]; 
NSXPCInterface *remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(InYourFaceInterface)]; 
[remoteObjectInterface setClasses:incomingClasses forSelector:@selector(takeThese:reply:) argumentIndex:0 ofReply:YES]; 
xpcConnection.remoteObjectInterface = remoteObjectInterface; 

Tóm lại, bất cứ điều gì là nhận các vật thể lạ cần phải là một đối tượng có trong danh sách trắng các đối tượng lạ. Bạn không chắc đây có phải là vấn đề của bạn hay không, nhưng tôi chắc chắn nó sẽ là của ai đó.

EDIT: Bây giờ tôi đã làm việc với XPC trong một thời gian lâu hơn, tôi nhận ra rằng câu trả lời của tôi, trong khi giải quyết một vấn đề, không giải quyết được vấn đề của bạn. Tôi đã chạy vào điều này bây giờ một vài lần khác nhau và tôi vẫn không chắc chắn làm thế nào để sửa chữa nó bên ngoài thực hiện lớp bộ sưu tập của riêng tôi, đó là ít hơn lý tưởng.

gốc trả lời: Tôi biết nó đã được một thời gian khá kể từ khi bạn yêu cầu này, nhưng sau một tấn tìm kiếm với không ai trả lời câu hỏi này, tôi nghĩ rằng tôi muốn gửi câu trả lời của tôi cho những gì đã gây ra nó (có thể có những nguyên nhân khác, nhưng điều này đã sửa nó cho tôi).

Trong lớp phù hợp với NSSecureCoding, theo phương pháp initWithCoder:, bạn cần giải mã một cách rõ ràng các bộ sưu tập bằng cách chuyển vào tập hợp tất cả các lớp có thể có trong bộ sưu tập. Hai đầu tiên là những ví dụ tiêu chuẩn của giải mã, và người cuối cùng được giải mã một bộ sưu tập:

if (self = [super init]) { 
    self.bar = [aDecoder decodeInt64ForKey:@"bar"]; 
    self.baz = [aDecoder decodeObjectOfClass:[Baz class] forKey:@"baz"]; 
    NSSet *possibleClasses = [NSSet setWithObjects:[Collection class], [Foo class], nil]; 
    self.foo = [aDecoder decodeObjectOfClasses:possibleClasses forKey:@"foo"]; 
} 

Vì vậy, nếu bạn bộ sưu tập là một tập hợp chứa NSStrings, các lớp học có thể sẽ là [NSSet class][NSString class].

Tôi chắc chắn bạn đã chuyển từ vấn đề này, nhưng có thể ai đó cần câu trả lời này nhiều như tôi đã làm.

+0

Vấn đề của tôi đã được giải quyết bằng câu trả lời ban đầu của bạn. Trong khi tôi đang sử dụng XPC, vấn đề về danh sách trắng mà tôi gặp phải là trong quá trình triển khai NSCoding. Tôi đã giải mã một từ điển và chỉ có danh sách trắng NSDictionary, nhưng tôi cần phải đưa vào danh sách trắng các loại giá trị có thể có trong từ điển cũng như bạn hiển thị trong ví dụ của mình. Cảm ơn. – Andrew

+0

@Andrew - Vâng, tôi để lại mọi thứ ở đây vì tất cả chúng đều thể hiện vấn đề của họ theo những cách rất giống nhau. Vui mừng ít nhất một trong ba câu trả lời của tôi có thể giúp ích. – DrGodCarl

+0

"Câu trả lời gốc" cũng giải quyết được vấn đề này cho tôi.Tôi đã có một NSMutableArray của chuỗi trên đối tượng tùy chỉnh của tôi và đã sử dụng -decodeObjectOfClass: [NSMutableArray class] thay vì sử dụng phương thức -decodeObjectOfClasses: forKey:. – Bryan

0

tôi gặp phải vấn đề này cùng, tôi phải rõ ràng danh sách trắng NSArray* cũng

NSSet *classes = [NSSet setWithObjects: [Foo class], [NSArray class], nil]; 

Đó là một chút phản trực giác kể từ khi documentation không đề cập đến yêu cầu này.

0

Trên thực tế có vẻ như bạn cần phải thêm lớp tùy chỉnh của bạn để những người đã trong danh sách trắng:

NSSet currentClasses = [remoteObjectInterface classesForSelector:@selector(takeThese:reply:) argumentIndex:0 ofReply:YES]; 


NSSet *allIncomingClasses = [currentClasses setByAddingObjectsFromSet:[NSSet setWithObjects:[Foo class], [NSNumber class], nil]; 

NSXPCInterface *remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(InYourFaceInterface)]; 
[remoteObjectInterface setClasses:allIncomingClasses forSelector:@selector(takeThese:reply:) argumentIndex:0 ofReply:YES]; 
xpcConnection.remoteObjectInterface = remoteObjectInterface; 
Các vấn đề liên quan