2012年12月17日 星期一

隨手看正妹的利器-無名隨身相簿

身為一個男人,利用手機看看正妹是再正常不過的事了。

tyche 就出了一個專門欣賞無名每日選出的十四本正妹相簿,是每日更新喔!

立刻上 Apple Sotre 上搜尋 無名隨身相簿 吧!

若您知道朋友的無名帳號,可在“搜尋“頁面可輸入無名帳號直接瀏覽哦

第二個功能為主要功能啦,就是欣賞無名小站每日更新的14本精選正妹相簿加上小編的最愛!

點擊喜歡的正妹相簿就可以開始欣賞照片啦,左滑滑右滑滑,真的很方便呢!也可以儲存到手機膠卷內哦!
歷史紀錄會暫存你點擊過的正妹相簿,方便隨時回來欣常唷。

若有真的很喜歡的正妹,可以點擊紅色的愛心加入我的收藏內!





2012年11月22日 星期四

Mobile X 第一彈 - 暗黑菜市場

經過大概兩個月的時間,終於把這個 App 完成送審了。

這個 App 的 Idea 由來是因為 Ptt 的暗黑版有六日才能發交易文的限制,連署新版又有困難,於是就有了一個自已來的念頭。 也因為如此,整個 App 的流程都和在Ptt上的動作相仿,也就是 PO文+搜尋+水球

開始介紹暗黑菜市場前必須先提一下,我們希望這種線上交流媒合的概念未來可以應用其他遊戲上,所以我們創造了 Mobile X 這個平台,而暗黑菜市場只是在 Mobile X 的第一款應用。

因此在使用暗黑菜市場時需先申請一個Mobile X的會員帳號,有了這個帳號才可以在 App 內PO文和聊天,且這個帳號未來將可以登入任何一款建立在 Mobile X 的 App 上。

最後要解釋一點的是這個 App 基本上是全英文的!有人會問,為什麼不做成多國語系?這不是台灣人做的 App 的嗎? 是的,我們團隊全都是呆灣人,會使用全英文的原因其實很簡單,就是因為暗黑的字型只有英數字,為了配合整體風格我們採取了折衷的方法,就是盡量簡化英文並用圖形取代。 當然啦,在這 App 裡不管聊天還是搜尋開房都還是可以打中文的!

暗黑菜市場:

主要頁面

一進入 App 便會看到熟悉的經典抓痕和烏鴉叫且若有登入會員的話經典的抓痕還會有火焰的效果唷!

下方的功能選項以圖示表示,分別為:拍賣場、聊天室、設定頁面。


















搜尋頁面

搜尋頁面提供三個條件,分別為伺服器、分類以及關鍵字。 填完搜尋條件後按下右邊的 Search 便會出現符合的文章,點擊有興趣的文章後再點擊文章內容(It is a easy / simple ......)便可以傳訊息給這篇文章的主人進行談話,很簡單吧。

已申請加入Mobile X並登入的會員可以隨時按下 Create 把自已想買/賣的物品放到拍賣場中哦。
















輸入條件和內容,輕鬆將買/賣的物品資訊張貼至拍賣場!
點擊文章內容後便可與文章的主人進行溝通。
聊天的內容會保存在訊息頁面,隨時都可再次與對方談話。
輸入 email/user/pw 即可完成註冊。
輸入 Email 及 密碼 即可登入


2012年10月2日 星期二

@property 與 @synthesize


原文為 堤刻科技技術長 分享給同仁的信件

----------------------------

今天還是很基本的地方, 設 @property 和 @synthesize 從很粗淺的地方開始說,
他們就是幫開發者建立一對可以存取該變數的 function, 假設有一個變數叫做

NSString *myString;

然後我幫他配置了

.h 裡面的
@property (nonatomic, retain) NSString *myString;

.m 裡面的
@synthesize myString;

在這個當下, 就相當於聲明了

用以 get 的 function
-(NSString*) myString {
     return _myString;
}

用以 set 的 function
-(void) setMyString : (NSString*) newValue {
     [newValue retain];
     [_myString release]; //文件中說明到, 如果當 _myString 為 nil 時, nil 做 release 這個動作是合法, 並且不會出問題的.
     _myString = newValue;
}

另外, 在這樣的情況下,

myString = xxx;



self.myString = xxx;

的意義是不相同的, self.myString = xxx; 會被轉換成 [self setMyString:xxx];
所以,

myString = [[NSString alloc] init];

不會造成 leak,

self.myString = [[NSString alloc] init];

一寫出來, 瞬間就 leak 了。


舉另外一個常用的例子說,

UILabel *myLabel;

不管是用 myLabel.text = xxx; 或是 [myLabel setText:xxx]; 都不會造成 leak.

有了這些基本的知識以後, 才有辦法去了解 @property 後面參數的含意,
從分類上來說, 其實是有三類,

1. 可不可以讀寫 readwrite or readonly,
- 預設是 readwrite, 因此, 通常很少在我們的扣看到這個, 他同時會產生 set 跟 get.
- readonly 的話表示這個變數只能被讀取, 他只產生 get, 並且會在你想亂 set 的時候, 在 compiler 階段報錯.

2. 存的方法 strong or weak or copy or assign or retain, 注意, 我說的是存的方法, 因此只影響 set 時的動作,
先從比較容易的開始說,

- retain, 上面那個舉例的 set function 就是他的形態, 他會 retain 新的東西, release 掉舊的,
然後把自己設成新的東西.
- copy, 如同 retain, 只是 copy 會把新的東西做 copy, 而不是做 retain.
- assign, 就是很單純的將本身設成新的東西, 不做 retain 也沒有 copy, 喔對了, 如果什麼都沒寫的話, assign 是預設.
- strong 跟 weak 我也不是太懂, 從 document 裡面我也看不太出來他跟 retain 究竟有多大的差異,
反正比較少用, 所以以後再來看.

3. 原子小金剛, 我不知道該怎麼翻譯 nonatomic or atomic.....這其實是個有深大意義, 但是我們以前都沒有發現的參數,
最一開始的時候只知道 nonatomic 比較好.....

- 比較常用就先從 nonatomic 開始說, nonatomic 在 iphone 開發上是被推獎的, 因為他比較快, 比較單純, 
比較適合 single-thread, 但是就表示, 他在 multi-thread 是有缺陷的, 比方說 A 進了 get function,
他沒有辦法阻攔 B, C, D 同時在做 set 的動作, 所以最後你不確定你得到的值是 A 原來想拿的那個, 
或者是 B, 或者是 C, 或者是 D, 然後就會 debug 到發瘋.

- 相對的 atomic 就會幫你在 multi-thread 的時候多做一點處理, 如果 A 在 get, 那麼 B, C, D 想 set 都會被擋住,
直到 A 把東西拿走之後, 才繼續給 B, C, D 使用.

最後, 其實也可以從頭到尾都不寫 @property 跟 @synthesize, 只要你可以控管好你每一個變數的使用就可以了.



reference by : 
The Objective-C Programming LanguageAdvanced Memory Management Programming Guide
Atomic vs nonatomic properties

NSLock 與 @synchronized 的不同

原文為 堤刻科技技術長 分享給同仁的信件

--------------------

今天重新再看過一次一些比較基本的 document, 把死背的東西部分的重新消化過一次,
其中有一個可能比較有趣的地方應該是 NSLock 和 @synthesize, 如果這個世界只有單 thread,
那麼我的 function 只要這樣寫

-(void) myFunction {
    NSLog(@"%d", count++);
}

