2013年3月26日 星期二

Key-Value Observing機制

//這是一個簡單又好用的機制
//對你要觀察的物件calendar加入觀察者self,再把你想要觀察的屬性calendar.selectedDate,就會在屬性值改變時呼叫下面的方法
- (void)viewDidLoad{

//對calendar做KVO
 [self.calendar addObserver:self forKeyPath:@"selectedDate" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];

}

//加入一個下列的方法,一旦上面的觀察值有所改變,就會執行下面的方法
-(void) observeValueForKeyPath:(NSString *)keyPath
                                      ofObject:(id)object
                                        change:(NSDictionary *)change
                                       context:(void *)context
 {
      NSLog(@"observeValueForKeyPath is run");
   if([keyPath isEqual:@"selectedDate"]){
        //改變值存在change這個dictionary中,要用key= old或new去取值
        NSLog(@"old price is %@",[change objectForKey:@"old"]);
        NSLog(@"new price is %@",[change objectForKey:@"new"]);
       
    }
 }

判斷是否為iPhone 5

判斷是否為iPhone 5的代碼 #define iPhone5 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 1136), [[UIScreen mainScreen] currentMode].size) : NO) 所以當使用時,僅需照以下寫法使用即可囉 if (iPhone5) //do something for iPhone 5 else //do something for iPhone 4s 4 3GS etc..

2013年3月21日 星期四

新增檔案時,選項的區別

轉貼自http://blog.csdn.net/mygamezone/article/details/8513327 1.Create groups for any added folders: 把選擇的文件添加到工程的group下。 應該它生成的文件夾是黃色的。 2.Create folder references for any added folders: 這種方法是建立一個文件夾的索引,同時文件夾中的所有文件也會添加到整個工程。 應該他生成的文件夾是藍色的。 黃色和藍色有什麼區別呢? http://img.my.csdn.net/uploads/201301/17/1358404441_9553.png 我們做一個測試 self.image.image=[UIImage imageNamed:@"111.jpg"]; // 不會顯示圖片 self.image.image=[UIImage imageNamed:@"myimages/111.jpg"]; // 顯示圖片 self.image.image=[UIImage imageNamed:@"222.jpg"]; // 顯示圖片 self.image.image=[UIImage imageNamed:@"images/222.jpg"]; // 不會顯示圖片 也就是說 我們在做ios開發的時候經常是黃色的,在做cocos的時候經常是藍色的, 如果文件夾是黃色的,你不需要加上路徑 如果文件夾是藍色的,你需要加上路徑 其實我們可以這樣理解 看到黃色文件夾,說明它很色,它已經把衣服脫了,你可以直接使用它裡面的東西 看到藍色文件夾,說明它很矜持,如果你想怎麼的,你需要給它脫一脫

2013年3月19日 星期二

Facebook SDK 3.2

如果你是用github下載FacebookSDK
你將先build the framework

打開command line進入FacebookSDK的路徑
輸入
scripts/build_framework.sh
Then, FacebookSDK.framework will appear in FacebookSDK/build

在Delegate中一定要實做下面這兩個方法,不然授權完回到我們的App時不會觸發login等相關的動作。
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
return [self.facebook handleOpenURL:url];
}

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [self.facebook handleOpenURL:url];
}

這裡有詳細教學
http://www.erawppa.com/整合-ios-facebook-sdk/
http://bani.org/blog/?tag=objective-c

2013年3月18日 星期一

frame跟bound的差別

常遇到的錯誤訊息與解決方式


  • 錯誤訊息:Undefined symbols for architecture i386 error
遇到這個錯誤碼代表你Code中有使用到你尚未載入的framework,把該加入的framework加一加就可以compile過了

  • 錯誤訊息:Apple Mach-O Linker Error 
解決方式:Project ->Build Settings -> Build Active Architecture Only -> 設成YES


  • 錯誤訊息:linker command failed with exit code 1 
解決方式: 把 Valid Architectures 的值改為 armv7 : PROJECT --> Build Settings --> Architectures --> Valid Architectures 他的值本來是 armv7 armv7s (ios6.0下) 把armv7s 去掉即可 同樣的操作 TARGETS --> Build Settings --> Architectures --> Valid Architectures 做同樣的修改 後來發現發生這些錯誤是因為引用了EVENTKIT但沒有先匯入它


  • 錯誤訊息:Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to create description in descriptionForLayoutAttribute_layoutItem_coefficient. Something is nil'
解決方式:有些之前拉過的線已經失效了,把它找出來刪掉即可。
  • 錯誤訊息:*** Assertion failure in -[UITableViewCell _setHostsLayoutEngine:], /SourceCache/UIKit/UIKit-3318.16.14/NSLayoutConstraint_UIKitAdditions.m:2760
解決方式:在你的storyboard中有些TableView的content屬性為Dynamic Prototypes,你卻拉了客製化的cell進去TableView中。或者是你把cell直接拉到UIView當中。看樣子iOS7以後對cell的階層定義的很嚴格。

  • 錯誤訊息:file '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.0/include/limits.h' has been modified since the precompiled header '/Users/YourName/Library/Developer/Xcode/DerivedData/YourProject-bafemyyfpibvkfbxdrsjfkyzjmxb/Build/Intermediates/PrecompiledHeaders/YourProject-Prefix-hkhsfrjbjnwlltfbputhdimgctvv/YourProject-Prefix.pch.pch' was built
