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

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

Related

Objective-C Split a String and get last item

I have a string like so:
NSString *path = #"\\fake\aaa\bbb\ccc\ddd\eee.pdf";
and I split the string into an array like so:
NSArray *array = [path componentsSeparatedByString:#"\"];
Now there are two things I need here.
I need a string with everything except eee.pdf
I need the last item in the array as a string (eee.pdf)
How would I do this?
Just for fun, there is a little-known way to get an NSURL with its benefit from a windows file path
NSString *path = #"\\\\fake\\aaa\\bbb\\ccc\\ddd\\eee.pdf";
NSURL *url = CFBridgingRelease(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)path, kCFURLWindowsPathStyle, false));
NSString *fileName = url.lastPathComponent;
NSString *parentDirectory = url.URLByDeletingLastPathComponent.path;
Finally you have to convert parentDirectory back to windows path style (backslashes).
But if you mean POSIX paths used in OS X, it's much easier
NSString *path = #"/fake/aaa/bbb/ccc/ddd/eee.pdf";
NSURL *url = [NSURL fileURLWithPath:path];
NSString *fileName = url.lastPathComponent;
NSString *parentDirectory = url.URLByDeletingLastPathComponent.path;
I think you're trying to get the filepath and filename from a full path. There are better ways of doing that. But since you simply asked for the question, here's my answer. Please note that this is not the best approach. In addition, you have to escape the backslashes by using a preceding backslash.
NSString *path = #"\\fake\\aaa\\bbb\\ccc\\ddd\\eee.pdf";
NSArray *array = [path componentsSeparatedByString:#"\\"];
NSMutableArray *removedArray = [[NSMutableArray alloc] init];
for(int i=0; i< array.count -1; i++){
[removedArray addObject:[array objectAtIndex:i]];
}
NSString *joinedString =[removedArray componentsJoinedByString:#"\\"];
NSString *fileName = [array lastObject];
NSLog(#"Path: %#", joinedString);
NSLog(#"Filename: %#", fileName);
For the last element use the lastObject property of the NSArray.
For a string without the last element use subarrayWithRange: using array.count-1 for the NSRange length.
Then join the remaining array with componentsJoinedByString:.
NSString *fileName = [array lastObject];
NSArray *newArray = [array subarrayWithRange:NSMakeRange(0, array.count-1)];
NSString *directoryPath = [newArray componentsJoinedByString:#"\\"];

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

How to parse a string format like [***]***?

I need to parse a string like [abc]000, and what I want to get is an array containing abc and 000. Is there an easy way to do it?
I'm using code like this:
NSString *sampleString = #"[abc]000";
NSArray *sampleParts = [sampleString componentsSeparatedByString:#"]"];
NSString *firstPart = [[[sampleParts objectAtIndex:0] componentsSeparatedByString:#"["] lastObject];
NSString *lastPart = [sampleParts lastObject];
But it's inefficient and didn't check whether the string is in a format like [**]**.
For this simple pattern, can just parse yourself like:
NSString *s = #"[abc]000";
NSString *firstPart = nil;
NSString *lastPart = nil;
if ([s characterAtIndex: 0] == '[') {
NSUInteger i = [s rangeOfString:#"]"].location;
if (i != NSNotFound) {
firstPart = [s substringWithRange:NSMakeRange(1, i - 1)];
lastPart = [s substringFromIndex:i + 1];
}
}
Or you could learn to use the NSScanner class.
As always, there are lots of ways to do this.
OPTION 1
If these are fixed length strings (each part is always three characters) then you can simply get the substrings directly:
NSString *sampleString = #"[abc]000";
NSString *left = [sampleString substringWithRange:NSMakeRange(1, 3)];
NSString *right = [sampleString substringWithRange:NSMakeRange(5, 3)];
NSArray *parts = #[ left, right ];
NSLog(#"%#", parts);
OPTION 1 (shortened)
NSArray *parts = #[ [sampleString substringWithRange:NSMakeRange(1, 3)],
[sampleString substringWithRange:NSMakeRange(5, 3)] ];
NSLog(#"%#", parts);
OPTION 2
If they aren't always three characters, then you can use NSScanner:
NSString *sampleString = #"[abc]000";
NSScanner *scanner = [NSScanner scannerWithString:sampleString];
// Skip the first character if we know that it will always start with the '['.
// If we can not make this assumption, then we would scan for the bracket instead.
scanner.scanLocation = 1;
NSString *left, *right;
// Save the characters until the right bracket into a string which we store in left.
[scanner scanUpToString:#"]" intoString:&left];
// Skip the right bracket
scanner.scanLocation++;
// Scan to the end (You can use any string for the scanUpToString that doesn't actually exist...
[scanner scanUpToString:#"\0" intoString:&right];
NSArray *parts = #[ left, right ];
NSLog(#"%#", parts);
RESULTS (for all options)
2013-05-10 00:25:02.031 Testing App[41906:11f03] (
abc,
000
)
NOTE
All of these assume well-formed strings, so you should include your own error checking.
try like this ,
NSString *sampleString = #"[abc]000";
NSString *pNRegex = #"\\[[a-z]{3}\\][0-9]{3}";
NSPredicate *PNTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", pNRegex];
BOOL check=[PNTest evaluateWithObject:sampleString ];
NSLog(#"success:%i",check);
if success comes as 1 then you can perform the action for separating string into array.

how to read a txt file and store in NSArray?

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

Parsed TouchXML XML file crashes when reading NSString

I'm able to successfully parse the contents of a XML file using TouchXML, but when I try to read an individual NSString, from the NSMutableArray that stores the parsed content, the iPhone app crashes.
My NSLog shows me that the file has been parse as it should, giving this output:
(
{
href = "mms://a19349.l412964549958.c41245496.f.lm.akamaistream.net/D/194359/4125596/v0001/reflector:49944";
},
{
href = "mms://a4322.l4129624350471.c414645296.a.lm.akamaistream.net/D/473432/4129566/v0001/reflector:546441";
} )
Here is the code I'm using to do the parsing:
NSMutableArray *res = [[NSMutableArray alloc] init];
.... Parsing happens here ....
Then I try to retrieve the string from the NSMutableArray, using this code (and the app crashes when trying to read this line of code, posted below NSMutableString *string1 = [NSMutableString stringWithString:url];
NSString *url = [[NSString alloc] init];
url = [res objectAtIndex:0];
NSMutableString *string1 = [NSMutableString stringWithString:url];
[string1 deleteCharactersInRange: [string1 rangeOfString: #"href = "]];
[string1 deleteCharactersInRange: [string1 rangeOfString: #";"]];
NSLog(#"Clean URL: %#", string1);
Please, how can I solve this problem? Thank you!
TouchXML returns you an array of NSDictionaries. In order to extract string you need to take value from this NSDictionary:
NSString *url = [[res objectAtIndex:0] objectForKey:#"href"];