Programování na Macu - Aplikace pro kontrolu nové pošty (5) - MujMAC.cz - Apple, Mac OS X, Apple iPod

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

Soutěž

Sponzorem soutěže je:

IDIF

 

Jaký fotograf/ka získal/a cenu za nejpopulárnější příspěvek v Nikon Photo Contest?

V dnešní soutěži hrajeme o:

Seriály

Více seriálů



Informace

Programování na Macu - Aplikace pro kontrolu nové pošty (5)

6. srpna 2008, 00.00 | V tomto posledním díle si ukážeme, jak indexovat texty mailů, aby v nich bylo

možné efektivně vyhledávat.

Index bude reprezentován instanci třídy NSMutableDictionary, což je efektivní asociativní pole z frameworku Foundation. Klíči budou jednotlivá slova z předmětu a těla mailů, hodnotami pole pak instance třídy NSSet (rovněž z Foundation), která bude obsahovat odkazy na maily, v nichž se slovo vyskytuje. Přidáme tedy do souboru AppController.h deklaraci pro vlastnost index:

NSMutableDictionary* index;

Index nebudeme ukládat v Javě, ale přímo v Objective-C do podadresáře aplikace v Library/Application Support. Do souboru AppController.m přidejte metodu pathForDataFile:

- (NSString*)pathForDataFile
{
  NSFileManager* fileManager = [NSFileManager defaultManager];
  NSString* folder = @"~/Library/Application Support/Email Notifier/";
  folder = [folder stringByExpandingTildeInPath];
  if ([fileManager fileExistsAtPath: folder] == NO)
  {
    [fileManager createDirectoryAtPath: folder attributes: nil];
  }
  NSString* fileName = @"Email Notifier.index";
  return [folder stringByAppendingPathComponent: fileName];   
}

Tato metoda nejprve zjistí, zda existuje podadresář pro data naší aplikace. Pokud ne, vytvoří jej a vrátí plnou cestu k souboru Email Notifier.index.
V metodě awakeFromNib načteme index ze souboru do vnitřního objektu. Přidejte tyto řádky:

[NSApp setDelegate: self];

NSString* path = [self pathForDataFile];
index = [NSKeyedUnarchiver unarchiveObjectWithFile: path];
if (index == nil) index = [[NSMutableDictionary alloc] init];
[index retain];
NSLog(@"Index size: %d", [index count]);

První řádek nastaví náš controller jako delegáta aplikace, což využijeme pro ukládání. Dále získáme cestu k souboru s indexem a pomocí třídy NSKeyedUnarchiver se jej pokusíme otevřít. Pokud má index hodnotu nil, vytvoříme pomocí alloc a init novou instanci, tedy prázdný index. Nakonec pomocí funkce NSLog vypíšeme na konzolu velikost indexu předáním zprávy count.
O uložení indexu těsně před ukončením aplikace se postaráme v metodě applicationShouldTerminate:

- (NSApplicationTerminateReply)applicationShouldTerminate: (NSApplication *)sender {
    NSString* path = [self pathForDataFile];
    [NSKeyedArchiver archiveRootObject: index toFile: path];
    return NSTerminateNow;
}

Jako při otevření indexu získáme nejprve cestu k souboru s indexem a potom pomocí třídy NSKeyedArchiver index uložíme.
Nyní se přepněte do Interface Builderu a vytvořte následující okno:
V AppController vytvořte, podobně jako dříve pro okno preferencí, dva outlety searchPanel a searchField a akci search. Outlety propojte s oknem a textovým polem, tlačítko s akcí. Do souboru AppController.h přidejte příslušné deklarace:

IBOutlet NSPanel *searchPanel;
IBOutlet NSTextField *searchField;

...

- (IBAction)search:(id)sender;

Musíme také upravit třídu Mail, aby nám poskytovala unikátní identifikátor objektu. Toho dosáhneme použitím třídy UUID:

public class Mail {

    private String signature;
    private String id;
   
    public Mail() {
        id = UUID.randomUUID().toString();
    }
   
    public void init(String from, String subject, Date date) {
        signature = from + ":" + subject + ":" + date;
    }
   
    public String getId() {
        return id;
    }
   
    public String getSignature() {
        return signature;
    }
   
}

Do metody check třídy MailCheck přidáme volání metody updateIndex pro každou novou zprávu. To zajistí aktualizaci indexu pro každý nový mail:

if (msg.getContent() instanceof String)
    updateIndex(index, mail, msg.getSubject() + " " + msg.getContent());


Všimněte si, že pro jednoduchost zpracováváme pouze jednoduché textové maily, správně bychom měli zohlednit i zprávy skládající se z více částí (typ MimeMultipart).
Vlastní metoda updateIndex vypadá takto:

import com.apple.cocoa.foundation.*;

protected void updateIndex(NSMutableDictionary index, Mail mail, String text) {
    StringTokenizer st = new StringTokenizer(text, " ,.;:()[]{}-\"\'/<>=?!@");
    while (st.hasMoreTokens()) {
        String token = st.nextToken();
        NSMutableSet docs = (NSMutableSet) index.objectForKey(token);
        if (docs == null) index.setObjectForKey(docs = new NSMutableSet(), token);
        docs.addObject(mail.getId());
    }
}

V argumentu text máme dohromady předmět mailu i jeho tělo. První řádek využívá třídu StringTokenizer k rozdělení textu na tzv. tokeny, tj. základní textové jednotky (typicky slova a interpunkční znaménka). Pro každý token zjistí, zda se už v indexu vyskytuje. Pokud ano, přidá do příslušné množiny identifikátor právě zpracovávané zprávy. V opačném případě nejprve vytvoří prázdnou množinu (novou instanci třídy NSMutableSet), vloží do ní identifikátor aktuální zprávy a poté množinu přidá do indexu.
Nakonec si ukážeme kód, jak v indexu vyhledávat. Jedná se vlastně jen o jeden řádek:

- (void)search:(id)sender {
    NSString* pattern = [searchField stringValue];
    NSSet* docs = [index valueForKey: pattern];
    NSLog(@"Pattern: %@ -- %d message(s)\n", pattern, [docs count]);
}

Nejprve získáme z textového pole slovo, které chceme vyhledat. Následně nám index vrátí množinu všech zpráv, v nichž se toto slovo vyskytuje. Pro kontrolu vypíšeme na konzolu její velikost.
Nyní by bylo třeba nějakým pěkným způsobem nalezené zprávy vypsat, například v samostatném okně do tabulky (např. pomocí NSTableView). To nechť už si každý naimplementuje sám, třeba podle článku Ondřeje Čady (viz http://www.mujmac.cz/art/sw/Cocoa_54.html).

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » Informace  

 » Rubriky  » Agregator  

 » Rubriky  » Software  

Poslat článek

Nyní máte možnost poslat odkaz článku svým přátelům:

Váš e-mail:

(Není povinný)

E-mail adresáta:

Odkaz článku:

Vzkaz:

Kontrola:

Do spodního pole opište z obrázku 5 znaků:

Kód pro ověření

 

 

 

 

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: