Can't read file - objective-c

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);
}
}

Related

Using RCTAsyncLocalStorage + getAllKeys

I'm trying to get the AsyncStorage on iOS native code. So this is my code
- (void)jsonFromLocalRNStrogeForKey:(NSString *)key completion:(void (^)(NSDictionary * _Nullable, NSError * _Nullable))completion {
RCTResponseSenderBlock rnCompletion = ^(NSArray *response) {
NSString *jsonAsString;
if (response.count > 1) {
NSArray *response1 = response[1];
if (response1.count > 0) {
NSArray *response2 = response1[0];
if (response2.count > 1) {
jsonAsString = response2[1];
}
}
}
#try {
NSData *jsonAsData = [jsonAsString dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSDictionary *json = [
NSJSONSerialization
JSONObjectWithData:jsonAsData
options:NSJSONReadingMutableContainers
error:&error
];
completion(json, error);
}
#catch (NSException *exception) {
NSLog(#"error: %#", exception.reason);
NSMutableDictionary * info = [NSMutableDictionary dictionary];
[info setValue:exception.name forKey:#"ExceptionName"];
[info setValue:exception.reason forKey:#"ExceptionReason"];
[info setValue:exception.callStackReturnAddresses forKey:#"ExceptionCallStackReturnAddresses"];
[info setValue:exception.callStackSymbols forKey:#"ExceptionCallStackSymbols"];
[info setValue:exception.userInfo forKey:#"ExceptionUserInfo"];
NSError *error = [[NSError alloc] initWithDomain:#"" code:1 userInfo:info];
completion(nil, error);
}
};
// RCTAsyncLocalStorage *storage = [RCTAsyncLocalStorage new];
RCTAsyncLocalStorage *storage = [[RCTAsyncLocalStorage alloc] init];
dispatch_async(storage.methodQueue, ^{
#try {
// [storage performSelector:#selector(multiGet:callback:) withObject:#[key] withObject:rnCompletion];
[storage performSelector:#selector(getAllKeys:callback:) withObject:rnCompletion];
}
#catch (NSException *exception) {
NSLog(#"error: %#", exception.reason);
}
});
}
When I try to get one of my keys (multiGet)
[self jsonFromLocalRNStrogeForKey:#"session" completion:^(NSDictionary* data,NSError* error) {
if (data) {
NSString * name = [data valueForKeyPath: #"token"];
if (![name isKindOfClass:[NSNull class]]) {
[self reportIncomingCallFrom:name withUUID:callInvite.uuid];
}
} else {
NSLog(#"error: JSON Parsing Error: %#",error.localizedFailureReason);
}
}];
I'm always getting null
And when I try to get all the keys (...#selector(getAllKeys:...) to see what do I have in my AsyncStorage I got the exception
#"NSInvalidArgumentException" - reason: #"-[RCTAsyncLocalStorage getAllKeys:callback:]: unrecognized selector sent to instance 0x1085512c0"
The RN have RCT_EXPORT_METHOD(getAllKeys:(RCTResponseSenderBlock)callback) in RCTAsyncLocalStorage.m; but at RCTAsyncLocalStorage.h (void)getAllKeys:(RCTResponseSenderBlock)callback it doesn't exists and even adding it doesn't work (https://github.com/facebook/react-native/blob/master/React/Modules/RCTAsyncLocalStorage.h).
"react-native": "^0.48.4",
How can I return NSJsonSerialization
Firstly,
The RN have
RCT_EXPORT_METHOD(getAllKeys:(RCTResponseSenderBlock)callback) in
RCTAsyncLocalStorage.m; but at RCTAsyncLocalStorage.h
(void)getAllKeys:(RCTResponseSenderBlock)callback it doesn't exists
In Objective-C, you can invoke a method even though it is not declared in the header file using performSelector:withObject:.
Invoking this method directly (without first checking if the target respondsToSelector:) is bad practice, as the internal method declaration may change.
Secondly, this line is incorrect:
[storage performSelector:#selector(getAllKeys:callback:) withObject:rnCompletion];
Here, you're saying getAllKeys:: takes two arguments, however the implementation declares only one.
Hence, the correct way to extract all keys is the following:
dispatch_async(storage.methodQueue, ^{
if([storage respondsToSelector:#selector(getAllKeys:)]){
[storage performSelector:#selector(getAllKeys:) withObject:[^(NSArray* response){
NSLog(#"Contents: %#",response);
} copy]];
}else{
NSLog(#"storage does not respond to selector `getAllKeys:`");
}
});

SIGABRT when trying to parse JSON

I am trying to parse a JSON string but it falls with a SIGABRT error.
Code I am using:
NSString *test = #'{"notifications":[{"id":"fae9a890-2791-46e2-ad9c-5a72f602a2e8","created":"2017-06-17T21:57:28+00:00","thread_id":3964,"reply_id":null,"thread":{"id":3964,"subject":"[CakePHP] Pagination"},"users_from":{"username":"Royal"},"content":"has posted a reply in"},{"id":"00732627-f23e-423e-b885-add968575972","created":"2017-06-17T20:08:05+00:00","thread_id":3964,"reply_id":79478,"thread":{"id":3964,"subject":"[CakePHP] Pagination"},"users_from":{"username":"Royal"},"content":"has quoted you in"}]}';
NSError *error;
NSMutableDictionary *allCourses = [NSJSONSerialization JSONObjectWithData:test
options:kNilOptions
error:&error];
if( error )
{
NSLog(#"%#", [error localizedDescription]);
}
else {
NSArray *monday = allCourses[#"notifications"];
for ( NSDictionary *theCourse in monday )
{
NSLog(#"----");
NSLog(#"Title: %#", theCourse[#"subject"] );
NSLog(#"Id: %#", theCourse[#"id"] );
NSLog(#"----");
}
}
Thanks.
The mistake is in your NSString declaration:
NSString *test = #'{"notifications"}';
This is wrong.
NSString must always use this format: #"bla bla bla".
You need to incorporate escapes for double quotes in your test string like this
NSString *test = #"{\"notifications\"}";

How to check the NSString contains URL or string data?

I am fresher to iOS, i am getting problem at checking string object contains URL or string?
NSMutableArray *Arr=[NSMutableArray alloc]initWithObject:#"Welcome", #"http://abcd.com/Images/bus.png", nil];
int i;
i++;
NSString *str=[Arr objectAtIndex:i];
Now, i want to check condition, if string contains "Welcome", have to display on label or if it is URL , i need to display that URL image in ImageView. So how can i check it? Please help me in this problem.
Instead of initiating both as NSStrings, try differentiating between them by making urls a NSURL (special container specifically for urls):
NSMutableArray* Arr = [NSMutableArray alloc]initWithObject:#"Welcome", [NSURL URLWithString:#"http://abcd.com/Images/bus.png"], nil];
for(id object in Arr)
{
if([object isKindOfClass:[NSString class]])
{
NSString* string = object;
NSLog(#"String: %#", string);
}
else if([object isKindOfClass:[NSURL class]])
{
NSURL* url = object;
NSLog(#"URL: %#", url);
}
}
Try like this
NSMutableArray *Arr=[[NSMutableArray alloc]initWithObjects:#"Welcome", #"http://abcd.com/Images/bus.png",nil];
NSString *st=nil;
for(NSString *string in Arr)
{
NSArray *matches = [detector
matchesInString:string
options:0
range:NSMakeRange(0,
[string length])];
for (NSTextCheckingResult *match in
matches) {
if ([match resultType] ==
NSTextCheckingTypeLink) {
NSURL *url = [match URL];
} else
{
NSlog(#"it is a string");
}
}
}
Try this, it will help you:
NSMutableArray *Arr=[[NSMutableArray alloc]initWithObjects:#"Welcome", #"http://abcd.com/Images/bus.png", nil];
if([Arr count])
{
for (NSString *str in Arr)
{
if([str isEqualToString:#"Welcome"])
{
NSLog(#"str is %#",str);
//do whatever you want
}
if([str isEqualToString:#"http://abcd.com/Images/bus.png"])
{
NSLog(#"str is %#",str);
//do whatever you want
}
}
}
To check NSString is containing a URL You can Try This code
if ([stringName hasPrefix:#"http://"] || [stringName hasPrefix:#"https://"]) {
//show imageVivew
}

Mac OS: how to determine path is file or directory

I have a path and I want to know, is this directory or a file. Pretty simple, but I have a problem. Here's my path:
NSString *file = #"file://localhost/Users/myUser/myFolder/TestFolder/";
or
NSString *file = #"file://localhost/Users/myUser/myFolder/my_test_file.png";
Here is my code:
BOOL isDir;
// the original code from apple documentation:
// if ([fileManager fileExistsAtPath:file isDirectory:&isDir] && isDir)
// but even my if returns me "not ok" in log
if([[NSFileManager defaultManager] fileExistsAtPath:file isDirectory:&isDir])
{
NSLog(#"directory");
}
else
{
NSLog(#"not ok");
}
files and dirs on this pathes are exists and they are ok. But I thinks problem could be in it. But I don't know why. Help me with this please.
By the way, I get path from another method:
NSArray *contentOfMyFolder = [[NSFileManager defaultManager]
contentsOfDirectoryAtURL:urlFromBookmark
includingPropertiesForKeys:#[NSURLContentModificationDateKey, NSURLLocalizedNameKey]
options:NSDirectoryEnumerationSkipsHiddenFiles
error:nil];
after this in for loop, I get items that stored in array contentOfMyFolder
and get path like this:
for (id item in contentOfMyFolder) {
NSString *path = [item absoluteString];
}
I thinks this is perfectly valid path for method fileExistsAtPath:(NSString *)path isDirectory:(BOOL)isDir
Where the problem could hide?!
The problem is here:
NSString *path = [item absoluteString];
because that creates a string representation of the URL, such as
file://localhost/Users/myUser/myFolder/TestFolder/
and that is not what fileExistsAtPath: expects.
What you need is the path method to convert the URL to a path:
for (NSURL *item in contentOfMyFolder) {
NSString *path = [item path];
BOOL isDir;
if ([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDir]) {
if (isDir) {
NSLog(#"%# is a directory", path);
} else {
NSLog(#"%# is a file", path);
}
} else {
NSLog(#"Oops, %# does not exist?", path);
}
}
Alternatively, you can ask the URL for its "directory property":
for (NSURL *item in contentOfMyFolder) {
NSNumber *isDir;
NSError *error;
if ([item getResourceValue:&isDir forKey:NSURLIsDirectoryKey error:&error]) {
if ([isDir boolValue]) {
NSLog(#"%# is a directory", item);
} else {
NSLog(#"%# is a file", item);
}
} else {
NSLog(#"error: %#", error);
}
}

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.