Softshake 2013 Apiness SA l'envers du décor

Download Softshake 2013 Apiness SA l'envers du décor

Post on 06-Apr-2017

178 views

Category:

Technology

0 download

Embed Size (px)

TRANSCRIPT

  • Lenvers du dcor24 Octobre 2013

  • Apiness SA

    Laurent Kohler & Nicolas Marfurt

    www.apiness-software.ch

    http://www.apiness-software.chhttp://www.apiness-software.ch

  • Le dcor

  • Services Web

    Echange de donnes

  • Services Web

    Echange de donnes

  • Back-end Web

    Gestion du contenu de lapplication(data model business) Multilingue Multi-utilisateurs Gestion des autorisations

    - par fonction- sur la donne

    Web services de synchronisation

  • Application mobile

    Outil daffichage de donnes

    Fonctionne galement hors ligne

    Structure et design simple

    Synchronisation des donnes- robuste- performante

  • Effort de dveloppement

  • Effort de dveloppement

  • Effort de dveloppement

  • Un client demande une petite application mobile multi-plateformes

    aspect visuel et fonctionnel

    mais aussi dveloppement important :- back-end Web- synchronisation

    Situation typique

  • Lenvers du dcor

  • Web server & Web services

    Persistance donnes ct client mobile

    - Modle objet (Core Data)

    - Modle relationnel (SQLite natif)

    - Autre (XML, JSON, plist...)

    Options

  • Contexte: back-end

    LAMP

    CMS Joomla

    Donnes structures, modle relationnel (MySQL)

    Projet dexemple Audio Guide

  • Modle relationnelCorrespond au type de modle du back-end

    SQLite (sans Core Data)Optimisation du SQL et des paramtres db

    Contexte: application iOSProjet dexemple Audio Guide

  • Modle de donnes

    Modle server != modle appExemples :

    Serveur - Donnes multilingue - Gestion des autorisations

    Application - Une langue slectionne

  • Au travail !

  • iOS - Cocoa

  • Options daccs SQLite

  • Options daccs SQLite

    Utilisation de Core Data

  • Options daccs SQLite

    Utilisation de Core Data

  • Options daccs SQLite

    Utilisation de Core Data Utilisation directe de la libraire SQLite native

    Fonctions C

  • Options daccs SQLite

    Utilisation de Core Data Utilisation directe de la libraire SQLite native

    Fonctions C

    Wrapper ou framework existant FMDB

  • Options daccs SQLite

    Utilisation de Core Data Utilisation directe de la libraire SQLite native

    Fonctions C

    Wrapper maison

    Wrapper ou framework existant FMDB

  • - raison historique, plaisir dexplorer- mainmise sur le code (tests)

    Options daccs SQLite

    Utilisation de Core Data Utilisation directe de la libraire SQLite native

    Fonctions C

    Wrapper maison

    Wrapper ou framework existant FMDB

  • Architecture

    APSSQLite

    SQLite

    APSSQLiteDatabase APSSQLiteResultSetAPSSQLiteRequest

    APSSQLiteDatabaseController APSSQLiteObjectPersistingprotocolAPSSQLiteObjectCoding

    protocol

  • Architecture

    APSSQLite

    SQLite

    APSSQLiteDatabase APSSQLiteResultSetAPSSQLiteRequest

    APSSQLiteDatabaseController APSSQLiteObjectPersistingprotocolAPSSQLiteObjectCoding

    protocol

  • Architecture

    APSSQLite

    SQLite

    APSSQLiteDatabase APSSQLiteResultSetAPSSQLiteRequest

    APSSQLiteDatabaseController APSSQLiteObjectPersistingprotocolAPSSQLiteObjectCoding

    protocol

    MyProjectDatabaseController

  • Architecture

    APSSQLite

    SQLite

    APSSQLiteDatabase APSSQLiteResultSetAPSSQLiteRequest

    APSSQLiteDatabaseController APSSQLiteObjectPersistingprotocolAPSSQLiteObjectCoding

    protocol

    MyProjectDatabaseController

  • Architecture

    APSSQLite

    SQLite

    APSSQLiteDatabase APSSQLiteResultSetAPSSQLiteRequest

    APSSQLiteDatabaseController APSSQLiteObjectPersistingprotocolAPSSQLiteObjectCoding

    protocol

    MyClassResultSetMyProjectDatabaseController

  • Architecture

    APSSQLite

    SQLite

    APSSQLiteDatabase APSSQLiteResultSetAPSSQLiteRequest

    APSSQLiteDatabaseController APSSQLiteObjectPersistingprotocolAPSSQLiteObjectCoding

    protocol

    MyProjectDatabaseController MyClassResultSet

  • Architecture

    APSSQLite

    SQLite

    APSSQLiteDatabase APSSQLiteResultSetAPSSQLiteRequest

    APSSQLiteDatabaseController APSSQLiteObjectPersistingprotocolAPSSQLiteObjectCoding

    protocol

    MyProjectDatabaseController MyClassMyClassResultSet

  • Intgration

    Contrleur Modle

    MyViewController

    MyClassResultSet

    MyClass

    APSSQLite

    MyP

    roje

    ctDa

    taba

    seC

    ontro

    ller

  • Demo

  • Appel SQLite

    - (BOOL)executeCUDRequest:(APSSQLiteRequest *)request error:(NSError *__autoreleasing *)error {! BOOL success = YES;

    ! sqlite3_stmt *statement; int rc = sqlite3_prepare(self.db, [request.query UTF8String], -1, &statement, NULL); ! if(rc == SQLITE_OK) { rc = sqlite3_step(statement); ! ! if(rc != SQLITE_DONE) { *error = [[self class] errorWithCode:rc message:[NSString stringWithUTF8String:sqlite3_errmsg(self.db)]];! ! ! success = NO;! ! }! ! sqlite3_finalize(statement);! } else { *error = [[self class] errorWithCode:rc message:[NSString stringWithUTF8String:sqlite3_errmsg(self.db)]];! ! success = NO;! } ! return success;}

    APSSQLiteDatabase

  • Appel SQLite

    - (BOOL)executeCUDRequest:(APSSQLiteRequest *)request error:(NSError *__autoreleasing *)error {! BOOL success = YES;

    ! sqlite3_stmt *statement; int rc = sqlite3_prepare(self.db, [request.query UTF8String], -1, &statement, NULL); ! if(rc == SQLITE_OK) { rc = sqlite3_step(statement); ! ! if(rc != SQLITE_DONE) { *error = [[self class] errorWithCode:rc message:[NSString stringWithUTF8String:sqlite3_errmsg(self.db)]];! ! ! success = NO;! ! }! ! sqlite3_finalize(statement);! } else { *error = [[self class] errorWithCode:rc message:[NSString stringWithUTF8String:sqlite3_errmsg(self.db)]];! ! success = NO;! } ! return success;}

    APSSQLiteDatabase

    - (BOOL)executeCUDRequest:(APSSQLiteRequest *)request error:(NSError *__autoreleasing *)error {! BOOL success = YES;

    ! sqlite3_stmt *statement; int rc = sqlite3_prepare(self.db, [request.query UTF8String], -1, &statement, NULL); ! if(rc == SQLITE_OK) { rc = sqlite3_step(statement); ! ! if(rc != SQLITE_DONE) { *error = [[self class] errorWithCode:rc message:[NSString stringWithUTF8String:sqlite3_errmsg(self.db)]];! ! ! success = NO;! ! }! ! sqlite3_finalize(statement);! } else { *error = [[self class] errorWithCode:rc message:[NSString stringWithUTF8String:sqlite3_errmsg(self.db)]];! ! success = NO;! } ! return success;}

  • Excution dune requte

    + (TopicResultSet *)fetchAll { __block TopicResultSet *resultSet = nil; [[GuideDatabaseController sharedDatabaseController] performBlockAndWait:^(APSSQLiteDatabase *database) { NSString *query = @"SELECT * FROM audio_topic t WHERE t.isPublished = 1 ORDER BY t.sequence"; APSSQLiteRequest *request = [APSSQLiteRequest requestWithQuery:query]; request.resultClass = [TopicResultSet class]; NSError *error = nil; resultSet = [database executeFetchRequest:request error:&error]; // Handle error... }]; return resultSet;}

    TopicResultSet : APSSQLiteResultSet

  • Excution dune requte

    + (TopicResultSet *)fetchAll { __block TopicResultSet *resultSet = nil; [[GuideDatabaseController sharedDatabaseController] performBlockAndWait:^(APSSQLiteDatabase *database) { NSString *query = @"SELECT * FROM audio_topic t WHERE t.isPublished = 1 ORDER BY t.sequence"; APSSQLiteRequest *request = [APSSQLiteRequest requestWithQuery:query]; request.resultClass = [TopicResultSet class]; NSError *error = nil; resultSet = [database executeFetchRequest:request error:&error]; // Handle error... }]; return resultSet;}

    TopicResultSet : APSSQLiteResultSet

    + (TopicResultSet *)fetchAll { __block TopicResultSet *resultSet = nil; [[GuideDatabaseController sharedDatabaseController] performBlockAndWait:^(APSSQLiteDatabase *database) { NSString *query = @"SELECT * FROM audio_topic t WHERE t.isPublished = 1 ORDER BY t.sequence"; APSSQLiteRequest *request = [APSSQLiteRequest requestWithQuery:query]; request.resultClass = [TopicResultSet class]; NSError *error = nil; resultSet = [database executeFetchRequest:request error:&error]; // Handle error... }]; return resultSet;}

  • Affichage des donnes

    - (void)viewDidLoad { [super viewDidLoad]; self.topicResultSet = [TopicResultSet fetchAll];}

    MyViewController : UITableViewController

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.topicResultSet count];}

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { TopicTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:TopicListViewControllerTopicCell]; NSDictionary *topic = self.topicResultSet[indexPath.row]; cell.textLabel.text = topic[TopicColumnTitle]; cell.detailTextLabel.text = topic[TopicColumnDescription]; return cell;}

    @interface TopicListViewController ()

    @property (strong, nonatomic) TopicResultSet *topicResultSet;

    @end

  • Affichage des donnes

    - (void)viewDidLoad { [super viewDidLoad]; self.topicResultSet = [TopicResultS