Cum să creezi o aplicaţie simplă pentru iPhone în iOS 5: Partea 1/3

Ray Wenderlich

Acest articol este de asemenea disponibil în: Chineza simplificată, Engleză, Franceză, Japoneză, Spaniolă, Arabică, Ungară, Indoneziană, Coreană, Poloneză

Programarea pentru iPhone este ca o buburuză – uşoară şi doar puţin înfricoşătoare!

Programarea pentru iPhone este ca o buburuză - distractivă şi doar puţin înfricoşătoare!

Actualizare 2/16/12: Complet actualizat pentru iOS 5.

Iphone-ul este o platformă fantastică pentru a dezvolta aplicaţii de către programatori independenţi. Niciodată nu a fost mai simplu să vii cu propria ta idee de aplicaţie unică, să o implementezi şi să o faci să devină disponibilă pentru milioane de potenţiali clienţi!

În ultima vreme am primit o mulţime de întrebari de la oameni pentru care programarea în iOS este ceva complet nou legate de cum să înceapă. Aşa că m-am gândit că ar fi de ajutor dacă aş scrie o serie de tutoriale dedicate începătorilor.
Dar în loc să ne concentrăm în detaliu doar pe un singur aspect, vom face o abordare directă şi vom crea o întreagă aplicaţie funcţională de la zero. La final, te vei fi familiarizat cu multe aspecte ale programării în iOS şi vei fi gata să explorezi mai departe.

Deci care va fi aplicaţia pe care o vom concepe? Ei bine, există o poveste la baza ei…

În una din serile trecute, am văzut o poză a unui gândac de Colorado pentru prima dată şi m-am speriat deoarece era atât de mare şi urât! Apoi am devenit obsedat în a căuta tot felul de poze cu insecte înfricoşătoare pe Internet. Aşa că, pentru a împrăştia distracţia, vom realiza o aplicaţie pentru asta – evaluarea insectelor înfricoşătoare.

Pe măsură ce vom face aplicaţia, vom aborda unele dintre cele mai des utilizate aspecte în programarea iOS:

  • De ce ai nevoie pentru a începe să programezi pentru iPhone
  • Cum să stochezi datele aplicaţiei tale într-un model
  • Cum să utilizezi tabele – inclusiv adăugarea şi ştergerea rândurilor
  • Cum să creezi o interfaţă grafică detaliată pentru un rând
  • Cum să integrezi atât orientarea verticală cât şi cea orizontală
  • Cum să foloseşti controale de navigare
  • Cum să utilizezi un selector de imagini
  • Cum să foloseşti controale des utilizate ca şi control text, buton şi interfaţă grafică de tip imagine
  • Cum să adaugi iconiţe şi imagini implicite
  • Bonus: Cum să gestionezi operaţii de lungă durată

Pare foarte mult de parcurs, dar nu te speria – nu ne temem de nici o insectă!

În prima parte din această serie de trei părţi, vom explora cum să încărcăm modelul nostru cu o listă de insecte şi să le afişăm într-un tabel. (Sari la Partea a 2-a sau Partea a 3-a)

Acest tutorial este pentru dezvoltatorii iOS începători, însă presupune o anumită familiarizare cu Objective-C şi programarea în general. Dacă nu şti deloc Objective-C, îţi recomand să citeşti mai întâi Ghidul limbajului de programare Objective-C scris de Apple.

De ce ai nevoie

În primul rând – pentru a dezvolta aplicaţii pentru iPhone, vei avea nevoie de un Mac. Aproape orice Mac poate fi folosit, atâta timp cât e suficient de puternic pentru a rula ultima versiune a sistemului de operare Mac OS, Lion. Dar dacă doreşti să optezi pentru varianta ieftină, poţi achiziţiona un Mac Mini pentru o sumă relativ mică şi va funcţiona chiar bine ca şi resursă de dezvoltare.

Apoi, va trebui să faci rost de o copie de xCode, mediul integrat de dezvoltare IDE Apple pentru programarea în iOS. Deci dacă nu ai făcut-o deja, înregistrează-te pentru a obţine un cont gratuit la Centrul de dezvoltare iPhone şi descarcă o copie de xCode de la Mac App Store.

Dacă îţi va place, te vei putea înscrie pentru varianta plâtită a programului de dezvoltare pentru iPhone care îţi va permite să distribui aplicaţiile create pe App Store; dacă vrei doar să încerci programarea în iOS, contul gratuit funcţionează foarte bine.

