Pré-requis:
Avoir complété le tutoriel TIMFlix ou bien le laboratoire ‘Les amis de la science‘, ou bien avoir une maitrise de l’objet UITableView + segue + passage de paramètres entre les scènes d’une app.
Dans le tutoriel TIMFlix ou celui ‘Des Amis de la science‘, nous avons construit une application qui affichait une liste de données à l’intérieur d’un UITableView.
L’inconvénient de cette approche est évident lorsque vient le temps d’y ajouter de nouvelles données.
Dans ce tutoriel, nous verrons comment utiliser une API Web comme source de données à une application Xcode.
Historiquement, il a toujours été un peu complexe et lourd de traiter des données en format JSON sous swift. Nous pouvions nous rabattre sur des classes comme swiftyJSON pour alléger la tâche.
À partir de la version 4, swift propose les protocoles ‘Decodable‘ et ‘Encodable‘ pour le traitement facile des conversions de JSON vers des structures de données natives au langage et vice versa. L’alias ‘Codable’ représente ses deux protocoles
Note: Le protocole ‘Codable‘ n’est disponible qu’à partir de la version 4 de Xcode. Ce laboratoire est aussi disponible, sans le protocole ‘Codable’, pour la version 3 de swift.
Révision du 2017.10.25 – conversion vers Xcode 9.0, swift 4 et utilisation du protocole ‘Codable’.
C’est une pratique courante que d’offrir l’accès à des données d’un SGBD (système de gestion de la base de données) via des URLs web selon la méthode RESTful.
L’avantage de cette approche est qu’il n’est pas nécessaire d’offrir un accès direct au SGBD de l’organisation.
Exemples d’accès direct au SGBD;
Une solution à cet accès direct est d’offrir des scripts de type ‘serveur web’ de traitements et d’accès à la base de données.
Ces scripts, écrits en PHP, ASP, Python ou en node,js, peuvent alors être lancés à partir d’une simple requête HTTP, soit dans un fureteur ou à partir d’une application, en utilisant des fonctions ou des objets tel que curl(), NSArray(URL:) et autres.
Voir la définition de Representational State Transfer.
Suite au traitement des données, le script serveur pourra retourner les données dans un format indépendant du SGBD tel que;
Par exemple, l’URL suivante,
https://uneApi.org/obtenir_liste_stages.php?region=mtl&format=csv,
retourne la liste des lieux de stages de la région de Montréal en format csv:
‘Ubisoft’,2,’Hiv18′
‘Gameloft’,0,’Hiv18′
‘TIM.cie’,7,’Été59′
Pour programmer une API Web d’accès à une base de données il suffit d’avoir accès à un serveur Web (IIS, Apache, …), à un langage script coté serveur (php, ASP, node.JS, …) et à un SGBD (MySQL, MSSQL, Oracle, PostgreSQL, … ).
Dans le cadre d’apprentissages, une solution comme WAMP ou LAMP est idéale.
Voici comment programmer une API Web, d’interrogation d’une table SQL, retournant une liste de pensées du jour:
API.TIM.01 – À partir d’une table, ‘penseesdujours‘:
API.TIM.02 – Et du script PHP suivant
// Requête SQL pour obtenir les enregistrements de la table penseesdujours // Connexion à la BD mysql_connect("localhost", "user", "password") or die(mysql_error()); mysql_select_db("cours_xcode") or die(mysql_error()); // Exécuter un requête SQL $res = mysql_query("SELECT `nom_ajout` , `created_at` , `adresse_ip` , `pensee_texte`, `pensee_auteur`, `pensee_lien_image` FROM penseesdujours") or die(mysql_error()); // Parcourir les éléments du tableau de résultats while($r = mysql_fetch_assoc($res)) { $xx = array_map("utf8_encode", $r); foreach ($xx as $key => $value) { echo "clef = $key, valeur = $value\n"; } // foreach } // while encore un résultat
API.TIM.03 – L’API retournera le résultat texte suivant:
clef = nom_ajout, valeur = Alain
clef = created_at, valeur = 2014-11-01 05:11:43
clef = categorie, valeur = 3
clef = adresse_ip, valeur = 24.200.185.163
clef = pensee_texte, valeur = Il etait une fois un gars …
clef = pensee_auteur, valeur = Moi
clef = pensee_lien_image, valeur = http://www.imagesdoc.com/var/bayard/storage/images/smk/images-doc/images/images-doc-plus/que-vois-tu/photo-mystere-2-image-3/24513202-1-fre-FR/Photo-mystere-2-Image-3.jpg
lien de test
API.TIM.04 – Voici un script PHP qui retourne le résultat en format ‘Apple plist‘:
echo '<?xml version="1.0" encoding="UTF-8"?>'."\n"; echo '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'."\n"; echo '<plist version="1.0">'."\n"; echo "<!-- Liste générée par l'API TIM le ".date('Y-m-d h:m:s')." -->\n"; echo "<!-- (c) 2014-2016 par Alain Boudreault -->\n"; echo "<array>\n"; while($r = mysql_fetch_assoc($res)) { $xx = array_map("utf8_encode", $r); echo "\t<dict>\n"; foreach ($xx as $key => $value) { echo "\t\t<key>".$key."</key>\n\t\t<string>".$value."</string>\n"; } // foreach echo "\t</dict>\n"; } // while echo "</array>\n</plist>";
Note: Plusieurs classes du framework ‘Foundation‘ de Xcode savent travailler directement avec ce type de fichier. Voir la structure d’un fichier ‘plist’ sous Xcode:
API.TIM.05 – Produira le résultat suivant:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <!-- Liste générée par l'API TIM le 2017-10-25 09:11:55 --> <!-- (c) 2014-2017 par Alain Boudreault --> <array> <dict> <key>nom_ajout</key> <string>Alain</string> <key>created_at</key> <string>2014-11-01 06:11:47</string> <key>adresse_ip</key> <string>24.200.185.163</string> <key>pensee_texte</key> <string>On ne reçoit pas la sagesse, il faut la découvrir soi-même, après un trajet que personne ne peut faire pour nous, ne peut nous épargner.</string> <key>pensee_auteur</key> <string>Marcel Proust</string> <key>pensee_lien_image</key> <string>http://upload.wikimedia.org/wikipedia/commons/thumb/7/7e/Marcel_Proust_1900.jpg/220px-Marcel_Proust_1900.jpg</string> </dict> </array> </plist>
lien de test
API.TIM.06 – Un script PHP de mise en format ‘JSON‘
// tableau du résultat final $resultat = array(); $resultat['info'] = array("API_TIM" => "version 2017.10.26", "type_requete" => Input::get('mode')); while($r = mysql_fetch_assoc($res)) { // Encoder les caractères accentués. $tableauAvecAccents[] = array_map("utf8_encode", $r); } // while $resultat['resultat'] = $tableauAvecAccents; // Convertir un tableau en format JSON echo json_encode($resultat);
API.TIM.07 – Produira le résultat suivant:
{ "info":{"API_TIM":"version 2017.10.25","type_requete":"rnd"}, "resultat":[ { "nom_ajout":"admin", "created_at":"2014-11-01 10:11:56", "adresse_ip":"24.200.185.163", "pensee_texte":"La qualit\u00e9 d'un homme se calcule \u00e0 sa d\u00e9mesure ; tentez, essayez, \u00e9chouez m\u00eame, ce sera votre r\u00e9ussite\u0085", "pensee_auteur":"Jacques Brel", "pensee_lien_image":"https:\/\/encrypted-tbn2.gstatic.com\/images?q=tbn:ANd9GcQqWOL6fBMrhIECWoOuY3aEdxrm6biaZTdi5Kp72TC_xG9L11GS" }, ... ] }
lien de test
Exemple php complet:
<?php // ------------------------------------------------------------------- // Fichier: apitim.php // Par: Alain Boudreault // Date: 2016.10.23 // ------------------------------------------------------------------- // Description: Exemple d'un script qui retourne, vers le client Web, // le contenu d'un table SQL dans un // des trois formats suivants: // // texte, plist ou json. // // Note: Cette application a été développée pour les étudiants // et étudiantes du cours // // ProductionMultimédiaSurSupport.tim.cstj.qc.ca // ------------------------------------------------------------------- // M-A-J: A.B. 2017.10.25 - Ajout de commentaires // A.B. 2017.10.25 - Correction des dates // ------------------------------------------------------------------- $servername = "localhost"; $username = "votreAcces"; $password = "votreMotDePasse"; $dbname = "votreBD"; $mode = isset($_GET["mode"]) ? $_GET["mode"] : "all"; $quant = isset($_GET["quant"]) ? $_GET["quant"] : "2"; $format = isset($_GET["format"]) ? $_GET["format"] : "texte"; // Create connection $conn = new mysqli($servername, $username, $password, $dbname); // Check connection if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } $sql = "SELECT `nom_ajout` , `created_at`, `categorie`, `adresse_ip` , `pensee_texte`, `pensee_auteur`, `pensee_lien_image` FROM penseesdujours"; if ($mode == "all") { $sql = "SELECT `nom_ajout` , `created_at`, `categorie`, `adresse_ip` , `pensee_texte`, `pensee_auteur`, `pensee_lien_image` FROM penseesdujours"; } // mode=all if ($mode == "rnd") { $sql = "SELECT `nom_ajout` , `created_at`,`categorie`, `adresse_ip` , `pensee_texte`, `pensee_auteur`, `pensee_lien_image` FROM penseesdujours ORDER BY RAND() LIMIT $quant"; } // mode=rnd if ($mode == "adulte") { $sql = "SELECT * FROM (SELECT `categorie`,`nom_ajout`, `created_at`, `adresse_ip`, `pensee_texte`, " . " `pensee_auteur`, `pensee_lien_image` FROM penseesdujours where categorie = 3) as tmp ORDER BY RAND() LIMIT $quant"; echo $sql . "\n\n"; } // mode=adulte $res = $conn->query($sql); // En format plist if ($format == "plist") { echo '<?xml version="1.0" encoding="UTF-8"?>'."\n"; echo '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'."\n"; echo '<plist version="1.0">'."\n"; echo "<!-- Liste générée par l'API TIM le ".date('Y-m-d h:m:s')." -->\n"; echo "<!-- (c) 2014-2017 par Alain Boudreault -->\n"; echo "<array>\n"; while($r = $res->fetch_assoc()) { $xx = array_map("utf8_encode", $r); echo "\t<dict>\n"; foreach ($xx as $key => $value) { echo "\t\t<key>".$key."</key>\n\t\t<string>".$value."</string>\n"; } // foreach echo "\t</dict>\n"; } // while echo "</array>\n</plist>"; } // format = plist // En format texte if ($format == "texte") { // Liste simple while($row = $res->fetch_assoc()) { foreach ($row as $key => $value) { echo "clef = ".$key.", valeur = ".$value."<br>\n"; } // foreach } // while } // if format == texte // En format json if ($format == "json") { // tableau du résultat final $resultat = array(); $resultat['info'] = array("API_TIM" => "version 2017.10.25", "type_requete" => "json"); while($r = $res->fetch_assoc()) { // Encoder les caractères accentués. $tableauAvecAccents[] = array_map("utf8_encode", $r); } // while $resultat['resultat'] = $tableauAvecAccents; // Convertir un tableau en format JSON echo json_encode($resultat, JSON_PRETTY_PRINT); } // if format == json $conn->close(); // echo phpinfo(); ?>
Nous allons maintenant analyser un projet qui utilise l’API.TIM des pensées du jour.
Le but du projet est;
Action 4.1 – Cloner le projet suivant :
$ git clone https://github.com/ve2cuy/conversion-de-donnees-json-par-le-protocole-codable.git
Action 4.2 – Analyser, en suivant les directives de l’enseignant, les fichiers de la branche ‘master’
extension ViewController { //MARK:- Obtenir les données // ======================================================= func obtenirLaCitationDuJour(){ let uneURL = "http://prof-tim.cstj.qc.ca/cours/xcode/sources/apitim.php?mode=rnd&quant=5&format=json" if let _data = NSData(contentsOf: URL(string: uneURL)!) as Data? { // Note: Class.self veut dire "de type Class" let données = try! JSONDecoder().decode(Citation.self, from: _data) print(données) for contenu in données.resultat { // Note: ?? est le 'nil-coalescing operator' let auteur = contenu.pensee_auteur ?? "Erreur: Nom de l'auteur non disponible" let pensée = contenu.pensee_texte ?? "Erreur: Pensée de l'auteur non disponible" print ("\(auteur) a dit:\n\t \(pensée)\n\n") } } // if let } // obtenirLaCitationDuJour() }
// Citation.swift // -------------------------------------------- // Created by Alain on 17-10-25. // Copyright © 2017 Alain. All rights reserved. // import Foundation class Citation: Codable { var info: Dictionary<String, String> var resultat: Array<DetailCitation> } // Citation struct DetailCitation:Codable { var categorie: String var pensee_auteur: String? var pensee_texte: String? } // DetailCitation
Action 4.3 – Tester l’application
Action 4.4 – À réaliser par l’étudiant,
a) Remplacer la déclaration suivante:
var info: Dictionary<String, String>
par la structure ‘Information‘
Note: Il faut créer cette structure en observant les informations retournées par l’API.
b) Ajouter, à la structure ‘DetailCitation’, une propriété – de type optionnel – pour le lien de l’image .
Yahoo offre des nombreuses APIs permettant d’exploiter des données de plusieurs domaines.
Comme par exemple, la météo, le taux de change des devises, la valeur des actions, …
Voici un exemple d’interrogation du service des finances de Yahoo:
Obtenir cotes de la bourse via l’API finance de Yahoo
« &env=store://datatables.org/alltableswithkeys&format=json »
Retourne la structure suivante:
{ "query":{ // Dictionary<String, Any> "count":4, "created":"2016-11-01T15:53:16Z", "lang":"fr-ca", "results": { // Dictionary<String, Any> // *** Tableau des cotes "quote":[ // Array<Dictionary<String, Any>> // **** Premier élément { "symbol":"YHOO", "Ask":"40.89", "AverageDailyVolume":"10498500", "Bid":"40.86", "AskRealtime":null, "BidRealtime":null, "BookValue":"36.39", "Change_PercentChange":"-0.23 - -0.55%", "Change":"-0.23", "Commission":null, "Currency":"USD", "ChangeRealtime":null, "AfterHoursChangeRealtime":null, "DividendShare":null, "LastTradeDate":"10/31/2016", "TradeDate":null, "EarningsShare":"-5.11", "ErrorIndicationreturnedforsymbolchangedinvalid":null, "EPSEstimateCurrentYear":"0.58", "EPSEstimateNextYear":"0.62", "EPSEstimateNextQuarter":"0.14", "DaysLow":null, "DaysHigh":null, "YearLow":"26.15", "YearHigh":"44.92", "HoldingsGainPercent":null, "AnnualizedGain":null, "HoldingsGain":null, "HoldingsGainPercentRealtime":null, "HoldingsGainRealtime":null, "MoreInfo":null, "OrderBookRealtime":null, "MarketCapitalization":"39.78B", "MarketCapRealtime":null, "EBITDA":"90.38M", "ChangeFromYearLow":"15.40", "PercentChangeFromYearLow":"+58.89%", "LastTradeRealtimeWithTime":null, "ChangePercentRealtime":null, "ChangeFromYearHigh":"-3.37", "PercebtChangeFromYearHigh":"-7.50%", "LastTradeWithTime":"4:00pm - <b>41.55</b>", "LastTradePriceOnly":"41.55", "HighLimit":null, "LowLimit":null, "DaysRange":null, "DaysRangeRealtime":null, "FiftydayMovingAverage":"42.83", "TwoHundreddayMovingAverage":"39.65", "ChangeFromTwoHundreddayMovingAverage":"1.90", "PercentChangeFromTwoHundreddayMovingAverage":"+4.78%", "ChangeFromFiftydayMovingAverage":"-1.28", "PercentChangeFromFiftydayMovingAverage":"-2.98%", "Name":"Yahoo! Inc.", "Notes":null, "Open":null, "PreviousClose":"41.78", "PricePaid":null, "ChangeinPercent":"-0.55%", "PriceSales":"8.04", "PriceBook":"1.15", "ExDividendDate":null, "PERatio":null, "DividendPayDate":null, "PERatioRealtime":null, "PEGRatio":"-124.19", "PriceEPSEstimateCurrentYear":"71.64", "PriceEPSEstimateNextYear":"67.02", "Symbol":"YHOO", "SharesOwned":null, "ShortRatio":"4.25", "LastTradeTime":"4:00pm", "TickerTrend":null, "OneyrTargetPrice":"45.14", "Volume":"10108", "HoldingsValue":null, "HoldingsValueRealtime":null, "YearRange":"26.15 - 44.92", "DaysValueChange":null, "DaysValueChangeRealtime":null, "StockExchange":"NMS", "DividendYield":null, "PercentChange":"-0.55%"}, // *** Deuxième élément {"symbol":"AAPL","Ask":"113.60", ... } ] // **** Fin du tableau des cotes } // results } // query }
Voici comment obtenir et traiter ces données:
// ======================================================= func obtenirDonnéesDeMesActions(){ // Exemple d'utilisation de l'API finance Yahoo: // http://query.yahooapis.com/v1/public/yql?q=select * from yahoo.finance.quotes where symbol in ('MSFT','YHOO','FB','INTC','HPQ','AAPL','AMD','COKE')&env=store://datatables.org/alltableswithkeys&format=json // Il faudra convertir certains caractères en séquence d'échappement WEB // pour rendre l'URL compatible avec la classe URL. // http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20('MSFT','YHOO','FB','INTC','HPQ','AAPL','AMD','COKE')&env=store://datatables.org/alltableswithkeys&format=json // Construire l'URL vers l'API finance de Yahoo et remplacer les caractères invalides. // Liste des car à convertir let caracteresAConvertirEnFormatWeb = CharacterSet(charactersIn: " ").inverted // Former le début de l'URL let uneURL = "http://query.yahooapis.com/v1/public/yql?q=" // Ajouter la requête SQL et remplacer les ' ' par %20 + "select * from yahoo.finance.quotes where symbol in ('MSFT','YHOO','FB','INTC','HPQ','AAPL','AMD','COKE')".addingPercentEncoding(withAllowedCharacters: caracteresAConvertirEnFormatWeb)! // Ajouter la fin de l'URL + "&env=store://datatables.org/alltableswithkeys&format=json" //MARK:- Exécuter la commande seulement en mode DEBUG #if DEBUG print(uneURL) #endif if let _data = NSData(contentsOf: URL(string: uneURL)!) as Data? { // Note: YahooFinance veut dire "de type YahooFinance" let données = try! JSONDecoder().decode(YahooFinance.self, from: _data) print(données) for contenu in données.query.results.quote { let prix = contenu.Ask ?? "Prix non disponible" print ("\(contenu.Symbol): \(prix)") } } // if let } // obtenirDonnéesDeMesActions
Action 5.1 – Enlever le commentaire devant la ligne: ‘// obtenirDonnéesDeMesActions()’ et Tester l’application.
Résultat obtenu:
MSFT: 79.07 YHOO: Prix non disponible FB: 171.10 INTC: 40.90 HPQ: 21.640 AAPL: 157.53 AMD: 12.0800 COKE: 225.5000
L’affichage est réalisé par le code suivant:
// Afficher le symbole ainsi que le prix des actions. for contenu in données.query.results.quote { let prix = contenu.Ask ?? "Prix non disponible" print ("\(contenu.Symbol): \(prix)") }
Action 6.1 – Faire un ‘checkout‘ sur la branche ‘CGDDepart’ du projet précédent.
Action 6.2 – Analyser le code suivant:
override func viewDidLoad() { super.viewDidLoad() obtenirDonnéesDeMesActions() afficherDonnéesFinanceYahoo() } // viewDidLoad()
Action 6.3 – Tester l’application.
============================================ Voici les données du portefeuille d'actions: Début -------------------------------------> MSFT: 84.00 YHOO: Prix non disponible FB: 177.87 INTC: 44.60 HPQ: Prix non disponible AAPL: 162.94 AMD: 11.84 COKE: Prix non disponible Fin <---------------------------------------
Action 6.4 – Retirer le commentaire des lignes suivantes (2 et 8):
// TODO: Retirer le commentaire suivant // DispatchQueue.main.async ( execute: { // Obtenir les données via le Web if let _data = NSData(contentsOf: URL(string: uneURL)!) as Data? { // Note: YahooFinance.self veut dire "de type YahooFinance" self.donnéesFinanceYahoo = try! JSONDecoder().decode(YahooFinance.self, from: _data) } // if let // TODO: Retirer le commentaire suivant // }) // DispatchQueue()
Action 6.5 – Tester l’application.
Analysons le résultat obtenu:
============================================ Voici les données du portefeuille d'actions: Début -------------------------------------> Fin <---------------------------------------
Note: La liste est vide.
Raison: Nous affichons le contenu du tableau avant d’avoir reçu la réponse de l’API.
Précédemment, l’exécution du programme bloquait à la lecture des données à partir d’Internet.
Maintenant, avec ‘ DispatchQueue.main.async ( execute: ‘, la lecture des données est faite en arrière plan et notre programme principal continu les traitements.
obtenirDonnéesDeMesActions() // Envoyé en arrière plan afficherDonnéesFinanceYahoo() // *** N'attend plus après l'instruction précédente.
Avec cette technique, il faut traiter l’affichage des données et l’actualisation des composants MVC à l’intérieur du bloc de code du ‘dispatch’ (inline function, fonction anonyme).
De plus, dans ce bloc, les variables doivent-être précédées du mot clé ‘self‘. Par exemple,
self.donnéesFinanceYahoo = try! JSONDecoder().decode(YahooFinance.self, from: _data) self.unTableView.reloadData() self.nbLectures += 1 self.afficherDonnéesFinanceYahoo()
Action 6.6 – Retirer le commentaire suivant
// Action 6.6 - Retirer le commentaire suivant // self.afficherDonnéesFinanceYahoo()
Action 6.7 – Tester l’application
Action 6.9 – Retire le commentaire des lignes suivantes (3):
func viewDidLoad() { ... // Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(self.obtenirDonnéesDeMesActions), userInfo: nil, repeats: true) }
// Dans DispatchQueue.main.async : // TODO: Action 6.9 - Enlever les commentaires à l'étape du 'timer' // self.nbLectures += 1 // print("\n\n\(NSDate()) - Lecture numéro \(self.nbLectures)")
Action 6.10 – Tester l’application:
2017-10-28 15:56:33 +0000 - Lecture numéro 1 ============================================ Voici les données du portefeuille d'actions: Début -------------------------------------> MSFT: 84.00 YHOO: Prix non disponible FB: 177.87 INTC: 44.60 HPQ: Prix non disponible AAPL: 162.94 AMD: 11.84 COKE: Prix non disponible Fin <--------------------------------------- 2017-10-28 15:56:43 +0000 - Lecture numéro 2 ============================================ Voici les données du portefeuille d'actions: Début -------------------------------------> MSFT: 83.75 YHOO: Prix non disponible FB: 178.50 INTC: 38.67 HPQ: Prix non disponible AAPL: 162.99 AMD: 11.80 COKE: Prix non disponible Fin <---------------------------------------
Note: la version finale est disponible via la branche ‘GCDFinale’
Action 7.1 – Passer à la branche ‘tableView‘ du projet Xcode.
Action 7.2 – Tester l’application
Action 7.3 – Analyser le code du projet
// Le fichier json { "actions" : [ { "symbole" : "MSFT", "quant" : 5 }, { "symbole" : "FB", "quant" : 10 }, { "symbole" : "AAPL", "quant" : 25 }, { "symbole" : "AMD", "quant" : 50 }, { "symbole" : "MOMO" } ] }
Résultat de la console:
============================================ Voici les données du portefeuille d'actions: Début -------------------------------------> MSFT: 5 à 84.00 = 420.0 FB: 10 à 177.87 = 1778.7 AAPL: 25 à 162.94 = 4073.5 AMD: 50 à 11.84 = 592.0 MOMO: 0 à 30.54 = 0.0 La valeur du portefeuille est de 6864.2 $ Fin <---------------------------------------
Note: On charge un fichier json local, de la façon suivante:
if let _data = NSData(contentsOfFile: pathFichierPlist) as Data? { ... }
Indice: Les actions seront à la même position dans le tableau du portefeuille et la tableau des données de Yahoo.
Obtenir la valeur des monnaies en fonction de USD à partir de l’API suivante:
http://finance.yahoo.com/webservice/v1/symbols/allcurrencies/quote?format=json
Action: Écrire une application qui affiche, dans un UITableView, le Code (symbol) des devises ainsi que le prix (price). Actualiser les données à chaque 15 secondes.
Obtenir la température à partir de l’API suivante:
Température de 10 villes
Action: Écrire une application qui affiche, dans un UITableView, le nom de la ville ainsi que la température actuelle. Actualiser les données à chaque 15 secondes.
Astuce: Pour consulter les données json en format structuré, copier le résultat json dans Brackets et afficher avec le plugin ‘Pretty Json’
Résultat final:
Ce projet utilise un librairie externe pour la lecture des images à partir d’une URL;
SDWebImage disponible ici.
La librairie n’est pas incluse avec le projet, par contre, elle y est référée.
Il sera de la responsabilité de l’utilisateur d’ajouter les éléments manquants, requis pour le bon fonctionnement du projet.
Une façon simple est d’utiliser cocoapods
Voici: Une liste de librairies pour Xcode
Voici une autre liste :
https://medium.com/app-coder-io/33-ios-open-source-libraries-that-will-dominate-2017-4762cf3ce449
Voici un carrousel : https://github.com/nicklockwood/iCarousel
Un player video: https://github.com/mobileplayer/mobileplayer-ios
Comment?
1 – vérifier si cocoapods est installée sur votre poste en tapant ‘pod –version‘ dans la fenêtre terminal.
2 – Au besoin, il faudra l’installer:
$ sudo gem install cocoapods
ou par ‘homebrew‘
$ brew install cocoapods
3 – Dans le dossier de l’application, créer un fichier nommé ‘Podfile‘ renseignant les libraires à installer.
par exemple, pour le projet courant: Podfile
platform :ios, '8.0' use_frameworks! target 'MonDuProjet' do pod 'SDWebImage', '~> 4.0' end
Voici un autre exemple
platform :ios, '8.0' use_frameworks! target 'MyApp' do pod 'AFNetworking', '~> 2.6' pod 'ORStackView', '~> 3.0' pod 'SwiftyJSON', '~> 2.3' end
4 – Taper la commande suivante:
$ pod install
Note: La librairie devrait être installée et un espace de travail Xcode ‘xcworkspace’ créé.
5 – Ouvrir le projet en utilisant le fichier ‘nomDeApp.xcworkspace’
$ open App.xcworkspace
Exercice
1 – Créer un nouveau projet Xcode ‘testPod’.
2 – Fermer le projet
3 – Créer un nouveau fichier nommé ‘Podfile’ avec le contenu suivant – et enregistrer dans le dossier de l’application
platform :ios, '8.0' use_frameworks! target 'testPod' do pod 'SDWebImage', '~> 4.0' end
4 – Ouvrir une fenêtre ‘terminal’ dans le dossier de l’application
5 – Exécuter la commande ‘$ pod install’
6 – Ouvrir le ‘workspace’
Action – Cloner le projet à l’adresse suivante: https://github.com/ve2cuy/tim.ze.games.2017
$ git clone https://github.com/ve2cuy/tim.ze.games.2017 --branch versionFinale
Lien du projet sur GitHub: tim.ze.games
Version locale complète: tim.ze.games.v2017.01
Action – Analyse du projet – Suivre les directives en classe
Note: Ce projet présente, entre autre, des animations de propriétés ainsi que la lecture d’une trame sonore.
Voici une liste d’APIs disponibles via le web:
http://www.programmableweb.com/apis/directory
http://query.yahooapis.com/v1/public/yql?q=select%20item%20from%20weather.forecast%20where%20location%3D%22CAXX0301%22&format=json
Ce qui donne la météo pour Montréal (CAXX0301)
Voir: http://developer.yahoo.com/yql/
http://wxdata.weather.com/wxdata/search/search?where=montr
http://query.yahooapis.com/v1/public/yql?q=select%20%2a%20from%20yahoo.finance.quotes%20where%20symbol%20in%20%28%22YHOO%22%2C%22AAPL%22%2C%22GOOG%22%2C%22MSFT%22%29%0A%09%09&env=http%3A%2F%2Fdatatables.org%2Falltables.env&format=json
Ce qui donne les cotes de Yahoo, d’Apple et d’Amazon et de microsoft.
http://finance.yahoo.com/webservice/v1/symbols/allcurrencies/quote?format=json
http://api.tou.tv/v1/toutvapiservice.svc/json/GetPageRepertoire
Ce qui donne le répertoire de tou.tv
Voir: https://code.google.com/p/tou-tv-for-boxee/wiki/Api
Document par Alain Boudreault (c) 2016-2017