how to read a txt file and store in NSArray? - objective-c

i am trying to read a txt file and store it in a NSArray. here is my code, but it seems there is something missing that i don't know!
NSURL *url=[NSURL URLWithString:#"http://www.google.com/robots.txt"];
NSMutableArray *robots=[NSMutableArray arrayWithContentsOfURL:url];
NSLog(#"%#",robots);

You have to load the contents of URL into string first like
NSString *content = [NSString stringWithContentsOfURL:URL encoding:NSUTF8StringEncoding error:nil];
Then split this string like this:
NSArray *parsed = [content componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
Now parsed array will contain strings from the URL.
Edit:
If you want to filter your array, add this code:
NSIndexSet *indexes = [parsed indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
NSRange range = [(NSString *)obj rangeOfString:#"Disallow"];
if (range.location != NSNotFound)
{
return YES;
}
return NO;
}];
NSArray *disallowed = [parsed objectsAtIndexes:indexes];
disallowed will be populated with the strings that contains Disallow string

Related

How to convert NSData which contains a line break to a NSString

The following code works perfectly to convert the NSData that I got from a URL/JSON file to a NSString, EXCEPTION MADE by the cases that data contains line breaks!
What's wrong with my code?
My Code:
NSError *errorColetar = nil;
NSURL *aColetarUrl = [[NSURL alloc]initWithString:#"http://marcosdegni.com.br/petsistema/teste/aColetar3.php"];
NSString *aColetarString = [NSString stringWithContentsOfURL:aColetarUrl encoding:NSUTF8StringEncoding error:&errorColetar];
NSLog(#"NSString: %#", aColetarString);
if (!errorColetar) {
NSData *aColetarData = [aColetarString dataUsingEncoding:NSUTF8StringEncoding];
self.arrayAColetar = [NSJSONSerialization JSONObjectWithData:aColetarData options:kNilOptions error:nil];
}
NSLog(#"arrayAColetar %#", self.arrayAColetar);
Log Results:
**NSString**: [{"id_atendimento":"2","observacoes":"ABC-Enter-->
DEF-Enter-->
GFH-END"},{"id_atendimento":"1","observacoes":"123Enter-->
345Enter-->
678End"}]
**arrayAColetar** (null)
As you can see my bottom line is an empty array :(
Thanks in advance!
By checking the error message hidden under 'error:nil' I found a "Unescaped control character around character" issue and implemented the code below from Unescaped control characters in NSJSONSerialization
and got a new 'cleaned' string.
- (NSString *)stringByRemovingControlCharacters: (NSString *)inputString {
NSCharacterSet *controlChars = [NSCharacterSet controlCharacterSet];
NSRange range = [inputString rangeOfCharacterFromSet:controlChars];
if (range.location != NSNotFound) {
NSMutableString *mutable = [NSMutableString stringWithString:inputString];
while (range.location != NSNotFound) {
[mutable deleteCharactersInRange:range];
range = [mutable rangeOfCharacterFromSet:controlChars];
}
return mutable;
}
return inputString;
}

Why does -[NSString compare:options:] return true when the strings are not equal?

I am checking if a string appears twice in a row within an array. This code doesn't seem to work, as it just prints out the entire array. What am I missing?
NSString *nameString =
[NSString stringWithContentsOfFile:#"/usr/share/dict/words"
encoding:NSUTF8StringEncoding
error:NULL];
NSArray *names = [nameString componentsSeparatedByString:#"\n"];
//Save last item
NSMutableString *lastOne = [NSMutableString stringWithCapacity:20];
// Go through the array one string at a time
for (NSString *n in names) {
if ([n compare:lastOne options:NSCaseInsensitiveSearch]) {
NSLog(#"%#", n);
}
[lastOne setString:n];
}
compare: and related functions don't return booleans, they return an NSComparisonResult. If you want to see if a string is equal you should instead use
if ([n compare:lastOne options:NSCaseInsensitiveSearch] == NSOrderedSame)

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

Objective-C - Works with strings, find a substring with NSRange

I'm working with the strings and i have a little problem that i'm not understanding. In fact, i have a string like this: "ALAsset - Type:Photo, URLs:assets-library://asset/asset.JPG?id=168BA548-9C81-4B08-B69C-B775E5DD9341&ext=JPG" and i need to find the string between "URLs:" and "?id=" . For doing this, i'm trying to create a new string using the NSRange. In this mode i give the first index and the last index that i need, but it seems not working.
Here there is my code:
NSString *description = [asset description];
NSRange first = [description rangeOfString:#"URLs:"];
NSRange second = [description rangeOfString:#"?id="];
NSString *path = [description substringWithRange: NSMakeRange(first.location, second.location)];
It return to me this kind of string: "URLs:assets-library://asset/asset.JPG?id=168BA548-9C81-4B08-B69C-B775E5DD9341&ext=JPG". Is it correct? I'm expecting to obtain "assets-library://asset/asset.JPG" string.
Where i'm doing wrong? Is there a better way to do this?
I have followed this url for help: http://www.techotopia.com/index.php/Working_with_String_Objects_in_Objective-C
Thanks
Try this range:
NSMakeRange(first.location + first.length, second.location - (first.location + first.length))
Don't parse the ALAsset description string! If the description ever changes your code breaks. Use the methods ALAsset and NSURL provide you. First, get the dictionary of URLs (mapped by asset type) through the valueForProperty: method. Then, for each URL, get the absoluteString and remove the query string from it. I got the string you were looking for by placing the following code in the application:didFinishLaunchingWithOptions: method from the single-view iPhone app template.
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupAlbum usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
[group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop) {
NSDictionary *URLDictionary = [asset valueForProperty:ALAssetPropertyURLs];
for (NSURL *URL in [URLDictionary allValues]) {
NSString *URLString = [URL absoluteString];
NSString *query = [URL query];
if ([query length] > 0) {
NSString *toRemove = [NSString stringWithFormat:#"?%#",query];
URLString = [URLString stringByReplacingOccurrencesOfString:toRemove withString:#""];
NSLog(#"URLString = %#", URLString);
}
}
}];
} failureBlock:^(NSError *error) {
}];
NSRange first = [description rangeOfString:#"URLs:"];
gives you the position of the U, so you need to take first.location+5 to get the start position of assets-library.
NSRangeMake(loc,len) takes a starting location loc and a length, so you need to use second.location-first.location-5 to get the length you are looking for.
Adding it all up, replace the last line with:
NSRange r = NSMakeRange(first.location+5, second.location-first.location-5);
NSString *path = [description substringWithRange:r];

Spliting string to array by constant number

I'v been trying to split string to array of components by number, but have no idea how to do it. I know that each components lenght is 9 except the last one. But there is no separation between them. Maybe anyone would know how could i make this split possible?
string : E44000000R33000444V33441
And i'd like to get array with: E44000000 R33000444 V33441
in past I'v used this method, but i guess there should be a way to separate by constant number. Any ideas
NSArray *myWords = [message componentsSeparatedByString:#";"];
Please try the below code.
NSString *stringTest = #"E44000000R33000444V33441323";
NSMutableArray *arrayTest = [NSMutableArray array];
while([stringTest length] > 8) {
[arrayTest addObject:[NSString stringWithString:[stringTest substringToIndex:9]]];
stringTest = [stringTest substringFromIndex:9];
}
NSLog(#"arrayTest - %#", arrayTest);
Try this one..
NSString *mainString=#"E44000000R33000444V";
NSMutableArray *brokenString=[NSMutableArray new];
int start=0;
for (; start<mainString.length-9; start+=9) {
[brokenString addObject:[mainString substringWithRange:NSMakeRange(start, 9)]];
}
[brokenString addObject:[mainString substringFromIndex:start]];
NSLog(#"->%#",brokenString);
Output is :
->(
E44000000,
R33000444,
V
)
I investigated the NSString, and i didn't found any function like that. But you can create a category of NSString and put this function in that category and you can use as a NSString instance method.
- (NSArray *) componentSaparetedByLength:(NSUInteger) length{
NSMutableArray *array = [NSMutableArray new];
NSRange range = NSMakeRange(0, length);
NSString *subString = nil;
while (range.location + range.length <= self.length) {
subString = [self substringWithRange:range];
[array addObject:subString];
//Edit
range.location = range.length + range.location;
//Edit
range.length = length;
}
if(range.location<self.length){
subString = [self substringFromIndex:range.location];
[array addObject:subString];
}
return array;
}
You can get the substring upto the characters which you want in a loop(string length) & pass the next index for getting the next substring. After getting each substring you can add it to the array.
Used SubstringToIndex & SubstringFromIndex functions to get the substring.
Also not an requirement here, I want to propose a solution that is capable of handling characters from more sophisticated script systems, like surrogate pairs, base characters plus combining marks, Hangul jamo, and Indic consonant clusters.
#interface NSString (Split)
-(NSArray *)arrayBySplittingWithMaximumSize:(NSUInteger)size
options:(NSStringEnumerationOptions) option;
#end
#implementation NSString (Split)
-(NSArray *)arrayBySplittingWithMaximumSize:(NSUInteger)size
options:(NSStringEnumerationOptions) option
{
NSMutableArray *letterArray = [NSMutableArray array];
[self enumerateSubstringsInRange:NSMakeRange(0, [self length])
options:(option)
usingBlock:^(NSString *substring,
NSRange substringRange,
NSRange enclosingRange,
BOOL *stop) {
[letterArray addObject:substring];
}];
NSMutableArray *array = [NSMutableArray array];
[letterArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (idx%size == 0) {
[array addObject: [NSMutableString stringWithCapacity:size]];
}
NSMutableString *string = [array objectAtIndex:[array count]-1];
[string appendString:obj];
}];
return array;
}
#end
usage
NSArray *array = [#"E44000000R33000444V33441" arraysBySplittingWithMaximumSize:9
options:NSStringEnumerationByComposedCharacterSequences];
results in:
(
E44000000,
R33000444,
V33441
)