Archiwum
- Sierpień 2008 (4)
- Lipiec 2008 (5)
- Czerwiec 2008 (3)
- Maj 2008 (1)
- Kwiecień 2008 (2)
- Marzec 2008 (3)
- Luty 2008 (9)
- Styczeń 2008 (2)
- Grudzień 2007 (2)
- Listopad 2007 (3)
- Październik 2007 (6)
- Wrzesień 2007 (8)
- Sierpień 2007 (5)
- Czerwiec 2007 (1)
- Maj 2007 (10)
- Kwiecień 2007 (5)
- Marzec 2007 (26)
- Luty 2007 (21)
- Styczeń 2007 (11)
- Grudzień 2006 (4)
- Listopad 2006 (9)
- Październik 2006 (6)
- Wrzesień 2006 (2)
- Lipiec 2006 (1)
- Czerwiec 2006 (13)
- Maj 2006 (2)
- Kwiecień 2006 (9)
- Marzec 2006 (1)
- Luty 2006 (2)
- Styczeń 2006 (17)
- Listopad 2005 (5)
- Październik 2005 (1)
- Sierpień 2005 (1)
- Lipiec 2005 (17)
- Czerwiec 2005 (2)
- Maj 2005 (4)
- Kwiecień 2005 (4)
- Marzec 2005 (7)
- Luty 2005 (20)
- Styczeń 2005 (24)
- Grudzień 2004 (21)
- Listopad 2004 (25)
- Październik 2004 (22)
- Wrzesień 2004 (38)
- Sierpień 2004 (5)
Kategorie
- Batalie (23)
- Emigracja (50)
- Komercha (4)
- Ogłoszenia (19)
- Ogólne (229)
- Opowiadacze (13)
- Pieprzenie (29)
- Podróże (23)
- Prasówka (6)
- Programowanie (39)
- Cocoa (14)
- iPhone (2)
- Mac OS X (17)
- Obj-C (12)
- Technikalia (21)
Czytam
Bazylek w Money.pl
Tak, opublikowano tam artykuł ze szczątkowym wywiadem ze mną.
Tak, przedstawiłem swoją opinię. Swoją - nie znaczy ogółu.
Ale na miłość Boską! Proszę czytać ze zrozumieniem!
Tak. iPhone 3G, czyli nowy model iPhone nie jest żadną rewelacja! Bo jak ma być, skoro dorzucili do niego rzeczy, które konkurencja ma od dawna?
Nie. iPhone sam w sobie nie jest wynalazkiem na poziomie bomby atomowej. To po prostu garść technologii zebranych do kupy, które fajnie działają. Lubię markę Apple i sam korzystam z ich komputerów (i nie tylko) właśnie z tych powodów - bo są dobrze zrobione.
I na koniec - jestem programistą NA platformę iPhone'a. A nie programistą samego systemu operacyjnego spod marki nagryzionego jabłuszka, jak to ktoś ładnie wykopał... jeno skąd?
Sam mam problem z wystrzeganiem się pierwszych reakcji po przeczytaniu pierwszego zdania. Ale nadal będę nawoływał do tego, żeby mnie nie linczować... przynajmniej jeszcze nie ;)
A z resztą. To w końcu moja opinia. Przedstawiłem ją i podpisałem się pod nią swoim imieniem i nazwiskiem.
A biczowany jestem strasznie anonimowo i często trochę bez sensu.
Uff. Wygadałem się i jest mi lepiej.
(Fr)Agile
Ostatnio coraz częściej zderzam się z ludźmi wierzącymi, że mają doskonałe pojęcie czym jest Agile. Zaglądam nawet na wikipedię i zwyczajnie oczom nie wierzę.
Agile zrobił się modny. Wszyscy chcą go używać i jednocześnie wszyscy doskonale wiedzą czym on jest. Problem w tym, że każdy sądzi podłóg siebie, definiując czym jest Agile po swojemu. Takie budowanie wielkiej teorii z niczego. Znajomy podsumował, że konstruują śmierdzącą kupę, pakują ją w celofan i ziu...
To był może niesmaczny cytat, ale jakże trafny.
Odkąd zacząłem pracę w Wielkiej Brytanii, każda firma, dla której pracowałem chwaliła się tym, że Agile wprowadza do swoich procesów biznesowych. Przywykłem nazywać te mutanty Fragile, bo dokładnie tym są. Wielką, śmierdzącą kupą, robiącą więcej zamieszania niż pożytku.
Ponieważ jednak - tak samo jak inni - mam swoją własną teorię na temat jak to działa, a co gorsze - używałem tego z powodzeniem w dużej firmie, może podzielę się swoimi spostrzeżeniami na ten temat.
Agile NIE JEST procesem tworzenia oprogramowania. Jest jedynie WSPARCIEM istniejącego procesu. Teoria głosi kilka podstawowych zasad:
- Programista nie ma pojęcia w ile jest w stanie wykonać dane zadanie
- Manager kocha się rządzić i nie znosi słuchać, że coś jest trudne albo zajmie więcej czasu, niż on sobie wymyślił
- Zmiany last-minute są zawsze do dupy i zawsze psują smaczek pracy w tym zawodzie
Agile nie robi nic innego jak stara się rozwiązać te trzy podstawowe problemy. Z powodzeniem rozwiązuje dwa z nich. Trzeci traktuje troszkę po macoszemu.
Podstawową jednostką pracy w Agile jest SCRUM Team. Zespół ludzi pracujący nad danym fragmentem, bądź też całością kodu. W takim zespole wyróżnia się dwie nietypowe postaci. SCRUM Master ma za zadanie pilnować, żeby ludzie nie skakali sobie do gardeł. Pilnuje, żeby trzymać się reguł, ale nie posiada decyzyjności jako takiej. Product Owner jest przedstawicielem managementu, który chce wszystko i na wczoraj. Licytuje się z resztą zespołu co i na kiedy może być zrobione.
Podstawową jednostką czasu wykonania grupy zadań jest Sprint. Różne firmy, w zależności od natury projektu, wielkości zespołu itp. definiją sprint jako różne okresy. Ogólnie przyjęty jest miesiąc. Początkujące zespoły powinny jednak skracać go do dwóch tygodni. Czemu - wyjaśnimy sobie zaraz.
Przed rozpoczęciem sprintu, zespół licytuje się z Product Ownerem co ma być wykonane w danej jednostce czasu. Product Owner przedstawia żądania. Zespół funkcjonalności do zaimplementowania. Zespół, z pomocą SCRUM Mastera dzieli podane grupy funkcjonalności (backlog items) na pojedyncze zadania (backlog tasks). Podział powinien być dośc drobny, ale nie ZA drobny. Żeby jasno definiował jak coś będzie wykonywane.
W tak zwanym międzyczasie, Product Owner definiuje priorytety grup (backlog items). Zespół natomiast definiuje czasochłonność, mając na uwadze ile jest do wklepania i na ile trudne/skomplikowane jest to zadanie. Obciąża zadania (backlog tasks) liczbą wykonywalności (story points). Najczęściej używaną sekwencją liczb, są liczby Fibonacciego. Banalniackie zadanie - 1, proste - 2... Później 3,5,8,13... czasem używane jest 21, ale to już BARDZO rzadko.
Kiedy zespół dopiero obywa się z Agile, przyjęło się wybierać najprostrze zadanie z listy (backlog) i obciążać go wartością 2. Każdy kolejny krok przydziału ma referencję do innego prostego zadania. 1nki zdarzają się niezmiernie rzadko. Tak samo jak 21nki... 13 zazwyczaj określane jest jako - szalenie skomplikowane, ale wiemy co robimy. 21 natomiast jako nie mam bladego pojęcia. 21 to taka czerwona lampka, że zadanie powinno zostać podzielone na mniejsze dla jasności i teoretycznie (w praktyce w sumie również) nie powinno mieć miejsca.
Po przydziale punktów (story points) zespół licytuje się z Product Ownerem co wykonają w danym sprincie. Czasem dochodzi nawet do zmian priorytetów. Na początku ludzie mierzą ile dadzą radę zrobić w sprincie "na oko", niestety. Później to procentuje.
Po ustaleniu co zostanie wykonane, pozostajemy z kompletną listą (sprint backlog) definiującą co zostanie zrobione w danym czasie. Ta lista pozostaje niezmienna przez cały okres sprintu. W teorii. W praktyce bywa różnie, ale wtedy SCRUM Master jest naszym obrońcą. Licytuje się co z listy wyjąć, by włożyć coś innego. Zazwyczaj wyciąga się więcej niż wkłada ze względu na specyfikę pracy.
Po zakończeniu sprintu wiemy jedno. Czy się udał. Udał się jedynie wtedy jeśli wykonaliśmy plan w 100%. Jeśli wykonaliśmy 99.9% planu sprint się NIE POWIÓDŁ i należy zrediwować produktywność zespołu. Wszyscy muszą się tłumaczyć. Niepowodzenie powinno być zauważone również wcześniej. Ale o tym zaraz.
Zamknięcie sprintu pozostawia nam również informację za ile punktów udało nam się wykonać zadań w zespole. Ta wartość to wydajność zespołu (team velocity). Ze sprintu na sprint wartość ta będzie coraz stabilniejsza i da podstawy zespołowi, żeby określić ile faktycznie zadań są w stanie wykonać podczas pojedynczego sprintu. Daje to też informacje Product Ownerowi na ile wydajny jest zespół, czy może powinno się go podszkolić/zmienić?
Ostatnim istotnym elementem jest SCRUM daily meating. 15 minut dziennie, kiedy cały zespół spotyka się razem. Każdy członek zespołu jest odpytywany z tego co zrobił poprzedniego dnia, co ma zamiar robić danego dnia i czy stoją mu na przeszkodzie jakieś nieprzewidziane problemy (impediments). Zadaniem SCRUM Mastera jest rozwiązywanie tych trzecich.
Ale SCRUM Meeting to nie tylko sposób na komunikowanie problemów. To dwukierunkowa komunikacja zespół <-> management i, co najważniejsze motywator. Z czasem, jeśli podczas spotkania wszyscy mówią, że zrobili postępy, a jedna osoba nie może się pochwalić żadnymi, sam z siebie będzie robił wszystko, żeby to zmienić. Wymówką od niezrobienia czegoś jest jedynie poważny impediment, którym musi się zająć SCRUM Master.
Agile składa się oczywiście z miliona innych rzeczy, ale kwintesencja działania tego systemu została powyżej rozpisana. Czy działa? Działa znakomicie. Mogę to powiedzieć z całą pewnością, bo wdrażałem ten proces w jednej firmie i z sukcesem używałem przez długi kawałek czasu (dopóki pracy nie zmieniłem :P).
Ludzie dorabiają milion teorii do Agile. Przekombinowują, tłumacząc sobie backlogi jako minimalistyczne kodowanie. Kończy się to tym, że ludzie przepisują z iteracji na iterację cąły kod, bo nie przewidywali kolejnych kroków implementacji. BZDURA!
Jak już napisałem wcześniej - Agile to jedynie wsparcie procesu. Piramida SCRUM Teamów jest oczywista. Na górze architekci z managementem, poniżej Product Ownerzy w postaci architektów itd. To tylko wspomaganie procesów. RUP, planowanie i testowanie definiowane są gdzie indziej. Ludzie konstruują milion dokumentów na temat jak rozwiązane są powyższe problemy. Zupełnie inaczej definiują też zasady działania zespołów.
Szczerze mówiąc, włos mi się jeży na głowie, kiedy czytam te bzdury. Nie znoszę, kiedy ludzie zabierają się za filozofowanie na temat nie mając kompletnie żadnej praktyki w używaniu Agile. Szukają rozwiązań, wynajdując koło na nowo.
Ludzie! Trochę zdrowego rozsądku!
EDIT: Zamiana SCRUMM na SCRUM
Niskopoziomówka
Ostatnio bawię się dość intensywnie w programowanie na iPhone.
Potrzeba nakazała jednak korzystać z bibliotek niższego poziomu niż proste UIKit dostarczane przez Apple. Jest to oczywiście możliwe, ale jednak zupełnie inne niż zabawa w wygodne interface'y Cocoa Touch.
Zacząłem więc zabawę w obudowywanie biblioteki niższego poziomu - Core Graphics. Jest to znacznie trudniejsze niż proste budowanie Applowych aplikacji, ale w końcu co to dla nas, nie? :-)
O tym jak bardzo jest to inne i jak wygodnie się tym posługiwać już niebawem na łamach Apple Blog. Tymczasem już jutro kolejny odcinek o znacznie prostrzych rzeczach, ale o ileż piękniejszych - proste, natywne aplikacje w Cocoa Touch dla iPhone.
Marzenia się spełniają
I tak właśnie w tej chwili siedzę przed swoim nowym, firmowym komputerem. Nie jest to oczywiście nic wyszukanego. Ot - zwykły MacMini z powiększoną ilością pamięci.
Ale jest! A ja mam tylko jedno zadanie - przystosować naszą firmową aplikację do pracy na iPhone.
Firma właśnie wzbogaciła się o jednego, strasznie szczęśliwego programistę... :D
Marzenia się spełniają
Na prawdę się spełniają.
Odkąd pamiętam, zawsze lubiłem programować w zamkniętych systemach. Głównie na urządzenia mobilne. Telefony, PDA. Dlatego wybrałem taką firmę. Praca z tego rodzaju aplikacjami sprawia mi radość. Jest przyjemna. Trzeba zwracać uwagę na wszystkie aspekty. Wydajność, zarządzanie pamięcią. Ciężka praca, ale dająca efekty.
Kiedy widzisz, jak ktoś używa Twojej aplikacji na telefonie, krzyczysz: "O! To ja napisałem!".
Moją drugą pasją są maczki. Kocham te komputery. Lubię na nie programować, choć często mam na to mało czasu. Zawsze więc chciałem pisać NA maczku i NA maczki.
Wczoraj Apple ogłosiło oficjalne SDK do iPhone'a. Innymi słowy opublikowało zestaw narzędzi do pisania oprogramowania na ich telefon, który powoli staje się kultowy. Może nie dla wszystkich, ale na pewno dla mnie.
Stworzyło to dogodną sytuację. Możliwość połączenia obu pasji. Maczków i telefonów.
I stało się.
Dziś zostałem zaproszony na dywanik do szefa. Po krótkiej konsultacji dostałem przykaz wyznaczenia maczka potrzebnego do pracy. Jeszcze dziś po południu na moim firmowym biurku stanie maczek. Od przyszłego tygodnia pracuję nad wersją naszego oprogramowania pracującą na iPhone.
Toż to prawdziwe spełnienie marzeń!
Orgazm normalnie!
Strony internetowe
Kiedy zaczynałem zabawę z komputerami, pierwszą pracę, jaką udało mi się złapać, było robienie stronek internetowych. Już w tamtym czasie traktowano tego rodzaju pracę jako zdeczka upadlającą. Że niby to takie dłubanie w g..., a w sumie to nawet bardzo proste dłubanie.
Kiedy ostatnimi czasy zacząłem się bawić w zrobienie swojej własnej strony domowej (i redesign mojego bloga), zorientowałem się, jak bardzo nie mają racji ci, którzy tak sądzą.
Wielokrotnie wystawiałem znajomych webdeveloperów na próby zadając im kretyńskie (tak mi się zdaje) pytania. Irytowałem się, jak coś, co w moim mniemaniu jest dobrze, nie wyświetla się w przeglądarce jak powinno.
Innymi słowy - szlag mnie trafiał.
Po kilku bogatszych wypowiedziach jednego znajomego na temat tego jak rzeczywiście działa xHTML, czy CSS, zacząłem rozumieć jaki kawał wiedzy kryje się za tym, żeby dobrze i sprawnie budować serwisy internetowe.
To, że się do tego specjalnie nie nadaję to jedno. Ale z drugiej strony, wszyscy webdeveloperzy z prawdziwego zdarzenia (a poznałem ich trochę w ostatnim czasie) mają u mnie spory szacunek.
Wyrazy szacunku, drodzy koledzy. Odwalacie kawał dobrej roboty.
And I really mean it!
Cocoa
Ostatnio - po dyskusji ze znajomym na temat jego statystyk bloga - postanowiłem samemu sprawdzić po jakich słowach kluczowych ludziska wyszukują moje wypociny.
Poza podstawową frazą bazyl blog znalazła się inna.
Programowanie Cocoa
Gugiel wyjawił mi tajemnicę. W Polsce NIE MA materiałów na ten temat poza kilkoma bzdetnymi artykułami na jakiś wiki i kilkoma moimi (do tego z poważnymi błędami) artykułami.
Należałoby to chyba jednak zmienić.
Szukam chętnych :)
Żeby nie było, że się obijam
XCode działa niemal non stop. Oto jak moje biurko teraz wygląda:

