write html content to NSString and display on iphone - iphone-sdk-3.0

i have a webveiw where i can show small html value but i have a issue
if is do this
NSString *HTMLData =#"<h3><span style=font-family:Helvetica-Bold > <strong> Information</strong> </span></h3>";
HTMLData= [HTMLData stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
[web loadHTMLString:HTMLData baseURL:nil];
then its wokring fine
but if my NSString has a break line lets say
NSString *HTMLData =#"<h3><span style=font-family:Helvetica-Bold >
<strong> Information</strong>
</span></h3>";
then i am getting error how to avoid this error???
my error is missing terminator charcter

To break long NSStrings across multiple lines, you need to put double quotes at the end and beginning of each line:
NSString *HTMLData =#"<h3><span style=font-family:Helvetica-Bold >"
"<strong> Information</strong>"
"</span></h3>";
Edit:
An example with NSMutableString:
NSMutableString *HTMLData = [[NSMutableString alloc] initWithCapacity:100];
[HTMLData appendString:#"<h3><span style=font-family:Helvetica-Bold >"];
[HTMLData appendString:#"<strong> Information</strong>"];
[HTMLData appendString:#"</span></h3>"];
//more appends...
//do something with HTMLData here
[HTMLData release];
The initWithCapacity just tells how many characters to allocate space for initially (it's not a limit).
NSMutableString also has the appendFormat: method which works like stringWithFormat:.

One solution for this could be simply write your HTML as an String.
and show the string as an Attributed String for Label.
let htmlText = "<p>etc</p>"
if let htmlData = htmlText.dataUsingEncoding(NSUnicodeStringEncoding) {
do {
someLabel.attributedText = try NSAttributedString(data: htmlData,
options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
documentAttributes: nil)
} catch let e as NSError {
print("Couldn't translate \(htmlText): \(e.localizedDescription) ")
}
}
reference : How to show an HTML string on a UILabel

Related

Replacing bad words in a string in Objective-C

I have a game with a public highscore list where I allow layers to enter their name (or anything unto 12 characters). I am trying to create a couple of functions to filter out bad words from a list of bad words
I have in a text file. I have two methods:
One to read in the text file:
-(void) getTheBadWordsAndSaveForLater {
badWordsFilePath = [[NSBundle mainBundle] pathForResource:#"badwords" ofType:#"txt"];
badWordFile = [[NSString alloc] initWithContentsOfFile:badWordsFilePath encoding:NSUTF8StringEncoding error:nil];
badwords =[[NSArray alloc] initWithContentsOfFile:badWordFile];
badwords = [badWordFile componentsSeparatedByString:#"\n"];
NSLog(#"Number Of Words Found in file: %i",[badwords count]);
for (NSString* words in badwords) {
NSLog(#"Word in Array----- %#",words);
}
}
And one to check a word (NSString*) agains the list that I read in:
-(NSString *) removeBadWords :(NSString *) string {
// If I hard code this line below, it works....
// *****************************************************************************
//badwords =[[NSMutableArray alloc] initWithObjects:#"shet",#"shat",#"shut",nil];
// *****************************************************************************
NSLog(#"checking: %#",string);
for (NSString* words in badwords) {
string = [string stringByReplacingOccurrencesOfString:words withString:#"-" options:NSCaseInsensitiveSearch range:NSMakeRange(0, string.length)];
NSLog(#"Word in Array: %#",words);
}
NSLog(#"Cleaned Word Returned: %#",string);
return string;
}
The issue I'm having is that when I hardcode the words into an array (see commented out above) then it works like a charm. But when I use the array I read in with the first method, it does't work - the stringByReplacingOccurrencesOfString:words does not seem to have an effect. I have traced out to the log so I can see if the words are coming thru and they are... That one line just doesn't seem to see the words unless I hardcore into the array.
Any suggestions?
A couple of thoughts:
You have two lines:
badwords =[[NSArray alloc] initWithContentsOfFile:badWordFile];
badwords = [badWordFile componentsSeparatedByString:#"\n"];
There's no point in doing that initWithContentsOfFile if you're just going to replace it with the componentsSeparatedByString on the next line. Plus, initWithContentsOfFile assumes the file is a property list (plist), but the rest of your code clearly assumes it's a newline separated text file. Personally, I would have used the plist format (it obviates the need to trim the whitespace from the individual words), but you can use whichever you prefer. But use one or the other, but not both.
If you're staying with the newline separated list of bad words, then just get rid of that line that says initWithContentsOfFile, you disregard the results of that, anyway. Thus:
- (void)getTheBadWordsAndSaveForLater {
// these should be local variables, so get rid of your instance variables of the same name
NSString *badWordsFilePath = [[NSBundle mainBundle] pathForResource:#"badwords" ofType:#"txt"];
NSString *badWordFile = [[NSString alloc] initWithContentsOfFile:badWordsFilePath encoding:NSUTF8StringEncoding error:nil];
// calculate `badwords` solely from `componentsSeparatedByString`, not `initWithContentsOfFile`
badwords = [badWordFile componentsSeparatedByString:#"\n"];
// confirm what we got
NSLog(#"Found %i words: %#", [badwords count], badwords);
}
You might want to look for whole word occurrences only, rather than just the presence of the bad word anywhere:
- (NSString *) removeBadWords:(NSString *) string {
NSLog(#"checking: %# for occurrences of these bad words: %#", string, badwords);
for (NSString* badword in badwords) {
NSString *searchString = [NSString stringWithFormat:#"\\b%#\\b", badword];
string = [string stringByReplacingOccurrencesOfString:searchString
withString:#"-"
options:NSCaseInsensitiveSearch | NSRegularExpressionSearch
range:NSMakeRange(0, string.length)];
}
NSLog(#"resulted in: %#", string);
return string;
}
This uses a "regular expression" search, where \b stands for "a boundary between words". Thus, \bhell\b (or, because backslashes have to be quoted in a NSString literal, that's #"\\bhell\\b") will search for the word "hell" that is a separate word, but won't match "hello", for example.
Note, above, I am also logging badwords to see if that variable was reset somehow. That's the only thing that would make sense given the symptoms you describe, namely that the loading of the bad words from the text file works but replace process fails. So examine badwords before you replace and make sure it's still set properly.

Creating substrings from text file

I have a text file that contains two lines of numbers, all I want to do is turn each line into a string, then add it into an array (called fields). My problem arrises when trying to find the EOF character. I can read from the file with no problem: I turn it's content into a NSString, then pass to this method.
-(void)parseString:(NSString *)inputString{
NSLog(#"[parseString] *inputString: %#", inputString);
//the end of the previous line, this is also the start of the next lien
int endOfPreviousLine = 0;
//count of how many characters we've gone through
int charCount = 0;
//while we havent gone through every character
while(charCount <= [inputString length]){
NSLog(#"[parseString] while loop count %i", charCount);
//if its an end of line character or end of file
if([inputString characterAtIndex:charCount] == '\n' || [inputString characterAtIndex:charCount] == '\0'){
//add a substring into the array
[fields addObject:[inputString substringWithRange:NSMakeRange(endOfPreviousLine, charCount)]];
NSLog(#"[parseString] string added into array: %#", [inputString substringWithRange:NSMakeRange(endOfPreviousLine, charCount)]);
//set the endOfPreviousLine to the current char count, this is where the next string will start from
endOfPreviousLine = charCount+1;
}
charCount++;
}
NSLog(#"[parseString] exited while. endOfPrevious: %i, charCount: %i", endOfPreviousLine, charCount);
}
The contents of my text file look like this:
123
456
I can get the first string (123) no problem. The call would be:
[fields addObject:[inputString substringWithRange:NSMakeRange(0, 3)]];
Next, I make the call for the second String:
[fields addObject:[inputString substringWithRange:NSMakeRange(4, 7)]];
But I get an error, and I think it is because my index is out of bounds. Since the index starts from 0, there is no index 7 (well I think its supposed to be the EOF character), and I get an error.
To sum everything up: I don't know how to deal with an index of 7 when there are only 6 characters + the EOF character.
Thanks.
You can use componentsSeparatedByCharactersInSet: to get the effect that you are looking for:
-(NSArray*)parseString:(NSString *)inputString {
return [inputString componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
}
Short answer is to use [inputString componentsSeparatedByString:#"\n"] and get the array of numbers.
Example:
Use the following code to get the lines in an array
NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:#"aaa" ofType:#"txt"];
NSString *str = [[NSString alloc] initWithContentsOfFile: path];
NSArray *lines = [str componentsSeparatedByString:#"\n"];
NSLog(#"str = %#", str);
NSLog(#"lines = %#", lines);
The above code assumes that you have a file called "aaa.txt" in your resources which is plain text file.

Weird IF THAN not working with Requested data from URL text problem

Hey all, i am checking for an internet connection by checking for a file on my server. The file only has the word LIVE displayed on the page. No HTML or anything else is there, just the word LIVE.
When i run this code, i do get the NSLog as saying "LIVE" but once i go to check it with the IF statement, it fails and i just do not know why???
NSString* myFile = [NSString stringWithFormat:#"http://www.xxx.com/iPodTouchPing.html"];
NSString* myFileURLString = [myFile stringByReplacingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSData *myFileData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:myFileURLString]];
NSString *returnedMyFileContents=[[[NSString alloc] initWithData:myFileData encoding:NSASCIIStringEncoding] autorelease];
NSLog(#"%#", returnedMyFileContents);
if (returnedMyFileContents == #"LIVE") {
NSLog(#"LIVE!");
}else{
NSLog(#"Not Live");
}
What am i doing wrong? I can not seem to find the reason??
David
You can't compare strings like that in Objective C - you're just comparing their addresses, not their contents. Change your code to this:
if ([returnedMyFileContents isEqualToString:#"LIVE"]) {
NSLog(#"LIVE!");
} else {
NSLog(#"Not Live");
}

How to check if NSString begins with a certain character

How do you check if an NSString begins with a certain character (the character *).
The * is an indicator for the type of the cell, so I need the contents of this NSString without the *, but need to know if the * exists.
You can use the -hasPrefix: method of NSString:
Objective-C:
NSString* output = nil;
if([string hasPrefix:#"*"]) {
output = [string substringFromIndex:1];
}
Swift:
var output:String?
if string.hasPrefix("*") {
output = string.substringFromIndex(string.startIndex.advancedBy(1))
}
You can use:
NSString *newString;
if ( [[myString characterAtIndex:0] isEqualToString:#"*"] ) {
newString = [myString substringFromIndex:1];
}
hasPrefix works especially well.
for example if you were looking for a http url in a NSString, you would use componentsSeparatedByString to create an NSArray and the iterate the array using hasPrefix to find the elements that begin with http.
NSArray *allStringsArray =
[myStringThatHasHttpUrls componentsSeparatedByString:#" "]
for (id myArrayElement in allStringsArray) {
NSString *theString = [myArrayElement description];
if ([theString hasPrefix:#"http"]) {
NSLog(#"The URL is %#", [myArrayElement description]);
}
}
hasPrefix returns a Boolean value that indicates whether a given string matches the beginning characters of the receiver.
- (BOOL)hasPrefix:(NSString *)aString,
parameter aString is a string that you are looking for
Return Value is YES if aString matches the beginning characters of the receiver, otherwise NO. Returns NO if aString is empty.
As a more general answer, try using the hasPrefix method. For example, the code below checks to see if a string begins with 10, which is the error code used to identify a certain problem.
NSString* myString = #"10:Username taken";
if([myString hasPrefix:#"10"]) {
//display more elegant error message
}
Use characterAtIndex:. If the first character is an asterisk, use substringFromIndex: to get the string sans '*'.
NSString *stringWithoutAsterisk(NSString *string) {
NSRange asterisk = [string rangeOfString:#"*"];
return asterisk.location == 0 ? [string substringFromIndex:1] : string;
}
Another approach to do it..
May it help someone...
if ([[temp substringToIndex:4] isEqualToString:#"http"]) {
//starts with http
}
This might help? :)
http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/occ/instm/NSString/characterAtIndex:
Just search for the character at index 0 and compare it against the value you're looking for!
This nice little bit of code I found by chance, and I have yet to see it suggested on Stack. It only works if the characters you want to remove or alter exist, which is convenient in many scenarios. If the character/s does not exist, it won't alter your NSString:
NSString = [yourString stringByReplacingOccurrencesOfString:#"YOUR CHARACTERS YOU WANT TO REMOVE" withString:#"CAN either be EMPTY or WITH TEXT REPLACEMENT"];
This is how I use it:
//declare what to look for
NSString * suffixTorRemove = #"</p>";
NSString * prefixToRemove = #"<p>";
NSString * randomCharacter = #"</strong>";
NSString * moreRandom = #"<strong>";
NSString * makeAndSign = #"&amp;";
//I AM INSERTING A VALUE FROM A DATABASE AND HAVE ASSIGNED IT TO returnStr
returnStr = [returnStr stringByReplacingOccurrencesOfString:suffixTorRemove withString:#""];
returnStr = [returnStr stringByReplacingOccurrencesOfString:prefixToRemove withString:#""];
returnStr = [returnStr stringByReplacingOccurrencesOfString:randomCharacter withString:#""];
returnStr = [returnStr stringByReplacingOccurrencesOfString:moreRandom withString:#""];
returnStr = [returnStr stringByReplacingOccurrencesOfString:makeAndSign withString:#"&"];
//check the output
NSLog(#"returnStr IS NOW: %#", returnStr);
This one line is super easy to perform three actions in one:
Checks your string for the character/s you do not want
Can replaces them with whatever you like
Does not affect surrounding code
NSString* expectedString = nil;
if([givenString hasPrefix:#"*"])
{
expectedString = [givenString substringFromIndex:1];
}

NSString tokenize in Objective-C

What is the best way to tokenize/split a NSString in Objective-C?
Found answer here:
NSString *string = #"oop:ack:bork:greeble:ponies";
NSArray *chunks = [string componentsSeparatedByString: #":"];
Everyone has mentioned componentsSeparatedByString: but you can also use CFStringTokenizer (remember that an NSString and CFString are interchangeable) which will tokenize natural languages too (like Chinese/Japanese which don't split words on spaces).
If you just want to split a string, use -[NSString componentsSeparatedByString:]. For more complex tokenization, use the NSScanner class.
If your tokenization needs are more complex, check out my open source Cocoa String tokenizing/parsing toolkit: ParseKit:
http://parsekit.com
For simple splitting of strings using a delimiter char (like ':'), ParseKit would definitely be overkill. But again, for complex tokenization needs, ParseKit is extremely powerful/flexible.
Also see the ParseKit Tokenization documentation.
If you want to tokenize on multiple characters, you can use NSString's componentsSeparatedByCharactersInSet. NSCharacterSet has some handy pre-made sets like the whitespaceCharacterSet and the illegalCharacterSet. And it has initializers for Unicode ranges.
You can also combine character sets and use them to tokenize, like this:
// Tokenize sSourceEntityName on both whitespace and punctuation.
NSMutableCharacterSet *mcharsetWhitePunc = [[NSCharacterSet whitespaceAndNewlineCharacterSet] mutableCopy];
[mcharsetWhitePunc formUnionWithCharacterSet:[NSCharacterSet punctuationCharacterSet]];
NSArray *sarrTokenizedName = [self.sSourceEntityName componentsSeparatedByCharactersInSet:mcharsetWhitePunc];
[mcharsetWhitePunc release];
Be aware that componentsSeparatedByCharactersInSet will produce blank strings if it encounters more than one member of the charSet in a row, so you might want to test for lengths less than 1.
If you're looking to tokenise a string into search terms while preserving "quoted phrases", here's an NSString category that respects various types of quote pairs: "" '' ‘’ “”
Usage:
NSArray *terms = [#"This is my \"search phrase\" I want to split" searchTerms];
// results in: ["This", "is", "my", "search phrase", "I", "want", "to", "split"]
Code:
#interface NSString (Search)
- (NSArray *)searchTerms;
#end
#implementation NSString (Search)
- (NSArray *)searchTerms {
// Strip whitespace and setup scanner
NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
NSString *searchString = [self stringByTrimmingCharactersInSet:whitespace];
NSScanner *scanner = [NSScanner scannerWithString:searchString];
[scanner setCharactersToBeSkipped:nil]; // we'll handle whitespace ourselves
// A few types of quote pairs to check
NSDictionary *quotePairs = #{#"\"": #"\"",
#"'": #"'",
#"\u2018": #"\u2019",
#"\u201C": #"\u201D"};
// Scan
NSMutableArray *results = [[NSMutableArray alloc] init];
NSString *substring = nil;
while (scanner.scanLocation < searchString.length) {
// Check for quote at beginning of string
unichar unicharacter = [self characterAtIndex:scanner.scanLocation];
NSString *startQuote = [NSString stringWithFormat:#"%C", unicharacter];
NSString *endQuote = [quotePairs objectForKey:startQuote];
if (endQuote != nil) { // if it's a valid start quote we'll have an end quote
// Scan quoted phrase into substring (skipping start & end quotes)
[scanner scanString:startQuote intoString:nil];
[scanner scanUpToString:endQuote intoString:&substring];
[scanner scanString:endQuote intoString:nil];
} else {
// Single word that is non-quoted
[scanner scanUpToCharactersFromSet:whitespace intoString:&substring];
}
// Process and add the substring to results
if (substring) {
substring = [substring stringByTrimmingCharactersInSet:whitespace];
if (substring.length) [results addObject:substring];
}
// Skip to next word
[scanner scanCharactersFromSet:whitespace intoString:nil];
}
// Return non-mutable array
return results.copy;
}
#end
If you are looking for splitting linguistic feature's of a string (Words, paragraphs, characters, sentences and lines), use string enumeration:
NSString * string = #" \n word1! word2,%$?'/word3.word4 ";
[string enumerateSubstringsInRange:NSMakeRange(0, string.length)
options:NSStringEnumerationByWords
usingBlock:
^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
NSLog(#"Substring: '%#'", substring);
}];
// Logs:
// Substring: 'word1'
// Substring: 'word2'
// Substring: 'word3'
// Substring: 'word4'
This api works with other languages where spaces are not always the delimiter (e.g. Japanese). Also using NSStringEnumerationByComposedCharacterSequences is the proper way to enumerate over characters, since many non-western characters are more than one byte long.
I had a case where I had to split the console output after an LDAP query with ldapsearch. First set up and execute the NSTask (I found a good code sample here: Execute a terminal command from a Cocoa app). But then I had to split and parse the output so as to extract only the print-server names out of the Ldap-query-output. Unfortunately it is rather tedious string-manipulation which would be no problem at all if we were to manipulate C-strings/arrays with simple C-array operations. So here is my code using cocoa objects. If you have better suggestions, let me know.
//as the ldap query has to be done when the user selects one of our Active Directory Domains
//(an according comboBox should be populated with print-server names we discover from AD)
//my code is placed in the onSelectDomain event code
//the following variables are declared in the interface .h file as globals
#protected NSArray* aDomains;//domain combo list array
#protected NSMutableArray* aPrinters;//printer combo list array
#protected NSMutableArray* aPrintServers;//print server combo list array
#protected NSString* sLdapQueryCommand;//for LDAP Queries
#protected NSArray* aLdapQueryArgs;
#protected NSTask* tskLdapTask;
#protected NSPipe* pipeLdapTask;
#protected NSFileHandle* fhLdapTask;
#protected NSMutableData* mdLdapTask;
IBOutlet NSComboBox* comboDomain;
IBOutlet NSComboBox* comboPrinter;
IBOutlet NSComboBox* comboPrintServer;
//end of interface globals
//after collecting the print-server names they are displayed in an according drop-down comboBox
//as soon as the user selects one of the print-servers, we should start a new query to find all the
//print-queues on that server and display them in the comboPrinter drop-down list
//to find the shares/print queues of a windows print-server you need samba and the net -S command like this:
// net -S yourPrintServerName.yourBaseDomain.com -U yourLdapUser%yourLdapUserPassWord -W adm rpc share -l
//which dispalays a long list of the shares
- (IBAction)onSelectDomain:(id)sender
{
static int indexOfLastItem = 0; //unfortunately we need to compare this because we are called also if the selection did not change!
if ([comboDomain indexOfSelectedItem] != indexOfLastItem && ([comboDomain indexOfSelectedItem] != 0))
{
indexOfLastItem = [comboDomain indexOfSelectedItem]; //retain this index for next call
//the print-servers-list has to be loaded on a per univeristy or domain basis from a file dynamically or from AN LDAP-QUERY
//initialize an LDAP-Query-Task or console-command like this one with console output
/*
ldapsearch -LLL -s sub -D "cn=yourLdapUser,ou=yourOuWithLdapUserAccount,dc=yourDomain,dc=com" -h "yourLdapServer.com" -p 3268 -w "yourLdapUserPassWord" -b "dc=yourBaseDomainToSearchIn,dc=com" "(&(objectcategory=computer)(cn=ps*))" "dn"
//our print-server names start with ps* and we want the dn as result, wich comes like this:
dn: CN=PSyourPrintServerName,CN=Computers,DC=yourBaseDomainToSearchIn,DC=com
*/
sLdapQueryCommand = [[NSString alloc] initWithString: #"/usr/bin/ldapsearch"];
if ([[comboDomain stringValue] compare: #"firstDomain"] == NSOrderedSame) {
aLdapQueryArgs = [NSArray arrayWithObjects: #"-LLL",#"-s", #"sub",#"-D", #"cn=yourLdapUser,ou=yourOuWithLdapUserAccount,dc=yourDomain,dc=com",#"-h", #"yourLdapServer.com",#"-p",#"3268",#"-w",#"yourLdapUserPassWord",#"-b",#"dc=yourFirstDomainToSearchIn,dc=com",#"(&(objectcategory=computer)(cn=ps*))",#"dn",nil];
}
else {
aLdapQueryArgs = [NSArray arrayWithObjects: #"-LLL",#"-s", #"sub",#"-D", #"cn=yourLdapUser,ou=yourOuWithLdapUserAccount,dc=yourDomain,dc=com",#"-h", #"yourLdapServer.com",#"-p",#"3268",#"-w",#"yourLdapUserPassWord",#"-b",#"dc=yourSecondDomainToSearchIn,dc=com",#"(&(objectcategory=computer)(cn=ps*))",#"dn",nil];
}
//prepare and execute ldap-query task
tskLdapTask = [[NSTask alloc] init];
pipeLdapTask = [[NSPipe alloc] init];//instead of [NSPipe pipe]
[tskLdapTask setStandardOutput: pipeLdapTask];//hope to get the tasks output in this file/pipe
//The magic line that keeps your log where it belongs, has to do with NSLog (see https://stackoverflow.com/questions/412562/execute-a-terminal-command-from-a-cocoa-app and here http://www.cocoadev.com/index.pl?NSTask )
[tskLdapTask setStandardInput:[NSPipe pipe]];
//fhLdapTask = [[NSFileHandle alloc] init];//would be redundand here, next line seems to do the trick also
fhLdapTask = [pipeLdapTask fileHandleForReading];
mdLdapTask = [NSMutableData dataWithCapacity:512];//prepare capturing the pipe buffer which is flushed on read and can overflow, start with 512 Bytes but it is mutable, so grows dynamically later
[tskLdapTask setLaunchPath: sLdapQueryCommand];
[tskLdapTask setArguments: aLdapQueryArgs];
#ifdef bDoDebug
NSLog (#"sLdapQueryCommand: %#\n", sLdapQueryCommand);
NSLog (#"aLdapQueryArgs: %#\n", aLdapQueryArgs );
NSLog (#"tskLdapTask: %#\n", [tskLdapTask arguments]);
#endif
[tskLdapTask launch];
while ([tskLdapTask isRunning]) {
[mdLdapTask appendData: [fhLdapTask readDataToEndOfFile]];
}
[tskLdapTask waitUntilExit];//might be redundant here.
[mdLdapTask appendData: [fhLdapTask readDataToEndOfFile]];//add another read for safety after process/command stops
NSString* sLdapOutput = [[NSString alloc] initWithData: mdLdapTask encoding: NSUTF8StringEncoding];//convert output to something readable, as NSData and NSMutableData are mere byte buffers
#ifdef bDoDebug
NSLog(#"LdapQueryOutput: %#\n", sLdapOutput);
#endif
//Ok now we have the printservers from Active Directory, lets parse the output and show the list to the user in its combo box
//output is formatted as this, one printserver per line
//dn: CN=PSyourPrintServer,OU=Computers,DC=yourBaseDomainToSearchIn,DC=com
//so we have to search for "dn: CN=" to retrieve each printserver's name
//unfortunately splitting this up will give us a first line containing only "" empty string, which we can replace with the word "choose"
//appearing as first entry in the comboBox
aPrintServers = (NSMutableArray*)[sLdapOutput componentsSeparatedByString:#"dn: CN="];//split output into single lines and store it in the NSMutableArray aPrintServers
#ifdef bDoDebug
NSLog(#"aPrintServers: %#\n", aPrintServers);
#endif
if ([[aPrintServers objectAtIndex: 0 ] compare: #"" options: NSLiteralSearch] == NSOrderedSame){
[aPrintServers replaceObjectAtIndex: 0 withObject: slChoose];//replace with localized string "choose"
#ifdef bDoDebug
NSLog(#"aPrintServers: %#\n", aPrintServers);
#endif
}
//Now comes the tedious part to extract only the print-server-names from the single lines
NSRange r;
NSString* sTemp;
for (int i = 1; i < [aPrintServers count]; i++) {//skip first line with "choose". To get rid of the rest of the line, we must isolate/preserve the print server's name to the delimiting comma and remove all the remaining characters
sTemp = [aPrintServers objectAtIndex: i];
sTemp = [sTemp stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];//remove newlines and line feeds
#ifdef bDoDebug
NSLog(#"sTemp: %#\n", sTemp);
#endif
r = [sTemp rangeOfString: #","];//now find first comma to remove the whole rest of the line
//r.length = [sTemp lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
r.length = [sTemp length] - r.location;//calculate number of chars between first comma found and lenght of string
#ifdef bDoDebug
NSLog(#"range: %i, %i\n", r.location, r.length);
#endif
sTemp = [sTemp stringByReplacingCharactersInRange:r withString: #"" ];//remove rest of line
#ifdef bDoDebug
NSLog(#"sTemp after replace: %#\n", sTemp);
#endif
[aPrintServers replaceObjectAtIndex: i withObject: sTemp];//put back string into array for display in comboBox
#ifdef bDoDebug
NSLog(#"aPrintServer: %#\n", [aPrintServers objectAtIndex: i]);
#endif
}
[comboPrintServer removeAllItems];//reset combo box
[comboPrintServer addItemsWithObjectValues:aPrintServers];
[comboPrintServer setNumberOfVisibleItems:aPrintServers.count];
[comboPrintServer selectItemAtIndex:0];
#ifdef bDoDebug
NSLog(#"comboPrintServer reloaded with new values.");
#endif
//release memory we used for LdapTask
[sLdapQueryCommand release];
[aLdapQueryArgs release];
[sLdapOutput release];
[fhLdapTask release];
[pipeLdapTask release];
// [tskLdapTask release];//strangely can not be explicitely released, might be autorelease anyway
// [mdLdapTask release];//strangely can not be explicitely released, might be autorelease anyway
[sTemp release];
}
}
I have my self come across instance where it was not enough to just separate string by component many tasks such as 1) Categorizing token into types 2) Adding new tokens 3)Separating string between custom closures like all words between "{" and "}"For any such requirements i found Parse Kit a life saver.
I used it to parse .PGN (prtable gaming notation) files successfully its very fast and lite.