Dacă vei deveni serios interesat de programarea în iOS, vei dori probabil să ai de asemenea şi dispozitive fizice (iPhone/iPhone 4/iPod Touch/iPad). Este adevărat că poţi face multă testare pe simulator, însă există anumite API-uri ce nu funcţionează pe Simulator şi vei avea nevoie de un dispozitiv fizic pentru testarea de performanţă.

Asta este tot – deci dacă nu ai făcut-o deja, descarcă o copie de xCode, configureaz-o şi hai să continuăm!

Salut, tabelule!

Vom începe prin a folosi unul dintre cele mai utilizate controale pe iPhone – tabelul. Probabil că ai văzut deja tabelul folosit în multe aplicaţii.

Iată câteva exemple:

Exemple de utilizare UITableView

Aşadar, primul ecran al aplicaţiei va avea un astfel de control, pentru a afişa o listă de insecte înfricoşătoare!

Hai să începem prin a alege File/New Project în XCode, selectează tipul de aplicaţie iOSApplicationMaster-Detail Application şi dă click pe Next.

Crearea unei aplicaţii cu şablonul de aplicaţie principal detaliat

Pe următoarea pagină, tastează ScaryBugs pentru numele produsului, tastează un şir de caractere unic pentru identificatorul companiei tale (com.yourcompanyname sau com.yourname este cel mai bine), alege iPhone pentru familia de dispozitive şi asigură-te că opţiunile de utilizare de Storyboard şi numărarea automată a referinţelor (ARC) sunt selectate. Dă click pe Next când ai terminat.

Setări de proiect pentru aplicaţia insectelor înfricoşătoare

Alege un loc unde să salvezi proiectul tău şi dă click pe Create. Şi înainte de a face orice altceva, hai să vedem ce avem până acum! Alege din bara de opţiuni situată în partea superioară a ecranului opţiunea iPhone Simulator din lista de opţiuni, apoi dă click pe butonul Run. Dacă totul decurge bine, ar trebui să vezi următoarele în simulatorul tău:

Ecranul principal creat de şablonul principal detaliat

Poţi apăsa pe butonul “+” pentru a crea o nouă înregistrare, iar apoi apasă noul rând pentru a vedea o interfaţă grafică detaliată asociată lui:

 Ecranul detaliat creat de şablonul principal detaliat

Deci după cum vezi, deja avem un proiect funcţional pe care putem să construim mai departe deoarece am ales şablonul Master-Detail Application.

Nu vom intra în detaliile şablonului deoarece acest lucru depăşeşte obiectivele acestui tutorial, însă observă că avem un tabel gol şi o interfaţă grafică detaliată setate pentru noi şi gata pentru a fi utilizate – noi trebuie doar să introducem în el datele!

Deci pentru a face asta, hai să creăm o clasă care monitorizează insectele noastre înfricoşătoare.

Un model de date înfricoşător: Organizare

Observă că există o ierarhie de directoare în secţiunea Project Navigator din Xcode:

Navigatorul de proiect în Xcode

Şablonul e setat cu un grup rădăcină şi un grup de fişiere adiţionale. Aceste grupuri au doar scop organizaţional, deci poţi să le schimbi în orice mod doreşti. În cazul nostru, vom avea un număr semnificativ de fişiere în acest proiect, aşa că hai să organizăm lucrurile puţin.

Mai întai, creează un nou grup pentru a stoca fişierele interfeţei grafice. Pentru a face asta, apasă şi fă click pe noul grup creat, selectează Rename şi numeşte-l “GUI”. Trage fişierele existente din rădăcină în grupul GUI (dar nu şi fişierele adiţionale). Acum ar trebui să arate astfel:

Organizarea arborelui de navigare a proiectului, partea 1

Acum creează un al doilea grup nou şi numeşte-l “Model”, deoarece suntem pe cale să adăugăm acolo o pereche de clase pentru modelul nostru de date.

Arborele tău ierarhic ar trebui acum să arate ca şi următoarele:

Crearea unui grup pentru model

Înainte de a începe, hai să vorbim despre cum vom organiza lucrurile:

  1. ScaryBugData: Conţine numele şi evaluarea insectei.
  2. ScaryBugDoc: Conţine imaginea în mărime completă, imaginea micşorată şi ScaryBugData.

