Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. iOS SDK
Code

Vytvoření hry s Bonjour - posílání dat

by
Difficulty:IntermediateLength:LongLanguages:

Czech (Čeština) translation by Tereza Foretová (you can also view the original English article)

V předchozím článku jsme položili základy síťové součásti hry tím, že umožňuje uživateli hostit nebo vstoupit do hry. Na konci kurzu jsme úspěšně navázáno připojení mezi dvěma zařízeními pro běh aplikace odděleně. V tomto kurzu bereme se blíže podívat na to, jak můžeme odeslat data z jedné zásuvky do jiného.


Úvod

Jak jsme viděli v předchozím tutoriálu, CocoaAsyncSocket knihovna díky práce s soketů docela snadno. Existuje však víc na příběh než odesílání jednoduchý řetězec z jednoho zařízení do druhého, jak tomu bylo v předchozím tutoriálu. V prvním článku této série jsem napsal, že protokol TCP může spravovat nepřetržitý proud dat ve dvou směrech. Problémem však je, že je doslova nepřetržitý proud data. Protokol TCP se stará o zasílání dat z jednoho konce připojení k druhému, ale je to až přijímač pochopit co je odesílán prostřednictvím tohoto připojení.

Existuje několik řešení tohoto problému. Protokol HTTP, který je založen na protokolu TCP, odešle hlavičku HTTP s každého požadavku a odpovědi. HTTP hlavička obsahuje informace o požadavku nebo odpovědi, které příjemce může použít k smysl příchozí proudu dat. Klíčovou součástí záhlaví HTTP je délka těla. Je-li příjemce ví, délka těla požadavku nebo odpovědi, to tělo extrahovat z příchozí proudu dat.

To je skvělý, ale jak příjemce ví, jak dlouho je hlavička? Každé pole hlavičky HTTP končí CRLF (Carriage Return, Line Feed) a hlavičky protokolu HTTP, sám také končí znak CRLF. To znamená, že v hlavičce každého požadavku HTTP a odpovědi končí dvěma CRLFs. Pokud příjemce přečte příchozí data z čtení proudu, má pouze hledat pro tento vzor (dvě po sobě jdoucí CRLFs) v čtení datového proudu. Tímto způsobem, může příjemce identifikovat a extrahovat hlavičku HTTP požadavek nebo odpověď. S hlavičkou extrahovány, extrahování tělo HTTP požadavku nebo odpovědi je velice jednoduché.

Strategie, kterou budeme používat se liší od jak funguje protokol HTTP. Každý paket dat, který posíláme prostřednictvím připojení předponu záhlaví, který má pevnou délku. V záhlaví není tak složitý jako hlavičky protokolu HTTP. Záhlaví, které budeme používat obsahuje jeden kus informace, délka těla nebo paketu, která přichází po hlavičce. Jinými slovy v záhlaví není nic jiného než číslo, které informuje příjemce o délce těla. Tyto znalosti může přijímač úspěšně extrahovat tělo nebo paket z příchozí proudu dat. I když je to jednoduchý přístup, funguje to překvapivě dobře, jak uvidíte v tomto kurzu.


1. paketů

Je důležité pochopit, že výše uvedené strategie jsou přizpůsobeny protokolu TCP a fungují jen kvůli jak funguje protokol TCP. Protokol TCP dělá to nejlepší, aby se zajistilo, že každý paket dosáhne svého místa určení v pořadí, ve kterém byla odeslána; tedy strategie, které jsem nastínil fungovat velmi dobře.

Krok 1: Vytvoření třídy paketu

I když můžeme poslat libovolný typ dat prostřednictvím připojení TCP, doporučujeme vlastní strukturu pro uložení dat, které bychom chtěli poslat. Lze toho dosáhnout vytvořením paketů vlastní třídy. Výhoda tohoto přístupu se projeví, jakmile začneme používat třídu paketů. Myšlenka je jednoduchá, ale. Třída je Objective-C třída, která obsahuje data; tělo, pokud budete. Zahrnuje také některé další informace o paket, nazývá hlavičky. Hlavní rozdíl u protokolu HTTP je, že nejsou striktně odděleny hlavičky a těla. Paket třída také muset dodržovat NSCoding protokol, což znamená, že instance třídy mohou být kódovány a dekódovat. To je klíčový, pokud chceme odeslat instance třídy paketů prostřednictvím připojení TCP.

