2012年12月29日 星期六

取得存取Google雲端服務的API Key

Google身為雲端的霸主,提供許多免費好用的雲端服務。然而Google也是有經濟壓力的,為了怕破產,定了一定數量的存取上限。當以不具名的使用者身份連結網址,存取雲端服務時,如果那天存取雲端服務的API reqeust數量已超過上限,此時我們將暫時無法取得資料,只能好好地睡一覺,等隔日reqeust數量歸零重計,才能存取。

不過為了滿足需要大量呼叫API的需求,Google也提供了另一個機制。如果在呼叫API時搭配API key,到時候reqeuest數量的限制將綁定此API key,而不用像不具名存取那樣,和其它人一同共享API reqeust數量。

一個google帳號可以建立多個project,而每個project都有自己獨一無二的API key。因此,我們只要建立project,即可擁有API key,利用它來存取雲端服務。以下彼得潘將一步步介紹取得Google API key的流程:


1. 登入google帳號

2. 連到Google API Console頁面
https://code.google.com/apis/console/

3. 點選Create project按鈕

如果之前沒有建立任何的project,將看到Create Project的按鈕。請點選它以建立project, 取得API key。


4. 點選左邊選單區塊裡的Services,進入Services分頁。

預設建立的project名稱為API Project。在Services分頁我們可以看到Google提供的各項Service,以及每個Service每天的使用上限。一開始所有的Service權限都是關閉的,必須將權限打開才能存取。(Service status設為On)如圖所示,我們想要使用Calendar API,因此將其設為On。




5. 點選左邊區塊的API Access,查詢API key。

API key只能用來存取和使用者無關的資料。如果想要存取使用者的資料,還需要搭配OAuth token。




6. 查詢API使用的數據

點選左邊區塊的Reports,可查詢API的Request數量,檢查是否超過上限。如圖所示,我們的Calendar API request數量已經達到上限10k,因此使用者將無法再存取,只能明日再戰。



7. 建立新的project

點選Project名稱後,從下拉選單裡可點選Create建立Project。記住,API request的上限是綁定API key,也就是綁定project。因此不同的project,API request數量是獨立分開計算的,不會互相影響。





2012年12月28日 星期五

使用Urban Airship廣播

1. 登入urban airship網站

http://urbanairship.com

2.  進入某個App的頁面

3. 點選Push  -> Send Broadcast進行廣播



4. 設定推播內容

(1) Badge:  App Icon上顯示的數字

(2) Alert: 推播的訊息

(3) Sound: 使用者收到推播時發出的音效。

     default將播放內建的收到訊息音效。如果此欄位留白,將產生無聲的推播。


點選"Send it"即可送出推播。






2012年12月26日 星期三

政大資管演講

感謝政大資管送的杯子。聽到台下政大學生們的笑聲,彼得潘就感覺不虛此行了。年輕真好,相信政大的學生們未來也將展開屬於自己的逐夢旅程。







2012年12月23日 星期日

Mac上的檔案分享,打造新歡舊愛間愛的連線

彼得潘的舊愛Macbook上存有許多不能說的秘密,有了新歡Macbook Pro Retina後,為了保險起見,決定趕快來打造新歡和舊愛間愛的連線,將舊愛上的機密文件分享給新歡,讓親歡也能知道這些不能說的秘密。

於欲分享檔案的舊愛Macbook上做設定:

1. 啟動系統偏好設定 App

2. 點選"共享"進入分享頁面。



3.  勾選"檔案共享" 

設定分享的資料夾和允許存取資料夾的使用者。當連線的使用者以此台Mac上存在的帳號登入時,預設即可存取此帳號下的所有東西,不需額外設定。在此畫面我們可以看到此台Mac的IP 192 .168.2.105,請一定要記得此IP, 它就像我們打給女朋友播的電話號碼般重要,到時候連線就靠它了。



如果存取分享檔案的電腦也是Mac,將透過Mac的AFP機制連線,AFP連線的大門預設即是開啟的。但若不幸想以Windows連到Mac,必須經由坎坷的SMB連線。Mac和Windows之間水火不容,所以此連線想當然預設是封閉的,需要額外啟動。請點選"選項"按扭進入設定頁面啟動SMB。



從新歡Macbook Pro Retina連線到舊愛Macbook

1. 點選Finder App menu上的Go -> Connect to Server 開啟愛的連線



2.  輸入舊愛的IP。


3. 輸入登入的帳號和密碼


4. 選擇要存取的資料夾。



若是愛的連線成功建立,我們即可直接經由Finder存取舊愛Macbook上的檔案,它將對我們毫無保留,讓我們看得清清楚楚。(其實也不是毫無保留啦,一切都依當初設定此帳號可以存取哪些資料夾) 

ps: 藍色圖示,3個人手牽手的硬碟圖示即表示此為經由網路分享連線到的硬碟。至於為什麼是3個人,跟劈腿是否有關係,這點彼得潘就不予評論了。



安藤忠雄,自學一年內讀完大學四年的教科書




"安藤忠雄,靠自學一年內讀完大學四年的教科書。" 遙想彼得潘大學時候也是浪費時光,睡到中午,半夜3,4點才睡,期末考前一天不睡念考古題就可以過關。 所以大學真的需要唸4年嗎? 根本不用,4年是為了讓我們花時間體驗老師不會教的事情,像是愛情,友情,社團。雖然說老師的確不太會教,唯有自己能像安藤忠雄一樣自修,無師自通的東西才是自己的。學問要靠自己學,而不是等別人來教。彼得潘的App也是自學的,老師就是大量的好書。希望未來彼得潘可以寫出更多的好書讓大家自學,學校是來談戀愛,交朋友的,學習還是要靠自己。



2012年12月20日 星期四

Finder上顯示硬碟的剩餘空間

現在的硬碟愈來愈大,已經成長到從前無法想像的T的境界。可惜貪心是人類的天性,當我們賺得愈多,硬碟空間愈大時,往往也花得愈凶,存入愈多的檔案。

Finder預設並沒有顯示硬碟的剩餘空間,為了怕不小心塞爆硬碟,我們還是解開封印,時時刻刻提醒自己硬碟的剩餘空間比較保險。

解除封印:
點選Menu上的"顯示方式" -> "顯示狀態列", 即可顯示硬碟剩餘空間。





如圖所示,狀態列位於Finder視窗的下方,清楚地告訴著我們還有458MB的空間,雖然尚有空間,但已經無能為力再容納最新的電影,該是加顆硬碟的時候了。


Macbook Pro 15 Retina

Macbook Pro 15 Retina入手,不為什麼,只為愛瘋一切為蘋果! 希望它能伴著彼得潘創作更多App程式設計的相關書籍。



2012年12月16日 星期日

推播音效任我訂,尖叫尖笑都可行 ( 彼得潘App程式設計第101式)



UILocalNotification物件有個NSString型別的soundName property,正是讓我們設定音效的。UILocalNotificationDefaultSoundName將播放內建的提醒音效,也就是我們收到簡訊時聽到的聲音。


    UILocalNotification *localNotification = [[UILocalNotification alloc] init];

   localNotification.soundName = UILocalNotificationDefaultSoundName;

除了內建的音效,我們也可以自訂音效,不管是嚇死人的驚聲尖叫還是笑死人的驚聲尖笑都可以,只要將soundName指定為音效檔的檔名(記得要事先將音效檔加到專案裡),例如以下程式碼:

       localNotification.soundName = @"test.wav";



不過對於推播的音效檔,Apple倒是有以下2點限制:
a. 檔案必須是caf, wav或是aiff格式。
b. 聲音長度必須少於30秒,否則將播放內建的提醒音效。

若是指定的soundName檔案不存在,也會播放內建的提醒音效。

一般我們經由iTunes將CD存入Mac的音樂都是m4a的格式,若是想轉為推播格式,可於Terminal輸入以下指令輸出caf檔。

    afconvert  你就是我要的.m4a  你就是我要的.caf -d ima4 -f caff –v

