15 Aralık 2012 Cumartesi

Thoughts about Smartfox on iPhone

We have been using smartfox in our isometric 2D social game for a very long time (since the beginning of it in fact). And I wanted to give a review to it for that reason.

 First of all, I only know the iphone client of it, because I've only used it in iphone. So this review is valid for iphone client of smartfox.

 They made iphone client closed source after some version. Because of that if a problem happens, which is likely to happen, you can not debug it. It is like a black box. And for an unknown reason it's crashing a lot. By a lot, I mean really a lot. Checking the crash statistics of our app I can say 90% of the crashes are smartfox related and number of crashes is in thousands.

Seeing so many crashes and with the fact that it is a blackbox thing, I would unfortunately not recommend using SmartFox for your multiplayer project. There is a forum of it but it doesn't seem to help in getting quick help either.

I don't know if there are good open-source multiplayer game servers but if there are, I would strongly suggest using one of them. A multiplayer game server is just a layer of getting commands and sending events or responses to clients after all. Whichever server you are using, most of the work will be your extension, which is the game logic. What SmartFox provides in addition to that is some default game concepts like rooms, users, banning etc. But they should not be so hard to implement. So I would suggest using a lightweight event mechanism for that. It can be even something like now.js or maple.js if you are into node.js.

9 Aralık 2012 Pazar

AppSurfer ve Pratik Sözlük

Birkaç ay önce aklıma Android uygulamalarını webde çalıştıran bir web uygulaması olabilir mi acaba diye bir soru gelmişti. O zamanki aramamda böyle birşey bulamamıştım. Dün ise AppSurfer diye bir sitenin bu hizmeti verdiğini öğrendim. Tam olarak benim düşündüğüm şey olmasa da Android uygulamalarını web sitelerinde çalıştırabiliriyor, kullanıcılara "canlı" bir demo şansı tanıyor AppSurfer. Uygulamalarınızın apk'sini yükleyerek hizmeti aktive edebilir, dilerseniz benim buraya koyduğum gibi widget'ını blogunuza yada web sitenize entegre edebilirsiniz. Güzel düşünülmüş bir servis.

 Aşağıdan Pratik Sözlük uygulamasını canlı canlı test edebilirsiniz :)

 

20 Ekim 2012 Cumartesi

Dropping ios 4.3 support

If you are one of the developers who think ios 4.3 is not worth supporting any more but can't be sure about it at the same time, here comes the latest stats to the rescue. I saw from live stats that currently ios 4.3.x seems to have 3% percentage in active sessions.

I think it is okay to drop 4.3.x support from now on. It's only 3% and it creates a lot of trouble for the developers who want to use ios 5 or 6 features. At the best case, your code is filled with if (IOS_VERSION > 5.0f) statements, at the worst case you get crashes in ios 4.3.x.

If you don't want to lose those guys using ios 4.3.x completely, you might degrade gracefully for them. That is some features will not be supported in ios 4.3 but they will still be able use the app with basic functionality. Try not to crash if you will follow this approach. Otherwise you can get low ratings from them.

But still, even if you drop support for ios 4.3.x, don't forget to follow MVC correctly and try not to abuse UIViewController's. See my previous blog post about it.

1 Ekim 2012 Pazartesi

NSString length for 4-byte characters

If you worked with 4 bytes characters -such as emoji- on ios, you should have noticed that NSString handles those 4-byte characters a little different than expected. Well, I might be missing something but it counts a 4-byte emoji as 2 characters.

Hence, If you need to process a string which contains a 4-byte character, you might need some new methods to calculate the length or offset in that string. I wrote two category methods for this purpose. One finds the length of the string and the other converts an offset calculated by NSString methods to the correct value. Feel free to use them if you need:


Note: NSString counts a 3-byte character as 1 character as expected.

15 Eylül 2012 Cumartesi

Java neden yavaş?

Hayattaki klişelerden birisi de herhalde "Java yavaş" sözüdür.  Bu sözü ara sıra ufak çaplı bilgisayarcı tartışmalarında duymak mümkündür. Doğruluk payı yok değil aslında, Java yavaştır, ama neden ve ne zaman yavaştır sorusunun cevabı daha önemli.

Java'nın yavaş olmasına sebep olarak genellikle makine kodu yerine bytecode'a çevirmesi söylenir. Bu belki bir instruction ilk kez çalıştırılırken doğrudur, ama JIT mekanizması sayesinde aynı instruction'ın sonraki çalıştırılmalarında doğrudan doğruya makine kodu çalışacaktır. Dolayısıyla web server gibi uzun süreli çalışan programlarda bu bir yavaşlık oluşturmamalıdır.

Peki Java neden yavaştır? Java'nın yavaş olmasının benim gördüğüm iki büyük sebebi vardır.