然後我用一個 for 到 100 的迴圈去跑他的時候, 他可以按照順序的從 0~99 乖乖的排好,
但是當我 thread 變多的時候, 同時間衝進來拿到 count 這個數字的人可能就不只有一個,
所以通常的狀況就會是跑不滿到數字 99 就停了, 這個 function 有被執行 100 次,
只是最後的數字不會是 99.

在 obj-c 裡面提供了一個簡單而好用的做法, 讓開發者可以不用花太多心力, 
而能保持同一個程式碼區段的單一性, 只要在這個 function 裡面的部份加上

-(void) myFunction {
    @synchronized (self) {
        NSLog(@"%d", count++);
    }
}

那麼, 數字又會乖乖的從 0~99 排好, 即使是在 multi-thread 的情況下,
但是, 如果我把這段程式碼改成用 NSLock 來表達會變得怎麼樣?
假想起來會是這麼寫的

-(void) myFunction {
    if ([lock tryLock]) {
        NSLog(@"%d", count++);
        [lock unlock];
    }

}

想起來還蠻合理的, 就是當有人進來, 我就試試能不能鎖, 可以鎖的話我就開始做,
等做完之後再把他解鎖給下一個人用, 但是其實錯了~ O3O
因為在 multi-thread 的情況下, 所有的人都直接衝進這個 function, 當第一個人進去之後,
他就把門鎖上, 其他的人都因為進不去, 直接的就結束 function 了, 因此,
只會被 run 一次, 如果要從 NSLock 去做到 @synchronized的效果也是可以,
不過就要花費更多的程式碼在這上面, 不如使用 @synchronized.

所以雖然都是保護程式碼區塊的功能, 但是他們還是有些微的差異,

當我想要每一個進來這個 function 的人都依序執行的話, 那麼選擇用 @synchronized

當我想要防止這個 function 重複 call, 還沒有執行完就猛摳猛摳的囉嗦鬼, 那麼選擇用 NSLock

2012年9月3日 星期一

經緯度表示的距離

最近開發兩個小型的 GIS App,也比較深的接觸 GIS 的相關知識。

也忽然對經緯度座標的算法產生一些興趣。就查了一下公式和算法。

一查才發現,哇靠,公式超複雜的。

算了,我只是想知道每1公里在經緯度到底差多少。

算經緯度距離

這個網站可以算出任兩點經緯度的距離多少。

簡單算了一下便得知我要的資訊

經度每差 0.01 大約實際距離是 1.024 公里
緯度每差 0.01 大約實際距離是 1.112 公里

2012年8月22日 星期三

免費好用的音樂下載 App Tyche Radio


Tyche Radio 2.0 全新改版!!

你喜歡上 youtube 找歌嗎? 愛用 iPhone 聽歌嗎?

那你一定不能錯過這個免費好用的音樂下載 App ,叫做 tyche radio.

請直接至 Apple store 搜尋 tyche radio 就有了!

全新 Tyche Radio 以手勢操控為主,簡單說明一下手勢,未來也會把說明放到 App 裡哦

點兩下 -> 播放/暫停

往右滑 -> 下一首

往左滑 -> 上一首

上下移動 -> 調整音量

長按 -> 快轉



下載歌曲直接點擊左上方圖示即可

各個手勢說明


歌單列表,可編輯順序,修改歌名


熱門及搜尋介面









趕快下載吧!!!!


2012年8月21日 星期二

判斷使用者是否開啟 GPS @ iOS

最近在寫一個結合 Server 和 GPS 的小 App 剛好有遇到這個問題,分享一下吧。

只要 App 會用到 GPS 的功能就會跳出一個視窗詢問使用者是否同意該 App 使用 GPS 的功能,如下圖。




那我在程式內要如何判斷使用者是點選"同意"還是"不同意"呢?換句話說就是要判斷該 App 揪~~竟~~能否使用 GPS 功能!

其實不難,但是要先了解 GPS 是否開啟其實有分兩個開關。 一是 GPS 總開關(Location Services),二是各別 App 是否開啟 GPS 功能(例如 Big Lens 就被我關掉,Camera則可以使用)。



