Show contents of two merged directory listings - objective-c

I would like to merge the two directories listings (already done and works they show up in NSTableView), but also display the contents of the files in an NSScrollview, now the problem lies in iterating through the list, and I couldn't figure out how I would come about that problem, I tried different techniques.
For now I get: "-[NSTextView replaceCharactersInRange:withString:]: nil NSString given.", probably because the iteration code is incorrect...
NSInteger row = [logsTableView selectedRow];
NSString *path1 = [NSHomeDirectory() stringByAppendingPathComponent:#"Library/Logs/"];
NSString *path2 = #"/Library/Logs/";
NSArray *directoryList1 = [[[NSFileManager defaultManager] contentsOfDirectoryAtPath:path1 error:nil]
pathsMatchingExtensions:[NSArray arrayWithObjects:#"log", nil]];
NSArray *directoryList2 = [[[NSFileManager defaultManager] contentsOfDirectoryAtPath:path2 error:nil]
pathsMatchingExtensions:[NSArray arrayWithObjects:#"log", nil]];
NSMutableArray *directoryList = [NSMutableArray array];
[directoryList addObjectsFromArray:directoryList1];
[directoryList addObjectsFromArray:directoryList2];
for (NSUInteger i = 0; i < directoryList.count; i++)
{
if (row == i)
{
for (NSUInteger i = 0; i < directoryList1.count; i++)
{
NSString *filePath = [NSHomeDirectory() stringByAppendingFormat:#"Library/Logs/%#", [directoryList objectAtIndex:i]];
NSString *content = [NSString stringWithContentsOfFile:filePath
encoding:NSUTF8StringEncoding
error:NULL];
[logsScrollViewTextView setString:content];
}
for (NSUInteger i = directoryList.count - directoryList1.count; i < directoryList.count; i++)
{
NSString *filePath = #[#"/Library/Logs/%#", [directoryList objectAtIndex:i]];
NSString *content = [NSString stringWithContentsOfFile:filePath
encoding:NSUTF8StringEncoding
error:NULL];
[logsScrollViewTextView setString:content];
}
}
}

You don't need to iterate. All you need to do is to check which array the file name came from.
Assuming you aren't sorting the list, this is if (row >= directoryList1.count). This check tells you which list it came from so you can set the prefix.
If you are sorting and the names are unique you could use [directoryList1 containsObject:...).

Related

Error writing to long value to file Objective-C

I'm trying to create 9 text files on my Desktop which are named by variable i in the for loop. Inside each text file I want to write a long value determined by my bigInt function. The long value must then be written in the file 1000 times before moving on to the next text file. But I keep getting the error: Incompatible pointer types sending 'NSString*' to parameter of type 'NSData*'
My Function:
long bigInt(int i){
long big = 99*(i*99);
long evenBigger = big*(big*(big*big));
return evenBigger;
}
My main method:
long use;
int x = 0;
for (int i = 1; i<10; i++) {
while (x < 1000) {
use = bigInt(i);
//[NSString stringWithFormat:#"%ld", use];
//NSString *content = #"Text to write to file";
NSString *path = [NSString stringWithFormat: # "/Users/ou_snaaksie/Desktop/%i.txt", i];
//NSData *fileContents = [use dataUsingEncoding:NSUTF8StringEncoding];
[[NSFileManager defaultManager] createFileAtPath:path contents:[NSString stringWithFormat:#"%ld", use] attributes:nil];
x++;
}
}
I think you need to pass NSData instead of NSString object to contents in createFileAtPath:contents:attributes: method or you can do something like below:
if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
[[NSFileManager defaultManager] createFileAtPath:path contents:nil attributes:nil];
}
[[string dataUsingEncoding:NSUTF8StringEncoding] writeToFile:path atomically:YES];
You are passing a string as contents when it requires NSData. You have to convert the string to NSData. Try this in the body of your while loop:
use = bigInt(i);
NSString* str = [NSString stringWithFormat:#"%ld", use];
NSData* data_contents = [str dataUsingEncoding:NSUTF8StringEncoding];
NSString *path = [NSString stringWithFormat: # "/tmp/%i.txt", i];
[data_contents writeToFile:path atomically:YES];
x++;

Storing data from a plist file into an array

I have spent all of yesterday trying to figure this out with no luck at all. Here is the code im working with.
NSString *path = [[NSBundle mainBundle] pathForResource:#"file" ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
NSArray *array = [NSArray arrayWithArray:[dict objectForKey:#"root"]];
for(int num = 0; num < 5; num++)
{
NSLog(#"my array:%#", array);
}
NSLog(#"items in my array: %lu", (unsigned long) [array count]);
Here are the views for the plist file im working with.
<plist version="1.0">
<dict>
<key>New item</key>
<string>hello</string>
<key>New item - 2</key>
<string>world</string>
<key>New item - 3</key>
<string>again</string>
<key>New item - 4</key>
<string>and</string>
<key>New item - 5</key>
<string>again</string>
</dict>
</plist>
This code does not return null like when i tried using an NSArray over the NSDictionary, but when i run it console does not print out any data retrieved from the plist. It just prints out:
my array:{}
my array:{}
my array:{}
my array:{}
my array:{}
items in my array: 0
If i try to print out dict by changing the NSLog to NSLog(#"my array:%#", array); i get this.
my array:(NULL)
my array:(NULL)
my array:(NULL)
my array:(NULL)
my array:(NULL)
items in my array: 0
Everything you could print for such plist is
NSLog(dict[#"new item"]);
Also you probably should use
for(int num = 0; num < array.count; num++)
{
NSLog(#"my array:%#", array[i]);
}
instead of
for(int num = 0; num < 5; num++)
{
NSLog(#"my array:%#", array);
}
Don't know what keys are in dictionary? No need to concern about keys in this case. Try this
NSString *path = [[NSBundle mainBundle] pathForResource:#"file" ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
if(dict.count != 0)
{
NSArray *array = [dict allKeys];
for(int num = 0; num < array.count; num++)
{
NSLog(#"my array item:%#", [dict objectForKey:array[num]]);
}
}
else
{
NSLog(#"Your dictionary is empty.");
}
Are you trying to put all the values form the dict into the array ?
If so add:
NSArray *array = [NSArray arrayWithArray:[dict allValues]];
//Check for file;
NSString *path = [[NSBundle mainBundle] pathForResource:#"file" ofType:#"plist"];
if (![[NSFileManager defaultManager] fileExistsAtPath:path])
NSLog(#"NO FILE AT PATH: %#", path);
I found the issue. I had to create a build phase and add the plist files to it. That way when i use the pathToResource ofFile it has a file to find when i use the rest of the code.

How do I initialize all positions in an array of numbers?

I want to store the same number in an array 100 times. These numbers will change later on, but I want to write an if statement using a counter to populate all 100 slots initially with the value of 0. Is there an easy way to do this?
Something like this, where 'block01' needs to change to 'block02', 'block03' etc.:
int block01 = 0;
NSMutableDictionary* myDict = [[NSMutableDictionary alloc] init];
if(myDict)
{
[myDict setObject:block01 forKey:#"block01stored"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath = [paths objectAtIndex:0];
NSString *path = [documentPath stringByAppendingPathComponent:#"blocks.save"];
BOOL successfulWrite = [myDict writeToFile: path atomically: YES];
if(successfulWrite == NO)
}
This should help you. It's a loop that will execute 99 times (1 - 100) adding zero as the object for a key formatted to include the current number.
NSMutableDictionary* myDict = [[NSMutableDictionary alloc] init];
for (int i = 1; i <= 100; i ++) {
if(myDict)
{
[myDict setObject:[NSNumber numberWithInt:0] forKey:[NSString stringWithFormat:#"block%.3istored",i]];
}
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath = [paths objectAtIndex:0];
NSString *path = [documentPath stringByAppendingPathComponent:#"blocks.save"];
BOOL successfulWrite = [myDict writeToFile: path atomically: YES];
if(successfulWrite == NO)
EDIT: To get the value for a certain key you can use the following:
int myInt = [[myDict objectForKey:#"block050stored"] intValue];
And if you want to replace the object for a certain key it's as easy as:
[myDict setObject:[NSNumber numberWithInt:1] forKey:#"block020stored"];
Now, the %.3i tells the string to add a number (i) formatted to always be three digits long. (000, 001, 010, 099, 100)
[NSString stringWithFormat:#"block%.3istored",i]
So the above line basically means, create a string with the words "block" and "stored" with a three digit representation of what ever the current value of the int "i" is in between them.
You can create NSNumber (which is an object, but int is not) and then store it into NSMutableDictionary:
NSNumber* num = [NSNumber numberWithInt:0];
for (int i = 1; i<=100; i++) {
[myDict setObject:num forKey:[NSString stringWithFormat:#"block%dstored",i]];
}

replace an object inside nsmutablearray

I have a NSMutableArray where i want to replace the sign | into a ; how can i do that?
NSMutableArray *paths = [dic valueForKey:#"PATH"];
NSLog(#"pathArr ", paths)
pathArr (
(
"29858,39812;29858,39812;29925,39804;29936,39803;29949,39802;29961,39801;30146,39782;30173,39779;30220,39774;30222,39774|30215,39775;30173,39779;30146,39782;29961,39801;29949,39802;29936,39803;29925,39804;29858,39812;29858,39812;29856,39812;29800,39819;29668,39843;29650,39847;29613,39855;29613,39855;29613,39856;29605,39857;29603,39867;29603,39867;29599,39892;29596,39909;29587,39957;29571,40018;29563,40038;29560,40043"
)
)
Update
This is where i got my path from
NSArray *BusRoute = alightDesc;
int i;
int count = [BusRoute count];
for (i = 0; i < count; i++)
{
NSLog (#"BusRoute = %#", [BusRoute objectAtIndex: i]);
NSDictionary *dic = [BusRoute objectAtIndex: i];
NSMutableArray *paths = [dic valueForKey:#"PATH"];
}
Provide that your object in the array path is string, you can do this
NSMutableArray *path2=[[NSMutableArray alloc]initWithArray:nil];
for (NSObject *obect in path) {
for (NSString *string in (NSArray*)obect) {
[path2 addObject:[string stringByReplacingOccurrencesOfString:#"|" withString:#","]];
}
}
NSLog(#"pathArr %# ", path2);
your array paths contains an another array which has string as object.
Hope this helps
//Copy the Array into a String
NSString *str = [paths componentsJoinedByString: #""];
//then replace the "|"
str = [str stringByReplacingOccurrencesOfString:#"|" withString:#";"];
i did this to replace a string in a .plist so it might work for you
array1 = [NSMutableArray arrayWithContentsOfFile:Path1];
NSString *item = [#"dfdfDF"];
[array1 replaceObjectAtIndex:1 withObject:item];
[array1 writeToFile:Path1 atomically:YES];
NSLog(#"count: %#", [array1 objectAtIndex:1]);
you may cast or convert paths to NSString and then do:
paths = (NSString *) [paths stringByReplacingOccurrencesOfString:#"|" withString:#";"];
if this does't work, create new NSString instance that containing pathArr text, invoke replaceOccurrences method and do invert conversion
NSMutableString *tempStr = [[NSMutableString alloc] init];
for (int i = 0; i < [paths count]; i++)
{
[tempStr appendString:[path objectAtIndex:i]];
}
then use this method for tempStr. And then try:
NSArray *newPaths = [tempStr componentsSeparatedByString:#";"];
may be last method not completely correct, so try experiment with it.
Uh, why don't you just go:
NSString *cleanedString = [[[dic valueForKey:#"PATH"] objectAtIndex:0] stringByReplacingOccurrencesOfString:#";" withString:#"|"];
If there are more than one nested array, you can go
for(int i = 0; i < [[dic valueForKey:#"PATH"] count]; i++)
{
NSString *cleanedString = [[[dic valueForKey:#"PATH"] objectAtIndex:i] stringByReplacingOccurrencesOfString:#";" withString:#"|"];
// do something with cleanedString
}

Determine folder Size

With this code I determine the file size if the checkbox is NSOnState, but with a folder value is always 0. The directory is correct.
Can you help me?
unsigned long long resultsize=0;
if(imagehistoryS.state == NSOnState) {
NSString *path = [NSString stringWithFormat:#"Users/Giovanni/Desktop/test", [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0]];
NSNumber *fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil] objectForKey:NSFileSize];
resultsize += [fileSize doubleValue];
}
[result setStringValue:[NSString stringWithFormat:#"Total size items selected: %f", resultsize]];
You're passing in a string, and yet specifying the NSUserDomainMask. I've tried this and it works.
NSUInteger resultSize = 0;
NSFileManager *fm = [[NSFileManager alloc] init];
NSURL *LibraryURL = [[fm URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject];
NSURL *previewsURL = [LibraryURL URLByAppendingPathComponent:#"/Caches/com.apple.Safari/Webpage Previews"];
resultSize = [[[fm attributesOfItemAtPath:[previewsURL path] error:nil] objectForKey:NSFileSize] unsignedIntegerValue];
NSLog(#"Size: %lu", resultSize);
This is for an ARC environment.
Note, I'm using NSURLs instead of NSString filepaths as much as possible. Also, you don't need to hardcode the user's name in the search path.
Updated to show the specific folder as requested in the comments
In you stringWithFormat you are missing the format specifier %#.