2014年7月15日 星期二

MAC OS X: Sweep IP Address: 在 MAC 上,去掃描網路上的 ip address。

想知道,網路上有那些 IP 位址己經被使用了嗎了,在 Windows 上,可以使用Angry IP Scanner。 但,在 MAC 上,並不用這麼麻煩,只要打開終端機(terminal), 在上面鍵入以下指令即可。

xCedar$ for x in {1..254}; do ping -c 1 -W 100 192.168.1.$x | grep 'time='; done

以上,簡單吧~! 指令中,以 for ... done 為主的迥圈,設定 x 的值,從 1 到 254; 並變數 x 的值,
以 $x 代入 ping 的指令中。
-c 1: ping 的次數為一次; -W 100: 等待回應時間為 100ms。
最後以關鍵字 "time=" 來列出有回應的 IP 位址。

Ref:Ping Sweep for MAC OS X

2014年6月26日 星期四

iOS 7 的 MotionEffects

iOS 7 剛出來時,大家第一個會注意到的事在 Lock Screen 有一個會動的背景;那就是 Motion Effects。
其實它很簡單,我試著在一個UIView 加上一個 UIButton,接著讓 Button 是浮動的。看程式碼就懂了。

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    aButton.layer.mask.frame = aButton.bounds;
    aButton.layer.masksToBounds = YES;

    UIInterpolatingMotionEffect *xAxis = [[UIInterpolatingMotionEffect alloc]
                                          initWithKeyPath:@"center.x"
                                          type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];

    xAxis.minimumRelativeValue = [NSNumber numberWithFloat:-90.0];
    xAxis.maximumRelativeValue = [NSNumber numberWithFloat:90.0];

    UIInterpolatingMotionEffect *yAxis = [[UIInterpolatingMotionEffect alloc]
                                          initWithKeyPath:@"center.y"
                                          type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];

    yAxis.minimumRelativeValue = [NSNumber numberWithFloat:-90.0];
    yAxis.maximumRelativeValue = [NSNumber numberWithFloat:90.0];

    UIMotionEffectGroup *group = [[UIMotionEffectGroup alloc]init];
    group.motionEffects = @[xAxis, yAxis];
    [aButton addMotionEffect:group];
}

2014年4月28日 星期一

Mac OS X Mavericks 開啟 關閉 系統內建的 FTP Server

在Mac OS X Mavericks 上,己經將原來放置在 "檔案共享"裡的 "FTP伺服器" 選項己經拿掉了。現在只能透過 command line 中的 launchctl 去啟動和關閉系統內建的"FTP伺服器"。

開啟

sudo -s launchctl load -w /System/Library/LaunchDaemous/ftp.plist

關閉

sudo -s launchctl unload -w /System/Library/LaunchDaemous/ftp.plist

2014年1月4日 星期六

Sublime text 2 setup

最近常使用 Sublime Text 來編輯一些文件,有時候,電腦重灌就忘了一些常用套件是怎麼裝旳,以下列一些常用的套件的URL吧!

Sublime Text 2 http://www.sublimetext.com/2
Package Control https://sublime.wbond.net/installation#st2
Markdown preview https://github.com/revolunet/sublimetext-markdown-preview

2013年12月9日 星期一

如何新增一筆聯絡人資料到通訊錄

接著上一篇如何存取iPhone 通訊錄裡的資料,接著就是要新增一筆資料寫入通訊錄了。其實很簡單,只要呼叫 ABPersonCreate(); 便可產生一筆空白資料,多項資料(MultiProperty)比單項資料(Property)多了一道處理程序;直接來看範例~

 NSString *firstName, *lastName, ... ;
 NSDictionary *emails;
 ...

 //產生 AddressBook 物件
 ABAddressBookRef addressBookObj = ABAddressBookCreateWithOptions(NULL, NULL);

 //產生一筆空白聯絡人資料
 ABRecord record = ABPersonCreate();

 //處理單項資料 (property)
 ABRecordSetValue(record, kABPersonFirstNameProperty, CFBridgingRetain(firstName) , nil);
 ABRecordSetValue(record, kABPersonLastNameProperty, CFBridgingRetain(lastName) , nil);

 //處理多項資料 (MultiProperty)
 NSArray *allLabels = [emails allKeys];
 ABMutableMultiValueRef multiValue = ABMultiValueCreateMutable(kABMultiStringPropertyType);
 for(NSString *label in allLabels) {
    NSString *value = [emails objectForKey:label];
    ABMultiValueAddValueAndLabel(multiValue, CFBridgingRetain(value), CFBridgingRetain(label), NULL);
 }
 ABRecordSetValue(record, kABPersonEmailProperty, multiValue, nil);

 //寫入&儲存
 ABAddressBookAddRecord(addressBookObj,record,nil);
 ABAddressBookSave(addressBookObj);

