Reading rtf information from entity entries to NSString - objective-c

I have an entity (named Song) that one of the Attributes is binary data (a rtf field) that I use to to store chord charts or notes about a song. I need to be able to print this field along with the other string fields of this entity. I have tried every permutation of this I can think of:
NSAttributedString* myDataTry = [[[NSAttributedString alloc] initWithRTF:myData documentAttributes:NULL]autorelease];
When I run this through the debuger the summary for myDataTry reads "out of scope" until the next line break and then myDataTry reads nil.
What do I need to change to make this thing go?

The reference for initWithRTF:documentAttributes: reads:
Returns an initialized object, or nil if rtfData can’t be decoded.
Are you absolutely certain that your RTF data can be decoded?

Here is what worked:
NSString *aStr = [[NSString alloc] initWithData:myData encoding:NSASCIIStringEncoding];
NSRange r = [aStr rangeOfString:#"{"];
NSString *newAStr = [aStr substringFromIndex:r.location];
NSData *newMyData;
newMyData = [newAStr dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:1];
NSAttributedString* myDataTry = [[[NSAttributedString alloc] initWithRTF:newMyData documentAttributes:NULL]autorelease];
Now to insert that into the window with everything else! Thanks for your point in the right direction #ShaggyFrog

Related

How to save text from textview?

I have a textview where you can write multiple lines of text. How do you save that text in a file or variables?
I used the multiline text field but it doesn't let me go to next line unless I hit control enter.
What I'm thinking is like a text editor, after you type everything you save that in a file. Or I can get each line from the text view into a variable.
What's the best way to do this?
NSString can save text up to 4.2 billion characters. \n denotes a line break, so no need to save into multiple parameters.
NSString *text = textView.text;
OSX
NString *text = [[textView textStorage] string];
If you're looking for each individual line for whatever reason, you could use componentsSeparatedByString
NSArray *linesArray = [textView.text componentsSeparatedByString:#"\n"];
Each line will be available at linesArray[0], linesArray[1] etc...
[linesArray count] will give you the total number of lines... with linesArray[[linesArray count]-1] being the last line in the string.
The textView.text property is an NSString also... so when you say saved.. do you mean intra app session? If so you can use NSUserDefaults
Save object
[[NSUserDefaults standardUserDefaults]setObject:textView.text forKey:#"TheKeyForMyText"];
Get object
NSString *text = [[NSUserDefaults standardUserDefaults]objectForKey:#"TheKeyForMyText"];
Assign
In swift
let var_name = textfield.text
Or in objective C
NSString *string_name = textfield.text;
And use the variable where you want to.

Reading plist data

I was wondering if one of you could help me read data from the following plist (see image)
What I want to do is create an NSArray, for example called "OriginatingKey" with the objects: {"Crew Oxygen", "EXT", "Hatch/Safety Equipment", "ALT Doors/Inhibits Switch"}
So far I am using:
NSString *plistpath = [[NSBundle mainBundle] pathForResource:#"fileName" ofType:#"plist"];
NSDictionary* DATA = [NSDictionary dictionaryWithContentsOfFile:plistPath];
NSArray *list1 = [DATA valueForKey:#"OriginatingKey"];
Saddly enough, this produces a list the correct number of objects. When I print the description of one of these objects I get an error. When I type NSLog(#"list1[0]") I get a minor error: "Format string is not a string literal", but the log does print the corresponding string.
Thank you for your help in advance!
Try to replace this line:
NSArray *list1 = [DATA valueForKey:#"OriginatingKey"];
with:
NSArray *list1 = [DATA objectForKey:#"OriginatingKey"];
The actual problem may be in the way you use NSLog.
Do it like this:
NSLog(#"list1[0] = %#", list1[0]);

Having trouble taking an index of an array and making it an NSString

I get an array from a JSON and I parse it into an NSMutableArray (this part is correct and working). I now want to take that array and print the first object to a Label. Here is my code:
NSDictionary *title = [[dictionary objectForKey:#"title"] objectAtIndex:2];
arrayLabel = [title objectForKey:#"label"];
NSLog(#"arrayLabel = %#", arrayLabel); // Returns correct
//Here is where I need help
string = [arrayLabel objectAtIndex:1]; //I do not get the first label (App crashes)
NSLog(#"string = %#", string);
other things that I have already tried are as follows:
string = [NSString stringWithFormat:#"%#", [arrayImage objectAtIndex:1]];
and
string = [[NSString alloc] initWithFormat:#"%#", [arrayImage objectAtIndex:1]];
Any help is greatly appriciated!
EDIT: The app does not return a single value and crashes.
Your code doesn't match the structure of your JSON. In your comment on the deleted answer, you said you got an exception when sending objectAtIndex: to an NSString. In your case, arrayLabel isn't an array when you think it is.
If your JSON has an object, your code needs to treat it as an NSDictionary. Likewise for arrays and NSArray and strings and NSString.
In addition to whatever else was going on, you repeatedly refer to "first" but use the index 1. In most C-based programming languages (and others, as well) the convention is that indexes into arrays are 0-based. So, use index 0 to get the first element.

NSMutableArray with NSDictionary to Labels without the surrounding brackets

I'm making a scoreboard for my game. And when I do a NSLog of the data it comes out as this:
{
name = TTY;
score = "3.366347";
}
So my question is how do I remove this brackets and also just grab the name (TTY) and score (3.36 without the quotations) and place them in variable for me to put into labels.
Currently I can place them in labels but they have the lingering curly braces "{" and "}".
Any hints would be helpful as I'm happy to search further I just don't know the vocab to search for it.
thanks
For NSDictionary if you want to get the values you use objectForKey: method;
[scoreDictionary objectForKey:#"name"];
In your case the method will return TTY
You can store this in a variable like normal:
NSString *entryName = [scoreDictionary objectForKey:#"name"];
For NSArray (and NSMutableArray) you use objectAtIndex: method;
[scoresArray objectAtIndex:0];
I'm guessing that you have many NSDictionary in the NSArray, in which case you can combine the two methods above and get;
[[scoresArray objectAtIndex:0] objectForKey:#"name"];
which will give you the value of name in the first dictionary of the array.
Also if you want to access multiple key values you can use;
NSDictionary *entry = [scoresArray objectAtIndex:0];
NSString *entryName = [entry objectForKey:#"name"];
NSString *entryScore = [entry objectForKey:#"score"];

Using NSXMLElement to add a tag in the middle of a block of text

I need to create an XML document with the following type of format.
<Para>
This is some text about <someMethod> that you need to know about.
</Para>
I'm having no issues with general XML generation, but this one aspect is giving me some issues.
One approach is to make a mutable copy of the stringValue of the para node and then insert your tags around the "someMethod" text. Create a new NSXMLNode from that using -[NSXMLNode initWithXMLString:error:] and replace the old NSXMLNode with the new NSXMLNode. That's probably shorter, but it requires some string manipulation.
If you know the para node is a single run of text, then you can use this category on NSXMLNode I just wrote which seems a bit more verbose to me than what I described. Depends on what your needs are and how much you like messing around with NSMutableStrings. :)
#implementation NSXMLElement (ElementSplitting)
- (void)splitTextAtRangeInStringValue:(NSRange)newNodeRange withElement:(NSString *)element {
/* This is pretty simplistic; it assumes that you're attempting to split an element node (the receiver) with a single stringValue. If you need to do anything more complicated, you'll have to do some more work. For this limited example, we need three new nodes(!):
1. One new text node for the first part of the original string
2. One new element node with a stringValue of the annotated part of the string
3. One new text node for the tail part of the original string
An alternate approach is to use -[NSXMLNode initWithXMLString:error:] after making a mutable copy of the string and modifying that string with the new markup you want.
*/
NSXMLNode *prefaceTextNode = [[NSXMLNode alloc] initWithKind:NSXMLTextKind];
NSXMLElement *elementNode = [[NSXMLNode alloc] initWithKind:NSXMLElementKind];
NSXMLNode *suffixTextNode = [[NSXMLNode alloc] initWithKind:NSXMLTextKind];
NSString *fullStringValue = [self stringValue];
NSString *prefaceString = [fullStringValue substringToIndex:newNodeRange.location];
NSString *newElementString = [fullStringValue substringWithRange:newNodeRange];
NSString *suffixString = [fullStringValue substringFromIndex:newNodeRange.location + newNodeRange.length];
[prefaceTextNode setStringValue:prefaceString];
[elementNode setName:element];
[elementNode setStringValue:newElementString];
[suffixTextNode setStringValue:suffixString];
NSArray *newChildren = [[NSArray alloc] initWithObjects:prefaceTextNode, elementNode, suffixTextNode, nil];
for (id item in newChildren) { [item release]; } // The array owns these now.
[self setChildren:newChildren];
[newChildren release];
}
#end
...and here's a small example:
NSString *xml_string = #"<para>This is some text about something.</para>";
NSError *xml_error = nil;
NSXMLDocument *doc = [[NSXMLDocument alloc] initWithXMLString:xml_string options:NSXMLNodeOptionsNone error:&xml_error];
NSXMLElement *node = [[doc children] objectAtIndex:0];
NSString *childString = [node stringValue];
NSRange splitRange = [childString rangeOfString:#"text about"];
[node splitTextAtRangeInStringValue:splitRange withElement:#"codeVoice"];
If <someMethod> is actually an element, then you need to create a NSXMLNode of kind NSXMLTextKind (via initWithKind:), create your <someMethod> node, and create another text node, then add all three in order as children to your <Para> node. The key is creating the two text parts as separate nodes.
After rereading the question, I'm thinking maybe <someMethod> wasn't intended to be a node, but should have been text? If so, it's just an escaping problem (< | >) but I'm guessing that it's not something that simple, considering who you are. :)