Vytvořit novou třídu, Objective-C, aby to podtřída NSObject a pojmenujte ji MTPacket (obrázek 1). Pro hru, kterou budujeme třída paketů může být poměrně jednoduchý. Třída má tři vlastnosti, typ, akce a data. Type vlastnost se používá k identifikaci účelu paketu, a action vlastnost obsahuje záměr paketu. Data vlastnost se používá k uložení aktuální obsah nebo zatížení paketu. To vše bude jasnější po můžeme začít používat třídu paketu v naší hře.

Creating a Game with Bonjour - Sending Data - Creating the Packet Class
Vytvoření třídy paketu

Si prohlédnout rozhraní třídy MTPacket, viz níže. Jak jsem již zmínil, je nezbytné, aby instance třídy může být kódováno i dekódovat v souladu s NSCoding protokolu. Odpovídají NSCoding protokol, pouze musíme zavést dvě (požadované) metody, encodeWithCoder: a initWithCoder:.

Další důležitá věc je, že typ a action vlastnosti jsou typu MTPacketType a MTPacketAction, resp.. Můžete najít definice typu v horní části MTPacket.h. Pokud nejste obeznámeni s typedef a enum, si můžete přečíst více o tom na přetečení zásobníku. To vám usnadní práci s třídou MTPacket hodně.

Třída data vlastnost je typu ID. To znamená, že to může být libovolný objekt, Objective-C. Jediným požadavkem je, že to odpovídá protokolu NSCoding. Většina členů nadace rámce, například NSArray, NSDictionary a NSNumber, v souladu s NSCoding protokolu.

Chcete-li snadno k inicializaci instance třídy MTPacket, vyhlašujeme určené inicializátor, která přebírá data paketu, typ a akční jako argumenty.

Implementace třídy MTPacket by nemělo být příliš obtížné, pokud jste obeznámeni s NSCoding protokolem. Jak jsme viděli dříve, NSCoding protokol definuje dvě metody a obě jsou požadovány. Oni jsou automaticky vyvoláno instance třídy je kódován (encodeWithCoder:) nebo dekódovanou (initWithCoder:). Jinými slovy budete nikdy muset volat tyto metody. Uvidíme, jak to funguje o něco později v tomto článku.

Jak můžete vidět níže, provedení určeném inicializátor, initWithData:type:action: už nemůže být jednodušší. V souboru implementace také vyjde najevo proč jsme deklarovali tři řetězcové konstanty v rozhraní třídy. Je dobrým zvykem používat konstanty pro klíče, které používáte v protokolu NSCoding. Hlavním důvodem není výkon, ale překlepy. Klíče, které předáte při kódování třídy vlastnosti musí být shodné s klíče, které se používají při dekódování instance třídy.

Krok 2: Odesílání dat

Ještě než se vrhneme na další díl skládačky, chci ujistit že MTPacket třída pracuje podle očekávání. Co lepší způsob, jak otestovat než odesláním paketu, jakmile je připojení vytvořeno? Jakmile to vyjde, můžeme začít refaktoring logické sítě tím, že v vyhrazený řadič.

Když je navázáno připojení, instance aplikace hostitelem hry je o tom informována vyvolání socket: didAcceptNewSocket: delegovat metodu protokolu GCDAsyncSocketDelegate. Realizovali jsme tuto metodu v předchozím článku. Podívejte se na jeho realizaci níže osvěžit paměť. Poslední řádek jeho implementace by měl nyní být jasné. Řekneme, že nový socket začít číst data a míjíme značku, celé číslo, jako poslední parametr. Neurčujeme timeout (-1), protože nevíme, kdy můžeme očekávat první paket dorazí.

Co je skutečně zajímá nás, Nicméně, je první argument readDataToLength:withTimeout:tag:. Proč jsme jako první argument předejte sizeof(uint64_t)?

Sizeof funkce vrátí délku v bajtech funkce argument, uint64_t, který je definován v stdint.h (viz níže). Jak jsem vysvětlil dříve, záhlaví, které předchází každý paket, který posíláme má pevnou délku (obr. 2), který je velmi odlišný od hlavičky HTTP požadavku nebo odpovědi. V našem příkladu hlavičku má jen jeden cíl, říkají přijímači velikost paketu, který jej předchází. Jinými slovy, tím, že soket ke čtení příchozí data velikost hlavičky (sizeof(uint64_t)), víme, že jsme si přečetli kompletní hlavičky. Tím, že jakmile je sestavena z příchozích proudu dat, analýze záhlaví, příjemce ví, velikost textu, který následuje v hlavičce.

