論盡蛋
心で書く

Blog


Pull to refresh table view controller

Finally can pay my full attention to iOS development.

Basically this is a subclass of UITableViewController, which adds the functionality of pulling downward to refresh (or reload).

The following is the usage:

  1. Copy the files into your project:

    • PPPullToRefreshTableViewController.h
    • PPPullToRefreshTableViewController.m
    • pullToRefreshArrow.png
    • pullToRefreshArrow@2x.png
  2. your table view controller should inherit from PPPullToRefreshTableViewController (which is a UITableViewController subclass), instead of the original UITableViewController

    1. in YourTableViewController.h
      1. #import "PPPullToRefreshTableViewController.h"
      2. @interface YourTableViewController : PPPullToRefreshTableViewController
    2. override the following method:
      1. - (void) refreshing
        • you should call didRefresh inside this method in order to hide the refresh header view
    3. you may want to call willRefresh to start refreshing in code (this method by default shows the refresh header view, and calls refreshing automatically)
  3. In your build target's Link Binbary with Libraries section, add the QuartzCore.framework

You may clone the demo project, which is a Master-Detail application together with the PPPullToRefreshTableViewController source code, from here:

git clone git://github.com/peterwongpp/PPPullToRefreshTableViewController.git

The project's repository: PPPullToRefreshTableViewController

Any pull requests, discussions or issues are welcome!


Drop PostgreSQL database

Update:

If you are using Rails 4.x, please read this. Thank you Manuel Meurer for letting me know the following implementation applies to Rails 3.x only.

If you are using Rails 3.x, you may continue use the following patch.


Some of my projects uses PostgreSQL as my database. However, running rake db:drop always gives me the following error:

Couldn't drop PROJECT_NAME_development : #<ActiveRecord::StatementInvalid: PG::Error: ERROR:  database "PROJECT_NAME_development" is being accessed by other users
DETAIL:  There are 2 other session(s) using the database.
: DROP DATABASE IF EXISTS "PROJECT_NAME_development">

To resolve this problem, as hinted by the message about, is to stop all sessions using that database.

However, I just found (I think) better solution from this stackoverflow answer (which points to this gist).

It is to monkey patch the rake db:drop command. To do so, simply copy the code into lib/tasks/databases.rake and now rake db:drop is patched with this code which stops the connections.

The code is as follow:

#!ruby #{Rails.root}/lib/tasks/databases.rake
=begin
  Monkey Patch 
  activerecord-3.0.9/lib/active_record/railties/databases.rake
  clears obstinate stale PG session to get parallel_tests working
  also, PG user must be superuser to use these low level PG functions
=end
def drop_database(config)
  case config['adapter']
  when /mysql/
    ActiveRecord::Base.establish_connection(config)
    ActiveRecord::Base.connection.drop_database config['database']
  when /sqlite/
    require 'pathname'
    path = Pathname.new(config['database'])
    file = path.absolute? ? path.to_s : File.join(Rails.root, path)

    FileUtils.rm(file)
  when /postgresql/
    ActiveRecord::Base.connection.select_all("select * from pg_stat_activity order by procpid;").each do |x|
      if config['database'] == x['datname'] && x['current_query'] =~ /<IDLE>/
        ActiveRecord::Base.connection.execute("select pg_terminate_backend(#{x['procpid']})")
      end
    end
    ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
    ActiveRecord::Base.connection.drop_database config['database']
  end
end

String display width in given font in Javascript

Aim

To calculate the width of a given character or string.

Why

Even if you use monospace fonts, there are some characters are not in the same width (such as Chinese and Japanese).

Furthermore there is no simple way to know if a given character is double-sized or not.

How

jQuery Version

#!Javascript
String.prototype.widthInFont = function(font) {
  var f = font || '12px arial',
      o = $('<div>' + this + '</div>').css({
        'position': 'absolute',
        'float': 'left',
        'white-space': 'nowrap',
        'visibility': 'hidden',
        'font': f
      }).appendTo($('body')),
      w = o.width();

  o.remove();

  return w;
}

Performance

Reference

If you have better implementation, please let me know :)


