Arkiv för ‘Uncategorized’

Programming the Mobile Web

Detta är bok-recension av en bok om att göra mobila webbsidor. Bara mobiler. Inga laptops eller stora skärmar. Nu håller jag egentligen med de människor som säger att ”det finns ingen mobil webb det finns bara webb”. Så… ja, vi diskuterar mer om det sen. Boken är skriver av en man med det fantastiska namnet Maximiliano Firtman. För mig var han faktiskt helt okänd men efter lite efterforskningar så visade det sig att han faktiskt skrivit två andra böcker: ”jQuery Mobile: Up and Running” och ”Mobile HTML5″. Den här boken är utgiven 2010 av O’Reilly som skrivet en rad böcker om programmering. Bland annat ”Head First”-böckerna och ”JavaScript: The Definitive Guide” som jag faktiskt läser just nu och kanske kommer recensera senare om andan faller på.

Jag läste den här boken av två anledningar. Jag kände att jag behövde lite bättre koll på hur webb fungerar på andra mobiler än dagens Android och iPhone. Den andra anledningen var helt enkelt att boken fanns tillgänglig på kontoret. Ka-tsching. Jag hade faktiskt fått en liten snabbrecension av två medarbetare innan jag började läsa så mina förväntningar var på lagom nivå. Jag förväntade mig en bok om ett helt hav mobiler och alla deras egenheter och det var precis vad jag fick. Det var även det jag tyckte var intressant. En bok full av tabeller med information om vilka features som är kompatibla med vilka telefoner.

Att summera den här boken känns lite halvsvårt. Lite som att summera en telefonbok. Inte för att den är tjock utanför att den är så fakta-späckad. Men jag ska göra ett försök. Boken består av 14 kapitel. Det första kapitlet heter ”The Mobile Jungle” och behandlar myter om mobil webb, vad som räknas som mobil egentligen och de vanligaste mobilmodellerna, märkena och plattformarna. De följande kapitlena går sedan igenom browsing, vilka webbläsare som finns och deras kapacitet, hur man bör lägga upp arkitekturen och sin egen utvecklingsmiljö. Sedan följer ett par kapitel om markup, CSS, JavaScript och något halvluddigt om ”nya” tekniker såsom HTML5, Ajax och RIA. Det skrivs en hel del om hur man ska sniffa runt och känna av vilka mobiler man har att göra med så kallad ”server side detection” och WURFL rekommenderas för ändamålet. Ett kort kapitel om debuggning och testning som i stort sett kan sammanfattas som att det är svårt och superklurigt. Här skulle jag vilja komplettera med ett tips om utmärkta weinre som boken inte tar upp. (kanske för att den skrev innnan weinre uppfanns…?)

En sak jag skulle vilja ta gå in lite djupare på är författarens syn på ”One Web”. Det jag nämnde i inledningen här. ”One Web” konceptet handlar om att vi ska kunna skapa en gång och att det vi skapat sedan ska fungera och vara tillgängligt på alla enheter överallt. Maximiliano menar att detta inte kommer att vara möjligt på flera år. Jag håller inte med. Jag tycker att det alltid har varit möjligt i en viss utsträckning. Ja, man behöver testa och anpassa och tweaka. Men man ska inte alltid behöva göra flera versioner av samma innehåll. Jag gillar inte heller författarens syn på ”device-detection” utan jag tror på ”feature-detection”, det vills säga att istället för att kolla vilken enhet det är så kollar vi vad enheten är kapabel till. Jag vet att vissa tycker att detta är en utopi och något orealistiskt men det är något som vi måste sträva efter. Speciellt om vi vill bygga framtidssäkra webb-sidor som går att underhålla och inte växer till monster på enbart något år. Jag tycker att ”progressive enhancement” som jag tagit upp tidigare är vägen att gå.

Det jag verkligen gillade med boken (eller kanske snarare med författaren) var att det verkligen är nernördat. En hel mängd egenheter och klurigheter hos olika enheter tas upp. Det finns fina små rutor med fällor att undvika. Det hela känns lite som en bok-version av quirksmode om mobil webb. Det jag starkt ogillade och som jag redan tagit upp är författarens benägenhet att hela tiden bygga efter specifika modeller och märken. UA-sniffning är inte något fint men argument för och emot diskuteras tyvärr inte.

Boken är trots brister väldigt läsvärd och viktig. Framförallt tycker jag att det är viktigt för oss som jobbar med utveckling att inte glömma bort resten av mobil-världen. Det är viktigt att förstå att världen inte består av iPhones med snabba internetuppkopplingar och moderna webbläsare. Jag tycker att man ska läsa denna bok som trots sina tabeller och uppslagsbok-känsla faktiskt påminner oss om detta.

Pivotal Tracker är riktigt bra


På Creuna så använder vi Redmine som projekthanteringssystem. Ett möjligt alternativ skulle kunna vara Pivotal Tracker. Jag har hört mycket gott om produkten så jag ville testa. Det har ett superintuitivt interface, men det bästa av allt: git-integrationen

Jag lägger upp mina stories i pivotal och prioriterar genom drag and drop. Jag gör även en snabb estimering, som pivotal använder för att planera vad som borde hinnas med i sprinten baserad på teamets tidigare utvecklingshastighet.

När det är dags för mig att jobba på något så skriver jag:

➜ git feature
Retrieving latest features from Pivotal Tracker…
Story: Revert account link in prefs / account
URL: http://www.pivotaltracker.com/story/show/11125931
Updating feature status in Pivotal Tracker…
Enter branch name (will be prepended by 11125931) [feature]: revert-account-link
Creating 11125931-revert-account-link branch…
Switched to a new branch ‘11125931-revert-account-link’
/Users/matti/projects/fooproj git:(11125931-revert-account-link) ✗

Det hämtar den senaste storyn från trackern och skapar en ny lokal feature branch. Fördelen med feature branches är att man alltid har en körbar version i master trunken. Man kan enkelt jobba på flera features samtidigt genom att ha dom i olika branchar. Man håller de lokala brancharna ajour med master branchen via sk. rebasing.

Man committar delstegen man gör på storyn. När man är klar så skriver man
➜ git finish

Det markerar storyn som klar i pivotaltracker som håller koll på hur lång tid det tog att genomföra storyn jämfört med hur komplex man hade estimerat den till att vara = din utvecklingshastighet). Sen tar den bort feature branchen och mergar in i master trunken.

Det blir inte enklare än så här. Det är agilt utan skitsnack. Jag har bara kört på soloprojekt hittils, men det borde ju vara ännu bättre i team.

Coders at Work

Coders at Work är en samling intervjuer baserade på samtal författaren Peter Seibel haft med 15 olika programmerare. Siebel är själv en erfaren programmerare vilket antagligen har bidragit till att boken blivit så bra, då han kunnat ställa de rätta frågorna. Många av de intervjuade var okända för mig men några namn var bekanta: Douglas Crockford som skapade JSON, Joshua Bloch som skrev Java-biblioteken för collections och Brendan Eich som uppfann JavaScript. Boken avslutas med en intervju med Donald Knuth, en programmerarlegend som borde vara välkänd för de flesta, inte minst för att han skrev ”The Art of Computer Programming”.

Boken är såklart fylld med intressanta anekdoter och citat, men det som jag fann mest intressant var att många av dem som gjort saker som mer eller mindre förändrat världen var sådan utstuderade pragmatiker. Många utvecklare idag, inte minst jag själv, tenderar att vara purister till viss del, må det gälla TDD, S.O.L.I.D., dynamisk typning, statisk typning, graceful degradation, progressive enhancement etc. etc. Flertalet av de intervjuade i denna boken gav dock intrycket av att till viss del tillåta sig skjuta från höften, bara så länge fungerande mjukvara levererades. Väldigt uppfriskande läsning.
Coders at Work var överhuvudtaget väldigt rolig och underhållande, den innehåller flera riktigt sköna berättelser om debugging från den tiden ett program bestod av en samling papper med hål i.

Min första utveckling mot iPhone

När jag surfade genom App Store efter appar till min iPhone och sedan såg att Debaser släppte ett sprillans nytt API fick jag en idé om att göra en app som jag själv skulle ha nytta av. En app att kunna använda deras API, ta del av data och se vad som hände på de olika arenor Debaser har här i Stockholm men också i Malmö.