Creating a Game with Bonjour - Sending Data - Using a Header with a Fixed Length
Pomocí záhlaví s pevnou délkou

Import souboru hlaviček třídy MTPacket a změnit implementaci socket: didAcceptNewSocket: jak je uvedeno níže (MTHostGameViewController.m). Po vyučování nový socket začít monitorovat příchozí proud dat, jsme vytvořit instance třídy MTPacket, naplňte ji s fiktivní údaje a paket předat sendPacket: metoda.

Jak jsem psal dříve, můžeme pouze odeslat binární data prostřednictvím připojení TCP. To znamená, že potřebujeme kódovat instance MTPacket, kterou jsme vytvořili. Protože třída MTPacket odpovídá NSCoding protokolu, to není problém. Podívejte se na sendPacket: způsobem uvedeným níže. Vytvořit instanci NSMutableData a použít jej k inicializaci s klíčem archivátor. Třída NSKeyedArchiver je podtřída NSCoder a má schopnost kódovat objekty vyhovující protokolu NSCoding. S klíčem archivátor máme k dispozici jsme kódovat paket.

Poté vytvořte další NSMutableData instance, která bude datový objekt, který budeme předávat do zásuvky o něco později. Datový objekt, však pouze nevlastní kódovaného instance MTPacket. Musí také obsahovat záhlaví, které předchází kódovaných paketů. Délka kódovaného paketu uložíme do proměnné s názvem headerLength, který je typu uint64_t. Pak jsme připojit hlavičku do vyrovnávací paměti NSMutableData. Jste na místě & symbol před headerLength? AppendBytes:length: metoda očekává vyrovnávací bajtů, nikoliv hodnota headerLength hodnotu. Konečně jsme připojit obsah packetData do vyrovnávací paměti. Vyrovnávací paměť je pak předána writeData:withTimeout:tag:. CocoaAsyncSocket knihovna se stará o natvrdlý písčitou detaily o vyslání dat.

Krok 3: Příjem dat

Pro příjem paketů, které jsme právě odeslali, musíme upravit třídu MTJoinGameViewController. Pamatujte si, že v předchozím článku jsme zavedli socket: didConnectToHost:port: delegát metoda. Tato metoda je vyvolána, když je navázáno připojení, poté, co klient se připojil hru. Podívejte se na její původní implementace níže. Stejně jako jsme to dělali v třídě MTHostGameViewController, řekneme socket začít číst údaje bez vypršení časového limitu.

Když socket přečetl úplné záhlaví předcházejícího paketová data, bude vyvolat socket: didReadData:withTag: delegát metoda. Tag, který je předán je stejný tag v readDataToLength:withTimeout:tag: metoda. Jak můžete vidět níže, realizace socket: didReadData:withTag: je překvapivě jednoduchá. Je-li značka je roven 0, jsme předat proměnné data parseHeader:, která vrátí záhlaví, tedy délku paketu, která následuje v hlavičce. Dnes víme, velikost kódovaných paketů a my tyto informace předat do readDataToLength:withTimeout:tag:. Časový limit je nastaven na 30 (sekundy) a poslední parametr značku, je nastavena na 1.

Než se podíváme na zavádění parseHeader:, pokračujme nejprve našeho průzkumu socket: didReadData:withTag:. Je-li značka je roven 1, víme, že jsme si přečetli kompletní kódovaných paketů. Analyzovat tento paket a opakujte cyklus tím, že socket pozor na hlavičku paketu Další, která dorazí. Je důležité, že jsme se projít -1 pro časový limit (časový limit), jako my nevíme, kdy dorazí další paket.

V parseHeader: metody, funkce memcpy dělá všechny těžké zvedání pro nás. Jsme kopírovat obsah dat v proměnné headerLength typu uint64_t. Pokud nejste obeznámeni s funkci memcpy, si můžete přečíst více o tom zde.

V parseBody:, děláme opak toho, co jsme udělali v sendPacket: metoda v třídě MTHostGameViewController. Vytvořit instanci NSKeyedUnarchiver, předávají data, které jsme četli z čtení proudu a vytvořit instanci MTPacket dekódování dat pomocí rozbalení archívu s klíčem. Dokázat, že vše funguje jak má, zaznamenáváme data paketu, typ a akci v Xcode konzole. Nezapomeňte importovat soubor záhlaví třídy MTPacket.

Spusťte dvě instance aplikace. Hostit hru v jedné instanci a připojit tuto hru na druhé instanci. Měli byste vidět obsah paketu protokolu ke konzole Xcode.


2. refaktoring

