7 Haziran 2020 Pazar

A gotcha in ReactDom.hydrate method

It is a common practice to do server side rendering and hydrating DOM on client using reactjs. Perhaps what is not common is rendering different things on server and client side. One example I can think of for that is ads, you probably wouldn't want to render ads on server side.

If you add more things to your dom only on client side, you may notice that some of your elements are omitted by react. That is caused by reactjs thinking some elements you render are some of the previous elements that got rendered before. In order to overcome this problem having a new state variable like isClient and rendering those elements only if isClient true. And you can initialize your state variable as usual:
useEffect(() => { setIsClient(true); }, []); 
It is quite cryptic to solve this issue otherwise since there is no warnings about it.

25 Eylül 2013 Çarşamba

npm ile paket kurarken package.json'a ekleme

bir node.js projesi geliştirirken önce package.json'ı değiştirip sonra npm install demenin çifte iş olduğunu düşünüyorsanız npm install paket --save tam size göre.

18 Şubat 2013 Pazartesi

Parsing html documents which contain script tags without cdata

If you are dealing with html document which has a script tag and some javascript code inside without an opening cdata section and trying to parse it as an xml, i.e. for xpath querying, then you might get in trouble. It's because the code inside script tag becomes against the xml syntax and parser libraries fail while parsing it.

I tried the same thing in python using lxml and elementtree libraries and they gave the same result. Happily, at the last time I was about to lose my hope, beautifulsoup library came to the rescue and did my job. Appearantly they treat html files differently than an xml, which saves a day in my case.

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...

22 Mart 2011 Salı

Word 2003'de özel bir sayfadan numaralandırmaya başlamak

Word deneyimi fazla olmayanların, yada hep ara sıra kullandığı için Office'in ıncığını adam gibi öğrenmeye hep üşenenlerin genel sorunudur; Word'de sayfa numaralarının spesifik bir sayfadan başlaması. Bu yazımda bunu Word 2003 için anlatacağım. Kişisel tavsiyem LaTeX kullanmanız yönünde, esneklik açısından.

Neyse, direkt konuya girelim. Bunun için öncelikle numaralandırmanın başlamasını istediğiniz sayfayı ayrı bir bölüm içine almanız gerekiyor. Word'de bir dökümanı birden çok bölüme ayırabiliyorsunuz. Böylece aslında iki farklı Word dökümanınız tek dosyada birleşmiş gibi birşey oluyor, gibi birşey yani. Yeni bölüm oluşturmak için o sayfanın en üst satırının başına gelin ve Ekle>Kesme diyin. Çıkan menüden sonraki sayfayı seçin. Yeni bir bölümünüz olmuş olmalı.

Yeni bölüm ekledikten sonra yapmanız gereken şey ise sadece bu bölüme has bir numaralandırma yapmak. Bunun için önce bu bölümün dipnot (yada üste koyacaksanız üstnot) kısmını önceki bölümlerden bağsız hale getirmeniz gerekiyor. Bunu yapmak için yine bölümün ilk sayfasında dipnot kısmına iki kere tıklayın ve dipnot alanını açın. Alanın üstünde belirecek ufak menüde "önceki kısma bağla" gibi birşey yazan seçeneği devredışı bırakın. Böylece önceki bölümlerden bağımsız bir dipnot kısmınız oldu. Bundan sonra yapmamız gereken şey sayfa numaralarını eklemek. Bunun için üst menüden sayfa numarası ekle diyoruz, gelen menüde gelişmiş ayarlar kısmında "önceki bölümden başla" kısmını değil de ötekini seçiyoruz. Tamam deyince sadece o bölüme ait bir numaralandırma eklemesi lazım.

Not: Bu yazıyı linux'ta Word önümde açık olmadan yazdım. O yüzden bazı menü ve buton isimleri tamı tamına tutmayabilir.

11 Mart 2011 Cuma

Ubuntu'da shift + numkey kullanma

Büyük ekranlı laptoplarda genel uygulamadır, numlock kapalı ise numpaddeki tuşlar home,pgdown gibi işlevler edinir. Laptopta bu işlevde başka tuş da olmadığından bendeniz gibi işini klavyeden halletmeyi sevenler numlock'u genellikle kapalı tutar.
Buraya kadar tamam, ubuntu bir sorun çıkarmıyor. Ancak bir satırı tümden seçmek istediğinizde windows'tan alışık olduğunuz shift + home gibi kombinasyonları yapmanıza ubuntu izin vermiyor, ayarlayıncaya kadar tabii.
Lafı fazla uzatmadan bunun nasıl ayarlandığına geçiyorum:
Tercihler>Klavye>Düzenler>Seçenekler>Çeşitli Uyumluluk Seçenekleri>Shift with numeric keypad keys works as in MS Windows.

ve laptop'ta shift + home'umuza kavuştuk.

5 Eylül 2010 Pazar

Ev bilgisayarında SVN Server oluşturma

SVN gerçekten çok güzel bir araç. İster bir takım halinde, ister tek başınıza yazılım geliştiriyor olun projenizin versiyon hesabını SVN ile tutmanız gerçekten yararınıza.

