11
votes

Besoin de contenu dans UiWebView pour afficher rapidement

Une partie de mon application met en cache les pages web pour une consultation hors ligne. Pour ce faire, je gardais le code HTML récupéré à partir d'un site et la réécriture img urls pour pointer vers un fichier sur le magasin. Quand je charge le code html dans un UIWebView, il charge les images comme prévu et tout va bien. Je suis également la mise en cache des feuilles de style de cette façon.

Le problème est que quand je mets le téléphone en mode avion, le chargement de ce cache html provoque le UIWebView pour afficher un écran vide et pause pendant un certain temps avant d'afficher la page. J'ai compris qu'il est causé par des URL non référencées en cache de la doc HTML original que l'affichage Web tente de chercher. Ces autres URL comprennent des images dans les feuilles de style mises en cache, contenu dans iframes et javascript qui établit une connexion à chercher d'autres ressources. La pause se produit lorsque le UIWebView essaye de récupérer ces ressources, et la page Web apparaît uniquement après toutes ces récupérations ont expiré.

Ma question est, comment puis-je faire UIWebView afficher juste les trucs que je l'ai mis en mémoire cache immédiatement? Voici mes pensées:

  • écriture de code encore plus à mettre en cache ces autres références. Ceci est potentiellement une tonne plus de code pour attraper tous les cas de pointe, etc., ayant notamment pour analyser le Javascript pour voir ce qu'il charge après chargement de la page
  • la force UIWebView en temps immédiatement donc il n'y a pas de pause. Je ne l'ai pas compris comment le faire.
  • en quelque sorte obtenir ce qui est déjà chargé pour afficher même si les références externes n'ont pas fini encore aller chercher
  • dépouiller le code de tous les scripts, les balises de liens et iframes à « effacer » les références externes. J'ai essayé celui-ci, mais pour certains sites, la page résultante est sérieusement foiré

    Aide Quelqu'un peut-il me ici? Je travaille sur ce pour toujours, et je suis à court d'idées.


0 commentaires

4 Réponses :


1
votes

Générer un Nsurlrequest avec + DemandeWithURL: Cachepolicy: TimeOnterval: . Définissez la stratégie de cache sur NSURLREQUESTRETURNCacheDataDontload . Chargez la demande dans le WebView à l'aide de -LoLoDrequest: . Documents complets ici .


1 commentaires

Bonjour, mon commentaire de réponse était trop long alors je l'ai coincé dans une réponse ci-dessous.



1
votes

Merci pour le plomb! Cela m'a été déconsidéré. Malheureusement, je semble courir dans une bouquet de barroscuits routiers.

Le problème est que si j'utilise NsurlrequestretourcachedataDataDontload, je pense que les ressources que je chargent doivent déjà être dans le cache. P>

mettre les dans le cache, j'ai essayé ceci: p> xxx pré>

J'ai reçu ce code d'ailleurs sur le filet ", mais je pense que bien que cela fonctionnait sur le Mac, ce n'est pas Travailler sur l'iPhone, ma plate-forme cible. P>

Il ne semble pas insérer l'élément dans le cache; Le NSLOG imprime NULL pour "cache =% @". p>

alors, j'ai essayé de surcharger Nsurlcache: P> xxx pré>

dans ma demande, je spécifie une stratégie de cache de NsurlrequesReturnCachedataDataDontLoad. Cette méthode semble être appelée juste bien, mais il a des comportements étranges sur l'iPhone. Peu importe si je retourne ou non une instance NSCachedurLResponse, l'UIWebView renvoie toujours une erreur: p> xxx pré>

C'est comme si l'UIWebView ignore le fait qu'il convient à quelque chose d'autre que NIL NILD et échouer quand même. J'ai ensuite eu des méfiants et je me suis demandé si l'ensemble du système de chargement de l'URL a tout simplement tout simplement ignoré de -CachedesponseForrequest, donc j'ai créé une sous-classe de NSCachedurLresponse qui ressemble à ceci: p>

    result = [[DebugCachedURLResponse alloc] initWithResponse:reponse data:dataAtURL
        userInfo:nil storagePolicy:NSURLCacheStorageAllowedInMemoryOnly] ;


2 commentaires

Salut Leftspin - J'ai passé beaucoup de temps à traverser des essais et des tribulations similaires. Dans un code précédent, je crois que cela a réellement accepté les réponses en cache, mais maintenant, je reçois les mêmes résultats que vous (il s'agit de ma réponse mise en cache mais de l'ignorer). Toute chance depuis que tu as posté ceci?


Je viens de poster une réponse à une question similaire ici: Stackoverflow.com/questions/1343515/... Mon approche était la même: Sous-classe NsurlCache , mais je n'appelais jamais [Super et compter pleinement sur mon propre mécanisme: je manipule la demande par moi-même. Cela fonctionne correctement sur mon côté même si je pense qu'il ne respecte pas pleinement l'approche de cache du disque de cache / la mémoire: tout est obligé de la FS. Mais je ne pouvais pas penser à une solution plus élégante ici: /



10
votes