Není to výhodné ukládat síťové logiku v MTHostGameViewController a MTJoinGameViewController třídy. To bude jen nám problémy po silnici. Je vhodnější použít MTHostGameViewController a MTJoinGameViewController pro navázání spojení a předání připojení - socket - na řadič, který je odpovědný za řízení a tok hry.

Tím složitější je problém, problém má více řešení a řešení jsou často velice specifické pro problém. Jinými slovy řešení uvedená v tomto článku je schůdné řešení, ale nepovažujeme to za jediné řešení. Pro jeden z mých projektů, Pixelstream, jsem rovněž používá Bonjour a knihovnu CocoaAsyncSocket. Můj přístup pro tento projekt, je však velmi odlišný než ten, který jsem zde prezentují. V Pixelstream musím být schopen odesílat pakety z různých míst v aplikaci a proto se rozhodli využít jednoho objektu, který spravuje připojení. V kombinaci s dokončení bloků a fronty paketů toto řešení funguje velmi dobře pro Pixelstream. V tomto článku se však nastavení proto méně komplikovaný problém je poměrně jednoduchá. Nemám komplikovala věci, pokud není nutné.

Strategie, kterou používáme je jednoduchý. MTHostGameViewController a MTJoinGameViewController třídy mají delegáta, která je oznámena, když je vytvořeno nové připojení. Delegát bude naše MTViewController instance. Ta vytvoří herní zařízení, instance třídy MTGameController, která spravuje připojení a tok hry. Třída MTGameController bude mít na starosti připojení: odesílání a přijímání paketů, stejně jako užívání vhodná opatření na základě obsahu paketů. Kdyby jste pracovat na složitější hru, pak by bylo dobré oddělit síť a herní logiku, ale já nechci komplikovala věci příliš mnoho v tomto příkladu projektu. V této sérii chci se ujistěte se, že chápete, jak různé části do sebe zapadají tak, že můžete přizpůsobit tuto strategii Ať pracujete na projektu.

Krok 1: Vytvoření delegát protokoly

Delegát protokoly, které musíme vytvořit nejsou složité. Každý protokol má dvě metody. I když mám alergii na duplikaci, myslím, že je užitečné vytvořit protokol samostatné delegáta pro každou třídu, MTHostGameViewController a MTJoinGameViewController třídy.

Níže je uveden prohlášení delegáta pro třídu MTHostGameViewController. Pokud jste vytvořili vlastní protokoly před, nenajdete žádná překvapení.

Delegát protokol deklarované v třídě MTJoinGameViewController je téměř totožné. Jediné rozdíly jsou podpisy metody delegáta metody.

Musíme také aktualizovat hostGame: a joinGame: akce ve třídě MTViewController. Jediná změna, kterou uděláme je přiřazení MTViewController instance jako delegát instance MTHostGameViewController a MTJoinGameViewController.

To také znamená, že třída MTViewController musí odpovídat MTHostGameViewControllerDelegate a MTJoinGameViewControllerDelegate delegovat protokoly a Implementujte metody každého protokolu. Můžeme se podívat na implementaci těchto delegovat metody za pár okamžiků. Za prvé chtěl bych i nadále Refaktoring tříd MTHostGameViewController a MTJoinGameViewController.

Krok 2: Refaktoring MTHostGameViewController

První věc, kterou musíme udělat je aktualizovat socket: didAcceptNewSocket: delegovat metodu protokolu delegát GCDAsyncSocket. Metoda se stává mnohem jednodušší, protože práce je přesunut na delegáta. Jsme také vyvolat endBroadcast, pomocnou metodu, která bude implementovat ve chvíli. Když je navázáno připojení, pomineme zobrazení řadič hostitele a hra může začít.

V endBroadcast jsme si jisti, že jsme všechno vyčistit. Je to také vhodný čas pro aktualizaci zrušit: akce, kterou jsme nechali nedokončené v předchozím článku.

V poli zrušit: akce, jsme upozornit na druhé metody delegáta a my také vyvolat endBroadcast, jak jsme dříve.

Před pokračováním naší refaktoringu spree, je vhodné vyčistit věci v zobrazení řadiče dealloc metody, jak je uvedeno níže.

Krok 3: Refaktoring MTJoinGameViewController

Podobně jako jsme dělali v socket: didAcceptNewSocket: metody, musíme aktualizovat socket: didConnectToHost:port: způsob, jak je uvedeno níže. Upozornit, zastavit služby a zavřete zobrazení řadič.