Missing gcc-4.2 on Mountain Lion

Recently I upgraded to Mountain Lion (OK actually not quite recent XD), which kind of resets my development environment. But it's okay, not a big deal :)

Rails 3.2.8 is out, and it fixes 3 security issues. So it should be worth to upgrade ChordsPresent's rails version. However it seems I could not get it done very easy (I expected less than 1 minute, but actually took me nearly 5 minutes...)

Replacing by gem 'rails', '3.2.8' in the Gemfile and ran bundle update rails, I get the following error:

#!bash
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

    /Users/PeterWong/.rvm/rubies/ruby-1.9.3-head/bin/ruby extconf.rb 
creating Makefile

make
compiling generator.c
make: /usr/bin/gcc-4.2: No such file or directory
make: *** [generator.o] Error 1


Gem files will remain installed in /Users/PeterWong/.rvm/gems/ruby-1.9.3-head@chordspresent/gems/json-1.7.4 for inspection.
Results logged to /Users/PeterWong/.rvm/gems/ruby-1.9.3-head@chordspresent/gems/json-1.7.4/ext/json/ext/generator/gem_make.out
An error occurred while installing json (1.7.4), and Bundler cannot continue.
Make sure that `gem install json -v '1.7.4'` succeeds before bundling.

Basically it complained that it cannot find my gcc at /usr/bin/gcc-4.2.

The first response I took was which gcc which yields: /usr/bin/gcc. But then I realised that it should not be that simple. Mountain Lion changed to llvm-gcc.

And my curiosity caused me to type ls /usr/bin/llvm-gcc together with two tabs and it showed the two results: llvm-gcc llvm-gcc-4.2.

Still do not know why bundle update wanted gcc-4.2 yet, but it should work if I just make a symbolic link:

#!bash
sudo ln -s /usr/bin/llvm-gcc-4.2 /usr/bin/gcc-4.2

And yeah it works now, bundle update rails ran successfully now :)


我的 SSH config

如果你跟我一樣有用 Heroku,相信你都有遇到過有兩個 accounts 的問題。每個 ssh key 只能上傳到一個 account。假如你想 git clone 兩個不同 account 的 projects 的話,就會發現單純 heroku login 幫不到忙。

這是因為 git clone 靠 ssh 來 authenticate 的。但 heroku login 不會更改你的 ssh keys,也不會自動選用合適的那條 key。

一個簡單的解決方法就是用 ~/.ssh/config

現況

首先先說明一下我的實際情況。

  1. 個人 account
    • peter@peterwongpp.com
    • ssh key: ~/.ssh/id_rsa
  2. 公司 account
    • peter@primitus.com
    • ssh key: ~/.ssh/primitus_heroku

這兩條 keys 以以下分式 upload 的:

#!bash
$ heroku login
Email: peter@peterwongpp.com
Password (typing will be hidden):
Authentication successful.

$ heroku keys:add
Found the following SSH public keys:
1) id_rsa.pub
2) primitus_heroku.pub
Which would you like to use with your Heroku account? 1

$ heroku login
Email: peter@primitus.com
Password (typing will be hidden):
Authentication successful.

$ heroku keys:add
Found the following SSH public keys:
1) id_rsa.pub
2) primitus_heroku.pub
Which would you like to use with your Heroku account? 2

問題

但現在應該會有如下的 error:

#!bash
$ git clone git@heroku.com:primitus-project.git
Cloning into 'primitus-project'...

 !  Your key with fingerprint ...... is not authorized to access primitus-project.

fatal: The remote end hung up unexpectedly

解決

首先是 ~/.ssh/config(如沒有請自行建立)

#!bash
Host HerokuPrimitus
  HostName heroku.com
  User git
  IdentityFile ~/.ssh/primitus_heroku
  IdentitiesOnly yes

簡單來說就是用 HerokuPrimitus 來代替 heroku.com,但指定了 ssh key。(另外也可以指定 port number etc)

然後是再來 git clone

#!bash
$ git clone git@HerokuPrimitus.com:primitus-project.git
Cloning into 'primitus-project'...
remote: Counting objects: ......