Caches et NSDictionary a partire du web

elfelf Membre
09:25 modifié dans API AppKit #1
Bonjour,

Pour gérer la mise à  jour, mais aussi l'enregistrement (dialoguer avec mon serveur) j'utilise une bidouille asser simple et très pratique:

- (void)lookForUpdate:(BOOL)forceCheck<br />{<br />	NSURL *versionFileURL = [NSURL URLWithString:URLDEPLISTENLIGNE];<br />	NSDictionary *plist = [[[NSDictionary alloc] initWithContentsOfURL:versionFileURL] autorelease];<br />	if(!plist)<br />	{<br />		NSLog(@&quot;impossible de se connecter a ss pour verifier les updates&quot;);<br />		NSBeep();<br />		return;<br />	}<br />	NSString *vraiVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@&quot;CFBundleVersion&quot;];<br />	NSString *newVersion = [plist objectForKey:@&quot;version&quot;];	<br />	<br />	if(!forceCheck &amp;&amp; [newVersion isEqualToString:[prefs objectForKey:@&quot;lastUpdateNotified&quot;]])<br />		return;<br />	<br />	if(![vraiVersion isEqualToString:newVersion])<br />	{<br />		int alertPanelResult = NSRunAlertPanel(NSLocalizedString(@&quot;UpdateAvaiableTitle&quot;, nil),<br />											&nbsp;  [NSString stringWithFormat:NSLocalizedString(@&quot;UpdateAvaiableMsg&quot;, nil),<br />												&nbsp;  [plist objectForKey:@&quot;version&quot;]],<br />											&nbsp;  NSLocalizedString(@&quot;UpdateAvaiableDownload&quot;, nil),<br />											&nbsp;  NSLocalizedString(@&quot;UpdateAvaiableOK&quot;, nil),<br />											&nbsp;  nil);<br />		if(alertPanelResult == NSOKButton)<br />		{<br />			[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[plist objectForKey:@&quot;downloadPage&quot;]]];<br />		}<br />		else if(alertPanelResult == NSCancelButton)<br />		{<br />			[prefs setObject:newVersion forKey:@&quot;lastUpdateNotified&quot;];<br />		}<br />		else<br />			NSBeep();<br />	}<br />}<br />


En gros ce code initialise le dictionnaire qui me dit si il y a une nouvelle version directement à  partire de l'internet.

Le problème est que je crois que une fois que ça été initialisé il me le met en cache, et j'aimerais que il ne le cache pas: mais que il le recharge à  chaque fois!

Comme faire cela?

Merci d'avance,
elf

Réponses

  • AliGatorAliGator Membre, Modérateur
    09:25 modifié #2
    Utilises plutôt + (id)requestWithURL:(NSURL *)theURL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval qui te permet de choisir la politique utilisée pour le cache. En particulier en utilisant la constante NSURLRequestReloadIgnoringCacheData.

    Tu ne pourras plus utiliser initWithContentsOfURL mais ça va pas compliquer des masses les choses.
  • elfelf Membre
    09:25 modifié #3
    C'est bien les requêtes, sauf que je ne sais pas comment utiliser.. tu n'aurrais pas un exemple, ou une explication du moins?
  • AliGatorAliGator Membre, Modérateur
    09:25 modifié #4
    A partir d'une NSURLRequest, tu peux utiliser NSURLDownload pour télécharger un fichier sur le disque, ou NSURLConnection pour effectuer un téléchargement asynchrone.

    Je ne le savais pas avant d'aller à  l'instant faire un tour dans la doc... donc bon je te laisse chercher je vais pas le faire à  ta place  ;)

    surtout que tu as déjà  à  priori tout ce qu'il te faut ici, enfin je pense.
  • elfelf Membre
    mars 2006 modifié #5
    Bon, j'ai fait un petit essay:

    - (void)lookForUpdate:(BOOL)forceCheck<br />{<br />	forceCheckUpdate = forceCheck;<br />	NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:URLDEPLISTENLIGNE]<br />											&nbsp; cachePolicy:NSURLRequestReloadIgnoringCacheData<br />										&nbsp; timeoutInterval:60.0];<br />	[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];<br />}<br /><br />- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error<br />{<br />	NSLog(@&quot;impossible de se connecter a ss pour verifier les updates&quot;);<br />	NSBeep();<br />	[connection release];<br />}<br /><br />- (void)connectionDidFinishLoading:(NSURLConnection *)connection<br />{<br />	NSURL *versionFileURL = [NSURL URLWithString:URLDEPLISTENLIGNE];<br />	NSDictionary *plist = [[[NSDictionary alloc] initWithContentsOfURL:versionFileURL] autorelease];<br />	if(!plist)<br />	{<br />		NSLog(@&quot;impossible de se connecter a ss pour verifier les updates&quot;);<br />		NSBeep();<br />		return;<br />	}<br />	NSString *vraiVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@&quot;CFBundleVersion&quot;];<br />	NSString *newVersion = [plist objectForKey:@&quot;version&quot;];	<br />	<br />	if(!forceCheckUpdate &amp;&amp; [newVersion isEqualToString:[prefs objectForKey:@&quot;lastUpdateNotified&quot;]])<br />		return;<br />	<br />	if(![vraiVersion isEqualToString:newVersion])<br />	{<br />		int alertPanelResult = NSRunAlertPanel(NSLocalizedString(@&quot;UpdateAvaiableTitle&quot;, nil),<br />											&nbsp;  [NSString stringWithFormat:NSLocalizedString(@&quot;UpdateAvaiableMsg&quot;, nil),<br />												&nbsp;  [plist objectForKey:@&quot;version&quot;]],<br />											&nbsp;  NSLocalizedString(@&quot;UpdateAvaiableDownload&quot;, nil),<br />											&nbsp;  NSLocalizedString(@&quot;UpdateAvaiableOK&quot;, nil),<br />											&nbsp;  nil);<br />		if(alertPanelResult == NSOKButton)<br />		{<br />			[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[plist objectForKey:@&quot;downloadPage&quot;]]];<br />		}<br />		else if(alertPanelResult == NSCancelButton)<br />		{<br />			[prefs setObject:newVersion forKey:@&quot;lastUpdateNotified&quot;];<br />		}<br />		else<br />			NSBeep();<br />	}<br /><br />	[connection release];<br />}<br /><br />
    


    Est-ce la manière correcte de procéder?
    Ne seraice pas mieux de télécharger le fichier dans un dossier temporaire et de l'initaliser depuis le disque ensuite? SI oui, comment faire?
  • elfelf Membre
    09:25 modifié #6
    Bon j'ai essaye comme ca aussi et ca cache le dictionnaire...

    Je crois que la solution est de telecharger le fichier depuis le serveur (peutetre avec curl? mais ca m'air l'air tres compliquer pour rien...) sur le disque dans /tmp/... et de ll'ouvrire depuis le disque avec un [monDict initWithContentOfFile:path];

    Mais comment faire ca en cocoa, quelqu'un aurrais un code?
  • Eddy58Eddy58 Membre
    09:25 modifié #7
    A mon avis tu utilises mal NSURLRequest, car dans connectionDidFinishLoading tu initialises à  nouveau une simple NSURL pour aller chercher ton fichier, et te retrouver avec un cache, donc c'est comme :(renaud): dans un violon. ;)
    Il faut passer par les méthodes adéquates de NSURLRequest ou autre classe exploitant un objet NSURLRequest pour récupérer le contenu du fichier, mais là  j'ai pas encore pratiqué, mais je vais en avoir besoin bientôt, donc je vais pas tarder à  tomber dedans.
    Sinon, ton code comporte aussi des fuites mémoires :
    [tt]
    NSURLConnection *connection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
    [/tt]
    serait déjà  mieux.
  • Eddy58Eddy58 Membre
    09:25 modifié #8
    J'ai fait comme ci-dessous (code de la doc à  peine modifié...) en passant par NSURLDownload. :o
    [tt]
    -(void)startDL
    {
          // Créer la requete
    NSURLRequest *request=[[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@URLFichier] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60.0];

          // Commencer le DL
    NSURLDownload *download=[[NSURLDownload alloc] initWithRequest:request delegate:self];
    [request release];

    if (download)
    {
             // Setter le fichier de destination
    [download setDestination:@CheminFichierDestination allowOverwrite:YES];
    }
    else
    {
    NSLog(@DL fail);
    }
    }

    -(void)downloadDidFinish:(NSURLDownload *)download
    {
        [download release];

        NSLog(@DL Ok);
    }

    -(void)download:(NSURLDownload *)download didFailWithError:(NSError *)error
    {
        [download release];

        NSLog(@DL failed! Error - %@ %@",
              [error localizedDescription],
              [[error userInfo] objectForKey:NSErrorFailingURLStringKey]);
    }
    [/tt]

    Les autres classes (comme NSURLConnection, NSURLHandle), permettent de travailler directement en mémoire mais il faut que le fichier comporte un NSData, donc cela implique d'utiliser NSArchiver pour encoder ton dictionary en NSData avant sa mise en ligne, et NSUnarchiver pour le décoder ensuite lors de sa récupération.
Connectez-vous ou Inscrivez-vous pour répondre.