解決方式:在你重新安裝xcode之後,舊的專案的暫存檔會跟新的衝突,所以要先把暫存檔資料夾清空,打開你的終端機輸入
cd ~/Library/Developer/Xcode/DerivedData/ModuleCache,然後用rm -f -r ./*把這裡的cache都清掉。


  • 錯誤訊息:process launch failed: NotFound

解決方式:如果xcode一直跳出這訊息,無法實機測試,把手機重新開機就可以了。

  • 錯誤訊息:*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIViewController _loadViewFromNibNamed:bundle:] loaded the "SignupViewController" nib but the view outlet was not set.'

解決方式:跳這個訊息代表你在Xib的File's Owner的view沒有連上UI上的view。


  • 錯誤訊息:

Thread : Crashed: com.apple.main-thread
0  libobjc.A.dylib                0x0000000195757bdc objc_msgSend + 28

解決方式:到Project -> Build Settings -> ENABLE_STRICT_OBJC_MSGSEND 將它設為NO。

  • 錯誤訊息:Error Domain=NSURLErrorDomain Code=-1022 "The resource could not be loaded because the App Transport Security policy requires the use of a secure connection."

解決方式:Apple在iOS 9的更新訊息中提到預設為強制使用https當作api的網址。

但如果你必須要用http可以去Info.plist修改預設值。
1. 新增App Transport Security Settings欄位
2. 把欄位下的Allow Arbitrary Loads設為YES
或是把欄位下的Exception Domains加入你的網址

Event Kit Framework 匯入iOS行事曆

[轉自http://iosdevelopersnote.blogspot.tw/2010/09/ios-event-kit-framework.html] iOS 4.0 可以充許開發者去存取存iPhone裡的行事曆, 和通訊錄相同的行事曆的整個是用Core Foundation架構起來的是C 而不是Objective-C Core Foundation是C, Foundation是Objective-C 但是兩者之間有很方便的轉換方法,其實就是直接cast,這個又叫做Toll-Free bridge 比如CFStringRef和NSString *要轉換就直接寫 CFStringRef cfString = xxxxxx; NSString * objString = (NSString *) cfString; 這樣就可以直接用objString來當成cfString的替身了 先介紹一下幾個重要的c structure在event kit 會用到的 CFGregorianDate : 標準的日曆表示法,含有年,月,日,時,分,秒。至於為什麼叫Gregorian 請參考 CFGregorianUnits : 表示一段時間,和CFGregorianDate有相同的結構,但沒有限制值的範圍。比如說在CFGregorianDate"時"的值不能超過24小時,但在CFGregorianUnits"時"的值就可以超過24小時,因為它代表的是一段時間 我們來直接來看一個按下去按鈕就新增自訂event的例子 -(IBAction) createEvent:(id)sender{ NSLog(@"launched");
 EKEventStore * myEventStore = [[EKEventStore alloc] init];
 EKEvent * myEvent = [EKEvent eventWithEventStore:myEventStore];
myEvent.title = @"Knowledage Convergence Meeting";
CFGregorianDate gregorianStartDate, gregorianEndDate;
CFGregorianUnits startUnits = {0, 0, 0, 1, 3, 0};
CFGregorianUnits endUnits = {0, 0, 0, 1, 5, 0};
CFTimeZoneRef timeZone = CFTimeZoneCopySystem(); gregorianStartDate = CFAbsoluteTimeGetGregorianDate( CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTimeGetCurrent(), timeZone, startUnits), timeZone);
gregorianStartDate.hour = 17;
gregorianStartDate.minute = 55;
gregorianStartDate.second = 10;
gregorianEndDate = CFAbsoluteTimeGetGregorianDate( CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTimeGetCurrent(), timeZone, endUnits), timeZone);
 gregorianEndDate.hour = 17;
gregorianEndDate.minute = 55;
gregorianEndDate.second = 25;
NSDate* startDate = [NSDate dateWithTimeIntervalSinceReferenceDate:CFGregorianDateGetAbsoluteTime(gregorianStartDate, timeZone)];
NSDate* endDate = [NSDate dateWithTimeIntervalSinceReferenceDate:CFGregorianDateGetAbsoluteTime(gregorianEndDate, timeZone)];
CFRelease(timeZone);
myEvent.startDate = startDate;
myEvent.endDate = endDate;
myEvent.calendar = [myEventStore defaultCalendarForNewEvents];
 EKAlarm *myAlarm = [EKAlarm alarmWithAbsoluteDate:startDate];
 myEvent.alarms = [NSArray arrayWithObject:myAlarm];
NSError *theError = nil;
 [myEventStore saveEvent:myEvent span:EKSpanThisEvent error:&theError];
NSLog(@"error is %@", theError);
 }
這個流程主要就是產生自己的EKEvent, 藍色的property都是必要的,除了alarms之外,EKEvent又必需要和 EKEventStore結合,因為event實體是EKEventStore給的,event裡的calendar也是EKEventStore給的,而EKEventStore實體的產生就只是用alloc, init方式。 其中最麻煩的就是startDate和endDate,輾轉要從 CFGregorianDate 或是 CFGregorianUnits而來 單看是要從 CFAbsoluteTimeGetGregorianDate產生還是要從 CFAbsoluteTimeAddGregorianUnits產生,不過記得一點,產生 CFGregorianDate 的實體之後可以從他的field,year, month, day, hour, minute, second 來設定絕對的時間就如墨綠色部分所示。 EKAlarm 可有可無,它是先和NSDate結合,再一起被設定到EKEvent