Motivul pentru care setăm astfel lucrurile este că va face lucrurile mai uşoare de făcut în restul tutorialului, unde vom începe să salvăm datele noastre pe disc, vom implementa schimbul de fişiere şi alte aspecte de acest gen.

Un model de date înfricoşător: Implementare

Bine deci hai să o facem! Apasă şi fă click pe grupul Model şi dă click pe “New File…”. Selectează şablonul de clasă iOSCocoa TouchObjective-C şi dă click pe Next.

Crearea unui fişier cu şablonul de clasă Objective-C

Numeşte clasa ScaryBugData, tastează NSObject pentru subclasă şi dă click pe Next.

Crearea unei clase derivate din NSObject în XCode

În ultimul meniu dă click pe Create din nou. Dacă totul a decurs bine, fereastra ta Project Navigator ar trebui să arate acum asemănător cu aceasta:

Organizarea proiectului, partea 3

Bine, e timpul să creăm clasa noastră ScaryBugData. Înlocuieşte conţinutul lui ScaryBugData.h cu următoarele:

#import <Foundation/Foundation.h>
@interface ScaryBugData : NSObject
@property (strong) NSString *title;
@property (assign) float rating;
- (id)initWithTitle:(NSString*)title rating:(float)rating;
@end

Acestea sunt chestiuni destul de simple – pur şi simplu declarăm un obiect cu două proprietăţi – un şir de caractere pentru numele insectei şi un tip real pentru cât de înfricoşător am evaluat-o. Utilizăm două atribute specifice proprietăţilor pentru acestea:

  • strong: Acesta specifică faptul că mediul de rulare trebuie să păstreze în mod automat o referinţă puternică către obiect. Acesta este un mod inedit de a spune că mediul de rulare ARC va păstra obiectul în memorie atâta timp cât va exista o referinţă activă către el şi îl va dealoca atunci când nu mai există referinţe către el. Pentru mai multe informaţii, uită-te peste tutorialul nostru Începe ARC în iOS 5.
  • assign: Acesta înseamnă că proprietatea este setată în mod direct, fără a fi implicată gestiunea memoriei. Acesta este modul de setare pe care il vei folosi de obicei pentru tipuri simple (neobiect) ca şi cel real.

De asemenea, definim şi o metoda de iniţializare pentru clasă, în aşa fel încât putem seta titlul şi calificativul de evaluare atunci când creăm insecta.

Treci la ScaryBugData.m şi înlocuieşte conţinutul său cu următoarele:

#import "ScaryBugData.h"
@implementation ScaryBugData
@synthesize title = _title;
@synthesize rating = _rating;
- (id)initWithTitle:(NSString*)title rating:(float)rating {
    if ((self = [super init])) {
        self.title = title;
        self.rating = rating;
    }
    return self;
}
@end

Din nou, chestiuni extrem de simple aici. Sintetizăm proprietăţile şi creăm metoda de iniţializare pentru a completa variabilele de instanţă cu parametrii de apel. Observă că nu e nevoie de eliberarea explicită a memoriei, deoarece utilizăm ARC.

Bine, asta este tot legat de ScaryBugData. Acum urmează aceiaşi paşi pe care i-ai făcut mai sus pentru a crea o altă subclasă a NSObject, numită de această dată ScaryBugDoc.

Înlocuieşte conţinutul lui ScaryBugDoc.h cu următoarele:

#import <Foundation/Foundation.h>
@class ScaryBugData;
@interface ScaryBugDoc : NSObject
@property (strong) ScaryBugData *data;
@property (strong) UIImage *thumbImage;
@property (strong) UIImage *fullImage;
- (id)initWithTitle:(NSString*)title rating:(float)rating thumbImage:(UIImage *)thumbImage fullImage:(UIImage *)fullImage;
@end

Nimic important de semnalat aici – doar creăm nişte variabile de instanţă/proprietăţi şi o metodă de iniţializare.

Înlocuieşte conţinutul lui ScaryBugDoc.m cu următoarele:

#import "ScaryBugDoc.h"
#import "ScaryBugData.h"
@implementation ScaryBugDoc
@synthesize data = _data;
@synthesize thumbImage = _thumbImage;
@synthesize fullImage = _fullImage;
- (id)initWithTitle:(NSString*)title rating:(float)rating thumbImage:(UIImage *)thumbImage fullImage:(UIImage *)fullImage {   
    if ((self = [super init])) {
        self.data = [[ScaryBugData alloc] initWithTitle:title rating:rating];
        self.thumbImage = thumbImage;
        self.fullImage = fullImage;
    }
    return self;
}
@end

