2014年10月1日 星期三

iOS 開發筆記 - -[######## _viewControllerForSupportedInterfaceOrientationsWithDismissCheck:]: unrecognized selector sent to instance 0x########'

這幾晚和此 crash log 對抗了一下 Orz 這是一個在 iOS 8 才出現,但在 iOS 7 可以活得好好的 bug ,簡介一下狀況:

  • Project 採用 SingleView 建立,簡稱 ViewController1
  • 在 ViewController1 中,動態建立 UINavigationController ,並 push ViewController2 後,再透過 presentViewController 呈現,也就是在 ViewController1 沒有 UINavigationController 但 ViewController2 有。
  • 在 ViewController2 中,此 shouldAutorotate 皆回傳 YES

接著,只要在 ViewController2 中,透過 dismiss 返回到 ViewController1 時,再進行 device rotation 後,這時就會看到 crash log。但一樣的 code 擺在 iOS 7 卻能夠正常運作,並且可透過時間差進行 device rotation 觀看出發動 _viewControllerForSupportedInterfaceOrientationsWithDismissCheck 的物件,並非固定:

  • -[__NSCFString _viewControllerForSupportedInterfaceOrientationsWithDismissCheck:]: unrecognized selector sent to instance 0x########
  • -[UIStatusBarStyleRequest _viewControllerForSupportedInterfaceOrientationsWithDismissCheck:]: unrecognized selector sent to instance 0x########
  • -[__NSBlockVariable__ _viewControllerForSupportedInterfaceOrientationsWithDismissCheck:]: unrecognized selector sent to instance 0x########
  • ...

解法?就是從 ViewController1 就開始用 UINavigationController 吧!接著都走 UINavigationController 控制方式,例如 push、pop 後,即可避開這奇妙的問題。

2014年9月28日 星期日

iOS 開發筆記 - iPhone Simulator Document Path

開發 iOS app 時,若有資料儲存時,常常會想直接去翻 iPhone Simulator 的真實儲存位置,久了就記住位置:

$ ls ~/Library/Application\ Support/iPhone\ Simulator/7.1/Applications/

最近改用 iOS 8 時,卻找不到 8.0 位置 XD 直到在 App 中印出位置才得知換了,粗略位置:

$ ls ~/Library/Developer/CoreSimulator/Devices/########-####-####-####-###########/data/Containers/Data/Application/

2014年9月22日 星期一

[OSX] 找尋 ISO 639 和 ISO 3166 定義的 language list @ Mac OS X 10.9.5

想說翻一下 wiki 又有點 ooxx... 偷問一下高手,高手非常直觀地跟我說,用一下 /usr/share/locale !

由於我是用 Mac OS X ,該產品語言已經做得很不錯了!果真的輕輕鬆鬆找出我要的東西:

$ ls /usr/share/locale | grep -v "\\." | grep "_"
af_ZA
am_ET
be_BY
bg_BG
ca_ES
cs_CZ
da_DK
de_AT
de_CH
de_DE
el_GR
en_AU
en_CA
en_GB
en_IE
en_NZ
en_US
es_ES
et_EE
eu_ES
fi_FI
fr_BE
fr_CA
fr_CH
fr_FR
he_IL
hr_HR
hu_HU
hy_AM
is_IS
it_CH
it_IT
ja_JP
kk_KZ
ko_KR
lt_LT
nl_BE
nl_NL
no_NO
pl_PL
pt_BR
pt_PT
ro_RO
ru_RU
sk_SK
sl_SI
sr_YU
sv_SE
tr_TR
uk_UA
zh_CN
zh_HK
zh_TW


高手獻技:

$ cd /usr/share/locale && echo ??_??
af_ZA am_ET be_BY bg_BG ca_ES cs_CZ da_DK de_AT de_CH de_DE el_GR en_AU en_CA en_GB en_IE en_NZ en_US es_ES et_EE eu_ES fi_FI fr_BE fr_CA fr_CH fr_FR he_IL hr_HR hu_HU hy_AM is_IS it_CH it_IT ja_JP kk_KZ ko_KR lt_LT nl_BE nl_NL no_NO pl_PL pt_BR pt_PT ro_RO ru_RU sk_SK sl_SI sr_YU sv_SE tr_TR uk_UA zh_CN zh_HK zh_TW


後來又找到對應表: http://www.localeplanet.com/icu/

<?php
// http://www.localeplanet.com/icu/
$lang_map = array(
        'af_ZA' => 'Afrikaans (Suid-Afrika)',
        'am_ET' => 'አማርኛ (ኢትዮጵያ)' ,
        'be_BY' => 'беларуская (Беларусь)' ,
        'bg_BG' => 'български (България)',
        'ca_ES' => 'català (Espanya)',
        'cs_CZ' => 'čeština (Česká republika)',
        'da_DK' => 'dansk (Danmark)',
        'de_AT' => 'Deutsch (Österreich)',
        'de_CH' => 'Deutsch (Schweiz)',
        'de_DE' => 'Deutsch (Deutschland)',
        'el_GR' => 'Ελληνικά (Ελλάδα)',
        'en_AU' => 'English (Australia)',
        'en_CA' => 'English (Canada)',
        'en_GB' => 'English (United Kingdom)',
        'en_IE' => 'English (Ireland)',
        'en_NZ' => 'English (New Zealand)',
        'en_US' => 'English (United States)',
        'es_ES' => 'español (España)',
        'et_EE' => 'eesti (Eesti)' ,
        'eu_ES' => 'euskara (Espainia)',
        'fi_FI' => 'suomi (Suomi)',
        'fr_BE' => 'français (Belgique)',
        'fr_CA' => 'français (Canada)',
        'fr_CH' => 'français (Suisse)',
        'fr_FR' => 'français (France)',
        'he_IL' => 'עברית (ישראל)',
        'hr_HR' => 'hrvatski (Hrvatska)',
        'hu_HU' => 'magyar (Magyarország)',
        'hy_AM' => 'Հայերէն (Հայաստանի Հանրապետութիւն)',
        'is_IS' => 'íslenska (Ísland)',
        'it_CH' => 'italiano (Svizzera)' ,
        'it_IT' => 'italiano (Italia)',
        'ja_JP' => '日本語(日本)',
        'kk_KZ' => 'kk_KZ',
        'ko_KR' => '한국어(대한민국)',
        'lt_LT' => 'lietuvių (Lietuva)',
        'nl_BE' => 'Nederlands (België)',
        'nl_NL' => 'Nederlands (Nederland)',
        'no_NO' => 'no_NO',
        'pl_PL' => 'polski (Polska)',
        'pt_BR' => 'português (Brasil)',
        'pt_PT' => 'português (Portugal)',
        'ro_RO' => 'română (România)',
        'ru_RU' => 'русский (Россия)',
        'sk_SK' => 'slovenčina (Slovenská republika)',
        'sl_SI' => 'slovenščina (Slovenija)',
        'sr_YU' => 'sr_YU',
        'sv_SE' => 'svenska (Sverige)',
        'tr_TR' => 'Türkçe (Türkiye)',
        'uk_UA' => 'українська (Україна)',
        'zh_CN' => '中文(简体中文、中国)',
        'zh_HK' => '中文(繁體中文,中華人民共和國香港特別行政區)',
        'zh_TW' => '中文(繁體中文,台灣)'
);

2014年9月19日 星期五

[OSX] 使用 App Store 更新 Xcode 發生錯誤 @ Mac OS X 10.9.5, MBA


主因也有可能是空間太少了 :P
除了準備空間外,可以試看看 App Store Debug 界面:

$ defaults write com.apple.appstore ShowDebugMenu -bool true

接著重新打開 App Store 後,上方最右邊有 Debug 選項 -> Reset Application,大概多做幾次即可。如果很不幸的一直不幸,最終解法就是反安裝後,再下載。

2014年9月18日 星期四

iOS 開發筆記 - 驗證 Apple Push Notification PEM File 以及 Remove PEM Password

半年前曾開發過: 使用 Apple Push Notification service (APNs),最近更新 PEM  後,要驗證一下 PEM 是否正確。

驗證還滿簡單的,單純用 openssl 進行,假設是 dev 模式,對象就是 snadbox:

$ openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert cert.pem -key key.pem

其中 cert.pem 跟 key.pem 也可以合在一起:

$ cat cert.pem key.pem > out.pem
$ openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert out.pem


假設產出的 key.pem 有密碼保護,為了圖方便想要去密碼的話,可以用:

$ openssl rsa -in key.pem -out nopass.pem

如此一來就搞定了,若測試的是 Production PEM ,記得改用 gateway.push.apple.com:2195 即可。

$ openssl s_client -connect gateway.push.apple.com:2195 -cert cert.pem -key key.pem