1- Bütün objeler heap'te ayrılır, yani ayırma ve bırakma işlemi için işletim sistemine gidilir. c++'da ise bu iş stack'te halledildiğinden stack pointer'ını azaltıp arttırarak hızlıca allocation yapılabilir. Bu bilhassa  yoğun şekilde güncellenmesi gereken grafik tarzı programlarda çok önemli bir darboğaz yaratmaktadır. Sözgelimi 30fps ile çalışacak bir oyunun 33 milisaniyede bir güncellenebilmesi gerekir ve sürekli heapten alınıp bırakılan nokta tarzı hesaplama objeleri bunu zorlaştırabilir.

2- Obje cast'ları: Java'da bütün objelerin cast'ları dinamiktir. Generic(c++'taki template) kullanılsa bile bu değişmez bildiğim kadarıyla. C++'ta ise template kullanıldığı zaman bu cast compile zamanında halledilmiş olur. Çalışma zamanına ek bir yük bindirmez. Bu da performansı arttırır haliyle.

Java'nın object oriented tabiatından kaynaklanan birkaç performans eksikliğinin daha olduğunu biliyorum. Mesela fonksiyonları inline etmek gibi. Ama sanırım bu iki örnek yeterli, diğerleri de zaten biraz daha gelişmiş konular.

Özetle, Java'nın yavaş olmasının sebebi makine koduna çevirilmesinden kaynaklanmıyor. Herşeyin obje olmasından kaynaklanıyor. Bunu çözmek için de JNI diye birşey geliştirilmiş bu arada.

Hamiş: Obje kullanmaktan ileri gelen tüm yavaşlıklar Python ve PHP için de geçerli olmalı.

Replying to user reviews on Google Play publish page

Following Google IO 2012, Google announced its new feature for app publishers, which is a great thing; replying to user reviews on Google Play.

Sadly, they enabled it only for top developers. And they added they will offer it to additional developers based on feedback from users and developers.

This feature will help developers to respond to user reviews which mention a fixed bug or something not valid anymore. Even though the reviewer does not delete his review upon the reply, people seeing the review and reply will understand that the problem is no longer valid. This feature will be very useful for that purpose.

To be honest, I'm impatiently waiting for this feature to be active for all developers. Come on Google, make it open for everyone. We know that you can do it.

Android Developers Blog: Replying to User Reviews on Google Play

28 Ağustos 2012 Salı

How to properly use UIViewController and UIView on ios

I believe it's one of the biggest common misconceptions in writing for ios platform that every view should have a corresponding controller, specifically UIViewController.

I myself did this mistake when I first started writing ios applications too. I wasn't very experienced in writing UI code, so I didn't know MVC in detail. That might be the case for most of the people who makes this mistake. And since ios platform does not enforce you to avoid it, you are free to do it. (See how Android activities encourage you to use one Activity for a page which covers the entire screen)

Essentially, in MVC pattern, controller is the object which makes the communication between views in one page of the screen. Controller is not the delegate of a single view. Think of it in that way, if you need a static delegate object for a view class, why not do that delegating in that view itself?

Obviously, the view elements in UIKit which covers only a portion of the screen, such as UILabel, UIButton, UITableView are all subclasses of UIView. You don't need a seperate view controller for each instance of them. Even for UITableView you can assign an object as datasource and delegate and use it without a controller. Happily, we can say at least creators of the platform follow MVC correctly.

Prior to ios5, Apple did not even supported using multiple controllers by not calling view lifecycle methods(viewwilldisappear, viewdidload, etc) on controllers in deep hierarchy. But I believe since loading of a UIView from a nib was not explicitly and easily seen compared to loading a UIViewController, people preferred using a UIViewController per view element and that led to this biggest misconception.

From the day I got this enlightment that multiple view controllers in a page is unnecessary, I am trying to use UIView objects directly. I use KVO in views to listen model when possible. If the views are generic containers like UITableView, I create NSObject instances for them to act as delegate and/or datasource. I believe this is a more proper and tidy way of managing UI objects in code.

If you have different solutions or improvements to this approach, feel free to share your comments on the subject!

Some sources which discuss the same thing:
http://blog.carbonfive.com/2011/03/09/abusing-uiviewcontrollers/
http://stackoverflow.com/a/5691708/369001

27 Ağustos 2012 Pazartesi

Mevcut kodu svn'den git'e taşımak

Neden öyle oluyor bilmiyorum, ama herhalde çoğumuz ilk reposunu svn'de oluşturmuş, ilk commit'ini falan svn'le yapmıştır. Bunda herhalde svn'in baştaki öğrenme sürecinin düşük olmasının etkisi vardır. Nitekim svn'den git'e ilk geçişte de git biraz karışık gelebiliyor. Ama git'i bir kere öğrenip- ki karmaşık dediysem zorluktan değil yarım saatlik araştırmaya üşenmekten- geriye dönüp svn'e bakınca insan svn'de geçirdiği zamanına acıyor. O yüzden svn kullananlara önerimdir, bir an önce git'e geçiniz. Hele ki bu iş bir komut kadar kolaysa