Şi asta este tot – modelul nostru de date este complet! E timpul să creăm nişte date pentru testare şi să le afişăm în tabel.

Un tip diferit de listă de insecte

Mai întâi, hai să setăm tabelul nostru pentru a putea afişa o listă de ScaryBugDocs. Primul lucru pe care trebuie să-l facem este să modificăm tabelul nostru astfel încât să returneze o listă dinamică de rânduri (în loc de un singur rând dat de o valoare fixă setată de şablon).

Pentru a face asta, deschide MainStoryboard.storyboard. Aceasta îţi permite şă vizualizezi aranjarea diferitelor “ecrane” în aplicaţia ta. După cum vezi, aplicaţia este în prezent setată pentru a avea un control de navigare (obiectul ce face uşoară tranziţia între diferite ecrane), controlul rădăcină fiind ecranul “principal”, iar controlul secundar fiind ecranul “detaliu”.

Aranjarea principală din Storyboard

Selectează controlul principal şi în regiunea de selecţie din panoul din stânga, selectează tabelul. În regiunea de inspectare din dreapta, asigură-te că proprietatea Content e setată la valoarea Dynamic Prototypes.

Setarea tabelului pentru a folosi celule prototip dinamice

Aceasta este ceea ce îţi permite să concepi o singură celulă a tabelului în felul în care îţi place în editorul Storyboard şi să creezi cu uşurinţă instanţe ale celulei prin cod. Noi vrem doar o celulă simplă, aşa că hai să ne asigurăm că celula foloseşte stilul de bază.

Selectează celula tabelului din stânga şi în regiunea de inspectare a atributelor asigură-te că proprietatea Style e setată la valoarea Basic. De asemenea, setează proprietatea Identifier la valoarea MyBasicCell.

Setting cell style and reuse identifier

Pentru mai multe informaţii despre crearea celulelor personalizate, consultă tutorialul nostru Începe Storyboards in iOS 5.
Bine, acum că avem tabelul nostru setat corect din punct de vedere vizual, mai trebuie doar să actualizăm codul pentru a încărca tabelul cu o listă de insecte înfricoşătoare.

Vom stoca obiectele noastre de tip ScaryBugDocs într-o structură de date de tip NSMutableArray, clasa de tip colecţie pe care o foloseşti pentru vectori ce trebuie să-şi modifice dimensiunea în mod dinamic.

Adaugă următoarea linie la conţinutul lui MasterViewController.h, între liniile @interface şi @end:

@property (strong) NSMutableArray *bugs;

Aceasta va fi variabila de instanţă/proprietatea pe care o vom folosi pentru a monitoriza lista noastră de insecte.

Acum treci la fişierul MasterViewController.m şi fă următoarele modificări:

// La începutul fişierului
#import "ScaryBugDoc.h"
#import "ScaryBugData.h"
// După @implementation
@synthesize bugs = _bugs;
// La sfârşitul lui viewDidLoad
self.title = @"Scary Bugs";
// Înlocuieşte linia de returnare din shouldAutorotateToInterfaceOrientation cu:
return YES;
// Înlocuieşte linia de returnare din tableView:numberOfRowsInSection cu următoarele:
return _bugs.count;
// Înlocuieşte tableView:cellForRowAtIndexPath cu următoarele
- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView
         dequeueReusableCellWithIdentifier:@"MyBasicCell"];
    ScaryBugDoc *bug = [self.bugs objectAtIndex:indexPath.row];
    cell.textLabel.text = bug.data.title;
    cell.imageView.image = bug.thumbImage;
    return cell;
}

Bine, în sfârşit ceva interesant de discutat!

Mai întâi, observă că setăm o proprietate relativă la noi înşine numită “title” cu valoarea şirului de caractere “Scary Bugs.” “title” este o proprietate specială specifică controalelor de interfeţe grafice. Atunci când un control de navigare afişează un control de interfaţă grafică, textul setat în proprietatea “title” apare în bara de titlu. Deci, setând asta, ar trebui să vedem “Scary Bugs” în partea superioară!

