SpotLight
Paisible.fr
Membre
Bonjour,
Je souhaiterais ajouter une fonction à mon application qui consisterais effectuer une recherche sur un mot dans un dossier de fichier HTML. La recherche se ferais sur le contenu et pas sur le code html.
Je sais faire une recherche de texte en passant par les APIs de webKit, il me suffirais alors d'itérer sur toutes les pages HTML du dossier. ça pourrais fonctionner mais cela ne me semble pas très propre.
L'autre solution à laquelle je pensais été d'utiliser SpotLight qui me semble bien plus approprié. Malheureusement après bien des recherches je n'ai pas réussi à comprendre son fonctionnement. Tous ce que j'ai trouvé me parait fort complexe par rapport à mes besoins : gestion de threads, etc... qui me sont inutiles.
Quelqu'un aurait-il un exemple qui ferait la recherche d'un mot sur les fichiers d'un dossier sans thread etc... ?
Merci
Je souhaiterais ajouter une fonction à mon application qui consisterais effectuer une recherche sur un mot dans un dossier de fichier HTML. La recherche se ferais sur le contenu et pas sur le code html.
Je sais faire une recherche de texte en passant par les APIs de webKit, il me suffirais alors d'itérer sur toutes les pages HTML du dossier. ça pourrais fonctionner mais cela ne me semble pas très propre.
L'autre solution à laquelle je pensais été d'utiliser SpotLight qui me semble bien plus approprié. Malheureusement après bien des recherches je n'ai pas réussi à comprendre son fonctionnement. Tous ce que j'ai trouvé me parait fort complexe par rapport à mes besoins : gestion de threads, etc... qui me sont inutiles.
Quelqu'un aurait-il un exemple qui ferait la recherche d'un mot sur les fichiers d'un dossier sans thread etc... ?
Merci
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
ça n'est pas si compliqué !
Basiquement,
MDQueryCreate crée la recherche à effectuer
MDQuerySetSearchScope définit les emplacements de recherche
MDQueryExecute la lance
Et tu peux intercepter la progression avec des notifications.
Mais dans ton cas, tu peux aussi utiliser l'option kMDQuerySynchronous pour le MDQueryExecute, qui permet de ne pas effectuer le travail en tâche de fond, mais d'attendre le résultat !
Essaye donc un peu de bricoler avec ces fonctions, tu devrais vite obtenir un résultat.
+
Chacha
Voila une réponse fort utile et qui me permettra de débrouissaler le terrain.
Maintenant je sais dans quelle direction chercher.
Sinon :
1) La recherche spotlight fonctionnera t'elle sur les fichiers contenu à l'intérieur du bundle de l'application ?
2) Si je recherche dans la doc d'apple (ADC), toutes mes requêtes sur MDQueryCreate me donnent des pages indiquant que l'API est en carbon. C'est vraiment le cas ou c'est moi qui ne suit pas foutu de faire la bonne recherche ?
Il y a de toute façon 2 grandes API sous OSX, le framework Cocoa qui utilise comme langage l'Objective-C, et Carbon, qui utilise le langage C. D'ailleurs Cocoa n'est en fait qu'une surcouche de Carbon en général, un wrapper en Objective-C autour des méthodes Carbon en C.
Quand tu vois dans la doc des trucs comme tu vois bien que c'est du C (un type de retour + un nom de fonction + "(" + liste des paramètres (type+nom) + ")") et non de l'Objective-C (les types seraient entre parenthèses, les arguments auraient des noms avec ":" à la fin, etc) et que les types d'arguments sont CFxxx autrement dit des types CoreFoundation. C'est donc typiquement du C (API Carbon) et non de l'Objective-C (API Cocoa)*.
De plus avec des noms de méthode comme ça ("xxxCreate") on reconnait la patte de l'API Carbon ici aussi.
Alors certes, c'est déroutant, perso je suis pas fan de Carbon non plus et préfère Cocoa et le langage Objective-C. Mais comme dans ce cas il n'y a pas de surcouche/wrapper en Objective-C pour l'API de Spotlight, ben il faut bien se mettre à Carbon. Et en regardant 2-3 exemples au final c'est pas sorcier et on arrive à s'en sortir :P
* Bon y'a pas que c'est cas, je stéréotype un peu mais bon
Sauf que j'arrive pas à construire le MDQuerySetSearchScope comme je le souhaite.
En effet l'API est la suivante :
Et il est spécifié que :
Mon problème est que je n'arrive pas à construire cette foutue CFArray of CFStringRef avec deux ou trois chemins de type "/Users/toto/blabla/patati/patata". :crackboom:-
Mon dieu, vivement Leopard Snow qu'ils nous retirent ces couches Carbon du finder
En attendant pour ton problème, je crois que CFArray et NSArray sont toll-free-bridged, de même que NSString* et CFStringRef, il me semble (bon, à vérifier, mais ça ne m'étonnerait pas trop).
Du coup si c'est bien le cas, créer un NSArray de NSString et le caster en CFArray ensuite te simplifierai la tâche de création
Par contre bizzarement le code si dessous ne fonctionne pas :
Alors que le code suivant oui :
Il semble que la recherche textuelle ne fonctionne pas pour les fichiers à l'intérieur du bundle.
Si fait le meme test en mettant le dossier à l'extérieur ca fonctionne apparemment.
Quelqu'un peut confirmer / infirmer ?
Cela n'ennuie fortement car si c'est confirmé cela fout en l'air ma fonction de recherche.
Il ne faut pas oublier que Spotlight se sert d'une base d'indexation pour... indexer les métadonnées associées à tes fichiers (nom, contenu, type, durée des médias, ...). Il exécute ensuite sa recherche sur cette base d'indexation, donc dans sa base de données de ces metadatas.
Donc tout ce que tu lui as demandé explicitement de ne pas indexer, dans les préférences spotlight, il ne l'indexera pas. De même pour les fichiers système qu'il n'indexe pas... et de même pour le contenu des bundles !
Peut-être y a-t-il cependant une possibilité via l'API de demander d'indexer le contenu de ton/tes bundles ?
Quelques remarques/reflexions :
1) Je pense que j'ai commis une erreur sur l'égalité, il semblerais qu'il faut utiliser un double egal comme operateru pour le kMDItemTextContent si je m'en tient à la doc d'Apple. Je vais tester ce soir.
2) Je n'ai rien trouvé me permettant de "forcer" l'indexation d'un dossier/fichier donné. Pourtant il me semblait avoir vu une ligne de commande, mais j'ai peut-être révé
3) Si je ne peux effectuer une recherche spotlight textuel sur un ensemble de fichier dans mon bundle cela va fortement me decevoir et m'amener à chercher une autre solution qui sera forcement mois élegante. Ce serait dommage...
C'est bizarre, j'étais persuadé que Spotlight était accessible sous cocoa via les classes NSMetadata...
Effectivement, il semblerait que tu soit dans le vrai No :
C'est une bonne nouvelle, mais cela résoud en rien mon problème de pouvoir lancer une recherche textuel sur des fichiers stockés à l'interieur du bundle de mon application :-\\
Si j'ai tout compris tu cherches à faire une recherche dans des fichiers html stockés quelque part dans ton bundle application...
Peut être peux tu contourner la limitation de Spotlight en copiant ces html autre part au 1er lancement de ton appli (comme dans Application Support par exemple)...
Sinon, tu peux aussi essayer de créer ton propre mdimporter : un plugin spécifique à ton appli qui indexerai ton bundle...
Tu as parfaitement bien tout compris :adios!:
J'y ai bien pensé figure toi, mais :
1) c'est pas très "élegant"
2) je suis pas sur que "application support" soit le meilleur endroit pour cela. Quoique ...
Oui effectivement, mais :
1) Je trouve dommage de recoder quelque chose alors que SpotLight à déjà un MDImporter pour le HTML
2) Cela ne m'à pas l'air simple à faire. Enfin, du moins cela semble representer un certain investissement
Tente de faire l'expérience en forçant l'indexation d'un fichier html dans ton bundle, puis un coup de spotlight afin de voir si l'indexation est ok.
Exemple dans le terminal :
[tt]mdimport /Applications/monApplication.app/Contents/Resources/html/unFichier.html[/tt]
(pour indexer le fichier unFichier.html se trouvant dans un répertoire html lui même dans les ressources de l'appli).
Après quoi, si ça marche, Une série de NSTask au premier lancement de ton appli devrait faire l'affaire.
Mieux, faudrait aussi tester si mdimport supporte de ne mettre que le chemin d'un répertoire afin d'indexer tous les fichiers s'y trouvant...
Reste à savoir si ça te dérange ou pas.
Un rapide test sous 10.4 montre clairement que mdimport est incapable d'indexer des fichiers à l'intérieur d'un bundle .app, même en fournissant un path absolu à la commande.
Donc, faut abandonner spotlight pour les recherches intra bundle.
Reste les solutions :
- faire son propre outil de recherche (mais dans ce cas faudrait nous expliquer à quoi servent tes html dans le .app, et surtout pourquoi as-tu besoin d'y faire des recherches textuelles).
- transférer lesdits html vers un endroit scanné par spotlight (dans ce cas, /Library/Application Support/ est parfait : propre à l'appli, et reconnu par spotlight, mais avec les limitations -ou failles ?- relevées par Aligator sur le fait que l'interrogation ne sera pas spécifique à ton appli, mais à tous les utilisateurs ayant les droits suffisants).
Le même test rapide chez moi (mais sous 10.5) confirme cette conclusion.
De plus mes recherches sur le net semble corroborrer le tout.
Donc exit la recherche spotlight intra-bundle !
- La solution de faire un MDImporter ne changera rien au fait de pouvoir acceder au contenu intra-bundle je pense. Et puis quel dommage de recoder la même chose que le decodeur SpotLight pour l'HTML d'Appple.
- La solution de transférer les HTML dans le dossier /Library/Application Support/ (par exemple) me plaà®t moyennement car, d'une part il faut copier les fichiers au départ et c'est un peu dommage d'avoir deux fois le meme contenu de stocker. D'autre part, comme le mentionne Aligator, je ne pense pas que ce soit souhaitable de le voir en dehors de l'application. Meme si c'est pas bloquant en soit.
- Reste la solution de réaliser son propre outil de recherche. Actuellement je sais parfaitement faire une recherche sur un texte dans un fichier HTML affiché dans une webView. Donc, si j'arrive a effectuer la meme chose directement sur le fichier (sans passer par la webview) et itérant sur les fichiers du dossier je devrais pouvoir m'en tirer. Au pire, si je n'arrive pas à me passer de la weview, je peux toujours passer par une webView invisible.
- Enfin, une voie que je n'est pas encore explorée serait de passer par le SearchKit.
Par contre, les fichiers html doivent avoir un certain formatage (c'est à dire des balises spécifiques dans le html) afin que la recherche soit possible.
Cette API est disponible sous cocoa via la classe NSHelpManager.
Bonne idée No, mais dans mon cas cela ne va pas convenir.
Merci quand même.
Je pense creuser la piste du WebKit...