2012年12月13日 星期四

mini.Hana幸福插畫











mini.Hana幸福插畫上架了,同時支援3.7和4吋的大螢幕唷,明天拿到iPhone 5的朋友們就可以馬上下載了,希望能帶給大家溫暖幸福的Christmas。 

2012年12月12日 星期三

南台科大演講

主題  1. 彼得潘的App逐夢之旅
          2. App學習和工作之道






2012年12月6日 星期四

就算在背景,也要幸福地輪播音樂

在神聖的iOS國度裡,並不是所有事情都能夠在背景執行,然而音樂絕對是享有特權,能夠在背景繼續運作的第一人選。畢竟音樂的魔力實在是無人可檔,幾乎沒有人可以不拜倒在她的石榴裙下。

只要照著SDK文件的設定,即可輕易實現背景音樂播放的功能。然而,如此的背景音樂播放其實是有缺陷的,我們只能聽一首歌。若是那首歌當初設為重覆播放,那麼結果稍微好一點,我們可以無限地聽著同一首歌,直到世界末日。即便我們定義了audioPlayerDidFinishPlaying:successfully: method (此method將在一首歌播完時被呼叫),在曲終人未散時設定播放下一首,下一首的旋律卻讓我們望穿秋水,永遠苦等不到。

想要在背景實現輪播歌曲,其實很簡單,只要加入以下程式碼,然後再於audioPlayerDidFinishPlaying:successfully:設定每次歌播完時,下一首播放的歌曲即可:

    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];


此段程式碼其實很強大,讓我們在背景換歌只是它的雕蟲小技。當我們在iPhone桌面連按2下home鍵,再向右一滑時,即可浮現音樂控制選單,讓我們控制App裡音樂的播放。不過控制音樂這部分還需要補上額外的程式碼才能實現,目前這些按鍵不只按了不聽話,沒反應,也不會顯示任何歌名。




不過今天我們就先聊到這吧,已經辛苦地解決了音樂無法輪播的大難題,接下來就讓我們幸福一下,從youtube享受幸福三部曲的音樂輪播吧。









2012年12月5日 星期三

Mac OS X郵件妙管家 (PC home 2012.12)



