{"id":1065,"date":"2009-12-02T09:58:40","date_gmt":"2009-12-02T08:58:40","guid":{"rendered":"http:\/\/www.devapp.it\/wordpress\/?p=1065"},"modified":"2009-12-14T16:19:00","modified_gmt":"2009-12-14T15:19:00","slug":"t014-un-web-server-per-scaricare-files-e-immagini","status":"publish","type":"post","link":"https:\/\/www.devapp.it\/wordpress\/t014-un-web-server-per-scaricare-files-e-immagini\/","title":{"rendered":"T#014 &#8211; Un web server per scaricare files e immagini"},"content":{"rendered":"<p>Supponiamo che abbiate creato un&#8217;applicazione per ritoccare le immagini scattate. Inviarle per email non vi soddisfa e vorreste trovare una via pi\u00f9 veloce per trasferirle sul vostro computer collegato in rete locale.\u00a0Un modo semplice per condividere files tra iPhone e computer via WiFi \u00e8 quello di creare un web server lato iPhone e accedere ai contenuti da un browser inserendo l&#8217;indirizzo locale del vostro telefono. In questo tutorial impareremo ad implementare un framework open source all&#8217;interno delle nostre applicazioni.<!--more--><\/p>\n<p>Esistono diversi progetti gratuiti ma il pi\u00f9 promettente \u00e8 sicuramente <a href=\"http:\/\/cocoahttpserver.googlecode.com\/\" target=\"_blank\">CocoaHttpServer<\/a> disponibile su Google Code. Si tratta di un insieme di classi che si preoccupano di impostare un server HTTP al quale potranno collegarsi altri computer sulla stessa rete locale inserendo l&#8217;indirizzo IP del nostro iPhone. Al momento il progetto supporta il protocollo HTTP 1.1 ma non il WebDAV. Questo vuol dire che sar\u00e0 possibile collegarsi ad iPhone attraverso Safari (o altri browser) ma non direttamente dal Finder (tipo AirSharing o Files).<\/p>\n<p>Scarichiamo dunque il file <a href=\"http:\/\/cocoahttpserver.googlecode.com\/files\/iPhoneHTTPServer3.zip\" target=\"_blank\">iPhoneHTTPServer3.zip<\/a> che contiene tutte le librerie necessarie, scompattiamolo in una cartella e lanciamo il progetto iPhoneHTTPServer.xcodeproj. A questo punto, a seconda dell&#8217;OS con cui state sviluppando potrebbe essere necessario aggiornare il target. Fate cos\u00ec: nella barra laterale di XCode cliccate su Targets, selezionate iPhoneHTTPServer con il tasto destro del mouse e scegliete Get Info. A questo punto nel tab Build impostate il vostro Base SDK. Nel mio caso \u00e8 iPhone Device 3.0. Se volete svilupparlo su iPhone invece del Simulatore ricordatevi anche di impostare il Code Signing e di associarvi un profilo valido. Chiudete la finestra e impostate con il menu popup in alto a sinistra della toolbar di XCode l&#8217;SDK prescelto.<\/p>\n<p><center><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1066\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2009\/12\/HTTPServer-1.jpg\" alt=\"HTTPServer-1\" width=\"400\" height=\"300\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2009\/12\/HTTPServer-1.jpg 400w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2009\/12\/HTTPServer-1-300x225.jpg 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><br \/>\n<\/center><\/p>\n<p>A questo punto compilate e lanciate l&#8217;applicazione (tasto mela+R). Se necessario attivate il server cliccando sullo switch in centro allo schermo. Se tutto funziona iPhone vi restituir\u00e0 il vostro indirizzo IP seguito dalla prima porta libera individuata. Potrebbe volerci qualche secondo. Nel mio caso \u00e8 http:\/\/192.168.0.2:50334. Se ora inserite questo indirizzo in Safari aprirete una pagina dalla quale \u00e8 possibile uploadare files all&#8217;iPhone. A noi interessa di pi\u00f9 il processo inverso.<\/p>\n<p>L&#8217;obbiettivo del piccolo progetto che svilupperemo \u00e8 quello di consentire ad un browser esterno di scaricare una o pi\u00f9 immagini presentate dall&#8217;applicazione. Chiaramente potete usare tutte le immagini che volete. \u00a0Se non ne avete a portata di mano nessuna, potete scaricare questa: (tasto destro sull&#8217;immagine e poi Salva con nome&#8230;)<\/p>\n<p><center><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1067\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2009\/12\/photo.jpg\" alt=\"photo\" width=\"319\" height=\"480\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2009\/12\/photo.jpg 319w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2009\/12\/photo-199x300.jpg 199w\" sizes=\"auto, (max-width: 319px) 100vw, 319px\" \/><br \/>\n<\/center><\/p>\n<p>Rinominatela photo.jpg e trascinatela sulla cartella Resource nella barra laterale di XCode. Lasciate il tasto del mouse. Apparir\u00e0 una finestra che vi chieder\u00e0 se volete aggiungerla al progetto. Ricordatevi di selezionare l&#8217;opzione per copiarla nella cartella del progetto.<\/p>\n<p><center><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1068\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2009\/12\/HTTPServer-2.jpg\" alt=\"HTTPServer-2\" width=\"401\" height=\"448\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2009\/12\/HTTPServer-2.jpg 401w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2009\/12\/HTTPServer-2-268x300.jpg 268w\" sizes=\"auto, (max-width: 401px) 100vw, 401px\" \/><br \/>\n<\/center><\/p>\n<p>A questo punto possiamo iniziare a scrivere qualche riga di codice. Tutti i files e le immagini referenziate dal nostro http server devono trovarsi nella cartella documenti della nostra applicazione. La prima cosa che dobbiamo fare quindi \u00e8 copiare l&#8217;immagine photo.jpg in questa cartella. Apriamo quindi il file iPhoneHTTPServerAppDelegate.m e inseriamo all&#8217;inizio del primo metodo le seguenti righe:<\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo\">&#8211; (<span style=\"color: #b808a1\">void<\/span>)applicationDidFinishLaunching:(<span style=\"color: #7230a8\">UIApplication<\/span> *)application<\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo\">{<\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo\"><span> <\/span><span style=\"color: #7230a8\">NSError<\/span><span> <\/span>*error;<\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo;color: #410a80\"><span style=\"color: #000000\"><span> <\/span><\/span><span style=\"color: #7230a8\">NSString<\/span><span style=\"color: #000000\"> *docDirectory = [[<\/span>NSSearchPathForDirectoriesInDomains<span style=\"color: #000000\">(<\/span>NSDocumentDirectory<span style=\"color: #000000\">, <\/span>NSUserDomainMask<span style=\"color: #000000\">, <\/span><span style=\"color: #b808a1\">YES<\/span><span style=\"color: #000000\">) <\/span>objectAtIndex<span style=\"color: #000000\">:<\/span><span style=\"color: #3b00d6\">0<\/span><span style=\"color: #000000\">] <\/span>retain<span style=\"color: #000000\">];<\/span><\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo\"><span> <\/span><span style=\"color: #7230a8\">NSString<\/span> *httpImagePath=[docDirectory <span style=\"color: #410a80\">stringByAppendingPathComponent<\/span>:<span style=\"color: #cc2425\">@&#8221;photo.jpg&#8221;<\/span>];<\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo\"><span> <\/span><\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo\"><span> <\/span><span style=\"color: #410a80\">NSLog<\/span>(<span style=\"color: #cc2425\">@&#8221;%@&#8221;<\/span>,httpImagePath);<\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo;color: #410a80\"><span style=\"color: #000000\"><span> <\/span><\/span><span style=\"color: #b808a1\">if<\/span><span style=\"color: #000000\">( ![[<\/span><span style=\"color: #7230a8\">NSFileManager<\/span><span style=\"color: #000000\"> <\/span>defaultManager<span style=\"color: #000000\">] <\/span>fileExistsAtPath<span style=\"color: #000000\">:httpImagePath] )<\/span><\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo\"><span> <\/span>{<\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo;color: #410a80\"><span style=\"color: #000000\"><span> <\/span><\/span><span style=\"color: #7230a8\">NSString<\/span><span style=\"color: #000000\"> *httpImagePathFromApp = [[[<\/span><span style=\"color: #7230a8\">NSBundle<\/span><span style=\"color: #000000\"> <\/span>mainBundle<span style=\"color: #000000\">] <\/span>resourcePath<span style=\"color: #000000\">] <\/span>stringByAppendingPathComponent<span style=\"color: #000000\">:<\/span><span style=\"color: #cc2425\">@&#8221;photo.jpg&#8221;<\/span><span style=\"color: #000000\">];<\/span><\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo\"><span> <\/span><span style=\"color: #410a80\">NSLog<\/span>(<span style=\"color: #cc2425\">@&#8221;%@&#8221;<\/span>,httpImagePathFromApp);<\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo\"><span> <\/span>[[<span style=\"color: #7230a8\">NSFileManager<\/span> <span style=\"color: #410a80\">defaultManager<\/span>] <span style=\"color: #410a80\">copyItemAtPath<\/span>:httpImagePathFromApp <span style=\"color: #410a80\">toPath<\/span>:httpImagePath <span style=\"color: #410a80\">error<\/span>:&amp;error];<\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo\"><span> <\/span>}<\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo\"><span> &#8230;<\/span><\/p>\n<p>La variabile error contiene l&#8217;eventuale errore di un&#8217;operazione su files. La seconda riga trova il percorso della cartella documenti, mentre la terza riga crea il percorso all&#8217;immagine (attenzione: \u00e8 il percorso dell&#8217;immagine che copieremo non il percorso dell&#8217;immagine presente nel bundle dell&#8217;applicazione). Ci sono un paio di NSLog per vedere i risultati nella console durante il debug. Ora l&#8217;if si preoccupa di non copiare l&#8217;immagine se \u00e8 gi\u00e0 stata copiata in precedenza. Diversamente ottiene il percorso dell&#8217;immagine presente nel bundle dell&#8217;applicazione e la copia nella cartella documenti. Adesso dobbiamo preoccuparci di creare la pagina HTML che la nostra applicazione presenter\u00e0 ad ogni browser che si connette.<\/p>\n<p>Prima di mettere mano al codice \u00e8 per\u00f2 opportuno capire che cosa fanno i vari files. Le cartelle HTTP, TCP e Categories svolgono il lavoro pi\u00f9 complicato: inizializzano il server, gestiscono le connessioni asincrone, rispondono alle richieste esterne il tutto in perfetta aderenza ai protocollo TCP e HTTP.<\/p>\n<p>Noi focalizzeremo l&#8217;attenzione su MyHTTPConnection.m. Questa classe contiene il metodo<\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo\">&#8211; (<span style=\"color: #7230a8\">NSString<\/span> *)createBrowseableIndex:(<span style=\"color: #7230a8\">NSString<\/span> *)path<\/p>\n<p>che si preoccupa di presentare la pagina di risposta alle richieste che arrivano dall&#8217;esterno. Si tratta sostanzialmente di creare una pagina HTML sotto forma di stringhe in puro stile Objective-C.<\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo\">&#8211; (<span style=\"color: #7230a8\">NSString<\/span> *)createBrowseableIndex:(<span style=\"color: #7230a8\">NSString<\/span> *)path<\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo\">{<\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo;color: #410a80\"><span style=\"color: #000000\"> <\/span><span style=\"color: #7230a8\">NSArray<\/span><span style=\"color: #000000\"> *array = [[<\/span><span style=\"color: #7230a8\">NSFileManager<\/span><span style=\"color: #000000\"> <\/span>defaultManager<span style=\"color: #000000\">] <\/span>directoryContentsAtPath<span style=\"color: #000000\">:path];<\/span><\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo\">\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo;color: #7230a8\"><span style=\"color: #000000\"> <\/span>NSMutableString<span style=\"color: #000000\"> *outdata = [<\/span>NSMutableString<span style=\"color: #000000\"> <\/span><span style=\"color: #410a80\">new<\/span><span style=\"color: #000000\">];<\/span><\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo;color: #cc2425\"><span style=\"color: #000000\"><span> <\/span>[outdata <\/span><span style=\"color: #410a80\">appendString<\/span><span style=\"color: #000000\">:<\/span>@&#8221;&lt;html&gt;&lt;head&gt;&#8221;<span style=\"color: #000000\">];<\/span><\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo;color: #cc2425\"><span style=\"color: #000000\"><span> <\/span>[outdata <\/span><span style=\"color: #410a80\">appendFormat<\/span><span style=\"color: #000000\">:<\/span>@&#8221;&lt;title&gt;Il mio web server&lt;\/title&gt;&#8221;<span style=\"color: #000000\">];<\/span><\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo\">[outdata <span style=\"color: #410a80\">appendString<\/span>:<span style=\"color: #cc2425\">@&#8221;&lt;\/head&gt;&lt;body&gt;&#8221;<\/span>];<\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo;color: #cc2425\"><span style=\"color: #000000\">[outdata <span style=\"color: #410a80\">appendString<\/span>:<span style=\"color: #cc2425\">@&#8221;&lt;p&gt;&#8221;<\/span>];<\/span><\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo;color: #cc2425\"><span style=\"color: #000000\"> [outdata <\/span><span style=\"color: #410a80\">appendFormat<\/span><span style=\"color: #000000\">:<\/span>@&#8221;&lt;img src=photo.jpg&gt;&#8221;<span style=\"color: #000000\">];<\/span><\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo\">[outdata <span style=\"color: #410a80\">appendString<\/span>:<span style=\"color: #cc2425\">@&#8221;&lt;\/p&gt;&#8221;<\/span>];<\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo\"><span> <\/span><\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo;color: #cc2425\"><span style=\"color: #000000\"><span> <\/span>[outdata <\/span><span style=\"color: #410a80\">appendString<\/span><span style=\"color: #000000\">:<\/span>@&#8221;&lt;\/body&gt;&lt;\/html&gt;&#8221;<span style=\"color: #000000\">];<\/span><\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo\">\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo;color: #00870c\"><span style=\"color: #000000\"><span> <\/span><\/span>\/\/NSLog(@&#8221;outData: %@&#8221;, outdata);<\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo\"><span style=\"color: #b808a1\">return<\/span> [outdata <span style=\"color: #410a80\">autorelease<\/span>];<\/p>\n<p style=\"margin: 0.0px 0.0px 0.0px 0.0px;font: 11.0px Menlo\">}<\/p>\n<p>Il codice \u00e8 molto semplice: crea una pagina web con un solo elemento: un&#8217;immagine. Come potete vedere il nome \u00e8 photo.jpg e il programma andr\u00e0 a pescarla nella cartella documenti. Se a questo punto avete fatto tutto correttamente, lanciando l&#8217;applicazione e aprendo da Safari la pagina web relativa vi troverete davanti a questa schermata:<\/p>\n<p><center><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1074\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2009\/12\/HTTPServer-31.jpg\" alt=\"HTTPServer-3\" width=\"400\" height=\"597\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2009\/12\/HTTPServer-31.jpg 400w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2009\/12\/HTTPServer-31-201x300.jpg 201w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><br \/>\n<\/center><\/p>\n<p>In un prossimo tutorial vedremo come cambiare gli httpHeaders per impostare lo scaricamento automatico di files e immagini.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Supponiamo che abbiate creato un&#8217;applicazione per ritoccare le immagini scattate. Inviarle per email non vi soddisfa e&#8230;<\/p>\n","protected":false},"author":15,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[53,5,4,1,54],"class_list":["post-1065","post","type-post","status-publish","format-standard","hentry","category-tutorial-pratici","tag-immagini","tag-objective-c","tag-programmazione","tag-tutorial-pratici","tag-web-server"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/1065","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/users\/15"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/comments?post=1065"}],"version-history":[{"count":11,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/1065\/revisions"}],"predecessor-version":[{"id":1325,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/1065\/revisions\/1325"}],"wp:attachment":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media?parent=1065"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/categories?post=1065"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/tags?post=1065"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}