Apoi, observă că returnăm “yes” în shouldAutorotateToInterfaceOrientation, care îi spune sistemului de operare OS că trebuie să fim în stare să integrâm toate orientările – vertical, orizontal şi versiunile întoarse ale fiecăreia dintre ele. Deoarece această clasă este de tipul UITableViewController, asta este tot ce trebuie să facem – interfaţa grafică se va roti automat!

Apoi, atunci când construim un tabel cu rânduri dinamice trebuie să suprascriem metodele numberOfSectionsInTableView şi numberOfRowsInSection pentru a îi spune sistemului de operare OS câte secţiuni/rânduri trebuie să fie afişate în tabel Avem doar o singură secţiune, deci nu trebuie să facem nimic deoarece şablonul este setat deja să returneze o singură secţiune. În ceea ce priveşte rândurile, pur şi simplu returnăm numărul de obiecte din vectorul nostru de insecte.

În final, implementăm metoda tableView:cellForRowAtIndexPath, care este probabil cea mai importantă metodă de implementat atunci când realizezi un tabel. Aici configurezi celula ce va fi afişată pentru un anumit rând. Sistemul de operare OS va apela această metodă o singură dată pentru fiecare rând în parte şi astfel îl poţi configura.

Hai să aruncăm o privire mai detaliată asupra acestei metode, deoarece ea este extrem de importantă:

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView
          dequeueReusableCellWithIdentifier:@"MyBasicCell"];
    ScaryBugDoc *bug = [self.bugs objectAtIndex:indexPath.row];
    cell.textLabel.text = bug.data.title;
    cell.imageView.image = bug.thumbImage;
    return cell;
}

Prima linie apelează o funcţie ajutătoare numită “dequeueReusableCellWithIdentifier” pentru a încerca să returneze o celulă reutilizabilă. De ce este necesar să facă asta?

Ei bine, este vorba despre o importantă optimizare a performanţei. Reţine că tabelele pot conţine un număr foarte mare de rânduri, dar numai un anumit număr dintre ele sunt afişate pe ecran la un moment dat. Deci în loc să creeze o nouă celulă de fiecare dată când un rând nou apare pe ecran, sistemul de operare OS poate îmbunătăţi performanţa prin reutilizarea unei celule ce a fost deja creată, dar a dispărut de pe ecran.

Deci de aceea există apelul către metoda dequeueReusableCellWithIdentifier. Dacă nu există o celulă reutilizabilă disponibilă, pur si simplu creăm o nouă celulă bazată pe celula pe care ai configurat-o în constructorul de interfeţe grafice Interface Builder (îţi aminteşti cum am setat-o ca şi simplă şi i-am dat numele “MyBasicCell”?).

În editorul Storyboard poţi personaliza aranjamentul celulei sau poţi folosi una dintre cele implicite. În cazul nostru, am ales stilul de bază, care adaugă o etichetă şi o imagine pe care o poţi seta.

Dacă eşti curios cum arată diferitele opţiuni standard ale celulelor unui tabel, consultă secţiunea “Stiluri standard pentru celulele unui tabel” în

href="http://developer.apple.com/iphone/library/documentation/userexperience/conceptual/TableView_iPhone/TableViewStyles/TableViewCharacteristics.html#//apple_ref/doc/uid/TP40007451-CH3-SW14">Ghidul de programare al tabelelor.

În final, configurăm celula prin setarea valorilor proprietăţilor textLabel şi imageView (care sunt disponibile cu stilul de bază).

Crezi sau nu, asta este tot ce avem de făcut! Acum trebuie doar să configurăm nişte date de testare pe care tabelul să le afişeze.

Pozele insectelor înfricoşătoare!

Dar bineînţeles că vom avea nevoie de nişte poze cu insecte înfricoşătoare pentru aceasta! Poţi să cauţi pe Internet şi să găseşti câteva, sau descarcă-le pe acestea Pozele insectelor înfricoşătoare! pe care le-am găsit la adresa stock.xchng.

După ce ai descărcat fişierele sau le-ai obţinut pe ale tale personale, trage-le pe toate în rădăcina arborelului tău ierarhic Project Navigator.

Când apare meniul de opţiuni, asigură-te că opţiunea “Copy items into destination group’s folder (if needed)” este bifată şi apoi dă click pe Add.

Adăugarea fişierelor insectelor înfricoşătoare la proiect

Apoi deschide fişierul AppDelegate.m şi fă următoarele modificări:

