Setting the text of an NSTextField programmatically - cocoa

I have a GUI built on IB (Xcode 4).
It has a Static Text field connected to an NSTextField. After reading the information from an XML file it's supposed to change the text to whatever it is coming from the XML
the .h is as follow:
IBOutlet NSTextField * DataBaseLocation;
the .m
NSMutableArray* DBLoc = [[NSMutableArray alloc] initWithCapacity:1];
NSXMLElement* root = [doc rootElement];
NSArray* DBarray = [root nodesForXPath:#"//DataBaseLocation" error:nil];
for(NSXMLElement* xmlElement in DBarray)
[DBLoc addObject:[xmlElement stringValue]];
NSString * DBLocationString = [DBLoc objectAtIndex:0];
[DataBaseLocation setStringValue:DBLocationString];
NSLog(#"DBLoc: %#", DBLoc);
The NSLog shows that DBLoc has the correct string, yet the Text Field is empty and never gets set.
yes, I checked the connections in IB.
Any ideas? thanks!

Found the answer.
I needed to initialize the NSXMLDocument with NSXMLDocumentTidyXML like:
NSXMLDocument* doc = [[NSXMLDocument alloc] initWithContentsOfURL: [NSURL fileURLWithPath:input] options:NSXMLDocumentTidyXML error:NULL];

You should print out DBLocationString instead of DBLoc to make sure it's not empty or in some corrupted format that can't be passed as a string value and go from there.

Related

Setting UILabel to Same value as NSString

I have searched for hours on this one subject and still have not been able to solve my problem. I have a string value that I need converted into a label. In my code I save the NSString and then make sure I am getting a value with the NSLog (which I DO). Then is where I am having problems. I try to set the label value equal to the nesting but when I run its NSLog I get (null). So my question is how may I make my label equal the value of my string? Thank you so much!
NSString *linkString = self.product[#"link"];
NSLog(#"%#", linkString);
linkLabel.text = linkString;
NSLog(#"%#", linkLabel);
Your NSString will never be equal to your UILabel.
on the other hand, your UILabel's text property which is an NSString will be
try to change the code to this
NSString *linkString = self.product[#"link"];
NSLog(#"%#", linkString);
linkLabel.text = linkString;
NSLog(#"%#", linkLabel.text);
All I changed was linkLabel in your NSLog to linkLabel.text
Assuming like you said that linkString has a value, the second log should output the same as the first log.
EDIT: I saw your comment above, there is no need for a duplicate definition of the label as an #property and above that in the h file.
Are you sure that
NSString *linkString = self.product[#"link"];
works? Try this:
NSString *linkString = #"Test";
and use this for logging:
NSLog(#"%#", linkLabel.text);
Did you forget to hook up the linkLabel in your XIB? Is the value of linkLabel not nil?
What does NSLog(#"%#", linkLabel); print out?

Attaching multiple uitextfields to an email

I have multiple UITextFields and I want to attach them to an in app email. I can get one of them appear but not the rest. Here is what I am using.
MFMailComposeViewController *composer = [[MFMailComposeViewController alloc] init];
[composer setMailComposeDelegate:self];
[composer setSubject:#"My Subject"];
[composer setMessageBody:AddNotesTextField.text isHTML:YES];
[self presentModalViewController:composer animated:YES];
[composer release];
Thank you
You got it right already for the body using:
[composer setMessageBody:AddNotesTextField.text isHTML:YES];
So just repeat the procedure with the other fields like so:
[composer setSubject:mySubjectTextField.text];
Or if you are asking how to use the input from multiple text fields into the body of the email, you simply have to use NSString's stringWithFormat:
[composer setMessageBody:[NSString stringWithFormat:#"you can place static %# text in between %# these variables",AddNotesTextField.text,someOtherField.text] isHTML:YES];
In string with format, you escape the default string to add a string using "%#" for every instance where you want to insert some other string. Then after the original string ends you enter the names of the input strings separated by commas. [NSString stringWithFormat:#"%#%#",x,y]

Reading a plist

I'm trying to read ~/Library/Preferences/com.apple.mail.plist (on Snow Leopard) to get the email address and other information to enter into the about dialog. I'm using the following code, which is obviously wrong:
NSBundle* bundle;
bundle = [NSBundle mainBundle];
NSString *plistPath = [bundle pathForResource:#"~/Library/Preferences/com.apple.mail.plist" ofType:#"plist"];
NSDictionary *plistData = [NSDictionary dictionaryWithContentsOfFile:plistPath];
NSString *item = [plistData valueForKeyPath:#"MailAccounts.Item 2.AccountName"];
NSLog(#"Result = %#", item);
Moreover, the value I need to read is MailAcounts -> Item 2 -> AccountName and I am not sure I am doing this correctly (due to the space in the Item 2 key).
I tried reading Apple's developer guide to plist files but no help there.
How can I read a plist and extract the values as an NSString?
Thanks.
The first level is an array, so you need to use "MailAccounts.AccountName" and treat it as NSArray*:
NSString *plistPath = [#"~/Library/Preferences/com.apple.mail.plist" stringByExpandingTildeInPath];
NSDictionary *plistData = [NSDictionary dictionaryWithContentsOfFile:plistPath];
NSArray *item = [plistData valueForKeyPath:#"MailAccounts.AccountName"];
NSLog(#"Account: %#", [item objectAtIndex:2]);
Alternatively you can go by keys and pull the array from "MailAccounts" first using valueForKey: (which will yield NSArray*) and then objectAtIndex: to get the dictionary of that particular account (useful if you need more than the name).
Two things:
You don't want or need to use NSBundle to get the path to the file. The file lies outside of the app bundle. So you should just have
NSString *plistPath = #"~/Library/Preferences/com.apple.mail.plist";
You have to expand the tilde in the path to the user directory. NSString has a method for this. Use something like
NSString *plistPath = [#"~/Library/Preferences/com.apple.mail.plist" stringByExpandingTildeInPath];

NSTextView add URL link to the selected Text?

I Have an NSTextView.
I just want to add an Attribute (an NSLinkAttributeName) to the selected Text in the NSTextView...
Can You Help me ?
Thanks.
You want to get the view's textStorage (which is basically a mutable attributed string), then add the NSLinkAttributeName attribute to the selected range; the value of that attribute is the URL to link to.
[[textView textStorage] addAttribute: NSLinkAttributeName value: url range:[textView selectedRange]];
Been a while since I played with ObjC but this should do the trick. It replaces the selected text with the original content with your attr appended. Checked through it but please excuse any typos.
NSTextView *textView = ...;
NSDictionary *attributes = ...;
//Get selected text string from TextView (see Text superclass) and append attr link
NSRange selRange = [textView selectedRange];
NSMutableString *changedStr = [[[textView string] substringWithRange:selRange] mutableCopy];
[changedStr appendString:[attributes objectForKey:NSLinkAttributeName]];
//Replace the selected text range in the TextView
[textView replaceCharactersInRange:selRange withString:[NSString stringWithString:changedStr]];
[changedStr release];
See class defs:
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSText_Class/Reference/Reference.html
-replaceCharactersInRange:withString:
-selectedRange
-scrollRangeToVisible: if you want to present your change immediately
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html
substringWithRange:

overwriting instead of writing to a plist-cocoa

I have created a method to write data to a plist.
- (void)writeToPListUserType:(NSString *)type
andUserID:(NSString *)usid
andFirstName:(NSString *)fname
andLastName:(NSString *)lname
andPassword:(NSString *)pwd{
NSMutableDictionary *userDetails = [[NSMutableDictionary alloc] init];
[userDetails setObject:fname forKey:#"firstName"];
[userDetails setObject:lname forKey:#"lastName"];
[userDetails setObject:pwd forKey:#"password"];
NSMutableDictionary *userIDKey = [[NSMutableDictionary alloc] init];
[userIDKey setObject:userDetails forKey:usid];
[userCredentials setObject:userIDKey forKey:type];
[userIDKey release];
[userDetails release];
NSString *error;
NSString *rootPath = [NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *plistPath = [rootPath stringByAppendingPathComponent:
#"userCredentials.plist"];
NSData *plistData = [NSPropertyListSerialization
dataFromPropertyList:userCredentials
format:NSPropertyListXMLFormat_v1_0
errorDescription:&error];
[plistData writeToFile:plistPath atomically:YES];
}
I am able to write new data to the plist. However, when the new data is written, the old data is no longer there. In other words, the method is overwriting my plist.
Please tell me what is wrong with the method... :(
Thanks in advance...
With this line:
code>[userCredentials setObject:userIDKey forKey:type];
you are overwriting the existing "userCredentials" "type" key (I don't see it is newly allocated in the method) with new data.
So the userCredentials, which I suppose is a mutable dictionary created elsewhere, is overwritten with the new data.
1) read the plist from disk
2) create a mutable in memory copy
3) modify the (in memory) plist
4) overwrite the file you read, using the in memory plist

Resources