Jsme také aktualizovat Storno: a dealloc metody jako jsme to udělali v třídě MTHostGameViewController.

Ujistěte se, že jsme nic nezlomila, implementujte metody delegáta obou protokolů ve třídě MTViewController, jak je uvedeno níže a spustit dvě instance aplikace otestovat, zda jsme nic nezlomila. Pokud vše půjde dobře, měli byste vidět příslušné zprávy jsou protokolovány v konzoli Xcode a modální zobrazení řadiče by měl automaticky zrušit, když hra je připojen, to znamená, když je navázáno připojení.


3. provádění herního zařízení

Krok 1: Vytvoření herního zařízení třídy

Třída MTViewController nesmí být pověřená vyřizováním připojení a herní rozestavení. Třídy vlastní řadiče, MTGameController bude to vyšetřuje. Jedním z důvodů pro vytvoření samostatného řadiče třídy je, že jakmile hra spustí, nebudeme dělat rozdíl mezi serverem a klientem. Je proto vhodné mít řadič, který je odpovědný za připojení a hry, ale to nelze rozlišit mezi serverem a klientem. Dalším důvodem je, že jedinou zodpovědností tříd MTHostGameViewController a MTJoinGameViewController je vyhledávání hráčů v místní síti a navazování spojení. Neměly by mít žádné jiné povinnosti.

Vytvořit nové podtřídy NSObject a pojmenujte ji MTGameController (obrázek 3). Rozhraní třídy MTGameController je naprosto jasné, jak můžete vidět níže. To se změní, jakmile začneme provádění herní logiku, ale je to pro tuto chvíli. Určený inicializátor přebírá jeden argument, GCDAsyncSocket instanci, která bude řídit.

Creating a Game with Bonjour - Sending Data - Creating the Game Controller Class
Vytvoření třídy herního zařízení

Předtím, než realizujeme i initWithSocket:, musíme vytvořit soukromé vlastnictví Socket. Vytvořit rozšíření třídy, jak je uvedeno níže a deklarovat vlastnost typu GCDAsyncSocket s názvem soketu. Vzal jsem si také dovolil importovat soubor záhlaví třídy MTPacket a definovat TAG_HEAD a TAG_BODY usnadňují práci s tagy v GCDAsyncSocketDelegate delegáta metody. Jistě MTGameController třída musí dodržovat protokol delegát GCDAsyncSocketDelegate aby vše fungovalo.

Implementace initWithSocket: dole a nemělo by být příliš překvapivé. Ukládáme v soukromé vlastnictví, jsme právě vytvořili, odkaz na socket nastavit herní zařízení do zásuvky delegovat, a řekni socket začít číst příchozí data, to znamená, zachytit první záhlaví, které dorazí.

Zbývající část refactoring proces není složitý buď proto, že jsme už udělal většinu práce v MTHostGameViewController a MTJoinGameViewController třídy. Začněme tím, že pohled na implementaci protokolu delegát GCDAsyncSocketDelegate. Provedení nebude lišit od jsme viděli dříve v MTHostGameViewController a MTJoinGameViewController třídy.

Implementace sendPacket:, parseHeader: a parseBody: nejsou ani jinak.

ParseBody: metoda bude hrát důležitou roli v příběhu o něco později, ale je to pro tuto chvíli. Naším cílem je v tomto okamžiku si vše opět pracovat po refactoring proces je dokončen.

Ještě než se vrhneme, je důležité zavést dealloc metodu MTGameController třídy, jak je uvedeno níže. Vždy, když je platný herní zařízení, musí instance propojení zrušit voláním odpojit na instanci GCDAsyncSocket.

Krok 2: Vytvoření delegáta jiného protokolu

Třída MTViewController bude spravovat herní zařízení a komunikovat s ním. MTViewController zobrazí hru a uživatel má možnost pracovat s ním. Instance MTGameController a MTViewController musí komunikovat s navzájem a budeme používat jiný protokol delegáta pro tento účel. Komunikace je asymetrický, že zobrazení řadič ví o herního zařízení, ale o zobrazení řadič neví herního zařízení. Rozšíříme protokol, jak půjdeme, ale pro tuto chvíli zobrazení řadič by měl pouze oznámeno, když dojde ke ztrátě připojení.

MTGameController.h a případně deklarovat delegáta protokolu, jak je uvedeno níže. Kromě toho veřejný majetek je vytvořena pro herní zařízení delegáta.

Můžeme okamžitě dát protokol delegát oznámí delegát herního zařízení v jednom z GCDAsyncSocketDelegate metod, delegát, socketDidDisconnect:withError: abych byl přesný.