在上面的例子中,是直接產生一筆空白的聯絡人資料;若是換成即有存在的舊資料,也是可以的,但在處理多項資料時,若遇到已經存在的label,不可使用 ABMultiValueAddValueAndLabel,請改用 ABMultiValueReplaceValueAtIndex 去處理;

除了,直接寫入通訊錄外, framework 另外提供了預設的聯絡人的輸入UI,共有二套,一為 "ABNewPersonViewController";另一為 "ABUnknownPersonViewController";差別在於後者可以選擇覆寫即有的資料。

ABNewPersonViewController 的範例~

 ABNewPersonViewController *newPersonVC = [[ABNewPersonViewController alloc] init];
 ABRecordRef aNewRecord = ABPersonCreate();

 newPersonVC.newPersonViewDelegate = self;
 newPersonVC.addressBook = addressBookObj;
 newPersonVC.displayedPerson = aNewRecord;

 [currentNavigationViewController pushViewController:newPersonVC animated:YES];

ABNewPersonViewController 的範例~

 ABUnknownPersonViewController *unknowPersonVC = [[ABUnknownPersonViewController alloc]init];
 unknowPersonVC.unknownPersonViewDelegate = self;
 unknowPersonVC.displayedPerson = aOldRecord;
 unknowPersonVC.allowsAddingToAddressBook = YES;
 unknowPersonVC.allowsActions = YES;

 [currentNavigationViewController pushViewController:unknowPersonVC animated:YES];

2013年12月4日 星期三

如何存取iPhone 通訊錄裡的資料

iPhone 內部是使用 SQLite3 作為通訊錄的資料庫,但是因為沙盒的限制(沙盒「sandbox」: 指程式在一個獨立且受限的虛擬環境裡執行,可確保不會受其它干擾,也不干擾其它程式運作) 。所以,你是無法直接讀取的必需透過 XCode 所提供的 AddressBook.framework 來讀取和寫入資料。

而 AddressBook.framework 所提的 API,比較接近 C 語言,無法直接使用 NSArray, NSString 來定義變數;其實,在學XCode以來,在 AddressBook.framework 所定義的變數保留字,一直給我一種“為定義而定義”的感覺,很多餘。但不列出來,再過一陣子,我一定會忘了;在此,先列出在 AddressBook.framework 中所使用的變數保留字。

  • ABAddressBookRef : 用來宣告 AddressBook物件變數,AddressBook物件在使用上,和 NSManagedObjectContext 一樣,任何對 iPhone 通訊錄的讀取或儲存,都需要透過 AddressBook物件來完成;而建立一個 AddressBook物件指令為 ABAddressBookRef addressBookObj = ABAddressBookCreateWithOptions(NULL, NULL);
  • ABRecordRef : 用來宣告 ABPerson 物件變數,一筆資料即為一 ABPerson 物件。例如: 產生一筆空白資料,指令為 ABRecordRef newPerson = ABPersonCreate();
  • CFTypeRef : 萬用變數宣告,其實它就是 void* ;用於字串、任一數值, 例如: CFTypeRef firstName;
  • CFArrayRef : 用來宣告陣列變數;

知道了 AddressBook.framework 常用的變數保留字,就來將 iPhone 通訊錄中的 所有記錄取出來吧~

 //產生 AddressBook 物件
 ABAddressBookRef addressBookObj = ABAddressBookCreateWithOptions(NULL, NULL); 
 //取出所有聯絡人記錄
 CFArrayRef allPeoples = ABAddressBookCopyArrayOfAllPeople(addressBookObj);
 int numPeople = CFArrayGetCount(allPeoples);
 //依續取出每個聯絡人資料
 for(int i=0 ; i<numPeople; i++ ) {
    ABRecordRef onePeople = numPeople[i];
    // 取出該聯絡人所有資訊
 }

有了聯絡人,接著就著手處理聯絡人所包含資訊。首先,資料有分單一資料(Property)和多項資料(MultiProperty),取出後的處理方法也不一樣; 先釐清一個觀念,CFDictionary(屬性:kABDictionaryPropertyType)是單一資料,雖然,Dictionary 可以包含很多資料;而屬性 kABMultiDictionaryPropertyTyple 才是多項資料;很明顯地,在屬性鍵值有'multi’的字眼,便是多項資料; 取出資料的指令為

 CFTypeRef valueRef = ABRecordCopyValue(oenPeople, kABDictionaryPropertyType);

而要取出所有資料的方法如下:

 for(ABPropertyID propKey = kABPersonFirstNameProperty; propKey <= kABPersonSocialProfileProperty; propKey++) {
    //先取出數值
    CFTypeRef valueRef = ABRecordCopyValue(onePeople,propKey);

    ABPropertyType propType = ABPersonGetTypeOfProperty(propKey); 
    //判斷是單一資料或多項資料
    if(propType & kABMultiValueMask) {
        //多項資料處理
    } else {
        //單一資料處理
    }
 }

接著,讓我們看看在一筆聯絡人記錄中,帶有那些資訊吧~