// La începutul fişierului
#import "MasterViewController.h"
#import "ScaryBugDoc.h"
// La începutul lui application:didFinishLaunchingWithOptions
ScaryBugDoc *bug1 = [[ScaryBugDoc alloc] initWithTitle:@"Potato Bug" rating:4 thumbImage:[UIImage imageNamed:@"potatoBugThumb.jpg"] fullImage:[UIImage imageNamed:@"potatoBug.jpg"]];
ScaryBugDoc *bug2 = [[ScaryBugDoc alloc] initWithTitle:@"House Centipede" rating:3 thumbImage:[UIImage imageNamed:@"centipedeThumb.jpg"] fullImage:[UIImage imageNamed:@"centipede.jpg"]];
ScaryBugDoc *bug3 = [[ScaryBugDoc alloc] initWithTitle:@"Wolf Spider" rating:5 thumbImage:[UIImage imageNamed:@"wolfSpiderThumb.jpg"] fullImage:[UIImage imageNamed:@"wolfSpider.jpg"]];
ScaryBugDoc *bug4 = [[ScaryBugDoc alloc] initWithTitle:@"Lady Bug" rating:1 thumbImage:[UIImage imageNamed:@"ladybugThumb.jpg"] fullImage:[UIImage imageNamed:@"ladybug.jpg"]];
NSMutableArray *bugs = [NSMutableArray arrayWithObjects:bug1, bug2, bug3, bug4, nil];
UINavigationController * navController = (UINavigationController *) self.window.rootViewController;
MasterViewController * masterController = [navController.viewControllers objectAtIndex:0];
masterController.bugs = bugs;

Aici pur şi simplu folosim metoda de iniţializare a clasei ScaryBugDoc pentru a crea patru insecte pentru testare, completând titlul, calificativul de evaluare şi imaginea pentru fiecare. Le adăugăm pe toate la o structură de tip NSMutableArray şi configurăm tabelul nostru.

Dacă tot vorbim despre asta, putem să obţinem o referinţă către controlul de interfaţă grafică rădăcină deoarece ştim că este primul control de interfaţă grafică din stiva controlului de navigare. Există şi alte moduri prin care puteam de asemenea obţine o referinţă, dar aceasta este o soluţie simplă.

Şi asta este tot! Compilează şi rulează aplicaţia ta şi dacă totul funcţionează bine, ar trebui să vezi o listă de insecte (aproape toate) înfricoşătoare în tabelul tău!

Tabelul insectelor înfricoşătoare

Unde să mergi de aici?

Iată un proiect model ce conţine întreg codul sursă pe care l-am dezvoltat până acum în acest tutorial.

Te rog să mă informezi dacă orice am discutat mai sus este confuz sau dacă ţi-ar place să tratez oricare aspect mai detaliat.
Vom continua această serie de tutoriale, cu crearea unei interfeţe grafice detaliate a insectelor pentru a le putea edita şi evalua!

Ray Wenderlich

Ray is an indie software developer currently focusing on iPhone and iPad development, and the administrator of this site. He’s the founder of a small iPhone development studio called Razeware, and is passionate both about making apps and teaching others the techniques to make them.

When Ray’s not programming, he’s probably playing video games, role playing games, or board games.

Comentariile utilizatorului

0 Comment

Other Items of Interest

Buletinul de ştiri lunar online al lui Ray

Înregistrează-te pentru a primi un buletin de știri lunar cu siteurile mele de dezvoltare preferate și primești un tutorial amplu gratuit ca și bonus!

Fă reclamă cu noi!

Hang Out With Us!

Every month, we have a free live Tech Talk - come hang out with us!


Coming up in May: Procedural Level Generation in Games with Kim Pedersen.

Sign Up - May

Coming up in June: WWDC Keynote - Podcasters React! with the podcasting team.

Sign Up - June

Vote For Our Next Book!

Help us choose the topic for our next book we write! (Choose up to three topics.)

    Loading ... Loading ...

Cărțile noastre

Echipa noastră

Echipa de tutoriale

  • Kyle Richter
  • Dani Arnaout
  • Julian Meyer

... 55 în totalitate!

Echipa editorială

... 22 în totalitate!

Code Team

  • Orta Therox

... 1 în totalitate!

Echipa de traducători

  • Heejun Han
  • Victor Grushevskiy

... 38 în totalitate!

Experți în materie de subiecte

... 4 în totalitate!