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:
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.
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:
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 https://www.mujmac.cz/art/sw/Cocoa_54.html).
Obsah seriálu (více o seriálu):
- Programování na Macu - Aplikace pro kontrolu nové pošty (1)
- Programování na Macu - Aplikace pro kontrolu nové pošty (2)
- Programování na Macu - Aplikace pro kontrolu nové pošty (3)
- Programování na Macu - Aplikace pro kontrolu nové pošty (4)
- Programování na Macu - Aplikace pro kontrolu nové pošty (5)