Edit: soulignez simplement que cette question, et ses réponses, ont 4 ans. Je discute de iOS 3.x ci-dessous. Je peux facilement imaginer que les choses ont changé entre-temps - Heck, les appareils à eux seuls sont plus rapides que l'iPhone 3G. Ymmv. :)

Je regarde moi-même cela pour le passé, sans encore impliquer quoi que ce soit encore, il suffit de googler. Il semble que c'est globalement qu'il est très difficile / impossible de le faire sur l'iPhone en utilisant DonTload. Même en mars, il y avait des rapports qu'il fonctionne dans Simulator, mais pas sur le périphérique: http: //discussions.apple.com/message.jspa?MessageID=9245292

Je devine juste, mais sur la base d'autres questions Stackoverflow (par exemple, Celui-ci) Je pense peut-être que la mise en cache on-périphérique est d'une manière ou d'une autre plus limitée que ses homologues Mac et Safari.

Autres sur les forums Apple Signaler des expériences avec des ingénieurs rudes lors de la question de UIWebView et de Nsurlcache, où, dans BOG, les ingénieurs disent que cela devrait fonctionner, mais les développeurs réels disent que cela ne le fait pas. http://discussions.apple.com/thread.jspa?Trided=1588010 (Jul 29 au 20 août)

Certaines solutions peuvent être trouvées ici . Compte tenu de [UIIMAGE ImageWithData: ...], David décrit un certain code pour "une implémentation d'un téléchargeur d'image asynchrone de cache-cache pour iPhone".

Et maintenant j'ai découvert ce courrier électronique au 10 août sur la liste de diffusion Cocoa-Dev:

Le 10 août 2009, à 13 h 38, Mike Manzano a écrit:

Quelqu'un a-t-il été capable de réussir Obtenez le système de chargement de l'URL sur iPhone faire attention aux versions personnalisées de Nsurlcache? Il me semble que c'est être ignoré. Plus d'infos ici:

[Un lien vers cette page; enlevé.]

(voir la deuxième "réponse" à ce sujet page).

Vous avez juste besoin d'une sorte d'indice si je suis faire quelque chose de mal ou si mon code est juste être ignoré.

Oui, j'ai eu le travail - ça juste nécessite de faire votre propre cache instance et définir explicitement le cache partagé à cette nouvelle instance.

mais ça a absolument travaillé - une fois mis en œuvre, mon "Set la vue Table Image de la cellule à une image du filet " fonctionne bien (et sans défilement était douloureux au mieux).

glenn andreas gandrees @ xxxxxxxxxxxxx http://www.gandreas.com/ Wicked Fun! Fou, mauvais et dangereux de savoir

Le courrier électronique ci-dessus peut être trouvé sur http: // www.cocoabuilder.com/archive/Message/cocoa/2009/8/10/242484 (sans autre réponse)

Une preuve supplémentaire que NsurlCache peut fonctionner est trouvée dans ICAB Blog: filtrage de l'URL pour UiWebView sur l'iPhone (18 août 2009)

Quelqu'un ici devrait probablement aussi regarder l'application d'urlcache d'Apple, car il peut être pertinent pour leur travail: https://developer.apple.com/iphone/library/samplecode/urlcache/index.html sauf s'il suffit de la regarder maintenant, il est indiqué "Cette application n'utilise pas de nsurlcache Cache de disque ou de mémoire, notre stratégie de cache est donc de satisfaire la demande en chargeant les données de sa source. " et utilise CACHEPOLICY: NSURLREQUESTRELODOADIPOORLOCALCACHEDATA . C'est donc moins pertinent que je pensais, et pourquoi Cette personne appelait nsurlcache une blague.

Donc, il semble que Nsurlcache n'est pas aussi délicat ni impossible que j'ai commencé ce post en disant. Gotta aime trouver un moyen qui fonctionne lors de la recherche de raisons pour lesquelles cela ne fonctionnera pas. Je ne peux toujours pas croire qu'il n'y ait que 25 résultats de recherche Google pour "iPhone" et "NsurlrequesreturnCachedataDonsload" ... Cette réponse a à peu près chacun d'eux. Et je suis content que je l'ai écrit pour que je puisse y référer plus tard; -)


1 commentaires

Merci d'avoir pris le temps de résumer cela.



1
votes

Hey les gars, je pense avoir trouvé le problème. Il ressemble à NsurlrequestReturnCachedataelsEload et NsurlrequesReturnCachedataDonslande est cassé sur l'iPhone. Lorsqu'une NSCachedurLResponse est renvoyée dans le cache et contient des en-têtes HTTP indiquant que le contenu expiré (par exemple expire, le cache-contrôle, etc.), la réponse mise en cache est ignorée et la demande est apportée à la source d'origine.

La solution est la suivante:

  1. Implémentez votre propre sous-classe de NSHTTPURLRESSONNONSE qui vous permet de modifier le dictionnaire AllHeaderFields.
  2. Implémentez votre propre NsurlCache, remplacez CachedResponseForrequest: et renvoyez une nouvelle NSCachedurLResponse contenant une instance de votre sous-classe NSHTPURLRESPonse avec les en-têtes HTTP «expiration» pertinents supprimés.

0 commentaires