Krok 3: Aktualizace MTViewController třídy

Závěrečná část refaktoringu skládačky je uvedení MTGameController použít. Vytvořit vlastní vlastnost ve třídě MTViewController, splňují třídu MTViewController k MTGameControllerDelegate protokolu a importovat soubor záhlaví třídy MTGameController.

V řadič: didHostGameOnSocket: a řadiče: didJoinGameOnSocket:, vzýváme startGameWithSocket: a projít socket na nové připojení.

V startGameWithSocket: pomocná metoda, jsme vytvořit instanci instance třídy MTGameController předáním socket a obchod odkaz herního zařízení v zobrazení controller herní vlastnosti. Zobrazení řadič slouží také jako herní zařízení delegát jak jsme diskutovali dříve.

V controllerDidDisconnect: delegovat metodu protokolu MTGameControllerDelegate vzýváme koncovka pomocnou metodu, v němž jsme vyčistit herní zařízení.

Ujistěte se, že vše funguje, bychom měli vyzkoušet naše nastavení. Pojďme otevřít XIB soubor MTViewController a přidat další tlačítko v horní levé titulovaný odpojit (obr. 4). Uživatel může na toto tlačítko poklepejte, pokud si chce ukončit nebo opustit hru. Ukážeme toto tlačítko pouze v případě, že připojení bylo navázáno. Když je připojení aktivní, můžeme skrýt tlačítka pro hostování a vstoupit do hry. Proveďte potřebné změny v MTViewcontroller.xib (obrázek 4), v MTViewController.h vytvořit odbytiště pro každé tlačítko a připojit vývody v MTViewcontroller.xib.

Konečně, vytvořte akci s názvem odpojit: v MTViewController.m a spojte ji s názvem tlačítko Odpojit.

Creating a Game with Bonjour - Sending Data - Updating the User Interface
Aktualizace uživatelského rozhraní

V setupGameWithSocket: metoda, schováme, hostButton a joinButton, a ukážeme, disconnectButton. V metodě koncovka budeme dělat přesný opak, ujistěte se, že uživatel může hostit nebo vstoupit do hry. Musíme také skrýt disconnectButton v ovladači zobrazení zprávy metody.

Chcete-li otestovat, zda vše stále funguje, Musíme poslat testovací paket, jako jsme to udělali o něco dříve v tomto článku. Deklarovat metodu s názvem testConnection v MTGameController.h a realizovat jej, jak je uvedeno níže.

Zobrazení řadič by měl vyvolat tuto metodu při každém vytvoření nového připojení. Dobrým místem k tomu je v řadiči: didHostGameOnSocket: delegát metoda po inicializaci herního zařízení.

Spusťte aplikaci ještě jednou ověřit, že vše stále funguje po refactoring proces.


4. čištění

Nyní je čas vyčistit MTHostGameViewController a MTJoinGameViewController třídy tím, jak se zbavit jakéhokoli kódu, který již patří v těchto třídách. Pro třídu MTHostGameViewController, to znamená odstranění sendPacket: metoda a pro třídu MTJoinGameViewController, to znamená, že odstranění socket: didReadData:withTag: metoda CocoaAsyncSocketDelegate delegát protokolu, jakož i kód video parseHeader: a parseBody: pomocné metody.


Shrnutí

Lze si představit, že tento článek je trochu omámený nebo zahlceni opustil. Tam bylo hodně přijímat a zpracovávat. Nicméně chci zdůraznit, že složitost tohoto článku byl zapříčiněn zejména struktury samotná aplikace a ne tolik jak práci s Bonjour a knihovna CocoaAsyncSocket. To je často skutečnou výzvou, aby architekt aplikace takovým způsobem minimalizovat závislostí a ponechat aplikaci libové, výkonný a modulární. To je hlavním důvodem, proč jsme refactored naše počáteční implementace logiky sítě.

Nyní máme view řadič, který se stará o zobrazování hry uživatele (MTViewController) a controller (MTGameController), která zpracovává logiku hry a připojení. Jak jsem již zmínil dříve, je možné oddělit připojení a herní logiku vytvořením samostatné třídy pro každý z nich, ale pro tuto jednoduchou aplikaci, která není nezbytné.


Závěr

Jsme udělali značný pokrok s naší herní projekt, ale je zde jedna složka chybí... hra! V další díl této série budeme vytvářet hry a využít nadace, které jsme doposud vytvořili.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.