收發Email,可說是現代人每天除了吃飯,睡覺,上網外必做的第4件大事。雖然透過瀏覽器我們也能處理郵件,然而就像狡兔有三窟一樣,有些人需要同時申請多個email帳號,以應付來自世界各地的女朋友。在瀏覽器上一一登入不同的帳號收發信件,一來麻煩,二來不方便管理。幸好,Mac就像小叮噹的百寶袋般,什麼都有。內建的郵件App讓我們輕鬆管理來自不同帳號的信件。接下來,和彼得潘同月同日生的超人氣Model LUCY,將擺出最可愛的Pose,為大家介紹郵件妙管家的獨特魅力! (LUCY粉絲團Love LUCY Love: http://www.facebook.com/Love.Lucy.fans)

2012年12月4日 星期二

排版精算師 Autolayout (MacToday 2012. 12)




Autolayout是iOS 6全新推出的強大App排版功能。有了Autolayout,即使出現像星際大戰光劍那麼長的iPhone 99,或是期待中的大螢幕iTV,我們精心設計的App版面也不會出問題,因為Autolayout將聰明地依據我們設定的條件計算每個元件該顯示的大小和位置。接下來,就讓幸福插畫品牌Hana Mina超可愛的顆顆寶寶來為我們呈現Autolayout神乎奇技的巧妙排版吧 ~ 。

2012年11月30日 星期五

背景GPS模式提醒

Apple貼心地開放了某些功能,讓App即使進入了不見天日的背景模式,依然可以繼續執行這些功能。但是,如果選擇的是耗電的背景GPS偵測模式,請記得要在App Store上的App介紹提醒使用者,不然可是會讓Apple reject的! 


    

為了不被Apple reject,請記得加入以下文字



   

2012年11月29日 星期四

不再念舊,只保留@2x圖檔的國王新衣陷阱

iPhone就像美麗的model LUCY一樣,不只有內在,同時也有難以抗拒的外在。iPhone外觀的優點,就像LUCY美麗的點,十根手指也數不完。不過如果非要選出代表性的,想當然是高解析度的Retina螢幕當仁不讓地中選。

有了Retina螢幕,App可以呈現更高解析度,更高畫質的圖片。然而美麗是有代價的,一個不小心,可是會開天窗,變成國王的新衣,什麼都看不到! 接下來彼得潘將以LUCY的2張美麗照片為例,說明retina顯示暗藏的致命陷阱。

左邊的圖片為lucy.jpg,右邊為lucy@2x.jpg。聰明的iPhone在顯示圖片時,將根據檔名做判斷,加了@2x的圖片將現身於retina的高解析度螢幕,而少了@2x加持的圖片只有念舊仍然拿著低解析度iPhone的使用者看得到。




因此,當我們執行以下程式碼後,顯示結果如下:


self.imageView.image = [UIImage imageNamed:@"lucy.jpg"];



舊型iPhone (例如iPhone 3GS)



retina糖衣加持的新型iPhone (例如iPhone 5)




雖然念舊是個好習慣,不過有些時候人要向前看,像是為了促進經濟發展買iPhone 5,為了不讓新女友難過忘了舊情人。為了減少App的size,彼得潘決定將lucy.jpg狠心從App刪除,只保留lucy@2x.jpg。如果以剛剛的程式碼在舊型的iPhone再跑一次,結果如下:



iPhone真聰明,自動地將lucy@2x.jpg縮小,顯示於舊解析度的螢幕上。然而條條大路通羅馬,顯示圖片的方法也不只一種,如果採用以下方法,LUCY就像變魔術般,從螢幕上整個消失不見!


NSString *path = [[NSBundle mainBundle] pathForResource:@"lucy.jpg" ofType:nil];
NSLog(@"path %@", path);
self.imageView.image = [[UIImage alloc] initWithContentsOfFile:path];






說明:
線索其實很明顯。印出的Log訊息如下:

    path (null)

剛剛的程式碼,我們先取得圖檔的檔案路徑。然後再以UIImage的initWithContentsOfFile: method,傳入檔案路徑來設定顯示的圖片。但別忘了lucy.jpg早已不存在App裡,只留在彼得潘的記憶深處呀。 因為取得的檔案路徑path是空的,因此UIImageView完全不知道要顯示哪一張圖片,也就只能開天窗,一片空白了。



因此,如果堅持要使用 initWithContentsOfFile:來設定顯示的圖片,請記得要加下@2x,如此美麗的LUCY就可以再度出現在我們的眼前了。

NSString *path = [[NSBundle mainBundle] pathForResource:@"lucy@2x.jpg" ofType:nil];


2012年11月24日 星期六

不能說的秘密,就讓NSNotificationCenter來傳遞吧

利用NSNotificationCenter產生通知,我們可以輕易地讓不同物件跨越空間時間溝通。接下來彼得潘將以電影"不能說的秘密"舉例說明,女主角小雨,男主角彼得潘,男配角葉湘倫之間不能說的秘密,就讓NSNotificationCenter來為他們傳遞吧。

1. 定義Person類別


@interface Person : NSObject

@property (nonatomic, strong) NSString *name;

@end


2. 建立故事的三個主人翁


smallRain = [[Person alloc] init];
smallRain.name = @"小雨";

peterPan = [[Person alloc] init];
peterPan.name = @"彼得潘";

noBody = [[Person alloc] init];
noBody.name = @"葉湘倫";

3.  設計App畫面



畫面上加入按鈕(UIButton),按鈕的圖片上顯示小雨在大雨中對著天空吶喊的問題。


4. 傳送"不能說的秘密"通知

將按鈕的Touch Up Inside event連結至buttonPressed: method,並定義此method。我們已經看到按鈕上小雨詢問的問題了。為了不讓她等太久,我們希望按鈕按下時,馬上回應小雨。因此buttonPressed: 的定義如下:

- (IBAction)buttonPressed:(id)sender {
         [[NSNotificationCenter defaultCenter] postNotificationName:@"不能說的秘密" object:peterPan userInfo:@{@"答案":@"我在這邊,你在那邊,愛像風箏一條線,我經過千山萬水 停在這個定點,帶我的心,到你的世界"}];
}

說明:
利用NSNotificationCenter物件的postNotificationName:object:userInfo: method,我們可以發送通知讓對方知道,此method的定義如下:

- (void)postNotificationName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo;

(1)aName: 通知的名稱。在這裡我們傳入"不能說的秘密"。到時候只有表明想收到"不能說的秘密"通知的物件,才會收到此通知。

(2) anObject: 發送通知的物件。 在這裡我們傳入peterPan,表明peterPan是真心回應小雨的Mr.Right。若是想要匿名也是可以,只要傳入nil,對方即無法知道通知的來源,但如此有可能造成對方收不到通知,等會我們會說明。

(3) aUserInfo: 想讓接收物件知道的額外資訊。由於是NSDictionary型別,所以基本上我們可以傳入任何的資訊。在此我們傳入彼得潘想對小雨說的話( 其實此段話為伍思凱"這邊那邊"的歌詞)。

5. 申請接收"不能說的秘密"通知

 [[NSNotificationCenter defaultCenter] addObserver:smallRain selector:@selector(get:) name:@"不能說的秘密" object:peterPan];

小雨為了要收到彼得潘的回應,她必須先申請接收"不能說的秘密"通知。利用NSNotificationCenter物件的addObserver:selector:name:object: method,小雨可以讓自己收到通知,此method的定義如下:

- (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject;

(1) observer: 接收通知的物件,在此我們傳入smallRain,如此小雨即可收到通知。

(2) aSelector: 收到通知後執行的method。 小雨收到通知後,可能大哭,也可能大笑。不過別忘了我們是導演,我們傳入@selector(get:),等會再來定義get:。值得注意的,observer和aSelector是對應的,所以到時候get:將是定義在smallRain Person型別裡的method。

(3) aName: 通知的名稱,在此我們理所當然傳入"不能說的秘密"。

(4) anObject: 指定發送通知的對象。只有當通知是由此對象發送時,observer才會收到通知。在此我們傳入peterPan,所以只有當通知是由彼得潘發出時,小雨才會收到通知,get: method才會被呼叫。如果傳入nil了話,表示observer願意接收任何物件發出的"不能說的秘密"通知。因此如果傳入nil,小雨就可以收到葉湘倫發出的通知。但小雨是個專一的人,她的眼中只看得到彼得潘,看不到葉湘倫,所以我們還是傳入peterPan吧。

6. 定義小雨收到通知後執行的get: method (在Person.m裡)

-(void)get:(NSNotification*)noti
{
    Person *person = noti.object;
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:noti.userInfo[@"答案"] message:nil delegate:self cancelButtonTitle:person.name  otherButtonTitles:nil];
    [alertView show];    
}
說明:
NSNotification物件的object將等同發送通知的物件,也就是彼得潘。而NSNotification物件的userInfo則等於當初彼得潘發送通知時傳入的userInfo,因此從key"答案",我們可以取得彼得潘想說的話。當小雨看到彼得潘的回應時,感動地大聲朗誦出來,因此我們以UIAlertView在畫面上加以呈現。

執行App:

按下按鈕後,彼得潘果真回應了小雨,而小雨也收到了,因此我們在畫面上看到訴說著"我在這裡 ... "的UIAlertView。



如果當初發出通知的是代表葉湘倫的noBody,即便他很深情的以林俊傑"你要的不是我"的歌詞來回應,由於小雨早已指定只接收來自彼得潘的通知,所以小雨永遠也不會收到葉湘倫的訊息。

 [[NSNotificationCenter defaultCenter] postNotificationName:@"不能說的秘密" object:noBody userInfo:@{@"答案":@"你要的不是我,心碎的失去輪廓,曾經給你的感動,只是情緒的波動"}];

執行App:

不管我們按了幾百,幾千次按鈕,小雨都收不到來自葉湘倫的通知,因此永遠也看不到UIAlertView。



不可小看的背景陷阱:

如果當初我們呼叫postNotificationName:object:userInfo:發送通知時處在背景thread,而非main thread,到時候收到通知時所呼叫的method也將會在背景thread執行。以剛剛的例子來說,如果我們不幸在背景thread發送通知,到時候收到通知時,App將壯烈的crash死去。這是因為我們收到通知時會顯示UIAlertView,但此時卻處於背景thread,違反了UI相關程式一定要在main thread執行的規定。






2012年11月23日 星期五

最佳企業App LOCOMO (App Next 2012應用程式大賽 )

Passion Bean的LOCOMO獲選為最佳企業App !




英雄難過美人關,利用美人計啟動Facebook App

彼得潘常常和有著自己FB粉絲團的偶像,藝術家或是朋友合作App,恆久不變的除了我們之間合作的情誼外,另一個就是App的關於頁面了。關於頁面往往包含了相關的FB,Blog和網站連結。

連結至FB很簡單,只要利用UIWebView開啟對應的網址即可。然而針對iPhone特別設計的Facebook App,帶給使用者比純網頁好上100倍的瀏覽體驗。因此更貼心的做法其實是直接透過Facebook App開啟FB的連結。所謂英雄難過美人關,接下來彼得潘將以美女Model Lucy的Facebook粉絲團Love LUCY Love為例,說明如何利用美人計,讓Facebook App如此地英雄好漢聽話地幫我們打開LUCY的粉絲團。

 1. 查詢粉絲團的ID

我們可以指定Facebook App打開某個粉絲團或某個人的塗鴉牆,不過可惜它不識英文,不識中文,只識由數字組成的ID。在Facebook的世界裡,不管是粉絲團還是個人,都有一個獨一無二的識別ID,就好像我們的身份證字號一樣。

問題來了,要怎麼知道粉絲團Love LUCY Love的ID呢? 很簡單,只要以下3個步驟:

(1) 連到Love LUCY Love粉絲團,取得粉絲團的網址。


請先將視線從LUCY身上移開,往上瞧一點,觀察網址列裡的網址。

http://www.facebook.com/Love.Lucy.fans?fref=ts


(2) 取得粉絲團的username。


在網址列裡,在com/後,?之前的Love.Lucy.fans,正是我們夢寐以求的username

(3) 取得粉絲團的ID

有了username後,我們只要輸入以下網址,即可取得ID。(規則為http://graph.facebook.com/ 加 username)

http://graph.facebook.com/Love.Lucy.fans


雖然回報的資料密密麻麻,但都走到這一步了,努力地找一下吧,答案就藏在以下這一行

"id": "151582191520747",沒錯,就是你了,ID 151582191520747。


ps: 其實有些人沒有特別設定過Facebook上的username,他們的FB網址即直接帶有ID資訊,例如以下網址:
http://www.facebook.com/profile.php?id=100000045374040



 2. 啟動Facebook App



NSURL *url = [NSURL URLWithString:@"fb://profile/151582191520747"]; [[UIApplication sharedApplication] openURL:url];

說明:
利用UIApplication物件的openURL: method,我們可以啟動外部的App。至於啟動哪一個,關鍵就在於開頭的字串了。比方tel://會啟動電話App,而Facebook也不怕別人知道,坦蕩蕩地使用它的縮寫fb。所以我們只要以fb://profile/為開頭,然後加入千辛萬苦取得的ID,即可讓Facebook App上勾,墜入情網,心甘情願地為我們開啟LUCY的粉絲團。







LUCY簡介:
粉絲團: Love LUCY Love 
生日:  2月7日 (和彼得潘一樣,好日子)
科系: 輔大心理系 ( 對人心有深入了解) 
星座: 水瓶座 ( 好星座,不是只有天秤座才出帥哥美女呀 )
職業: Model,代言/平面/網拍/廣告/主持/展場/活動
聯絡: lucy.chiayun@gmail.com