Multiple text views

So, if I’m understanding this right, the array controller’s content array is bound in IB to gCardList?

What works? The saving of the data? What doesn’t work? Do you not see the text in the text view when you bring the data back in, or is it that you can’t put that text into a raw string as you mentioned a few posts back? With all this back and forth, I’ve forgotten what the question was. :confused:

Ric

Ric,

You asked me for some code, and it was necessary to give you the answers – I admit that my app is not just a script to tell iTunes to play my favorite songs. :stuck_out_tongue:

Yes, back to my question: according to the way my data is stored and retrieved, how do I access to the strings of my texts (of course no the one which is displayed, but any text).

Thank you for your patience :slight_smile:

Hello Ric,

I had some problems in binding the textView’s contents by “attributedString”, so, as you have seen, I bound them by “data”.

The storage on file is NSConcreteMutableData, and no methods like “string()”, “characters()” could work. I found this on Internet :

So I made this :

gCardController's setSelectedObjects_({theCard})
set theString to gTextView's |string|() as string

and got my string picobello!

I let the NSTextView work for me, and then I could use its methods to get the text string back.

I’m not displeased of me. :wink:

Thank you!

The text view’s contents are stored as NSConcreteData, but when you read them back in using the unarchiver, it should be back to a string (or attributed string), which is why none of these worked:

 set theString to theCard's cRefCard's cLongText's data as string -- nope
 set theString to theCard's cRefCard's cLongText's data's textStorage() as string -- nope
 set theString to theCard's cRefCard's cLongText's data's textStorage()'s |string|() -- nope

You referred to “data” in all of these tries (besides, data’s textStorage doesn’t make sense – the textStorage belongs to the text view). So, “set theString to gTextView’s |string|() as string” works because the contents are a string.

Ric

it should be back to a string (or attributed string)

… but it’s not:

set theString to theCard’s cRefCard’s cLongText’s textStorage() as string – nope

set theString to theCard’s cRefCard’s cLongText’s textStorage()'s |string|() as string – nope

set theString to theCard’s cRefCard’s cLongText as string – nope

set theString to theCard’s cRefCard’s cLongText’s |string|() as string – nope

You’re right in a sense, It’s not a string as it’s brought back in, it’s NSConcreteTextStorage – this makes sense because if you archive the text view’s textStorage, then that’s what you get back when you unarchive it. But, the text storage is just the storage layer for the text view and what it stores are strings and attributed strings (as I understand it). So, you don’t get the strings directly from the textStorage, but from the textView using the string() method.

I’m not sure what if anything these examples prove. As I said above, textStorage() is a method of NSTextView, so sending that message to cLongText is just wrong. As for the last 2 examples, I can’t quite figure out what is happening there, because I don’t know where in the code you attempted those.

Ric

What is exactly this NSConcreteTextStorage? Is it a private class? I can’t find any documentation about it. Is there a way to extract a string from it?

Like all of these “concrete” classes, the methods you use are just the ones from the class with the “concrete” removed, so NSTextStorage. You can in fact get the text from it using the method mutableString() (which NSTextStorage inherits from its superclass NSMutableAttributedString).

Ric

For my way of thinking, this would be a good idea, it certainly makes it simpler and easier for me to understand. I think part of the problem with understanding your code is all the different names, and trying to keep them straight. Having one less object to keep track of makes it seem more organized. I think of the cID as one of the attributes of your cards, just like the icon, image, sound and texts, so it really should be in the cRecord with all of them.

You can certainly put the cID into your table if you want, but just because it’s in your dictionary, doesn’t mean that you have to put it in if you think the table looks better without it.

Ric

Thank you helping me to keep my code smaller and (above all) clearer. All is now packed into the cRecord, it’s much better, in code as in IB.

My app is rather complex, but it’s a good learning terrain, and thanks to your help, I can now develop small apps in minutes.

PS :confused:
Always no way to extract this raw string from the NSConcreteMutableData. Maybe with a valueForKey_ ? And then, what shall I get with it? Or is it a coercion problem?

I can’t close this post until I have this string – even if I already got it using gTextView…

Regards,

The NSConcreteMutableData is just a “bag of bits”, you can’t read it unless you reverse the process that you used to create it – if you created it with an archiver, then you need to unarchive it before you can read it.

Ric

But at this stage, it has been unarchieved :

            set theCard to current application's NSKeyedUnarchiver's unarchiveObjectWithFile_(theFile)
            gCardController's addObject_(theCard)

theCard should be a NSMutableDictionnary… or it is not?

Furthermore, my app is again in bits and pieces: I have no more sorting in my lists, getting this:

2011-04-27 17:03:12.006 AutoText[11269:903] -[NSCFString objCType]: unrecognized selector sent to instance 0x7fff70dd70d0
2011-04-27 17:03:13.806 AutoText[11269:903] -[NSCFNumber length]: unrecognized selector sent to instance 0x200045200

This time, it’s a monday in wednesday’s disguise.:frowning:

But that wasn’t your question – you asked about NSConcreteMutableData, and that’s the question I answered.

You really need to do more logging to answer these questions yourself. Put in a log statement to look at theCard’s class – this is a very useful thing to do when you are debugging programs, I do it all the time.

Ric

Ok Ric, I understand. Thank you for all your answers so far.

Regards,

Of course, it was my error, and it was lying before my eyes from the start.

All this started with the incapacity of NSDictionary to write NSImages to a file. At this time, my cards were NSDictionnaries, and but I wanted texts containing images.

So I changed for NSData saving – and “of course” I bound my textView by data, not by attributed string. For obscure reasons (and lack of doc reading) I was sure “attributed string” was for RTF, not RTFD. Images=Data, this was my idea. So the KeyedArchiever saved my texts as NSConcreteData.

So far, so good, everything seemed to work as needed.

The problems occurred when I wanted to extract the text’s |string|() from this NSConcreteData – no way, no methods, nothing. “Concrete” indeed. I relied on the textView to install the text, deciphering it from that data block, and then called the textView’s methods. Nice, marvelous, exciting way to program. :confused:

Now the text is bound with attributed string. I had to throw my files to trash, of course, but I can call finally:

            set theString to theCard's cLongText's |string|() as string -- and it works.

I keep my promise: this post is now closed. :wink: