Mathieu Tozer's Dev Blog

Cocoa, the development of Words, and other software projects (including those dang assessment tasks).




Words: Merging Lookup and Words

0 comments

Ok, I'm going to try and merge the two projects so that I can automatically search for word definitions when I add them.

I've just realised I can hand the management of dictionaries to core data. This way they'll persist.

This isn't turning out to be as easy as I would have liked. So there are going to have to be some minor changes to the model and the controller. I've subclassed NSArrayController to DictionariesArrayController which takes care of the UI outlets and actions, and automatically prepares CD Dictionary entities. The only action to far is 'connect' which will be invoked when the user has entered dictionary details. It will create a new entitiy with the appropriate relationship to whichever language is selected, and plop the data that must persist between launches of the application into the entity (server, database, username, password). Then it should invoke the dictProtocolDictionary's own awakeFromInsert method which will then make the actual connection. In this way, when dictionaries are loaded at launch time into the array, they can reconnect to their servers and be ready to define words.

I've got a problem: The NSArrayController seems to only want to handle objects of one type. Why is this so? Surely I should be able to string up any kind of object I like in it. addObject:object kind of situation.
Maybe it's bindings that's restricting me. The tableview needs to know what to display. But I've told the arrayController that it's got to manage entities of type Dictionary, which is an abstract class. Which means that you can't actually make of these objects, to do so is useless! It's actually the same problem I've had with trying to get smart lists and manual lists in the same view. What if the array controller managed two separate arraycontrollers, then then pulled the two together into the same array? That would be a bit messy methinks.

I possibly don't need to have core data manage the Dictionary entity as such. I mean, if I never actually have an instance of one, then why does core data need to know? Entity DictProtocolDictionary can still have a relationship with Language, so that dictionaries of that type can know to whom they belong. The subclass behaviour can come from the manual hardcoding of the entities classes. The ArrayController can directly manage dictProtocolDictionaries for now.

Here's what the connect button in the controller object should do, as far as I can see so far.
- (IBAction)connect:(id)sender
{
//create a new DictProtocolDictionary in the moc
//create a new dictionary entity and populate it's data.
//add it to the array
//(this should invoke the entity's awake from insert method which will make the actual connection)
//once you're connected and there were no errors, clear the UI, ready for the next connection

}

Actually, awakeFromInsert isn't entirely appropriate. Because it isn't called when the object is being recalled from the moc. What we need is something that will go through the dictionaries in the system and connect them when they are summoned out of the moc.
awakeFromFetch is more appropriate! (For reconnecting).

So now I am able to create and delete persisting dictProtocolDictionaries in Words proper, which associate themselves to languages. The next thing to do is to make sure they are connected not only when they are fetched by the window, but at launch time too, so that they are connected and available even when the dictionary pane hasn't been opened yet (can work around this for a while).
Each time a word is entered, the applicationController should try to find definitions for it. Words that have been defined are checked off as having been done so. This is so that later on the application can go though and find undefined words and define them.


Still more work before I can call a milestone with a screenshot ;-)


Nothing Much New Today

0 comments

Ok, so I've got words (lookup) connecting to any dict protocol dictionary in the world, but I still have plenty of issues to address.

The results being returned are themselves hard to read in a table view. It may be necessary to parse them into one line, so that at least the first few words can be read.

Right now when people walk away from the internet, they have gone from having plenty of dictionaries, to having none.

Also, as words are added enmasse, the dictionary lookup service adds things to the array one by one, but the user interface isn't updated until the very last definition has been found. It would be nice to add each as they are found.. but having thought about that the dict protocol returns one struct for each query containing all things found as it is, so it wouldn't work that way definition by definition, but it could work for word by word, and it will work this way without any modification.

In the dictionaries preferences pane, whether the dictionary is available online or offline should be indicated. Users should be able to specify the name, and kind of dictionary, and if needed specify the location, whether it be server or local file.

There should be some indication of what is being done in the user interface. A spiral progress indicator should be spun while the definitions are being hunted down.

Kind of need to write up my application to do this as final year project.

Submitted the application today. I'm pretty tired tonight so might take a rest from Cocoa until tomorrow.



More notes that I took while thinking through today's developments...

I'm going to create a new interface to the UI AND to the class that will allow me to initialise a new dict Protocol object. It will then be available to the user to query while the program is running, and the results will be displayed on the right.


Hmmm

But how is this going to help words?

Within the Words system, whenever there are
1. Undefined words
2. A suitable dictionary available wither locally or remotely

it should try to automatically find definitions for each undefined words.

Fetch from the ManagedObjectContext all instances of the Word entity that have not been defined.
Order them in some way (or not). Importance??
Start from the top of the list and go to the bottom. For each Word object in the array.
[Dictionary define:word]
Place the definition

But I'm getting such varied quantities back from the dictionary. And that's only from the one server, in one database! What about when the possible servers and databases increases!?
The exact results are unpredictable, but they will be within reason. And we know how to handle definition objects well enough. Generally, the first few results fired back from the dictionary are the most relevant.
However, we cannot safely disregard the other definitions.
If the default is inappropriate, then the user must decide which definition they want to be 'Number 1', and promote it to the top of the definitions list. This is the definition that is used for quizzing, word lists etc, however, the alternative definitions are still available.

In the UI, all definitions will be available via an auxiliary window. The main definition will of course be viewable against the original word.

I could probably go right ahead and put the DictProtocolDictionary class right into my existing words prototype, but I want to make sure it is ready and will be able to do everything that I want it to do. But I suppose I can always add to it and modify its behaviour later.

What I think I need to workout next is the UI for this system. Words now has the ability to connect to any server that implements the dict protocol. How is the user going to
1. Create a new dictionary.
2. Specify which dictionary they want to use.
3. Remove Dictionaries.

I also have to make sure there is an internet connection available when the dictionary tries to connect, and to fail gracefully when there isn't (rather than crashing which is what lookup does at the moment!)

Possibly, the user can set any number of dictionaries themselves (or select a suggestion from the list) which then associates itself to the actively selected language.
The special case is that it's not a foreign language to you, in which case you are looking for only definitions, not translations to words. There might be a checkbox to allow the user to specify whether the dictionary is going to be used as translation or a definition dictionary.

I just sketched a preference pane which allows you to choose language, add and remove available dictionaries, check whether they are active or not, a text field to change the server and database, and below that the other dictionary settings.

The application will take from these available dictionaries their definitions.

Therefore dict class should have Cocoa compliant Getters and Setters so I can hook them up to an IB GUI.

Before I set up preferences and the like in Words proper, I need to make sure that the classes can handle all the setters and options etc within the cocoa environment. Can I create more than one dictProtocol dictionary and change it's database etc dynamically. This should be developed in the Lookup application.

Aaand here's the fruits of today's labours. What fun! I can't wait to make it easy for anyone to connect to any dictionary in the world with such a simple interface.

(Click) and look! It's translated cheese to fromage!

Of course, the end goal is to hook the above with what is in this image:

Use the services menu to add you existing word lists (or just a single word) to Words, and have it find the meaning for you, and then save it for later.

fyi

THESE are the dictionaries that reside on dict.org alone!

Database list:
gcide
        The Collaborative International Dictionary of English v.0.48
wn
        WordNet (r) 2.0
moby-thes
        Moby Thesaurus II by Grady Ward, 1.0
elements
        Elements database 20001107
vera
        Virtual Entity of Relevant Acronyms (Version 1.9, June 2002)
jargon
        Jargon File (4.3.1, 29 Jun 2001)
foldoc
        The Free On-line Dictionary of Computing (27 SEP 03)
easton
        Easton's 1897 Bible Dictionary
hitchcock
        Hitchcock's Bible Names Dictionary (late 1800's)
bouvier
        Bouvier's Law Dictionary, Revised 6th Ed (1856)
devils
        THE DEVIL'S DICTIONARY ((C)1911 Released April 15 1993)
world02
        CIA World Factbook 2002
gazetteer
        U.S. Gazetteer (1990)
gaz-county
        U.S. Gazetteer Counties (2000)
gaz-place
        U.S. Gazetteer Places (2000)
gaz-zip
        U.S. Gazetteer Zip Code Tabulation Areas (2000)
--exit--
        Stop default search here.
afr-deu
        Africaan-German Freedict dictionary
afr-eng
        Africaan-English Freedict Dictionary
ara-eng
        English-Arabic Freedict Dictionary
cro-eng
        Croatian-English Freedict Dictionary
cze-eng
        Czech-English Freedict dictionary
dan-eng
        Danish-English Freedict dictionary
deu-eng
        German-English Freedict dictionary
deu-fra
        German-French Freedict dictionary
deu-ita
        German-Italian Freedict dictionary
deu-nld
        German-Nederland Freedict dictionary
deu-por
        German-Portugese Freedict dictionary
eng-afr
        English-Africaan Freedict Dictionary
eng-ara
        English-Arabic FreeDict Dictionary
eng-cro
        English-Croatian Freedict Dictionary
eng-cze
        English-Czech fdicts/FreeDict Dictionary
eng-deu
        English-German Freedict dictionary
eng-fra
        English-French Freedict Dictionary
eng-hin
        English-Hindi Freedict Dictionary
eng-hun
        English-Hungarian Freedict Dictionary
eng-iri
        English-Irish Freedict dictionary
eng-ita
        English-Italian Freedict dictionary
eng-lat
        English-Latin Freedict dictionary
eng-nld
        English-Netherlands Freedict dictionary
eng-por
        English-Portugese Freedict dictionary
eng-rom
        English-Romanian FreeDict dictionary
eng-rus
        English-Russian Freedict dictionary
eng-spa
        English-Spanish Freedict dictionary
eng-swa
        English-Swahili xFried/FreeDict Dictionary
eng-swe
        English-Swedish Freedict dictionary
eng-tur
        English-Turkish FreeDict Dictionary
eng-wel
        English-Welsh Freedict dictionary
fra-deu
        French-German Freedict dictionary
fra-eng
        French-English Freedict dictionary
fra-nld
        French-Nederlands Freedict dictionary
hin-eng
        English-Hindi Freedict Dictionary [reverse index]
hun-eng
        Hungarian-English FreeDict Dictionary
iri-eng
        Irish-English Freedict dictionary
ita-deu
        Italian-German Freedict dictionary
jpn-deu
        Japanese-German Freedict dictionary
kha-deu
        Khasi-German FreeDict Dictionary
lat-deu
        Latin-German Freedict dictionary
lat-eng
        Latin-English Freedict dictionary
nld-deu
        Nederlands-German Freedict dictionary
nld-eng
        Nederlands-English Freedict dictionary
nld-fra
        Nederlands-French Freedict dictionary
por-deu
        Portugese-German Freedict dictionary
por-eng
        Portugese-English Freedict dictionary
sco-deu
        Scottish-German Freedict dictionary
scr-eng
        Serbo-Croat-English Freedict dictionary
slo-eng
        Slovenian-English Freedict dictionary
spa-eng
        Spanish-English Freedict dictionary
swa-eng
        Swahili-English xFried/FreeDict Dictionary
swe-eng
        Swedish-English Freedict dictionary
tur-deu
        Turkish-German Freedict dictionary
tur-eng
        Turkish-English Freedict dictionary
english
        English Monolingual Dictionaries
trans
        Translating Dictionaries
all
        All Dictionaries (English-Only and Translating)
web1913
        Webster's Revised Unabridged Dictionary (1913)
world95
        The CIA World Factbook (1995)


Words: Milestone. Dict Protocol Word Lookup

0 comments

After yesterday's productivity, today has seemed rather disappointing. What I have to remember is that even though I might not get on screen progress done, what I'm learning from my mistakes will help me program better in the future.

For example, I've learnt one lesson today - the less C++ there is my life that happier I think I'll be!

You see, there's this free program to access dict protocol compatible servers written in C, and there was a convenient wrapper to it written in C++. I tried to link it into my Lookup app, but it threw nasty errors at me for hours. Maybe I don't know the mechanics of it yet, and there is a simple way to do it. Anyway I realised that the C++ wrapper around the C code was actually what I should probably be rewriting for my own app in Objective-C.

Many hours, castings, photographs with Lord Mayor John So later...
@ 10.19pm

Bingo!

bingo!.jpg

Another milestone! I now have my DictProtocolDictionary instance importing definitions right into the object from somewhere in Alaska I believe. Should only be short work to extract the data from the struct it's currently residing in, and plop it into the definitions array controller to be shown in the table view.

bugGone.jpg
Done! Of course it's not perfect. There are multiple rows displayed in the table, and I'm going to have to parse the definitions for those that are meaningful, and take out things like procunciation, and word type in some handy variables. And give the dictionary server and dictionary database itself credit for the service.

Next I think I should create an interface which allows the user to specify which dict server and which dictionary on that server they wish to query.

Actually there still is some work to be done with the DictProtocolDictionary class. I haven't implemented all of the code that the C++ wrapper did that I was wrangling with on the tram this morning.

All this stuff is really starting to make sense now, and I'm loving it! You come across something tricky and you apply yourself for a few minutes, debug, think some more, realise something, then come up with something beautiful like this:

Definition *newDefinition = [[Definition alloc] initWith:[NSString stringWithCString:(theDefinition[idx]->ld_answord)] andDefinition:[NSString stringWithCString:(theDefinition[idx]->ld_ansdef)]];

Mwah! Bellissimo!

I start back at Uni tomorrow, and with any luck something from this blog will become my final year project and I will be able to spend even more time developing.


Words: Lookup

0 comments

Since I've hit a bit of a wall with smart lists (ideas anyone??), I'm going to put it aside and try to develop in isolation another hairy part of Words. The definition lookup feature.

By isolation I mean that I will start a new project, with a simple UI that is the front end to the lookup class (or classes) that take a word string as an argument, and return 'definition' objects. This is how I envision the system will work.

The following are the notes I took today while thinking and devloping what the screenshot shows below. They don't flow very well!

While I am aiming for language generality, I still believe that there will be language specific things that will need to be handled by a subclass of the generic 'dictionary' object.

LookupUtility has the function "(NSArray *)lookupWord:(NSString *)word inDict:(Dictionary *)dict" which is the interface for whatever needs to lookup a word in whatever dictionary. It returns an array of definition objects for word.

There should only ever be one LookupUtility instance per application.

This diagram shows neither the lookup utility (as I scrapped it in the end) nor a generic 'dict' protocol class (yet to be implemented).

Dictionary is an Abstract Class. The application should create instances of a Dictionary subclass that is applicable to the particular user's needs. Ie, If a user has specified that they are learning Japanese and their native language is English, then the application should instantiate a JapEngDictionary object that can churn out definitions when queried with a string.

The DictProtocolDictionary can be instantiated (not shown in the image), one for each dictionary that can be accessed via the dict protocol. In the user interface, the user might be able to cause this to happen

The user should be able to select which dictionary object the application should use to find definitions to their words by default. The application controller (delegate) should keep check of what dictionary objects are available (a dictionary manager view??). From here a user might be able to select a word and search again in dict:selectedDictionary for example, if they feel they can find better results elsewhere.

So to make the development easier and modularised from the main Words app, I am starting Lookup.xcodeproj (or whatever that filename is these days). With luck, the classes I develop should be able to be imported directly into Words and hooked up to the WordsAppDelegate no problem.

Because Lookup.application doesn't really need to STORE anything, I'll use the Cocoa Application template from within Xcode.

I've created a simple interface in IB, and have created AppController, with an action 'search' and an outlet 'wordToLookup'. Later I will add two NSArrayControllers, which will control the Dictionary and definition objects contained in the NSArrays returned by the dictionary objects. Bindings should take care of the display of this.

First I am going to check that this structure works by creating the classes with stubs that return static example Arrays.

Actually, I've just realised that the AppController doesn't control which dictionaries are available, the NSArrayController called dictionaries does. It can co-ordinate adding and deletion from the model... but in fact we don't want it to be able to do that. We want to do that programatically by asking the Controller nicely if it would please add this new dictionary object we've just created to its trusted care. Then we can autorelease it :-)

Ok, so now I've got some to-be dictionary object in the array.

How I handle these dictionaries has to be separate to how they work.

Later on that night...


I believe I've got the mechanics of it working well. Next step is to test whether its architecture is suitable for scalability. I'll create a new class for a French and English dictionary, and see if I can add it to the list of dictionaries, and ask it for definitions dynamically. Wait a sec... Yahaaa! I had checked 'Automatically Prepares Content' - a throwback to my yesterday Code Data ways. Of course, It's not to automatically prepare any content at all - I'm deciding to do all the work! This also explains the added extra definition object that was being automatically prepared in the Array.



So there I have it, a kind of 'framework' for me to handle multiple languages. A little simplistic, but a proof of concept.

Next is nothing but
1. Adding the code to actually access the dictionary databases (probably messy)
2. Parsing the results into nice rich fields that can go in the definition class / entity.
3. Creating as many Dictionary class subclasses for the dictionary databases that I can find.

And then attaching the whole lot the main Words app and running it all on each word that is input.

---

Brainwave. Have a thesaurus as well so that writers can use Words to search for alternative words, and keep track even of when they have used them.


Weekly Review: 07-16

0 comments

- Having difficulty with grouping system, so began work on dictionary management and lookup.
- Started a new, isolated project 'Lookup' to do so.
- Did preliminary design and brainstorming of how the system might work.
- Got the initial structure of the system working, which proved the concept
-Outlay what needed to be done.
- Utilised an open source dict protocol program by writing an Objective-c wrapper around it.
- Linked it to the Lookup project and connected the user interface to define words from dict.org, and display the results in the table view.
-Identified areas that needed improvement


+RSS | dev blog | Portfolio

About me

My status

Last posts

  • my del.icio.us
  • my flickr