要判斷總開關是否開啟很簡單,也最常使用,如下

[CLLocationManager locationServicesEnabled]


[CLLocationManager locationServicesEnabled] 會回傳一個 BOOL 值,YES就是開啟,NO就是關閉,沒啥好講的。

再來是要判斷各個 App 的 GPS 使用權,也正是此次遇到的問題。

其實 Apple 的官方文件裡也有寫,只是不知道為啥似乎很少人使用,Google 了一陣子才找到正解。官方文件

判斷各個 App 的 GPS Method 是

[CLLocationManager authorizationStatus]


[CLLocationManager authorizationStatus] 回的就不是 BOOL了,而是整數。定義如下

typedef enum {
    kCLAuthorizationStatusNotDetermined = 0,
    kCLAuthorizationStatusRestricted,        
    kCLAuthorizationStatusDenied,            
    kCLAuthorizationStatusAuthorized         
} CLAuthorizationStatus;


簡單說明一下各個代表的意義,官方文件都有詳細說明,有興趣的人請自行前往囉。

kCLAuthorizationStatusNotDetermined 表示使用者尚未選擇同意或不同意。

kCLAuthorizationStatusRestricted 代表GPS功能受限於某些限制,例如 parental controls(不懂這應該翻叫啥。。。)

kCLAuthorizationStatusDenied 代表使用者點選了不同意!

kCLAuthorizationStatusAuthorized 代表使用者點選同意 。


所以只要在我需要的地方打上

if ( [CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorized) {
    //you can not use GPS.
    //do something
}


就可判斷使用者有打開該 App 的 GPS 功能了,這麼簡單的東西也可以打這麼一大篇。。。






2012年8月15日 星期三

iOS UI設計基本知識

整理一下網路搜集的一些基本 UI 的基本知識,官方的詳細文件 iOS UI elements and guildline


螢幕像素與解析度 

iPhone: 3.5 inch display
  • iPhone 3GS before: 480x320px, 163ppi 
  • iPhone 4 after: 960x640px, 326ppi 

iPad:9.7 inch display
  • iPad 2 before: 1024x768px, 132ppi  The new iPad: 2048x1536px, 264ppi 

字型
  • iOS 5.1中內建字型有58種。
  • iOS Preview 版本中少了 DB LCE TEMP字型,並增加了 Avenir, Avenir Next, Avenir Next Condensed, 以及Symbol等四種字型
 從 Xcode 中取得字型列表
// List all fonts on iPhone
NSArray *familyNames = [[NSArray alloc] initWithArray:[UIFont familyNames]]; NSArray *fontNames;

NSInteger indFamily, indFont;
for (indFamily=0; indFamily<[familyNames count]; ++indFamily) 
{
     NSLog(@"Family name: %@", [familyNames objectAtIndex:indFamily]); 
fontNames = [[NSArray alloc] initWithArray: [UIFont fontNamesForFamilyName: [familyNames objectAtIndex:indFamily]]];
for (indFont=0; indFont<[fontNames count]; ++indFont) 
{
NSLog(@" Font name: %@", [fontNames objectAtIndex:indFont]);
}
}



Layout


  • 雖然具有Retina螢幕的iPhone 4以及the new iPad有 960x640 與 2048x1536 像素的畫面尺寸,但尺寸的標示依舊是以 480x320 與 1024x768 來進行。




  • 每個元件都會縮小一半



系統預設的高度

(1點意指Retina螢幕中的2像素,非Retina螢 幕中的1像素)


  • 系統列高度:20點






  • 導覽(Navigation Bar)/工具列 (Tool Bar)高度: 44 點


  • 頁籤列(Tab Bar)預設高度:49點,每個頁籤的圖示 (使用灰階透明背景圖片,官方的建議大小為30x30pts, 實作上可接受的最大圖示為48x32pts)




Magic Number on iOS:44


44x44這個大小同時也是蘋果的介面規範中所建議的最小點選區域。 實際上44 points在iPhone上是6.85mm,在iPad上是8.46mm. 需將這個數值謹記在心。



出圖需知

出圖時須針對Retina與非Retina設備提供對應大小的圖片

對於針對Retina螢幕所提供的圖片,請在主檔名加上後綴@2x,開發工具會完成 接下來的事。 

舉例來說:
image filename for non-Retina device: star.png
image filename for Retina device: star@2x.png 


其它像是 Icon 及 進場圖的規範官網都有文件詳細說明,擷圖如下:



這些已經精簡到不行了,下次再整理一下像素篇。








2012年8月14日 星期二

製作/更新 推播 SSL 憑證

原文在此 How to renew your Apple Push Notification Push SSL Certificate

還滿常用的功能,簡單翻釋一下,方便自已也方便他人。


 1) Log in,登入
