Getting errors in NSError code - objective-c

Am getting errors in this piece of code; I have placed the error messages in the comments. Can't figure it out.
Thanks in advance.
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
#autoreleasepool {
NSMutableString *str = [[NSMutableString alloc]init];
for (int i = 0; i < 10; i++) {
[str appendString:#"Aaron is cool!\n"];
}
// Declare a pointer to an NSError object, but don't instantiate it.
// The NSError instance will only be created if there is, in fact, an error.
NSError *error = nil;
// Pass the error pointer by reference to the NSString method
BOOL success =[str writeToFile:#"/tmp/cool.txt"; // Expected "]"
atomically:YES // Bad receiver type 'int'
encoding:NSUTF8StringEncoding
error:&error];
// Test the returned BOOL, and query the NSError if the write failed
if (success) {
NSLog(#"done writing /tmp/cool.txt");
} else {
NSLog(#"writing /tmp/cool/txt failed:#", error localizedDescription); // Expected ')'
}
}
return 0;
}

If your code doesn't have any typos this is the problem
// Pass the error pointer by reference to the NSString method
BOOL success =[str writeToFile:#"/tmp/cool.txt"; // Expected "]"
atomically:YES // Bad receiver type 'int'
encoding:NSUTF8StringEncoding
error:&error];
Remove the semicolon ";" from here.
BOOL success =[str writeToFile:#"/tmp/cool.txt"; // Expected "]"

try this:
#autoreleasepool {
NSMutableString *str = [[[NSMutableString alloc]init] autorelease];
for (int i = 0; i < 10; i++) {
[str appendString:#"Aaron is cool!\n"];
}
NSError *error = nil;
BOOL success =[str writeToFile:#"/tmp/cool.txt"
atomically:YES
encoding:NSUTF8StringEncoding
error:&error];
if (success) {
NSLog(#"done writing /tmp/cool.txt");
} else {
NSLog(#"writing /tmp/cool/txt failed: %#", [error localizedDescription]);
}
}
return 0;

Related

How to use blocks to handle errors returned by NS methods

I created a file using the following code:
NSMutableString *tabString = [NSMutableString stringWithCapacity:0]; // it will automatically expand
// write column headings <----- TODO
// now write out the data to be exported
for(int i = 0; i < booksArray.count; i++) {
[tabString appendString:[NSString stringWithFormat:#"%#\t,%#\t,%#\t\n",
[[booksArray objectAtIndex:i] author],
[[booksArray objectAtIndex:i] binding],
[[booksArray objectAtIndex:i] bookDescription]]];
}
if (![self checkForDataFile: #"BnN.tab"]) // does the file exist?
[[NSFileManager defaultManager] createFileAtPath:documentsPath contents: nil attributes:nil]; // create it if not
NSFileHandle *handle;
handle = [NSFileHandle fileHandleForWritingAtPath: [NSString stringWithFormat:#"%#/%#",documentsPath, #"BnN.tab"]]; // <---------- userID?
[handle truncateFileAtOffset:[handle seekToEndOfFile]]; // tell handle where's the file fo write
[handle writeData:[tabString dataUsingEncoding:NSUTF8StringEncoding]]; //position handle cursor to the end of file (why??)
This is the code I am using to read back the file (for debugging purposes):
// now read it back
NSString* content = [NSString stringWithContentsOfFile:[NSString stringWithFormat:#"%#/%#",documentsPath, #"BnN.tab"]
encoding:NSUTF8StringEncoding
error: ^{ NSLog(#"error: %#", (NSError **)error);
}];
I am getting 2 build errors on this last statement that says:
Sending 'void (^)(void)' to parameter of incompatible type 'NSError *__autoreleasing *'
and
Use of undeclared identifier 'error'
This is the first time I am using a block to handle method returned errors; I was unable to find any docs in SO or Google showing how to do this. What am I doing wrong?
That function is expecting an NSError** parameter, not a block. The way you should be calling it is something like:
NSError *error = nil;
NSString* content = [NSString stringWithContentsOfFile: [NSString stringWithFormat:#"%#/%#", documentsPath, #"BnN.tab"]
encoding: NSUTF8StringEncoding
error: &error];
if (content == nil) {
NSLog("error: %#", error);
}

iOS initializing any variable crashes the app

When I try to initialize any variable, my app crashes
NSString *str = #"Some String";
It crashes with the error message - "EXC_BAD_ACCESS"
This stmt is inside a function. Everywhere else in the program the initialization is working but when i call this function, my app crashes giving the error message
Here is my function
+ (NSString *) recvToFile:(NSString *)_fileName {
#try {
int _sz = [self recvNumber:4];
uint8_t t[_sz];
NSMutableData *data = nil;//[[NSMutableData alloc] init];
NSMutableData *fileData = [[NSMutableData alloc] init];
NSString *str = #"Some String";
long _pos = 0;
NSString *_fullPath = _fileName;
while (_sz > _pos) {
long _c = [m_sin read:t maxLength:_sz];
_pos += _c;
data = [NSData dataWithBytes:t length:_c];
if([Misc checkTempFileExists:_fileName]==nil)
[[NSFileManager defaultManager] createFileAtPath:_fullPath contents:nil attributes:nil];
[fileData appendData:data];
}
[fileData writeToFile:_fullPath atomically:YES];
NSDictionary *attr = [[NSFileManager defaultManager] attributesOfItemAtPath:_fullPath error:nil];
long long length = [[attr valueForKey:#"NSFileSize"] intValue];
if (length >= _sz)
return (_fullPath);
}
#catch (NSException * e) {
}
return (nil);
}
Everywhere else initializing is working but not for this function
In your code you are using class method and in that method you are initializing nonstatic string, i think tats the problem.Instead of that Can you please check it with static NSString=#"Some String"; after the import files in .m file.The same way you can create fullpath string also.Then u can assign like fullpath=_fileName;#aswinikumar..sorry for my english

NSJSONSerialization parsing error neither dictionary nor array

i am succesfully getting data from my server. and after getting it i send the data to the function to parse;
- (void)readIn:(NSMutableData *)s {
NSLog(#"Reading in the following:");
NSString * prints = [[NSString alloc] initWithData:s encoding:NSUTF8StringEncoding];
NSLog(#"%#", prints);
NSError *error = nil;
NSData *jsonData = [[NSData alloc] initWithData:s];
if (jsonData) {
id jsonObjects = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
if ([jsonObjects isKindOfClass: [NSArray class]])
NSLog(#"yes we got an Array");
else if ([jsonObjects isKindOfClass: [NSDictionary class]])
NSLog(#"yes we got an dictionary");
else
NSLog(#"neither array nor dictionary!");
if (error) {
NSLog(#"error is %#", [error localizedDescription]);
return;
}
NSArray *keys = [jsonObjects allKeys];
for (NSString *key in keys) {
NSLog(#"%# is %#",key, [jsonObjects objectForKey:key]);
}
} else {
// Handle Error
}
}
now my print on console is:
2012-08-17 13:59:57.667 TaraftarlikOyunu[1157:c07] Reading in the following:
2012-08-17 13:59:57.667 TaraftarlikOyunu[1157:c07] {"uID":"5878341","tm":"fb","hh":122,"pt":75,"coin":500,"ll":1,"qlevel":1,"coect":true,"potWeekly":{"pts":75,"intval":604800000},"acent":{"chamunt":0},"mes":[]}
2012-08-17 13:59:57.668 TaraftarlikOyunu[1157:c07] neither array nor dictionary!
2012-08-17 13:59:57.670 TaraftarlikOyunu[1157:c07] error is The operation couldn’t be completed. (Cocoa error 3840.)
it seems legal json object to me. where am i doing wrong?
i am getting data from the server with nsstream; and here is my code to get data:
case NSStreamEventHasBytesAvailable: {
if(stream == inputStream) {
NSLog(#"inputStream is ready.");
uint8_t buf[1024];
unsigned int len = 0;
len = [inputStream read:buf maxLength:1024];
NSLog(#"length %i", len);
if(len > 0) {
NSMutableData* data=[[NSMutableData alloc] initWithLength:0];
[data appendBytes: (const void *)buf length:len];
[self readIn:data];
}
}
break;
}
Try explicitly setting the jsonObjects to be an array:
NSError *myError = nil;
NSArray *jsonObjects= [NSJSONSerialization JSONObjectWithData:responseData ptions:NSJSONReadingMutableLeaves error:&myError];
for (NSDictionary * dict in jsonObjects) {
NSLog(#"Some data %#", [dict objectForKey:#"field"]);
//replace this to access a valid field
}
The reason for the failure is that the original data probably has some '\' characters in it quoting '"' characters. If you had searched on "Cocoa error 3840" you would have gotten a hint on this. What I suggest you do is print out the original data, one character at a time (its ascii so no need for UTF) and verify this.
char *ptr = [s bytes];
for(int i=0; i<[s length]; ++i) NSLog(#"%c ", *ptr++);
problem is that, json string i get is coming with null termination at the end and when i try to deserialize it it can not be converted to NSDictionary or NSArray. making a little change on the code makes everything perfect. the true code should be like that
case NSStreamEventHasBytesAvailable: {
if(stream == inputStream) {
NSLog(#"inputStream is ready.");
uint8_t buf[1024];
unsigned int len = 0;
len = [inputStream read:buf maxLength:1024];
NSLog(#"length %i", len);
if(len > 0) {
datum =[[NSMutableData alloc] initWithLength:0];
[datum appendBytes: (const void *)buf length:len-1];
NSDictionary * jsondict = [NSJSONSerialization JSONObjectWithData:datum options:NSUTF8StringEncoding error:nil];
NSLog(#"is valid json object %d",[NSJSONSerialization isValidJSONObject:jsondict]);
[self readIn:datum];
}
}
else {
NSLog(#"no buffer!");
}
break;
}
default: {
NSLog(#"Stream is sending an Event: %i", event);
break;
}
}
only difference from the other one is i threw the last byte and it became valid json dictionary.
thanks for the people who are interested in my question.
JSON doesn't accept any control characters other than tab, form feed, carriage return, and line feed in a JSON document, so your code works perfectly fine and does exactly what it is supposed to do by not reading anything.
So where does that nul character come from? Either your code reading the data is wrong, or the server is wrong. Looks to me like the problem is the server. Your "fix" by throwing away the last character is bad - if the server is ever fixed, you'll throw away the closing brace. I'd contact whoever is responsible for the server and fix the problem there.

Can't read file

Here is my method which reads content of file. Unfortunately doesn't work for me. The path to file is correct. What I miss ?
- (IBAction)readFile:(id)sender
{
NSString *str = [NSString stringWithContentsOfFile:#"/Users/joe/text.txt"
encoding:NSUTF32StringEncoding
error:nil
];
NSLog(#"%#", str); //Result is null
}
Try using the built-in functionality of stringWithContentsOfFile:encoding:error: and give it a NSError and you can see exactly whats wrong:
- (IBAction)readFile:(id)sender {
NSError *readFileError = nil;
NSString *str = [NSString stringWithContentsOfFile:#"/Users/joe/text.txt"
encoding:NSUTF32StringEncoding
error:&readFileError
];
if (readFileError) {
NSLog(#"%# - %#", [readFileError localizedDescription], [readFileError localizedFailureReason]);
} else {
NSLog(#"%#", str);
}
}

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];