2013年1月19日 星期六

這是100k的最好時代,也是22k的最壞時代




"這是最好的時代,也是最壞的時代”(狄更斯) 
”這是100k的最好時代,也是22k的最壞時代”(彼得潘)

最近22k話題殺很大,面臨22k處境的台灣看來應該是處於最壞的時代吧。其實彼得潘和”下班後的黃金8小時”作者都覺得現在是最好的時代。從前如果不是含著金湯匙出生,大概只能靠”十年寒窗無人問,一舉成名天下知”。但是現在處處都存在著機會,科技的進步讓我們不再受限於距離,住在北極的聖誕老人也可能是我們的顧客。對程式有興趣的,創作App一天可以賺3萬。對寫作有興趣的,電子書, blog讓我們出書更容易。對環遊世界有興趣的,邊玩還能邊做旅遊節目主持人。對唱歌有興趣的,滿目的選秀比賽任君挑選。

現在到底是一個什麼樣的時代呢?它可能是個什麼事情都可以帶來財富,帶來快樂,輕易100k的時代,但也可能是22k的最壞時代。最好,最壞,全看我們如何運用,如何把握一天的24小時。


2013年1月15日 星期二

暗藏殺機的App隱私權限設定

作為和使用者日夜相伴的iPhone,其上頭已經藏有太多私人的私密資料。為了防止陳冠希的照片事件重演,Apple在iOS 6更為重視使用者的隱私。如今App在存取使用者的照片,行事曆,通訊錄等私密資訊時,都需要先 徵求使用者的同意。而使用者也可以隨時改變心意,從”設定"App裡改變某個App存取個人資料的權限。

如下圖所示,從"設定"App -> 隱私 -> 行事曆,我們可以看到存取行事曆的App。每個App旁邊有個開關,控制著此App是否有權存取行事曆。

       

然而,誰也想不到,只是小小地調整開關,改變App存取的權限,竟會帶來殺機!"君要臣死,臣不得不死",在iOS的世界,為了一些正當且不得不的理由,系統有時會痛下殺手,偷偷地將背景中的App殺掉。最常見的原因莫過於系統的記憶體不足,所以只能把那些在背景中佔據大量記憶體的App殺掉,以挪出空間給目前真正跟使用者互動的前景App。而當我們修改App的隱私權限,比方將LOCOMO App存取行事曆的權限從on變為off,將使得LOCOMO App被系統殺掉,立即上天堂,如以下Apple的技術文件所說:if permissions changes, app is quit


其實這也不能完全怪系統。系統這麼做是有原因的。唯有這樣做,才能真正保護使用者的隱私。比方原本彼得潘同意LOCOMO存取行事曆,但後來彼得潘想想沒有人是可以信任的,約會的行程最好還是不要給第三人知道,因此決定將LOCOMO存取行事曆的權限關掉。此時系統若不馬上終結LOCOMO App的生命,將讓原本正在執行中的LOCOMO繼續在它自以為有權存取行事曆的假設下執行,可能會產生難以預料的可怕後果。







2013年1月14日 星期一

快速取得unix time對應的Mac系統時區時間

關於時間的問題,找Python大神就對了。經由Mac內建的python,我們可以很方便地查詢unix time對應的Mac系統時區時間:

1. 啟動terminal

2. $ python
python
Python 2.7.2 (default, Jun 20 2012, 16:23:33)
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>


3. >>>  from datetime import datetime

4. >>>  datetime.fromtimestamp(1358171586.312390)
datetime.datetime(2013, 1, 14, 21, 53, 6, 312390)

輸入unix time 1358171586.312390,
回報對應到目前Mac系統時區的時間2013年1月14日晚上9點53分6秒


2013年1月12日 星期六

好東西就是要和好朋友分享: Reminders分享

Mac和iOS上的Reminders讓我們可以很方便地設定提醒事項,有了它的貼心提醒,理論上,彼得潘跟女朋友約會不再遲到,期末考高分過關,寫書也不再拖稿。

結合強大的iCloud,不只設定彼得潘帳號的iPhone, iPad, Macbook Pro Retina可以共用存取同一份資料,所謂好東西要和好朋友分享,我們也可以分享給有iCloud帳號的好朋友。接下來,彼得潘將以小時候的偶像梁朝偉作品集為例子,說明如何分享彼得潘花費一生精力整理的”梁朝偉作品集”給朋友。


1. 在Mac上啟動Reminders App,新增”梁朝偉作品集”。




2. 點選右邊的分享圖示,輸入分享的對象

將滑鼠游標移至梁朝偉作品集的右手邊,將浮現”分享圖示”,點選後即可呼喚出分享視窗,於其中輸入分享對象的email。



3. 被分享的對象,將收到通知的email。

放心,這不是紅色炸彈,不會讓你的銀行戶頭少一毛錢。email內容明白說明了分享的內容為”梁朝偉作品集”,如果你也像彼得潘一樣是梁朝偉的粉絲,就可以開心地點選Join Reminders,共享此份清單了。



