iOS 4 SDK:sta puuttuvat toiminnot
Olen koodaillut tänä keväänä ja kesänä aika paljon iPad- ja iPhone-sovelluksia, lähinnä erilaisia prototyyppejä. Olen tunnistanut ainakin seuraavat kaksi jatkuvasti toistuvaa "patternia", joihin olisi kiva löytää vakioitu ratkaisu.
NSURLConnection: Jonotettu tiedonsiirto
Useimmat sovellukseni rakentuvat siten, että Core Datalla määritellään tietorakenne eli joukko SQLite-tauluja ja niiden kenttiä. Sitten verkosta haetaan JSON-muotoista tietoa ja tallennetaan se kyseisiin tauluihin.
iOS 4 SDK:n vakiotoiminnallisuus mahdollistaa vain yksittäisen taustalla latautuvan downloadin NSURLRequest- ja NSURLConnection-luokilla. Jokaista siirtoa varten pitää tehdä oma delegate-objekti, joka ymmärtää mitä vastaanotetulla tiedolla tehdään. Lisäksi sen pitää osata käynnistää seuraava tiedonsiirto edellisen päätyttyä.
Olisi paljon kätevämpää, jos voisi määritellä vapaamittaisen jonon ladattavia URLeja ja kullekin sitten yksinkertaisen käsittelylogiikan. Jonoon voisi lennossa heittää lisää tavaraa latautumaan sitä mukaa, kun esimerkiksi aiemmin ladatuista JSON-rakenteista huomataan, että tarvitaan myös niihin liittyviä kuvia tai videoita.
Rajapinta voisi toimia esimerkiksi näin:
// Wish for simpler queued NSURLConnections - (void)startDownloading { self.queue = [DownloadQueue queue] [queue addDataURL:[NSURL URLWithString:@"http://www.google.com"] target:self onComplete:@selector(googleComplete:data:) onError:nil]; } - (void)googleComplete:(DownloadQueue *)queue data:(NSData *)data { // Parse data and load images... [queue addDataURL:[NSURL ...] target:self onComplete:@selector(imageComplete:data:) onError:nil]; } - (void)imageComplete:(DownloadQueue *)queue data:(NSData *)data { // ... }
Core Data: "Hae kaikki" ja "Poista kaikki" -toiminnot
Core Data ei ole mielestäni kovinkaan onnistunut rajapinta. Sen käyttö on työlästä ja monimutkaista. Erityisesti ärsyttää se, että yksittäisen taulun kaikkien rivien poistaminen edellyttää niiden lataamista ensin muistiin ja sitten kunkin poistamista erikseen. Rivien lataaminenkin on aika työlästä, kun NSFetchRequest-koodia pitää kirjoittaa ~10 riviä.
Useimpia käyttötapauksia varten olisi siis kätevää olla yksinkeraisempi rajapinta, jolla voisi hakea tai poistaa taulun kaikki rivit. Rajapinnalle annettaisiin vain taulun nimi (entiteetti), ja mahdollisesti jotain yksinkertaisia järjestys- tai maksimirivimääräehtoja.
Rajapinta voisi toimia esimerkiksi näin:
// Wish for simpler NSFetchRequest NSFetchRequest *req = [NSFetchRequest requestEntities:@"Article" sortBy:@"pubDate" ascend:NO limit:10 offset:0 context:managedObjectContext]; // Wish for simpler "delete all" API [managedObjectContext deleteAllEntities:@"Article"];
4 Comments
NSURLConnectionin asynkroninen rajapinta on kieltämättä kankea. Yksi kokeilemisen arvoinen vaihtoehto on suosiolla käyttää NSURLConnectionin blokkaavia metodeja ja laittaa lataaminen taustasäikeeseen NSOperationQueuen avulla. Pääsäikeeseen voi postata notifikaation NSNotification-luokalla kun HTTP-pyyntö on suoriutunut loppuun.
Ideaa on selitetty tarkemmin Dr. Touchin blogipostauksessa.
Kannattaa kuitenkin pohtia kuinka monta rinnakkaista HTTP-yhteyttä käyttää. Hitaalla 3G-yhteydellä ei välttämättä kannata tehdä kauhean monta samanaikaista HTTP-pyyntöä.
Sqliten käpistelyyn olen käyttänyt fmdb-nimistä palikkaa. Se on toiminut muutamassa projektissa hyvin.
Oletko ilmoittanut näistä puutteista Applelle, ja saavatko kehittäjät sieltä mitään vastausta?
En tunne Applen kehittäjäsuhteiden hoitoa. Mediasuhteiden hoito tuntuu olevan ainakin eurooppalaisille olematonta. Juuri koskaan ei saa mitään vastausta mihinkään tiedusteluun.
Noup, olen vasta koodaillut omaa pientä kirjastoa, jolla olen kokeillut, miten kyseiset asiat voisi parhaiten ratkaista.
Suuttuuko Steve, jos sinne laittaa palautetta puutteista?
You can use Markdown to format your comment:
Separate paragraphs in your text with two newlines