登入 Apple iPhone Developer website 後點擊 iPhone Provisioning Portal. 在左邊的選單找到 App IDs 的選項,選擇你要製作/更新的 App,進入 Configure 後會看到已存在的憑證(若是第一次製作請勾選 Enable for Apple Push Notification service ),按下 Configure 啟動小精靈吧。

**Development Push SSL Certificate 是測試用
**Production Push SSL Certificate 是正式上線用





2) Generate a CSR,產生 CSR (Certificate Signing Request)。
根著小精靈完成即可,製作完後請妥善保管,以後很多機會會用到這份 CSR 檔。

3) Generate the certificate,產生憑證檔。
CSR 檔上傳成功後,小精靈會以你的使用者名稱產生一份 .cer 檔給你,按 Download 把憑證檔下載下來並點兩下安裝到你的 錀匙圈存取 裡.
**若使用 Chrome 或其他瀏覽器在上傳 CSR 檔時發生停住不動的情況,建議改換成 Safari 來製作憑證。




4. Export certificates / keys,(匯出憑證/Keys)
執行錀匙圈存取在左邊的類別選擇“我的憑證“後右邊會出現你目前這台電腦上擁有的憑證,你會看到有個叫做  “Apple Development IOS Push Services : 您的AppID“ 或是  “Apple Production IOS Push Services: 您的AppID“,點開憑證左邊的三角形會出現該憑證的 Key。接下來的動作就是要將證憑和對應的 Key 做匯出的動作。
假設今天我是要做測試版的憑證,在 Apple Development IOS Push Services: 您的AppID 上點右鍵選擇 “輸出Apple Development IOS Push Services: 您的AppID“ 並將他存成 apns-prod-cert.p12,接著同樣動作匯出 Key 並將他存成 apns-prod-key.p12。

**在匯出憑證和Key時會要求你對他們加密,空白即可。
**匯出的檔名可以自已取,但為方便執行下面的 command,建議照著文章取一樣的名字。


5) Convert to PEM format,轉成 PEM 格式

剛剛匯出的檔案必須轉成 PEM 的格式,可以利用終端機來操作。
在您的工具程式內找到終端機並執行它,熟悉的小黑窗就出現啦,執行以下2個指令吧。
openssl pkcs12 -clcerts -nokeys -out apns-prod-cert.pem -in apns-prod-cert.p12
openssl pkcs12 -nocerts -out apns-prod-key.pem -in apns-prod-key.p12

執行第二個指令時會強迫你一定要輸入密碼,為了方便起見,我們再輸入下面的指令把密碼拿掉。

openssl rsa -in apns-prod-key.pem -out apns-prod-key-noenc.pem



6) Merge files,合併檔案
最後,我們需要把剛才製作出來的兩個 PEM 檔案合併起來並用來連到 APNS (Apple Push Notification Server),指令如下:


cat apns-prod-cert.pem apns-prod-key-noenc.pem > apns-prod.pem
大功告成,打完收工!