ABPropertyID 描述
kABPersonFirstNameProperty; First name - kABStringPropertyType
kABPersonLastNameProperty; Last name - kABStringPropertyType
kABPersonMiddleNameProperty; Middle name - kABStringPropertyType
kABPersonPrefixProperty; Prefix ("Sir" "Duke" "General") - kABStringPropertyType
kABPersonSuffixProperty; Suffix ("Jr." "Sr." "III") - kABStringPropertyType
kABPersonNicknameProperty; Nickname - kABStringPropertyType
kABPersonFirstNamePhoneticProperty; First name Phonetic - kABStringPropertyType
kABPersonLastNamePhoneticProperty; Last name Phonetic - kABStringPropertyType
kABPersonMiddleNamePhoneticProperty; Middle name Phonetic - kABStringPropertyType
kABPersonOrganizationProperty; Company name - kABStringPropertyType
kABPersonJobTitleProperty; Job Title - kABStringPropertyType
kABPersonDepartmentProperty; Department name - kABStringPropertyType
kABPersonEmailProperty; Email(s) - kABMultiStringPropertyType
kABPersonBirthdayProperty; Birthday associated with this person - kABDateTimePropertyType
kABPersonNoteProperty; Note - kABStringPropertyType
kABPersonCreationDateProperty; Creation Date (when first saved) - kABDateTimePropertyType
kABPersonModificationDateProperty; Last saved date - kABDateTimePropertyType
kABPersonAddressProperty; Street address - kABMultiDictionaryPropertyType
kABPersonDateProperty; Dates associated with this person - kABMultiDatePropertyType
kABPersonKindProperty; Person/Organization - kABIntegerPropertyType
kABPersonPhoneProperty; Generic phone number - kABMultiStringPropertyType
kABPersonInstantMessageProperty; Instant Messaging - kABMultiDictionaryPropertyType
kABPersonURLProperty; URL - kABMultiStringPropertyType
kABPersonRelatedNamesProperty; Names - kABMultiStringPropertyType
kABPersonSocialProfileProperty kABMultiDictionaryPropertyType

先來看看多項資料,要怎麼處理?

 CFTypeRef *multiValueRef = ABRecordCopyValue(onePeople,propKey);

 //先取得資料的數量
 int numberOfValues = ABMultiValueGetCount(multiValueRef);

 //在來依續取出其中的資料
 for(int i = 0 ; i<numberOfValues ; i++) {
    CFTypeRef *singleValureRef = ABMultiValueCopyLabelAtIndex(multiValueRef,i);
    //單一資料處理
 }

問題來了,取出來的數值型別皆為 CFTypeRef,若是很熟悉 CFType,那直接使用吧,但我就不熟,所以,還是要轉換成 XCode 常用的型別;

 NSString *stringValue = CFBridgingRelease(valueRef);   **//kABStringPropertyType**
 NSNumber *numberValue = CFBridgingRelease(valueRef);   **//kABIntegerPropertyType**
 NSDate *dateValue = CFBridgingRelease(valueRef);       **//kABDateTimePropertyType**
 NSDictionary *dictionaryValue = CFBridgingRelease(valueRef);   **//kABDictionaryPropertyType**

2013年11月13日 星期三

XCode "區塊運算"分享

XCode "區塊運算"分享

Reference from: Blocks Programming Topics
在XCode的開發中,會看到 ^符號,它除了可以作為XOR運算外,在XCode還有一個很常用的操作,^可作為區塊運算的識別字。有關XCode 的區塊運算是一個非常方便的工具,它可以當作 callback function,也可以將一組function直接嵌入你要呼叫的function裡,例如:
//在沒有ARC下,可在ViewController 移除後,將自已給釋放
[myViewController dismissViewControllerAnimated:YES 
    completion:^() {
        [myViewController release];
        myViewController = nil;
    }
];
官網文件中,開宗明義指出You use the ^ operator to declare a block variable and to indicate the beginning of a block literal. The body of the block itself is contained within {}。 '^'符號作為區塊(Block)的開頭文字,在使用方法上,請見下圖不解釋了。

除了官網文件中所提到的範例,另外我也列出一些我在使用上所使用例子:
  • 當 callback function 使用
//MyViewController.h
typedef void (^TouchedInside)();

@interface MyViewController : UIView
{
    __strong TouchedInside  _insideBlock;
}
-(void)setTouchedInsideBlock:(TouchedInside)insideBlock;
@end
//MyViewController.m
@implementation FPTouchView
-(void)setTouchedInsideBlock:(TouchedInside)insideBlock
{
    _insideBlock = [insideBlock copy];
}

@end
  • 把區塊(block)直接嵌入要呼叫函數裡
//Declare in UIViewController.h
- (void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^)(void))completion;
//sample
[myViewController dismissViewControllerAnimated:YES 
    completion:^() {
        [myViewController release];
        myViewController = nil;
    }
];