Från början var tanken att göra det i den bejublande Flash-to-iPhone som Adobe hade utvecklat och skulle släppas i nya Flash Professional CS5. Men så kom bomben från Apple vilket gjorde det omöjligt att släppa en app som inte var skriven i antingen JavaScript för WebKit, Objective C, C eller C++. En annan väg jag provade var Titanium,  en gratis platform som portar om JavaScript till XCode-projekt, skrivna i Objective C. Det buggade ganska friskt och skulle aldrig bli helt och hållet nativt så jag gav mig in i djungeln att lära mig Objective C.

Det har varit en lång väg att gå eftersom mycket av det som skett naturligt för mig i Flash inte alls fanns stöd för i detta språk, som t.ex. garbage collection. Det har tagit minst lika lång tid att lära sig språket & utveckla i det, som att leta minnesläckor och släcka dessa i efterhand men efter ett par veckor har jag äntligen fått upp min app i App Store och väntar nu på att Apple ska granska den. Förhoppningsvis blir den snabbt godkänd och då även nedladdningsbar för alla, gratis.

Uppdaterat: Appen blev godkänd av Apple 7/6 och skådas här!

Deeplinking med SWFAddress

Deep linking definieras på wikipedia som making a hyperlink that points to a specific page or image on another website, instead of that website’s main or home page.

Innan jag ens visste om att det gick att använda deep linking i flash så kände jag att det skulle behövas i exempelvis bildgallerier gjorda med flash för att kunna länka till en specifik bild istället för att låta någon bläddra fram den, vilket skulle bli väldigt jobbig process ifall det fanns flera album med flera olika sidor. Eller om man skulle behöva peka ut ett kontaktformulär i en kampanj gjord i flash. Jag tänker inte grotta ned mig i stora tekniska detaljer utan mest redogöra för vad man kan göra med hjälp av denna teknik.

Vi har fram till idag i flashrummet gjort flera kampanjer med deep linking-funktionalitet, exempelvis i Libero Eco Actions (Q4, 2009) och TetraPak (Q2, 2009). Även i de fall när man behöver länka till bidrag i tävlingar har tekniken används för till exempel Libresse.

Jag har en sida för mina foton som är helt gjord i flash och tänkte förklara vad jag kände att den saknade kring just deep linking. Innan jag implementerade tekniken så kunde man byta sida i ett album, få upp en bild och stänga denna. Jag presenterar alla bilder högupplöst i förhållande till bildskärmen upplösning och webbläsarens storlek för att få ut så mycket som möjligt i detajlrikedom och upplevelse, men det fanns inget stöd för att snabbt kunna visa sista bilden tillexempel utan vägen man fick gå var från startsida till tumnagelvy, bläddra till sista sidan och klicka på bilden. Plus laddtider för allting. Det kändes onödigt långt och krångligt.

Jag använde SWFAddress (v2.4) som med hjälp av JavaScript kan se ifall adressfältets värde har ändrats och isåfall skickar ett event som jag senare hanterar i en funktion i flash. SWFAddress kan också ändra adressfältets värde från flashen under det att användaren byter bild eller sida.

En genererad adress kan se ut så här wwwroot/#/page3 eller wwwroot/#/page2/pic10
Nummertecknet (#) tillåter adressfältet att ändras utan att HTML-sidan med tillhörande flash behöver uppdateras.

Om flashen känner av det senare mönstret hoppar den över startsidan, laddar automatiskt sida 2 och sedan bild 10. Även om det redan finns laddare till både tumnaglar och vald bild kan det vara bra att låta besökaren veta att bildvalet nu istället sker automatiskt eftersom man valt att gå in på flashen via deep linking. (Det har jag ännu inte hunnit lägga till, på grund av tidsbrist och inte lathet :) Om man istället bara vill länka till specifik sida väljer man första mönstret. Prova /#/page3 och #/page4/pic24 själv!

Lista färgerna i en cssfil

Jag var tvungen att kolla igenom en cssfil för att bekräfta att vi höll oss till ett visst färgschema. Ruby är bra i såna här lägen.

require 'set'
unless ARGV.length == 1
   puts "usage: display_colors_in_css.rb [css_file]"
   exit 1
end

css = IO.read(ARGV[0])
color_refs = css.scan /\#[0-9A-Fa-f]{3,6}/
color_set = Set.new( color_refs.map(&:upcase) )
puts color_set.to_a.sort