Amatör ve tek geliştiricili projeler için en iyi modellerden birisi de geliştirme makinasına bir SVN server kurup uzaktaki bilgisayardan ev bilgisayarına bağlanarak ana versiyonları indirmek. Bu sayede geliştirme yapılan bilgisayarda daha hızlı işlem yapılacak ve her revizyon için internete bağlanma gereği duyulmayacak. Özellikle shared hosting modelinde olan web projeleri için bu model çok pratik ve hızlı.

Bu yazıda Windows'ta nasıl SVN sunucusu oluşturabileceğimizi anlatacağım. Adım adım gitmeyi tercih ediyorum.

1- Öncelikle Subversion'ın Windows için makine kodunu indirmemiz gerekli. İndirip kurduktan sonra subversion bin klasörünün Windows path'ine eklendiğinden emin olun.

2- Bilgisayarımızda bir SVN reposu olması gerekli. Bunun için

svnadmin create "%REPO-YOLU%"

komutunu verin. Repo yolunda bir repository oluşturulduğundan emin olun.

3- Bu adımda repomuza erişimi ayarlamamız gerekiyor. Bunun için repo yolunun altında conf/svnserve.conf dosyasını açın ve

anon-access = none
auth-access = write
password-db = passwd

satırlarına ulaşın (yorum ise baştaki #'ı silin). 3 satırın başında da gereksiz boşluk olmamasına dikkat edin.

4- Kullanıcı belirleme zamanı. Aynı klasörün içindeki passwd dosyasını açıp

harry = harryssecret
sally = sallyssecret

tarzında kullanıcılar ekleyebilirsiniz. Yine satırbaşlarında gereksiz boşluk olmamasına dikkat edin.

5- SVN repomuzu dışarıdan erişim için ayarlı hale getirdik. Şimdi bilgisayarımıza düşecek isteği değerlendirecek programı (svnserve.exe) açmamız gerek. Bunu her açılışta çalışan bir windows hizmeti olarak yapmayı tercih ediyorum.

sc create svnserver binpath= "%SVN_BIN_KLASORU%\svnserve.exe --service -r %REPO_YOLU%"
displayname= "Subversion" depend= Tcpip start= auto

komutu ile windows hizmetimizi oluşturuyoruz. Komutta %% arasındaki değişkenleri kendi kurulumunuza göre değiştirmeniz gerekiyor. "Subversion" hizmetimiz açılışta otomatik olarak açılacak şekilde ayarlansa da şu anda çalışmıyor. O yüzden

net start svnserver

komutu ile hizmeti başlatıyoruz.

6- SVN sunucumuz neredeyse hazır. Son adım olarak port ayarlarını yapmak kaldı. svn:// protokolü 3690 portunu kullanıyor. Sırasıyla bilgisayarınızın, anti-virüsünüzün ve ağınızdaki yönlendiricilerin(router) güvenlik duvarı ayarlarını yapıp 3690 portuna izin verildiğinden emin olun.

6 adımda svn sunucumuz hazır. İsterseniz kendi pcnizden localhost, yada dışarıdan ip nonuzu yazarak sunucuya bağlanabilirsiniz.
Örneğin aşağıdaki komutla daha önceden oluşturulmuş repo içindeki projem adlı klasörü uzaktan checkout edebilirsiniz:

svn checkout svn://%IP_NONUZ%/projem

1 Eylül 2010 Çarşamba

Timeout error in Mysql connection via Doctrine and Symfony

If you have used a local mysql server and decided to port to an external one, you might have a problem that symfony can not connect to the external db. It can't even get a response from the server.

If you experience that kind of issue, the thing might be that you forgot to include "host=" in your dsn definition.

replace
dsn: 'mysql:your-server-url;dbname=your-dbname'

with
dsn: 'mysql:host=your-server-url;dbname=your-dbname'

Notice the difference, which is 'host='. It is also forgotten on docs, not written neither on Practical Smyfony nor Definitive Guide. So you might also forget. It does not make a problem if you simply connect to a local mysql server.

404 not found error in production mode in Symfony

As a developer using Symfony hosted on an Apache server, I experienced an issue with production mode of Symfony.

Normally, production mode is reached via appending index.php to the end of base url. But thanks to mod_rewrite module of apache, index.php can be omitted. And links in production mode does not have the corresponding index.php part. That is good for user experience, but there is a problem that when trying to reach them, Apache server gives 404 error.

The problem is that apache mod_rewrite module is not loaded by default. Installed tough, but not loaded. So you need to tell Apache to load it on start. You can do this by uncommenting the line starting with "loadModule rewrite..." in http.conf file. The file resides in conf directory of Apache folder. After making changes, restart the server and that's it, the problem is solved.

19 Ağustos 2010 Perşembe

Timeout in Php MySQL connection

Have you ever got a timeout while trying to connect to a local mysql server from php code? Have you teared your nails trying to figure out cause and solution?
I unfortunately spent 3 hours trying to solve the issue.

Solution is again simple and absurd. The workaround is whether you hardcode the connection or use a framework such as Symfony, the same. If you write server url as "localhost" on some conditions the local server timeouts. The issue does not seem very well documented. Nevertheless, the solution is to make server "127.0.0.1" instead of "localhost".

Happy connections, healthy nails!