Xcode8預設產生Swift的NSManagedObject subclass
想替DataModel產生Objective-C的class,記得修改Code Generationg設定即可
[iOS]Version of iOS framework
相隔1年多又要客製打造iOS專用的framework,可能Xcode許多設定都不同了,卡關蠻久的,這邊紀錄一下關於framework的version定義
問題描述:
framework的m檔明明重新撰寫過,但不管怎麼封裝,使用此framework的app總是取到舊版的執行結果
解決版法:
更改framework的版本號,封裝時才能真更新內部內容
但是呢~framework的版本號分為Major和Minor,必須依照不同時機去改變,而不是把版本號通通加大,Major和Minor對應的修改處如下
Version定義與觀念請參考Apple官方說明 如果懶得看,就直接Apple整理的表格XD
[iOS]Crashlytics管理與發佈
1.Fabric的管理介面
申請安裝完畢後,除了Fabric.app管理小工具,最即時的crash report就要登入fabric提供的網站查看https://fabric.io/home
到fabric網站針對你管理的每個app去查看report
fabric.app很貼心(雞婆)每次Archive後會問你要不要自行發布測試版本給你的開發者
2.發送測試邀請
當測試人員收到email並接受邀請後,管理者回到fabric.app查看,可能會有如下的黃色warning
解決方式是管理者會收到一封來自fabric的信,裡面附有一個包含測試者手機UDID的附檔,請將這個附檔交付給團隊中負責管理上架的人員,至Apple Developer將此UUID加到Devices,並綁定到被測試App的Provisioning Profile
上架負責人幫你處理完畢後,請務必記得重新下載Provisioning Profile重包一版,再透過fabric.app發布測試通知給測試人員,這樣對方才能成功安裝!
對方成功安裝後,管理者再回頭查看fabric.app就不會再看到黃色warning了^^
3.查看crash report
PS: 如果測試者有安裝套用Crashlytics前的版本(例如Apple Store版),一定要先移除才行,不然會安裝失敗。
PS:產生crash後,基本上最慢幾分鐘就能在fabric網站看到(管理者會馬上收到mail通知),如果一直沒有crash資料進來,要請用戶再開一次app,因為crash report是在crash之後,再開一次app才會真正傳送上去 !
申請安裝完畢後,除了Fabric.app管理小工具,最即時的crash report就要登入fabric提供的網站查看https://fabric.io/home
到fabric網站針對你管理的每個app去查看report
fabric.app很貼心(
2.發送測試邀請
當測試人員收到email並接受邀請後,管理者回到fabric.app查看,可能會有如下的黃色warning
解決方式是管理者會收到一封來自fabric的信,裡面附有一個包含測試者手機UDID的附檔,請將這個附檔交付給團隊中負責管理上架的人員,至Apple Developer將此UUID加到Devices,並綁定到被測試App的Provisioning Profile
上架負責人幫你處理完畢後,請務必記得重新下載Provisioning Profile重包一版,再透過fabric.app發布測試通知給測試人員,這樣對方才能成功安裝!
對方成功安裝後,管理者再回頭查看fabric.app就不會再看到黃色warning了^^
3.查看crash report
PS: 如果測試者有安裝套用Crashlytics前的版本(例如Apple Store版),一定要先移除才行,不然會安裝失敗。
PS:產生crash後,基本上最慢幾分鐘就能在fabric網站看到(管理者會馬上收到mail通知),如果一直沒有crash資料進來,要請用戶再開一次app,因為crash report是在crash之後,再開一次app才會真正傳送上去 !
申請安裝Crashlytics
Crashlytics真的做得非常好,還沒真的導入到專案,就在安裝過程中感受到Twitter的誠意,無論是安裝流程或是後來的使用方式,真的是連笨蛋都會用XD
但還是紀錄一下吧,網路上目前的文章都有點舊了呢
安裝時間:2016年5月
安裝環境:Xcode 7.3
1.前往登入頁,申請使用Crashlytics
2.收到驗證信並開通
驗證信基本上幾分鐘內會收到(我是一提出申請馬上收到)
開通並輸入團隊名稱(方便管理專案)
3.開通成功,開始下載對應IDE的安裝檔
4.打開fabric.app並登入
5.選擇要導入的專案
6.選擇要安裝的SDK
這邊我先選Crashlytics而已
7.選擇安裝加載的方式(CocoaPods或Framework)
選完後會自動幫你把Xcode打開,我選CocoaPods,所以右圖是如何修改Podfile的指示
8.依照說明安裝
修改Podfile並update
9.將Fabric整合到Xcode(Add Run Script)
實際Add Run Script的步驟可參考官網步驟
10.開始寫code,讓Crashlytics可以在app中執行
按照指令將藍色highlight處貼到專案的AppDelegate.m
11.Done
給他一點時間跑,就完成啦!
真的很簡單呢!只要跟著第3步驟中安裝好的fabric.app,一步一步完成他所指示的所有事項,就能導入Crashlytics ^_^
PS:登入過程中如果遭遇錯誤,可能是你的公司網路環境有阻擋,請暫時先改用其他網路環境安裝嚕
但還是紀錄一下吧,網路上目前的文章都有點舊了呢
安裝時間:2016年5月
安裝環境:Xcode 7.3
1.前往登入頁,申請使用Crashlytics
2.收到驗證信並開通
驗證信基本上幾分鐘內會收到(我是一提出申請馬上收到)
開通並輸入團隊名稱(方便管理專案)
4.打開fabric.app並登入
5.選擇要導入的專案
6.選擇要安裝的SDK
這邊我先選Crashlytics而已
7.選擇安裝加載的方式(CocoaPods或Framework)
選完後會自動幫你把Xcode打開,我選CocoaPods,所以右圖是如何修改Podfile的指示
8.依照說明安裝
9.將Fabric整合到Xcode(Add Run Script)
實際Add Run Script的步驟可參考官網步驟
10.開始寫code,讓Crashlytics可以在app中執行
按照指令將藍色highlight處貼到專案的AppDelegate.m
11.Done
給他一點時間跑,就完成啦!
真的很簡單呢!只要跟著第3步驟中安裝好的fabric.app,一步一步完成他所指示的所有事項,就能導入Crashlytics ^_^
PS:登入過程中如果遭遇錯誤,可能是你的公司網路環境有阻擋,請暫時先改用其他網路環境安裝嚕
The dependency `AFNetworking ` is not used in any concrete target
AFHTTPSessionManager does not pass JSON error responses to failure block
AFHTTPSessionManager does not pass JSON error responses to failure block
以往採用AFNetworking 2.x呼叫API後,無論在success或failure的block,都可以取得http response資訊,從而依需求取得所需的資訊,像是API執行失敗後回拋的說明資料等等
但大升級到AFNetworking 3.x後,發現failure block不再提供response相關資訊,其實是全部統一包進NSError了,二種版本的差異如下
AFNetworking 2.x
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:url parameters:params success:^(AFHTTPRequestOperation *operation ,id JSON) {
// do something if success
} failure:^(AFHTTPRequestOperation *operation , NSError *error) {
// do something if failure
NSData *data = [operation.responseString dataUsingEncoding:NSUTF8StringEncoding];
id dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
[self showJWTError:[dict objectForKey:@"error_description"]];
}];
AFNetworking 3.x
[manager POST:url parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
// do something if success
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
// do something if failure
NSData *data = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
NSDictionary *serializedData = [NSJSONSerialization JSONObjectWithData: data options:kNilOptions error:nil];
[self showJWTError:[serializedData objectForKey:@"error_description"]];
}];
ps: showJWTError是我用來呈現錯誤資訊給用戶的自訂方法
以往採用AFNetworking 2.x呼叫API後,無論在success或failure的block,都可以取得http response資訊,從而依需求取得所需的資訊,像是API執行失敗後回拋的說明資料等等
但大升級到AFNetworking 3.x後,發現failure block不再提供response相關資訊,其實是全部統一包進NSError了,二種版本的差異如下
AFNetworking 2.x
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:url parameters:params success:^(AFHTTPRequestOperation *operation ,id JSON) {
// do something if success
} failure:^(AFHTTPRequestOperation *operation , NSError *error) {
// do something if failure
NSData *data = [operation.responseString dataUsingEncoding:NSUTF8StringEncoding];
id dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
[self showJWTError:[dict objectForKey:@"error_description"]];
}];
AFNetworking 3.x
[manager POST:url parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
// do something if success
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
// do something if failure
NSData *data = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
NSDictionary *serializedData = [NSJSONSerialization JSONObjectWithData: data options:kNilOptions error:nil];
[self showJWTError:[serializedData objectForKey:@"error_description"]];
}];
ps: showJWTError是我用來呈現錯誤資訊給用戶的自訂方法
Logical not is only applied to the left hand side of this comparison
若左側運算元 (left hand side operand) 旁邊有 Logical Not ,又沒有用括號包起來就會出現Logical not is only applied to the left hand side of this comparison警告
例如
if(![self.someParameter caseInsensitiveCompare:@"Group"] == NSOrderedSame)
if(!([self.someParameter caseInsensitiveCompare:@"Group"] == NSOrderedSame))
或是
if((![self.someParameter caseInsensitiveCompare:@"Group"]) == NSOrderedSame)
force UITextView to scroll to the top
當畫面中的UITextView被塞入了大量文字,且文字數量多到畫面可以scroll
這時候就需要透過撰寫程式碼的方式,強迫畫面重新scroll至最頂端,作法如下
- (void)viewDidLoad {
[super viewDidLoad];
NSString *verylongText = @"very looooooooooooong text";
[self.myTextView setText:verylongText];
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
// make the UITextView scroll to top
[self.myTextView scrollRectToVisible:CGRectMake(0,0,1,1) animated:NO];
}
這時候就需要透過撰寫程式碼的方式,強迫畫面重新scroll至最頂端,作法如下
- (void)viewDidLoad {
[super viewDidLoad];
NSString *verylongText = @"very looooooooooooong text";
[self.myTextView setText:verylongText];
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
// make the UITextView scroll to top
[self.myTextView scrollRectToVisible:CGRectMake(0,0,1,1) animated:NO];
}
訂閱:
文章 (Atom)