Objective-C i prywatne metody
Doskonale zdaję sobie sprawę, że sprzedaję truizmy, ale czasem początkującym programistom tego języka może się to przydać. Bo przecież... jak mieć do cholery prywatne metody w klasie języka Objective-C? Przecież słowa kluczowe @public, @protected czy @private są słowami kluczowymi, których da się użyć tylko w kontekście atrybutu.
A co z metodami?
Z pomocą przychodzi nam pewna zabawka tego języka, czasami określana mianem konkretyzacji. Nawet nie wiem, czy ja nie zmyśliłem tej nazwy, więc nie będę ściemniał. Sprzedam jedynie ideę.
Czasami okazuje nam się, że istnieje klasa, która spełnia prawie wszystkie nasze oczekiwania... poza jednym na ten przykład. Potrzebujemy więc dorzucić do klasy dodatkową metodę, ale nie mamy dostępu do jej źródeł. Z drugiej strony chcemy tę metodę dodać tylko w jednej części naszego kodu, a nie wszędzie. Jak to zrobić?
Załóżmy, że klasa, którą chcemy poszerzyć nazywa się NSSomeClass a metoda, jaką chcemy dorzucić to screwYou;. Wykorzystywać będziemy ją tylko w kontekście jednej jednostki kompilacji (pliku, jakby ktoś nie wiedział) przy implementacji innej klasy.
Zatem w pliku przed implementacją czegokolwiek dorzucamy taki kawałek:
@interface NSSomeClass (AdditionalMethod)
- (void)screwYou;
@end
@implementation NSSomeClass (AdditionalMethod)
- (void)screwYou
{
NSLog(@"Screw You!\n");
}
@end
Jak łatwo zauważyć dorzuca to dodatkową metodę (konkretyzuje klasę pod nazwą AdditionalMethod), a potem to implementuje.
Chyba łatwo zauważyć, że można to także zrobić w całości ze swoją klasą i najzwyczajniej w świecie dorzucić prywatne metody już w jednostce kompilacji, a nie pliku nagłówkowym?
W sumie wychodzi to całkiem fajnie, bo prywatne metody są tak prywatne, że nawet nie figurują w nagłówku :D
Test Driven Development pod Maczkiem
Ostatnio jest niewyobrażalne halo na punkcie programowania dyktowanego testami. Nie powiem, w wielu przypadkach się to przydaje. Na przykład w moim - pisząc frameworka chcę mieć ładne testy regresji i pilnować, żeby nic się przy nowych dodatkach nie schrzandoliło. I niekoniecznie chcę od razu cały kombajn aplikacji do tego, którą chcę pisać później.
Chłopaki z Apple postarali się dostarczyć magiczne coś, co się nazywa OCUnit. Kombajn, którego się tylko karmi klasami do testów i tyle. Wystarczy dodać projekt tego typu, pakować testy i patrzeć jak się ładnie testuje.
Wyczytałem na ten temat mnóstwo dobrego, ale osobiście stwierdzam, że jest to straszliwe badziewie. Ten projekt nie produkuje aplikacji tylko tzw. Bundle. W efekcie znaczy to, że żeby debuggować niewychodzący test trzeba się gimnastykować, czego nie znoszę przepotwornie.
No nic. Pozostaje mi zaimplementowanie własnego środowiska testującego. Zajęło mi to tylko godzinkę, ale efekt jest taki, jaki chciałem.
Na pohybel z tym co wymyślił te durnowate OCUnit!
Cocoa i wątki
Przez dłuższy czas zastanawiałem się, czy nadal używać POSIXowych wątków w swojej bibliotece, czy rzucić się na jakieś ciekawsze zastosowanie oryginalnych wątków Cocoa.
Dokumentacja na stronach Apple jest trochę lakoniczna, a i gugiel nie do końca pomaga. Zdecydowałem się więc rzucić trochę światła na ten banalniacki mechanizm.
Żeby odpalić nowy wątek musimy zrobić dwie podstawowe rzeczy. Mieć klasę która będzie miała metodę tego wątku (czyli takie coś, co będzie się pętlić i robić dziwne rzeczy, które są nam potrzebne) oraz użyć magicznej klasy NSThread.
Powiedzmy więc, że mamy klasę MojaKlasa i w niej metodę metodaWatku: . Nasza metoda powinna nie zwracać nic i przyjmować tylko jeden parametr typu id. Generalnie rzecz biorąc jest to strasznie podobniackie do funkcji puszczanej do pthread'a.
Żeby odpalić nasz nowy wątek wystarczy użyć jednej metody z klasy NSThread (metoda klasy, a nie obiektu, więc nic nie musimy tworzyć. Kod banalniacki podaję tutaj:
MojaKlasa *obiekcik = [[MojaKlasa alloc] init];
[NSThread detachNewThreadSelector: @selector(metodaWatku:) toTarget:obiekcik withObject: nil];
Co to zrobi? A mianowicie odpali w nowym wątku naszą metodę w podanym obiekcie obiekcik przekazując metodzie nil'a. Jeśli chcemy coś jej przekazać to podajemy to w ostatnim parametrze do metody detachNewThreadSelector:toTarget:withObject.
Mówiłem, że banalniackie :)
Jak zabić wątek? Zakończyć naszą metodę, albo wykonać metodę exit na obiekcie wątku (NSThread).
Oczywiście NSThread ma dodatkowo parę innych metod. Zarówno klasy jak i instancji. Pozwala na zidentyfikowanie w jakim wątku się aktualnie znajdujemy (metoda klasy currentThread) ustawianie priorytetu wątku i tym podobne pierdoły. Ale ogólnie rzecz biorąc całość jest przepotwornie prostacka.
Mimo wszystko spodziewałem się po kolegach z Apple trochę bardziej wyszukanych sposobów. Z drugiej strony oni się bardzo cieszą z tych selektorów, mimo że często dziedziczenie po ładnej klasie było by znacznie fajniejsze.
XMPP.Framework - wielki comeback
Ja chyba nigdy nie będę w stanie być słowny.
Tym razem postaram się po raz kolejny. Projekt iTalk'a nadal w powietrzu, czeka nieustannie, aż skończę XMPP.Frameworka do jako takiej sytuacji, żeby można było przynajmniej gadać normalnie.
I chyba w końcu prawie mi się to udało. Wszystko co miałem przepisałem praktycznie od zera. Zamiast swoich rozwiązań XMLowych użyłem NSXMLElement. Ponieważ od Tigera również jest libsasl, jego również tam znajdziecie, zamiast moich wypocin, które mogą być pełne wad. Oczywiście wziąłem do siebie ideę "KISS". Podszedłem do sprawy również na tyle inteligentnie, że najpierw zaprojektowałem co chcę zrobić. Efekt to doxygenowa dokumentacja interfejsów wersji 0.1. I trochę moich prywatnych wypocin jak co zrobić pod spodem.
Przy okazji podszkoliłem już mój Objective-C na tyle, że nauczyłem się pisać metody prywatne (korzystając z ładnego ukrywania rozszerzeń), co też odśmieciło kod.
Pod spodem oczywiście Expat. Jestem zadowolony. Zaczyna działać. A jeśli będzie tak dobrze, jak już wygląda, to niebawem wersja ta wyjdzie i będę mógł dołożyć jakiś interfejs graficzny na szybko :)
Ale nic nie obiecuję. Nie wychodzi mi to najlepiej.
Wkurzyłem się
Tygrysek i dodatkowe pół giga RAMu już do mnie jedzie. Bo w tym tempie i z tak przestarzałymi narzędziami jak XCode w wersji 1.5 (ostatnia wersja wydana na Panterkę) wobec obecnej wersji 2.4.1 to jednak kamień łupany.
Do tego musi się szybciej kompilować, bo za dużo czasu tracę na pierdoły. I dobrze debuggować, bo w 1.5 debuggowanie wielowątkowych aplikacji kuleje koszmarnie.
Jeszcze jakieś 2-3 dni czekania i będzie.
W końcu!
Się dzieje! - czyli wołanie o pomoc
Prace trwają nieprzerwanie i powoli już okienka zaczynają wyglądać. Niebawem (czyli dziś) zaczną być już również funkcjonalne, ale ja nie o tym chciałem.
Potrzebuję ikonek! Pilnie!
Aktualnie podprowadziłem ikonki stanów z psi crystal roster, ale pasuje mi to jak pięść do nosa.
Poratowałby ktoś czymś skromnym, ale i porządnym? Małym, ale zgrabnym i maczkowatym? :)
Będę wdzięczny za każdą pomoc.
A oto jak się prezentuje roster (z tymi beznadziejnymi ikonkami), co by designerzy wiedzieli do czego projektują :P
Technicznym być
Dawno, dawno temu, kiedy strasznie się napaliłem na zostanie "komputerowcem" (czasy podstawówki), nie zdawałem sobie sprawy z czym wiąże się taka droga.
Z urodzenia (genów i tym podobnych) mam umysł raczej humanistyczny, niż analityczny. Powodowało to wiele problemów zarówno w czasach liceum, jak i na studiach, które stały się - z właśnie tego powodu - dla mnie zbyt skomplikowane.
Całe życie wierzyłem, że to właśnie ten brak analityczności jest dla mnie przeszkodą. Że to jest moja pięta achillesowa. Że właśnie z tego powodu nigdy nie będę mógł zostać kimś w braży IT.
Po pierwsze nie okłamuj samego siebie
Miałem (mam) sporo racji w tym rozumowaniu. Pominąłem jednak jeden bardzo istotny element tej całej układanki. Analityczność umysłu rodzi się z dokładności. Dokładności, którą świat komercyjny dziwnie gardzi.Zabawę z komputerami - w sensie komercyjnym - rozpocząłem dość wcześnie. Oczywistym było, że szef / klient zawsze chciał wszystko na wczoraj. Z założenia wszystko miało działać. Niekoniecznie miało być dobrze zrobione. To pierwszy krok do lawiny problemów. Nieczysty kod się mści. Uczą tego na każdej uczelni. Źle sformułowane założenia mszczą się również. Zaczynamy zmieniać coś, co w zamyśle miało być inaczej. Robimy sobie jeszcze większy bałagan zmuszeni presją czasu.
Jest to złe. Ale bardzo często ciężko to zmienić. Póki ludzie nie zmienią swojego podejścia do programistów, czy ogólnie - tworzenia oprogramowania - zmiany są mało możliwe.
Jak już okłamałeś siebie, nie rób tego innym
Cała idea tyczy się to również ludzi z managementu firm programistycznych. Bardzo często starają się wprowadzać nowinki z zakresu zarządzania projektami. Aktualnie na topie jest coś, co określa się nazwą "Agile". Sam proces ma dużo ciekawych elementów, nie jest to jednak nic odkrywczego. Na całe szczęście jest to konstrukcja, która użyta z mózgiem i pomocą ludzi doświadczonych daje bardzo ciekawe rezultaty. Niestety - w większości przypadków ludzie zbytnio do serca biorą sobie formułę "adaptowania procesu do własnych potrzeb", wybierając sobie z całej idei jedynie fragmenty, które powodują jeszcze większy chaos. Doskonałym przykładem jest pojęcie minimalności (nie mylić z minimalizacją). W każdej iteracji powinno się robić kompletne minimum by spełnić wymagania w niej zdefinoiwane. Nikt oczywiście nie bierze pod uwagę następnych kroków, więc bardzo często trzeba przepisywać duże kawałki kodu, bo ktoś nie pomyślał o tym np. miesiąc wcześniej.Zupełna strata czasu.
Jak już wszędzie zawiodłeś nie rób z kłamstw swojego hobby!
Bo to jest rzecz, która najbardziej mnie przeraża. Przeglądając tony różnych projektów Open Source natrafiam na ten sam problem. Ludzie traktują swoją pasję - programowanie - jak kompletną szmatę. I nie jestem tutaj żadnym chlubnym wyjątkiem. Widzę doskonale jak popełniam te same błędy co inni, "skomercjalizowani" koledzy. Wydaję kawałki kodu, które nie spełniają nawet moich własnych wymagań. Pomijam implementację części specyfikacji, bo uznaję je za niepotrzebne. Chełpię się osiągnięciami, które są przecież dziurawe jak sito! Wprowadzam sobie we własny świat złe nawyki z świata komercyjnego, raniąc przy tym siebie nie mniej od innych. Zatracam się w tym biegu po wszystko tracąc na kunszcie, na którym przecież tak bardzo mi zawsze zależy.Wyobraźcie sobie na przykład, że fizyk ma przed sobą wyniki badań z jakiegoś doświadczenia. Było to jednak doświadczenia na innym sprzęcie, więc może on uzyskać lekko odmienne wyniki na swoich przyrządach. Ze względu na brak czasu, pomija on etap powtórzenia eksperymentu i od razu wykonuje eksperyment dla niego potrzebny i wnioskując na otrzymanych dokumentach i własnym doświadczeniu tworzy wyniki.
I jeśli nawet te błędy będą minimalne. Do pominięcia, a badania robił dla takiej elektrowni atomowej - na ten przykład - to nagle robi się wielkie BUM i pół Europy zamienia się w nowe morze ze świecącymi rybami.
A wszystko z braku czasu na dopracowaniu szczegółów.
Warto zwalczać?
Oczywiście, że warto! Nikt mi sianem nie wykręci, że informatyka za takie rzeczy nie odpowiada. Oczywiście, że odpowiada. A sterowanie samolotami? Promami kosmicznymi? Bankami, gdzie leżą pieniądze ludzi? Nie pracujecie nad tym? Ale moglibyście, prawda? I co wtedy? Przez waszą pomyłkę - brak czasu - samolot spada, prom wybucha, ludzie tracą oszczędności całego życia i lądują pod mostem.Apokaliptyczna wizja? Nierealna? Zdziwilibyście się.
Open Source może na tym więcej zyskać niź stracić. Pokazując, że ludzie z pasją, którzy nie pozwalają sobie na tego rodzaju błędy. Że coś co jest darmowe, powstawało znacznie dłużej (limit czasu plus dodatkowa poprawka na tę dokładność), ale jest znacznie bezpieczniejszy!
Jak zwalczać?
Rozmawiać. Podważać opinię ZAWSZE jak myślimy inaczej. Nie ważne czy rozmawiamy z człowiekiem o super doświadczeniu, czy ze zwykłym uczniakiem. Pomysły ma każdy i czasem zmienia sens naszego rozumowania.Z drugiej strony być otwartym na krytykę. Nie budować Flame War z byle przyczyny. Szczególnie, jak ktoś twierdzi, że może pomóc.
Tworząc swoje oprogramowanie zbudować sobie grupę ludzi, którzy zawsze służą radą i zawsze wytkną. Jeśli boisz się krytyki otwartej (jak na przykład ja), nie odkrywaj kodu przed wszystkimi. Najpierw dopracuj go z ludźmi, którym ufasz. Uodpornisz się na błędy i usuniesz te najbardziej trywialne.
I przede wszystkim kochać to, co się robi. W końcu to jest tworzenie. Twórcy nie są nieomylni, ale przynajmniej powinni się starać być dokładni.
STARTTLS i SASL Gotowe!
Jestem zaskoczony rozwojem sytuacji. Po kilku tygodniach wytężonej pracy w końcu udało mi się osiągnąć najważniejsze elementy nowej biblioteki. Negocjacje szyfrowania połączenia TLS jak i logowanie SASL (metodą DIGEST-MD5 i PLAIN) są gotowe!
Pozostaje jedynie posprzątać trochę kod, dodać parę callbacków i można zabrać się za kolejny etap - czyli obsługę zarzeń (message, presence no i oczywiście iq). Na początku będzie to obsługa podstawowa. Jedynie, by odpowiadać na zapytania version i obsłużyć roster. Ale to już coś!
Będzie można do tego dołożyć kilka okienek w Cocoa i będę już na etapie iChata. A to już dużo, szczególnie, że elastyczność rozwiązań daje łatwą możliwość rozbudowy możliwości biblioteki.
Nie mówię jeszcze hop. Prawdziwy test biblioteka przeżyje niebawem, kiedy obsłużywszy co trzeba spróbuję się zalogować na wszystkie serwery, na których mam konta (z gTalk włącznie).
Przepełnia mnie duma i radość.
Dla mnie to już duże osiągnięcie.
Problemy z OpenSSL
Rozwiązawszy już moje potworne problemy z pamięcią (oczywiście byłem debilem :P), zabrałem się za implementację TLS. Ostatniej rzeczy, jaka mi została do zrobienia. Używam biblioteki OpenSSL, ponieważ jest częścią systemu maczkowatego. Natknąłem się jednak na nie lada problemy.
Mało jest pomocniczych przykładów jak tego używać, w szczególności odnośnie TLS. Robię coś takiego:
SSL_library_init();
ssl_context = SSL_CTX_new(TLSv1_client_method());
ssl_ptr = SSL_new(ssl_context);
sock_bio = BIO_new_socket(sock, BIO_NOCLOSE);
if (sock_bio == NULL)
return NO;
SSL_set_bio(ssl_ptr, sock_bio, sock_bio);
if (0 == SSL_connect(ssl_ptr))
return NO;
Niby jak z przykładów. Problem w tym, że wszystko przechodzi gładziutko, ale jakiekolwiek próby użycia SSL_read() lub SSL_write kończy się całkowitą klapą. Rzuca błędem odczytu/zapisu i już.
Co ja do cholery robię źle?
Postępy
Na stronie projektu dodałem sobie zadania, jakie muszę wykonać, żeby zamknąć pierwszy kamień milowy. Masakra. Nawet w przypadku równouprawnienia wszystkich zadań (tj. faktu, że każdy zajmie mi tyle samo czasu i sił) to mam zrobione dopiero 15%.
Ciężka robota przede mną jeszcze.
Eh.
Strumienie w Cocoa
Cocoa ma bardzo wygodną i w sumie czystą implementację strumieni. Korzystamy z metody jednej klasy i już po chwili mamy śliczne strumienie wejściowe i wyjściowe działające gdzieś w tle, a my tylko siorbiemy, tudzież wysyłamy dane. Niestety NSStream jest dość niestabilne. Dlatego sugeruję jednak korzystać z POSIXowych rozwiązań, które zdają się być jednak bardziej użyteczne. Sam nadbudowałem ładną klasę do obsługi takowych. Nie jest to trudne, więc polecam.
Z drugiej strony - mój program wciąż rzuca SIGBUS, a ja, głupek, nie jestem w stanie wciąż zlokalizować dlaczego.
Eh...
DIGEST SASL DONE! Problem prawie rozwiązany
Właśnie. Prawie.
Z kompletnie niezrozumiałych dla mnie przyczyn na reinicjację strumienia, po otrzymaniu encji <success /> dostaję następującą wiadomość:
<?xml version='1.0'?>
Czy ktoś mądry może mi wyjaśnić, czego ta pierdoła ruska w postaci serwera ode mnie chce?
Nie dość, że zaczął cały strumień XML od zera (a nie tylko tag sesji), to przypieprza się do przestrzeni nazw, którą sam sobie narzuca i zmienia w drodze?
<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='823265377' from='bazyl.net' xml:lang='en'>
<stream:error>
<invalid-namespace xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
</stream:error>
</stream:stream>
O co tu, kurwa, chodzi???
Poziom
Przerzucam się na stałe na poziom 1.
Zwyczajnie mam już po prostu dość tych ludzisk i wiecznego "niepasowania".
Cytując naszego kochanego prezydenta: Spieprzaj pan!
XMPP (Postępy i pytanie)
Wczoraj dość niewiele udało mi się wykonać. Głównie przez zmęczenie i brak czasu. Dodałem jedynie rozpoznawanie adresu i portu serwera XMPP na podstawie JID'a (DNS i wpisy SRV). Dziś GSASL. Jutro może TLS. Zobaczymy jak to pierwsze mi pójdzie.
Chwilowo dręczy mnie jednak inne pytanie. Czy ktoś ma postawionego gdzieś jwchata? Strona projektu jest u mnie zablokowana na proxy firmowym, a nudzę się tak przeokrutnie, że przynajmniej posiedziałbym na IMie :P
Za każdą pomoc gorąco dziękuję.
XMPP.Framework
Pracowałem nad tym już wcześniej, publikując Jabbaha, który w jakimś tam stopniu był funkcjonalny. Przeszło mi, bo zapotrzebowanie było.. hm.. żadne? :)
Teraz sprawa ma się zupełnie inaczej. Staram się za wszelką cenę zaimplementować pełen protokół XMPP. Zarówno XMPP Core jak i XMPP IM. Oczywiście będzie też implementacja kolejnych rzeczy. Chwilowo jednak te elementy są dla mnie najważniejsze. Oznacza to na przykład pełne wsparcie dla języków i przestrzeni nazw XMLa. Z autoryzacją opisaną w protokole, czyli SASL. W planach jest obsługa jedynie dwóch sposobów logowania. Oczywiście są to SASL Digest i SASL PLAIN. Założeniem jest również utrzymanie biblioteki w bardzo czystej i wygodnej do wykorzystania formie. Nie będzie to jednak zwykły projekt Open Source. Na pewno jednak będzie można z niego za darmo korzystać.
Cała biblioteka przygotowana jest do projektu, który już powstał i powoli się rozwija. Jest jakby jego częścią, ponieważ na czymś funkcjonalność trzeba testować. Na razie idzie mi silnie pod górkę. Okazuje się bowiem, że tak jak i GSASL nie działa pod Maczkami jak trzeba, tak i obsługa zwykłego, głupiego TLS jest tam troszkę niedopracowana. Nie można dokonać "przerzutu" ze zwykłego połączenia na połączenie TLS. Oznacza to dodatkowy nakład pracy w zaimplementowanie własnej wersji Socketów. BXStream, BXInputStream i BXOutputStream.
Bardzo jednak zależy mi na uniknięciu wynajdowania koła od nowa, więc będę się starał wbudować znane biblioteki obu tych elementów do frameworka i nadbudować nad nimi jedynie interfejs w Objective-C.
Jedno jest pewne. Jestem silnie zdeterminowany, żeby poprowadzić dobrze ten projekt. Nie mam zamiaru odpierdzielać fuszerki. Pewnie dlatego zajmie mi to stanowczo za dużo czasu. Cieszę się bardzo, że są ludzie, którzy wspierają mnie przy tym. Smoku daje z siebie wszystko co tylko może, najbliźsi rozumieją, kiedy chowam się w kącie ze swoim komputerem i klnę cicho pod nosem, kiedy coś po raz setny nie chodzi jak trzeba. Jajcuś zapytany, zawsze stara się odpowiedzieć. Wytykają mi nieumiejętne czytanie specyfikacji protokołu. Ale to dobrze. Bo to musi być solidnie zrobione. Źródła już są na sieci. Nie są jednak publiczne. Mają dostęp do tego jedynie wybrańcy. Więc jeśli ktoś będzie zainteresowany obejrzeniem samego kodu - zapraszam. Dokumentacja korzystania z frameworka zostanie opublikowana bardzo niebawem. Niestety jeszcze przed samym frameworkiem. No ale cóż. Plan już jest od dawna. Tylko doba za krótka, żeby wszystko zrobić dostatecznie szybko.
Wynajduję koło od nowa
Niestety sprawa wygląda tak:
@interface BXSASL : NSObject
{
uint8_t mechanism;
NSString *realm;
NSString *username;
NSString *password;
NSString *nonce;
NSString *cnonce;
NSString *rspauth;
}
- (id)initWithUsername:(NSString *)usr password:(NSString *)pwd andMethod:(NSString *)meth;
- (void)dealloc;
- (BOOL)getAnswer:(NSString *)answer toChallenge:(NSString *)challenge whichIsBase64Encrypted:(BOOL)enc;
- (BOOL)saveRspAuth:(NSString *)theRspAuth whichIsBase64Encrypted:(BOOL)enc;
@end
Tak tak. Poczytałem trochę i wynajduję koło od nowa i implementuję własną obsługę SASL. Na razie zaimplementuję tylko metodę DIGEST-MD5 i (być może) PLAIN. Mam GSASL za wzór. Musi wystarczyć.
Zły jestem. Zawsze pod górkę. No ale takie życie :(
TLS
Mojej radości nie ma granic. Apple się postarał i strumienie (klasa NSStream) ma wsparcie do TLS!!!
Ależ roboty mi to ujmie! Pozostaje jedynie ten nieszczęsny SASL. Niestety GSASL robi mi hopsasy i nie chce się ładnie skompilić. Czeka mnie albo wciąganie całej biblioteki do projektu (Expat już się tego doczekał. A było z tym jazdy co nie miara! Jak można include'ować inne pliki .c wewnątrz innego pliku .c??? I to po 3-4 razy!).
Muszę jeszcze pogrzebać na stronach Apple'a. Może coś się tam dla mnie znajdzie. Mój najlepszy przyjaciel, jakoś ostatnio mało pomocny jest :(
Trzymać dalej kciuki!
SASL
Z racji faktu, że staram się być w pełni zgodny z protokołem XMPP, staram się zaimplementować SASLową implementację autoryzacyjną.
Przyznam się szczerze, że pisanie od zera tego mechanizmu się mi nie widzi. Czy ktoś zna wygodną bibliotekę, z której można skorzystać do tego celu?
Czy GSASL jest dobrym rozwiązaniem?
Każda rada mile widziana.
NSURL robi psikusy a NSStream nie wie o co chodzi
Ponieważ rzeczy podstawowe nadal zapełniają po kolei karty mojego mini-podręcznika, podzielę się drobną
uwagą na temat programowania w Cocoa.
Uważajcie z NSURL. Jeśli podacie mu adres bez podanego protokołu (np bazyl.net zamiast http://bazyl.net na ten przykład) to nie wyrzuci błęda. Ale wywołanie metody pobrania czystego adresu
zwróci NULL. Bardzo nieprzyjemne.
Problem jest tym większy, że jak Wam wpadnie do glacy korzystać z tej klasy do sprawdzania poprawności
adresu przed otworzeniem strumieni (NSStream) to możecie się nieźle zdziwić.
Konstruktor NSStream przejdzie gładziutko. Dostaniecie notyfikacje, że strumienie został otwarte i są gotowe na przyjęcie danych. Dopiero próba napisania czegoś po strumieniu wyjściowym (NSOutputStream) zwróci -1 jako błąd, po czym rzuci zdarzeniem błędu do metody nasłuchującej.
Moim skromnym zdaniem - to trochę głupie.
iCollins
Tak jak już obiecałem, wystawiam paczkę mojego interface'u słownika Collinsa pod Mac OS X.
Osobiście uważam, że implementacja, czyli program AngelaX jest znacznie wygodniejszym rozwiązaniem, to mogę się pochwalić przynajmniej ładnym kolorowaniem składni.
Nie wiem czy będę kontynuował ten projekt. Chwilowo spełnia moje wymagania, ale wszelkie uwagi są oczywiście mile widziane.
Chciałbym, żeby program był ściągany jedynie z tej strony, a nie rozprowadzany pocztą pantoflową. Gdyby jednak ktoś chciał to wystawić gdzieś u siebie, bardzo proszę o uprzedni kontakt ze mną (na mail, JID, czy co tam innego).
Życzę miłego korzystania
Słownik
Podczas pisania (i poprawiania) rozdziałów, nagle zabrakło mi jakiegoś słowa.
Zgłupiałem. Potrzebowałem słownika online, ale słówka akurat tam nie było. Z pomocą przyszedł dopiero współlokator i jego słownik Collinsa.
Niby słownik nie znów tak zajebisty, ale co potrzebowałem to miał.
Wiedząc, że istnieje projekt obsługi baz Collinsa pod linuxem, postanowiłem wziąć bazy tego słownika i korzystać z tego ncurses'owego narzędzia pod maczkiem (w końcu to UNIX).
Szybko mi to zbrzydło. Ponieważ YdpDict ma prostą bibliotekę do obsługi tych plików baz danych, szybko sklepałem swoje własne okienka.
I oto i one:
Niby nic specjalnego, ale sam znajduje słowo (rozpoznaje sam język) i wyświetla ładnie pokolorowane wyniki.
Zastanawiam się właśnie czy to nie spaczkować. W sumie robota żadna, ale może jest chętny?
Pedeefujemy podręcznikowo
Opublikowane dotychczas krótkie notki o programowaniu pod Maczkiem nie są może jeszcze czymś nadzwyczajnym, ale zdążyłem dopisać kilka rozdziałów. Dlaczego ich nie opublikowałem? Bo zacząłem zdawać sobie sprawę, że ominąłem wiele kwestii, które powinny się znaleźć wcześniej.
Podjąłem zatem decyzję, że na modłę Poradników przerzucę się na pisanie PDFów. Będzie to ciągła praca, rozwijany dokument z każdej możliwej strony. Poprawioną wersję z dodatkowymi rozdziałami, wstępniakiem staram się właśnie poskładać z wersji HTMLowej w coś bardziej czytelnego.
Tutaj mam prośbę do czytelników. Czy moglibyście mi poradzić coś do składania PDFów pod maczkiem (używam Pantery na G4)? Najlepiej bezpłatnego. Wiem, że to trudne, ale niestety chwilowo nie stać mnie na wydawanie kasy na programy. Tzn stać mnie, ale chcę to zrobić jak już kupię sobie nowiuśkiego maczka, na którego aktualnie składam :)
Od razu informuję, że nie będę pobierał żadnych opłat za tę "książkę". Wystawię jedynie możliwość płatności PayPal, jeśli ktoś stwierdzi, że warto wrzucić parę groszy za ten wysiłek.
Ów poradnik pojawiłby się szybko i byłby w kółko aktualizowany. O tych aktualizacjiach informowałbym oczywiście na blogu. Komentarze mile widziane.
Obiecane skrinszoty programów też powinny się pojawić niebawem. Bo w sumie jest już co skrinszotować :)
Za pomoc w doborze narzędzi, z góry dziękuję.


