Parse bmrk NSAppleEventDescriptor from final cut pro x - objective-c

In Final cut pro, I shared to my application.
With following code
[[NSAppleEventManager sharedAppleEventManager] setEventHandler:self
andSelector:#selector(handleAppleEvent:withReplyEvent:) forEventClass:kCoreEventClass andEventID:kAEOpenDocuments];
- (void)handleAppleEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent {
NSLog(#"handleAppleEvent %#", event);
}
I got something like this.
'aevt''odoc'{ '----':[ 'bmrk'(1012/$626F6F6BF403000000000410300000000000000000000000000000000000000000000000000000000000000000000000C00200000400000003030000000200000500000001010000557365727300000009000000010100006D75796F756E676B6F0000000900000001010000446F63756D656E747300000007000000010100006161612E6D7866001000000001060000100000002000000034000000480000000800000004030000BC300600000000000800000...
I expected readable information likes /Users/hansome/Document/a.mov
How can I parse this?

I found code without fully understanding.
NSLog(#"handleAppleEvent 1 %#", event);
NSAppleEventDescriptor* prop = [event paramDescriptorForKeyword:keyAEPropData];
NSLog(#"handleAppleEvent prop %#", prop);
NSAppleEventDescriptor* obj = [event paramDescriptorForKeyword:keyDirectObject];
NSLog(#"handleAppleEvent obj %#", obj);
if(obj != nil){
for(int j=0;j<10;j++){
NSAppleEventDescriptor* obj2 = [obj descriptorAtIndex:j];
if(obj2 != nil){
BOOL isStale;
NSError* error;
NSURL* url = [NSURL URLByResolvingBookmarkData:[obj2 data] options:NSURLBookmarkResolutionWithoutUI relativeToURL:nil bookmarkDataIsStale:&isStale error:&error];
NSLog(#"handleAppleEvent bmrk %#", url);
}
}
}

Related

RACSignal: Signal is never invoked

I have the following code which is invoked by another signal:
- (RACSignal *)uploadFormItemAttachment_SO:(MyManagedAttachment *)attachment attachmentHeader:(MyFormItemAttachmentHeader*) attachmentHeader
{
RACSignal* signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// Code omitted for brevity
// NSDictionary* parameters = #{ #"parameter1" : param1_value};
AFHTTPRequestOperation* operation = [self.requestOperationManager POST:#"UploadForm" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileURL:fileURL
name:#"content"
error:nil];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
[self logRequest:operation response:responseObject];
BOOL success = [responseObject[#"success"] boolValue];
if (success)
{
attachment.status = #(AttachmentStatusSent);
[attachment.managedObjectContext MR_saveToPersistentStoreAndWait];
[subscriber sendNext:#(success)];
[subscriber sendCompleted];
}
else
{
NSDictionary* userInfo = nil;
NSString* message = responseObject[#"message"];
if (message != nil && ![message isEqual:[NSNull null]])
{
userInfo = #{ NSLocalizedDescriptionKey : message };
}
else
{
userInfo = #{ NSLocalizedDescriptionKey : [NSString stringWithFormat:#"Error uploading image: %#", filename]};
}
NSError* error = [NSError errorWithDomain:SEFSAPIClientErrorDomain code:1100 userInfo:userInfo];
[subscriber sendError:error];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[self logRequest:operation error:error];
[subscriber sendError:error];
}];
[self.requestOperationManager.operationQueue addOperation:operation];
return [RACDisposable disposableWithBlock:^{
[operation cancel];
}];
}];
return signal;
}
My problem is that the signal object is never invoked and the code never runs. It goes straight into the last statement
return signal;
and the code inside the signal never gets executed. Could anyone help please?
I have tried adding a [subscriber sendNext: signal] at the end of the RACSignal definition but it makes no difference.
The previous method is called by this one below:
- (RACSignal *)uploadPendingAttachments_SO
{
NSArray *pendingAttachments = [MyManagedAttachment MR_findAllWithPredicate:[NSPredicate predicateWithFormat:#"status == %ld && form.status == %ld", MyAttachmentStatusPending, SEFSFormStatusUploadedForm]
inContext:[NSManagedObjectContext MR_defaultContext]];
RACSignal* batchSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[pendingAttachments enumerateObjectsUsingBlock:^(MyManagedAttachment* pendingImage, NSUInteger idx, BOOL *stop) {
// Check if we have a top list item id which indicates form data has been created on the back-end SharePoint server.
NSString* siteID = pendingImage.siteID;
NSString* formID = pendingImage.formID;
NSManagedObjectContext* context = [NSManagedObjectContext MR_contextWithParent:[NSManagedObjectContext MR_defaultContext]];
NSPredicate* predicate = [NSPredicate predicateWithFormat:#"projectID = %# AND formID = %#", siteID, formID];
MyManagedForm* form = [MyManagedForm MR_findFirstWithPredicate:predicate
inContext:context];
if (form.topListItemID && pendingImage.formItemID) {
NSString* listName = pendingImage.list;
RACSignal* getFormItemAttachmentHeadersSignal = [[self getFormItemAttachmentHeaders:listName
topListItemID:form.topListItemID
form:form
] map:^id(NSMutableArray* value) {
NSArray* attachmentHeaders = [value copy];
RACSignal* attachmentsBatchSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[attachmentHeaders enumerateObjectsUsingBlock:^(MyFormItemAttachmentHeader* attachmentHeader, NSUInteger idx, BOOL *stop)
{
// Look for the local attachment using attachment header from server
NSPredicate* predicate = [NSPredicate predicateWithFormat:#"identifier = %#", attachmentHeader.document];
NSArray* foundAttachment = [pendingAttachments filteredArrayUsingPredicate:predicate];
MyManagedAttachment* fullAttachment = foundAttachment[0];
NSString* listName = pendingImage.list;
RACSignal* uploadFormItemAttachmentSignal = [[self uploadFormItemAttachment_SO:fullAttachment
attachmentHeader:attachmentHeader ] map:^id(id value) {
BOOL success = [value boolValue];
return nil;
}];
[subscriber sendNext:uploadFormItemAttachmentSignal];
}];
[subscriber sendCompleted];
return nil;
}];
return attachmentsBatchSignal; // check this
}];
[subscriber sendNext:getFormItemAttachmentHeadersSignal];
}
else {
RACSignal* uploadFormSignal = [[self uploadAttachment:pendingImage] map:^id(NSNumber* value) {
NSMutableArray* valuesArray = [NSMutableArray array];
[valuesArray addObject:value];
[valuesArray addObject:pendingImage.objectID];
RACTuple* tuple = [RACTuple tupleWithObjectsFromArray:valuesArray
convertNullsToNils:YES];
return tuple;
}];
[subscriber sendNext:uploadFormSignal];
}
}];
[subscriber sendCompleted];
return nil;
}];
return [batchSignal flatten:2];
}

when try to overriding the nserror cant get anything

i want do base on the nserror info,create a new instance of nserror,but seem is not work at all
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError * *)outError
{
NSError *breakError = nil;
todoItems = [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListMutableContainers format:NULL error:&breakError];
if (todoItems == nil){
NSString *desc = NSLocalizedString(#"Can't do it!", #"");
NSDictionary *userInfo = #{ NSLocalizedDescriptionKey : desc };
*outError = [NSError errorWithDomain:#"com.pink.test" code:3084 userInfo:userInfo];
return NO;
}
// Insert code here to read your document from the given data of the specified type. If outError != NULL, ensure that you create and set an appropriate error when returning NO.
// You can also choose to override -readFromFileWrapper:ofType:error: or -readFromURL:ofType:error: instead.
// If you override either of these, you should also override -isEntireFileLoaded to return NO if the contents are lazily loaded.
NSException *exception = [NSException exceptionWithName:#"UnimplementedMethod" reason:[NSString stringWithFormat:#"%# is unimplemented", NSStringFromSelector(_cmd)] userInfo:nil];
#throw exception;
return YES;
}
i always only can get the default dialog message,even i not pass the nserror back
i sorry it if not clear,here is a demo for what i repeat what happen of mine.
加油了. 你想陈述的问题,跟别人看到的可能不一样.
If you have a error output in that function , there is no need to throw exception.
Here is a example making nserror from kxsmb:
static NSError * mkKxSMBError(KxSMBError error, NSString *format, ...)
{
NSDictionary *userInfo = nil;
NSString *reason = nil;
if (format) {
va_list args;
va_start(args, format);
reason = [[NSString alloc] initWithFormat:format arguments:args];
va_end(args);
}
if (reason) {
userInfo = #{
NSLocalizedDescriptionKey : KxSMBErrorMessage(error),
NSLocalizedFailureReasonErrorKey : reason
};
} else {
userInfo = #{ NSLocalizedDescriptionKey : KxSMBErrorMessage(error) };
}
return [NSError errorWithDomain:KxSMBErrorDomain
code:error
userInfo:userInfo];
}
it's done,turn out it's only can be use system define error,not can be custom,it means only can be errorWithDomain:NSCocoaErrorDomain and a valid code
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError * *)outError
{
if (*outError == nil){
NSString *desc = NSLocalizedString(#"Can't do it!", #"");
NSDictionary *userInfo = #{ NSLocalizedDescriptionKey : desc };
*outError = [NSError errorWithDomain:NSCocoaErrorDomain code:3840 userInfo:userInfo];
}
return NO;
thank for the all help.

GCDAsyncSocket not receiving all transmitted data, missing last "Chunk"

I am trying to send some strings and image data from a python script to an objective C application running on OSX.
I am collecting the transmitted data, using GCDAsyncSocket, and appending it to an NSMutableData until the server disconnects. I am then processing that NSData and splitting it into it's original parts.
The transmitted data consists of the following:
ID string, filled out to 16 bytes.
Image number string, filled out to 16 bytes.
Raw image data.
Termination string, filled out to 16 bytes.
The problem is that i am not receiving/getting the last chunk of data, i end up missing the end of the JPEG image, resulting in a corrupt (though mostly displayed) image, and a missing termination string.
Here is the code i am using with GCDAsyncSocket to get the data, and process it:
Socket connection:
- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket
{
// This method is executed on the socketQueue (not the main thread)
#synchronized(connectedSockets)
{
[connectedSockets addObject:newSocket];
}
NSString *host = [newSocket connectedHost];
UInt16 port = [newSocket connectedPort];
dispatch_async(dispatch_get_main_queue(), ^{
#autoreleasepool {
[self logInfo:FORMAT(#"Accepted client %#:%hu", host, port)];
}
});
[newSocket readDataToData:[GCDAsyncSocket CRLFData] withTimeout:-1 tag:0];
}
Socket Data Received
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
// This method is executed on the socketQueue (not the main thread)
dispatch_async(dispatch_get_main_queue(), ^{
#autoreleasepool {
NSLog(#"Thread Data Length is %lu", (unsigned long)[data length]);
if (!imageBuffer){
imageBuffer = [[NSMutableData alloc]init];
}
[imageBuffer appendData:[data subdataWithRange:NSMakeRange(0, [data length])]];
NSLog(#"Total Data Length is %lu", (unsigned long)[imageBuffer length]);
}
});
// Echo message back to client
[sock writeData:data withTimeout:-1 tag:ECHO_MSG];
[sock readDataToData:[GCDAsyncSocket CRLFData] withTimeout:-1 tag:0];
}
Socket Disconnected
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
if (sock != listenSocket)
{
dispatch_async(dispatch_get_main_queue(), ^{
#autoreleasepool {
[self logInfo:FORMAT(#"Client Disconnected")];
NSData *cameraNumberData;
NSData *imageNumberData;
NSData *imageData;
NSData *endCommandData;
//if ([data length] > 40){
cameraNumberData = [imageBuffer subdataWithRange:NSMakeRange(0, 16)];
imageNumberData = [imageBuffer subdataWithRange:NSMakeRange(16, 16)];
imageData = [imageBuffer subdataWithRange:NSMakeRange(32, [imageBuffer length]-34)];
endCommandData = [imageBuffer subdataWithRange:NSMakeRange([imageBuffer length]-16, 16)];
//}
NSString *cameraNumberString = [[NSString alloc] initWithData:cameraNumberData encoding:NSUTF8StringEncoding];
NSString *imageNumberString = [[NSString alloc] initWithData:imageNumberData encoding:NSUTF8StringEncoding];
NSString *endCommandString = [[NSString alloc] initWithData:endCommandData encoding:NSUTF8StringEncoding];
NSImage* image = [[NSImage alloc]initWithData:imageData];
if (cameraNumberString)
{
NSLog(#"Image recieved from Camera no %#", cameraNumberString);
[self logMessage:cameraNumberString];
}
else
{
[self logError:#"Error converting received data into UTF-8 String"];
}
if (imageNumberString)
{
NSLog(#"Image is number %#", imageNumberString);
[self logMessage:imageNumberString];
}
else
{
[self logError:#"Error converting received data into UTF-8 String"];
}
if (image)
{
NSLog(#"We have an image");
[self.imageView setImage:image];
}
else
{
[self logError:#"Error converting received data into image"];
}
if (endCommandString)
{
NSLog(#"Command String is %#", endCommandString);
[self logMessage:endCommandString];
}
else
{
[self logError:#"No command string"];
}
//self.imageBuffer = nil;
}
});
#synchronized(connectedSockets)
{
[connectedSockets removeObject:sock];
}
}
}
I have used wireshark, and the data is being transmitted, it's just not getting through GCDAsynSocket.
So, i'm obviously missing something. Socket programming and encoding/decoding of data like this is relatively new to me, so i am probably being an idiot.
Help greatly appreciated!
Thanks
Gareth
Ok, so i finally got this working. It involved modifying the transmitting code in Python to send a completion string at the end of the data, and watching for that. The biggest takeaway was that i needed to re-call the readDataToData: method each time the socket read some data, otherwise it would just sit there and wait, and the transmitting socket would also just sit there.
I also had to implement re-calling the second receive with a tag so i could store the received data in the correct NSMutableData object in an NSMutableArray, otherwise i had no way of knowing after the first receive which transmitting socket the data was coming from as the ID was only at the beginning of the first message.
Here is the didReadData code:
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
dispatch_async(dispatch_get_main_queue(), ^{
#autoreleasepool {
NSInteger cameraNumberNumber = 0;
NSString *cameraNumberString = [[NSString alloc]init];
if (tag > 10){
cameraNumberNumber = tag-11;
DDLogVerbose(#"Second data loop, tag is %ld", tag);
} else {
NSData *cameraNumberData;
//if ([data length] > 40){
cameraNumberData = [data subdataWithRange:NSMakeRange(0, 16)];
NSString *cameraNumberString = [[NSString alloc] initWithData:cameraNumberData encoding:NSUTF8StringEncoding];
cameraNumberString = [cameraNumberString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
cameraNumberNumber = [cameraNumberString intValue]-1;
}
if (cameraNumberNumber+1 <= self.images.count){
if ([self.images objectAtIndex:cameraNumberNumber] == [NSNull null]){
image* cameraImage = [[image alloc]init];
[self.images replaceObjectAtIndex: cameraNumberNumber withObject:cameraImage];
}
image* cameraImage = [self.images objectAtIndex:cameraNumberNumber];
[cameraImage.imageData appendData:[data subdataWithRange:NSMakeRange(0, [data length])]];
cameraImage.cameraNumber = cameraNumberString;
if (!imageBuffer){
imageBuffer = [[NSMutableData alloc]init];
}
[imageBuffer appendData:[data subdataWithRange:NSMakeRange(0, [data length])]];
DDLogVerbose(#"Total Data Length is %lu", (unsigned long)[imageBuffer length]);
} else {
DDLogInfo(#"Wrong camera quantity!");
NSAlert *testAlert = [NSAlert alertWithMessageText:#"Wrong camera quantity!"
defaultButton:#"Ok"
alternateButton:nil
otherButton:nil
informativeTextWithFormat:#"We have recieved more images than cameras, please set No.Cameras correctly!"];
[testAlert beginSheetModalForWindow:[self window]
modalDelegate:self
didEndSelector:#selector(stop)
contextInfo:nil];
}
[sock readDataToData:[#"end" dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:cameraNumberNumber + 11];
}
});
}
and here is the socketDidDisconnect code, a lot of things in here that don't make sense out of context, but it shows how i handled the received data.
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
if (sock != listenSocket)
{
dispatch_async(dispatch_get_main_queue(), ^{
#autoreleasepool {
totalCamerasFetched = [NSNumber numberWithInt:1+[totalCamerasFetched intValue]];
if ([totalCamerasFetched integerValue] >= [numberOfCameras integerValue]){
for (image* cameraImage in self.images){
NSData *cameraNumberData;
NSData *imageNumberData;
NSData *imageData;
NSData *endCommandData;
NSInteger cameraNumberNumber = 0;
cameraNumberData = [cameraImage.imageData subdataWithRange:NSMakeRange(0, 16)];
imageNumberData = [cameraImage.imageData subdataWithRange:NSMakeRange(16, 16)];
imageData = [cameraImage.imageData subdataWithRange:NSMakeRange(32, [cameraImage.imageData length]-32)];
endCommandData = [cameraImage.imageData subdataWithRange:NSMakeRange([cameraImage.imageData length]-16, 16)];
NSString *cameraNumberString = [[NSString alloc] initWithData:cameraNumberData encoding:NSUTF8StringEncoding];
cameraNumberString = [cameraNumberString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSString *imageNumberString = [[NSString alloc] initWithData:imageNumberData encoding:NSUTF8StringEncoding];
imageNumberString = [imageNumberString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSString *endCommandString = [[NSString alloc] initWithData:endCommandData encoding:NSUTF8StringEncoding];
NSImage* image = [[NSImage alloc]initWithData:imageData];
cameraNumberNumber = [cameraNumberString intValue]-1;
if (cameraNumberString)
{
DDLogInfo(#"Image recieved from Camera no %#", cameraNumberString);
}
else
{
DDLogError(#"No Camera number in data");
}
if (imageNumberString)
{
DDLogInfo(#"Image is number %#", imageNumberString);
}
else
{
DDLogError(#"No Image number in data");
}
if (image)
{
DDLogVerbose(#"We have an image");
NSString* dataPath = [[NSString alloc]initWithFormat:#"%#/image%#/",self.exportLocation, imageNumberString];
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath]){
NSError* error;
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error];
if (error)
{
DDLogError(#"[%#] ERROR: attempting to write directory for images", [self class]);
NSAssert( FALSE, #"Failed to create directory maybe out of disk space?");
}
}
NSString* dataPathVideo = [[NSString alloc]initWithFormat:#"%#/video%#/",self.exportLocation, imageNumberString];
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPathVideo]){
NSError* error;
[[NSFileManager defaultManager] createDirectoryAtPath:dataPathVideo withIntermediateDirectories:NO attributes:nil error:&error];
if (error)
{
DDLogError(#"[%#] ERROR: attempting to write directory for images", [self class]);
NSAssert( FALSE, #"Failed to create directory maybe out of disk space?");
}
}
NSString * exportLocationFull = [[NSString alloc]initWithFormat:#"%#/image%#/camera_%#.jpg",self.exportLocation, imageNumberString, cameraNumberString];
DDLogInfo(#"Full export URL = %#", exportLocationFull);
[imageData writeToFile:exportLocationFull atomically:YES];
self.currentSet = [NSNumber numberWithInt:[imageNumberString intValue]];
NSImage* imageToStore = [[NSImage alloc]initWithData:imageData];
[self.imagesToMakeVideo replaceObjectAtIndex: cameraNumberNumber withObject:imageToStore];
} else {
DDLogError(#"No image loacted in data");
}
if (endCommandString)
{
DDLogVerbose(#"Command String is %#", endCommandString);
//[self logMessage:endCommandString];
}
else
{
//[self logError:#"No command string"];
}
self.imageBuffer = nil;
}
self.totalCamerasFetched = [NSNumber numberWithInt:0];
[self loadandDisplayLatestImages];
[self createVideowithImages:imagesToMakeVideo toLocation:[[NSString alloc]initWithFormat:#"%#/video%#/image_sequence_%#.mov",self.exportLocation, self.currentSet, self.currentSet]];
processing = false;
}//end of for loop
}
});
#synchronized(connectedSockets)
{
[connectedSockets removeObject:sock];
}
}
}
also here is how i modified the Python code to add the extra "end" tag.
def send_media_to(self, ip, port, media_name, media_number, media_dir):
camera_number = self.camera.current_mode['option'].number
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, port))
try:
sock.send(bytes(str(camera_number).ljust(16), 'utf-8'))
sock.send(bytes(str(media_number).ljust(16), 'utf-8'))
with open(media_dir + media_name, 'rb') as media:
sock.sendall(media.read())
finally:
sock.send(bytes(str("end").ljust(16), 'utf-8'))
sock.close()
Hopefully this helps someone else stuck in the same situation!

Type-check: How to check if NSData is an NSArray?

I'm currently working with the Multipeer Connectivity Framework in XCode for an iPad App.
I want to send messages with the framework (NSStrings, Booleans & NSArrays) and Strings are working fine, but I need some sort of type-check to convert the NSData object into a String, Array, etc.
This is what my didReceiveData methode looks like:
- (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID{
NSString *message = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSMutableArray *recievedArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];
if ([message isEqualToString:#"PeerIsConnected"]) {
NSLog(#"Peer sended: Connected!");
self.connectionIsOn = TRUE;
dispatch_async(dispatch_get_main_queue(),^{
[self changeConnectionButton:TRUE];
});
NSLog(#"Connection is on (data received) : %#", (self.connectionIsOn) ? #"YES" : #"NO");
}
if ([message isEqualToString:#"Disconnect"]) {
NSLog(#"Peer sended: Disconnect!");
self.connectionIsOn = FALSE;
dispatch_async(dispatch_get_main_queue(),^{
[self changeConnectionButton:FALSE];
});
}
if ([message isEqualToString:#"GoWasClicked"]) {
self.muliplayergameIsOn = TRUE;
self.myTurn = TRUE;
self.startDate = [NSDate date];
self.stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0
target:self
selector:#selector(updateTimer)
userInfo:nil
repeats:YES];
}
I need some if case so I can cast the NSData object into a NSString OR NSArray OR etc.
How can I solve this problem?
Thanks in advance!
EDIT: This is how the Array is sended:
- (void) sendArray:(NSMutableArray *) arrayToSend{
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:arrayToSend];
NSError *error;
[self.mySession sendData:data toPeers:[self.mySession connectedPeers] withMode:MCSessionSendDataUnreliable error:&error];
}
You could use NSKeyedArchiver for all kinds of objects that you send
(string, array, ...). Then you can check on the receiving side with
id receivedObject = [NSKeyedUnarchiver unarchiveObjectWithData:data];
if ([receivedObject isKindOfClass:[NSArray class]]) {
NSArray *receivedArray = receivedObject;
// handle array ...
} else if ([receivedObject isKindOfClass:[NSString class]]) {
NSString *receivedString = receivedObject;
// handle string ...
}
//Added one more condition here...
id receivedObject = [NSKeyedUnarchiver unarchiveObjectWithData:data];
if ([receivedObject isKindOfClass:[NSArray class]]) {
NSArray *receivedArray = receivedObject;
// handle array ...
}
else if ([receivedObject isKindOfClass:[NSDictionary class]]) {
NSString *receivedString = receivedObject;
// handle dictionary ...
}
else if ([receivedObject isKindOfClass:[NSString class]]) {
NSString *receivedString = receivedObject;
// handle string ...
}

Handling NSError when reading from file?

I am just curious if I am doing this right.
NSString *fileContents;
NSError *fileError = nil;
fileContents = [[NSString stringWithContentsOfFile:fileOnDisk
encoding:NSMacOSRomanStringEncoding
error:&fileError] retain];
if(fileError != nil) {
NSLog(#"Error : %#", [fileError localizedDescription]);
}
// Other Code ...
[fileContents release];
.
EDIT (to reflect bbums comments)
.
NSString *fileOnDisk = #"/Users/Gary/Documents/Xcode/RnD/Maya.MEL";
NSError *fileError; // Should this be *fileError = nil;
NSString *fileContents;
int status = 0;
fileContents = [[NSString stringWithContentsOfFile:fileOnDisk
encoding:NSMacOSRomanStringEncoding
error:&fileError] retain];
if(fileContents == nil) {
NSLog(#"FileError: %#", [fileError localizedDescription]);
status = 1;
} else {
NSLog(#"Success : %#", fileContents);
}
// Clean up
[fileContents release];
[pool drain];
return status;
gary
NSError *fileError = nil;
....
if(fileError != nil)
....
That is incorrect. You must not assume anything about the return-by-reference value of fileError until you check whether or not fileContents was nil. Not ever. Setting fileError to nil prior to calling the pass-error-by-reference method does nothing useful.
That is, your code should read (fixed now that I'm no longer running from plane to plane and hopping on WiFi in between connections...):
NSString *fileContents;
NSError *fileError;
fileContents = [[NSString stringWithContentsOfFile:fileOnDisk
encoding:NSMacOSRomanStringEncoding
error:&fileError] retain];
if(fileContents == nil) {
NSLog(#"Error : %#", [fileError localizedDescription]);
// ... i.e. handle the error here more
return ...; // often returning after handling the errors, sometimes you might continue
}
// Other Code ...
[fileContents release];