İşimizi halleden komut şu:
git svn clone http://svn/repo/here/trunk
Bu komutla git svn reposundan bütün revizyonları tek tek çekiyor ve lokalde bunları git yapısına uygun olarak birleştiriyoruz. git log dediğiniz zaman da commit'i yapanın kullanıcı adını nasıl oluşturduğunu bilmediğim bir mail adresi ile birlikte düzgün gösteriyor. Kimin neye katkıda bulunmuş olduğu bilgisi kaybolmuyor yani.

E-mail adreslerini düzeltme:
Commit log'larındaki email adreslerini düzgün görmenin iki yolu var.

İlkinde(önerdiğim yöntem) en baştan bir txt dosyası vererek her kullanıcının ad soyad ve emailini girebilirsiniz. txt dosyasının formatı şu şekilde:
user1 = First Last Name 
user2 = First Last Name 
...
Bu dosyayı ilk komutumuza
-A dosya.txt
ek ayarı ile veriyoruz.

İkincisinde ise taşınmayı gerçekleştirdikten sonra aşağıdaki script ile belirli bir email adresindeki bütün commitleri değiştirebilirsiniz:
    git filter-branch --env-filter '
      if [ "$GIT_AUTHOR_EMAIL" = "wrong email" ];
      then
          export GIT_AUTHOR_EMAIL="correct email";
      fi
      ' HEAD

Bu komutla svn reposunu git'e kolaylıkla taşımış olduk. Verdiğim komutla branch'lerin ve tag'lerin taşınmamış olduğuna dikkat ediniz. Eğer standart bir klasör yapınız varsa (tags, branches, trunk) --stdlayout opsiyonu ile branch ve tag'ları birer remote branch olarak çekebilirsiniz. Bu durumda en son komutumuz aşağıdaki gibi olacaktır:
git svn clone --stdlayout -A dosya.txt http://svn/repo/here/trunk
Branch'leri remote branch olarak aldıktan sonra karşılık gelen local branch'leri oluşturmamız gerekecek. Tag'ler de branch olarak geldiğinden branch'lerin içine girip tag olarak eklememiz gerekecek. Yapmak isteyenler için git'i ilk defa kullanacaklarsa güzel bir alıştırma :)

Yeni git reponuz hayırlı olsun. Artık gelsin local branch'ler, stash'ler, cherry-pick'ler, rebase'ler...


8 Ağustos 2012 Çarşamba

BUDatePicker - A versatile datepicker

I think it was a little P.I.A. to use default UIDatePicker provided by Apple. Then I thought writing an alternative date picker.

 Those are the things about UIDatePicker that does not satisfy me:

  • If user has not selected a date completely(i.e. spinner is still spinning) it does not give the closest date to spinner. It simply returns the date before spinning started.
  • You can not control wrapping of months and days 
  • You can not control showing areas out of boundaries or not 
  • You can not easily control places of month, day and year components. 


 BUDatePicker aims to solve those problems. It is not a complete solution though, because I have not alloted much time on it. Nevertheless, I think it is way more versatile and easy to use than standard UIDatePicker. And best of all it is open source.

 You can check it out at https://github.com/ucarbehlul/BUDatePicker

 Feel free to contribute or fork!

16 Temmuz 2012 Pazartesi

Türkiye'de GSM operatörlerinin frekansları

ABD'den geçenlerde bir telefon aldım. Telefonu alırken 3G özelliğini TR'de de kullanabilmek benim için önemliydi(3g frekansları ABD'de değişik). Bunu araştırırken fark ettim ki Türkiye'deki operatörlerin frekanslarını internetten bulmak zor. Ben de forumlardan çıkardığım bilgiyi burada paylaşayım da ileride arayanlar için belki bir kolaylık olur dedim. Lafı fazla uzatmayalım ve değerleri verelim:

 2G değerleri:
    Turkcell ve Vodafone 900,
    Avea 1800 Mhz.
3G değerleri: 2100 Mhz.

 Alacağınız telefon bu frekansları destekliyorsa Türkiye'de sorunsuz çalışacaktır.

8 Mart 2012 Perşembe

Mac'teki terminal'e tuş ayarı verme

klasik bir linux kullanıcısı için mac terminalinin en sinir bozucu yanı büyük ihtimalle [control + sol ok] kombinasyonunu kullanamamak olacaktır(sağ ok da pek tabi). benim için de durum farklı değildi. neyse ki terminal uygulaması belirli tuşbasımlarına değişik stringler atamamıza izin veriyor. çözüm olarak terminal'de preferences'tan aşağıdaki ayarı giriyoruz.

--tuş kombinasyonu--      -string-
control cursor left            \033b
control cursor right          \033f

ve yeni açtığımız sekmemizde eski linux uçbirimlerimizdeki davranışa kavuşuyoruz...