4. 登入iCloud網站。
https://www.icloud.com

被分享的對象,可以在任何有設定iCloud Reminders同步的機器上看到”梁朝偉作品集”。即使沒有也不用心灰意冷,埋怨老爸不是李嘉誠,沒錢買iPhone 5。只要從瀏覽器上網,以被分享的帳號登入iClound網站,一樣可以看到分享的內容。




點選網站上的Reminders Icon進入Reminders頁面。



Reminders網頁成功顯示彼得潘分享的”梁朝偉作品集”。Apple果然一視同仁,不會因為對方從Windows的IE登入,就不讓他看到分享的內容。





2013年1月8日 星期二

明明就 明明就 明明就播放了,怎麼會聽不到呢?

播放音樂,透過iOS的AVAudioPlayer物件,成為一件再簡單不過的事。以下為播放音樂的標準程序:


 NSString *path = [[NSBundle mainBundle] pathForResource:@"明明就.m4a" ofType:nil];
 NSURL *url = [NSURL fileURLWithPath:path ];
 AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
 [audioPlayer play];
說明:
(1) NSString *path = [[NSBundle mainBundle] pathForResource:@"明明就.m4a" ofType:nil];
      NSURL *url = [NSURL fileURLWithPath:path ];

取得周杰倫的最新主打歌”明明就”的檔案路徑,然後建立NSURL物件。

(2)  AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];

建立專長播放音樂的AVAudioPlayer物件audioPlayer,只要 透過檔案路徑的url點歌,它即可正確無誤的播出歌曲,完全不會忘詞。

(3)  [audioPlayer play];

開始播放

如此簡單的程序,彼得潘馬上寫了個測試程式,在畫面上加入周杰倫新專輯的封面圖片做為按鈕,在按鈕被點選時的Touch Up Inside event觸發呼叫method
  - (IBAction)playMusic:(id)sender, 而此method的定義當然就是剛剛那一段程式碼。



明明就 明明就 明明就播放了,怎麼會 怎麼會 怎麼會聽不到呢? 連前奏也不給我們聽。失戀已經夠難過了,更難過的是連失戀情歌都聽不到。難道連iPhone都如此無情嗎?

iPhone當然是有情有義呀。問題完全出在我們寫的程式碼裡,和iPhone無關。我們剛剛在playMusic: method裡宣告AVAudioPlayer物件, 因此它是一個local變數,它的生命週期將隨著method執行完畢而終結。iPhone CPU的快是名震天下的,此method不用一秒鐘的時間就執行完了,我們當然聽不到一丁點的音樂呀。

現在彼得潘在原來的[audioPlayer play];後加入以下程式碼,

    [NSThread sleepForTimeInterval:10];

此行程式碼將延長此method的執行時間,要10秒後此method才執行完畢。當我們再此執行App後,終於可以聽到前奏了,但是只維持了10秒,還來不及聽到周杰倫的歌聲。


為了聽到完整歌曲,我們是要把sleep的時間加大,變大到300秒嗎? 當然不是,這不是個好方法。尤其像這種失戀時聽的情歌,最好是24小時不間斷地重覆播放,我們永遠無法確定要傳入多大的數字,有些人可能失戀療傷只要一天,有些人卻需要一年365天一直聽”明明就”呀

一勞永逸的方法很簡單,我們只要將AVAudioPlayer物件宣告為物件的member,而不是local變數,即可讓此物件不會因method執行結束而跟著死去。在剛剛的例子裡,彼得潘將AVAudioPlayer物件宣告為負責主畫面的ViewController的member。

@interface ViewController : UIViewController
{
    AVAudioPlayer *audioPlayer ;
}

然後將ViewController的playMusic: method稍做修改

- (IBAction)playMusic:(id)sender {
    
    NSString *path = [[NSBundle mainBundle] pathForResource:@"明明就.m4a" ofType:nil];
    NSURL *url = [NSURL fileURLWithPath:path ];
    audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
    audioPlayer.numberOfLoops = -1;
    [audioPlayer play];
    
}
說明:
(1)  audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];

audioPlayer不再是local變數,生命不再因playMusic: method執行結束而終結。

(2)  audioPlayer.numberOfLoops = -1;

將AVAudioPlayer物件的numberOfLoops設為負數時,音樂將不間斷地重覆播放,直到我們走出失戀情傷,結束App,才會停止音樂的播放。




2013年1月3日 星期四

數位藏寶箱iTunes 11 (PC home 2013.1)






幸福插畫mini.Hana的Collection View (MacToday 2013. 1)






iOS 6 全新推出的 collection view 元件,讓我們更容易在畫面上呈現整理好的大量資料,比方結婚時分享的甜蜜照片集,神秘的X 檔案清單等。雖然說傳統的 table view或scroll view也能勝任這些工作,但是畢竟它們是舊時代的產物,在許多方面早已跟不上新時代的腳步,接下來就讓我們好好深入了解collection view,學習利用它呈現可愛的 mini.Hana插畫圖 片,實現在傳統table view需要大費周章才能實現的功能。