今天同事把git上新的檔案拉下來
但發現storyboard壞了!!!
出現以下文字
An internal error occurred. Editing functionality may be limited
storyboard 的畫面無法編輯
可也不知是程式的問題還是 因為我們使用了最新的XCode 8 Beta的關係
但後來網路找了試了此方法
把
~/Library/Developer/Xcode/DerivedData
該專案的暫存檔刪除
重新啟用xcode就正常囉!!
2016年1月11日 星期一
[ios]判斷iPhone版本
if( [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad ){
self.label.text = @"iPad";
}else{
CGFloat detectionSize = 0;
if ( [[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationPortrait ){
detectionSize = self.view.bounds.size.height;
}else{
detectionSize = self.view.bounds.size.width;
}
NSInteger ht = detectionSize;
NSLog(@"ht:%ld",ht);
switch (ht){
case 480:
self.label.text = @"iPhone 4S";
break;
case 568:
self.label.text = @"iPhone 5/5s";
break;
case 667:
self.label.text = @"iPhone 6";
break;
case 736:
self.label.text = @"iPhone 6 Plus";
break;
default:
self.label.text = @"iPhone";
}
}
Swift version
if UIDevice.currentDevice().userInterfaceIdiom == .Pad{
label.text = "iPad"
}else{
var detectionSize:CGFloat = 0
if self.interfaceOrientation == .Portrait{
detectionSize = self.view.bounds.height
}else{
detectionSize = self.view.bounds.width
}
switch detectionSize{
case 480:
label.text = "iPhone 4S"
case 568:
label.text = "iPhone 5/5S"
case 667:
label.text = "iPhone 6"
case 736:
label.text = "iPhone 6 Plus"
default:
label.text = "iPhone"
}
}
2015年11月18日 星期三
iOS Enterprise in house發佈app記錄
最近在搞apple enterprise developer 的事情
在搞 in house的部份,
在iOS7.1之後有了些許的改變
發現原來有兩年沒有發佈in house的app了
在iOS9中,發佈in house的app
XCode會compile出一個plist與一個ipa檔
檔案需放至在https的server裡頭
我用以前的邏輯去建立出enterprise的App測試
但不知為何
發現放在自己的建立的https server就一直無法成功下載
後來將檔案與網頁檔放到dropbox上,
居然可以下載安裝 這就奇怪了
流程明明就一樣
所以就開始朝向https server找原因
oh 對了,
網頁是要提供使用者下載App的連結,
通常連結比較特別(html) 要如下:
manifest.plist就是你發佈出來的其中一個檔案
若你的下載的路徑不同的話,
可以開啟plist去修改裡面的網址
在說https server之前
我先說明一下若放到dropbox的作法
首先你要有dropbox的帳號
先上傳你寫好的網頁檔(html) 點選右鍵 分享鏈結 然後你會得到
https://www.dropbox.com/s/xxxxxxxxxxx/xxxx.html
把www.dropbox.com
改成
dl.dropboxusercontent.com
然後你可以先由此網址確認網頁是否能夠打得開
以上是放到dropbox的方式
然後實際我一直卡在是 https已經架了起了
但卻一直出現 "無法連結xxx.xxx.xxx.xx" (沒有放到https server 好像也也類似的錯誤訊息)
後來發現是https的證問題
網路上有人說ios9要購買外面的SSL授權?!
我想這不就要花了一筆錢
但後來發現其實不然
你要去查如何用SSL去建立出一個CSR檔
再利用CSR檔去建立出一個https可以使用的keystore
然後iOS手機要先至https下載CSR憑證
就可以跳過無法連結xxx.xxx.xxx.xxx的問題
好 以為這樣就很順利了
但what the fuxk!!!
為啥又出現
Unable to download App
xxx not be download at this time
(繁中:無法下載應用程序此時無法安裝xxx xx ”)
為了以上的問題 我煩惱了三天
為了in house下載煩惱了四天
所以一個星期就過了....
後來發現一件很蠢的問題
就是手機裡有原本App的profile檔
也就是之前實機測試裝上去的
把他砍了 重新執行下載
就能夠順利安裝了…
in house的資料是不多 且apple一直在改變
像我最無法安裝時 有查到以下的 解法
在搞 in house的部份,
在iOS7.1之後有了些許的改變
發現原來有兩年沒有發佈in house的app了
在iOS9中,發佈in house的app
XCode會compile出一個plist與一個ipa檔
檔案需放至在https的server裡頭
我用以前的邏輯去建立出enterprise的App測試
但不知為何
發現放在自己的建立的https server就一直無法成功下載
後來將檔案與網頁檔放到dropbox上,
居然可以下載安裝 這就奇怪了
流程明明就一樣
所以就開始朝向https server找原因
oh 對了,
網頁是要提供使用者下載App的連結,
通常連結比較特別(html) 要如下:
<a href="https://www.blogger.com/null" ref="itms-services://?action=download-manifest?&url=http://domain/manifest.plist">下載App</a>;
manifest.plist就是你發佈出來的其中一個檔案
若你的下載的路徑不同的話,
可以開啟plist去修改裡面的網址
在說https server之前
我先說明一下若放到dropbox的作法
首先你要有dropbox的帳號
先上傳你寫好的網頁檔(html) 點選右鍵 分享鏈結 然後你會得到
https://www.dropbox.com/s/xxxxxxxxxxx/xxxx.html
把www.dropbox.com
改成
若打得開就代表是成功
再來就把你的ipa檔放到dropbox上面
然後一樣的方式
先取得ipa的分享網址 記得改上面紅色的字
再把ipa的分享網址到plist裡面修改 因為plist檔裡會有一個是指向ipa的位置
再把plist上傳到dropbox 一樣的方式取得分享連結
再改上面紅色的位置 把網址copy下來
再貼到html的超連結
超連結改完後再上傳到dropbox 並且覆蓋
這樣就能夠由dropbox 的網頁下載安裝 ipa檔
以上是放到dropbox的方式
然後實際我一直卡在是 https已經架了起了
但卻一直出現 "無法連結xxx.xxx.xxx.xx" (沒有放到https server 好像也也類似的錯誤訊息)
後來發現是https的證問題
網路上有人說ios9要購買外面的SSL授權?!
我想這不就要花了一筆錢
但後來發現其實不然
你要去查如何用SSL去建立出一個CSR檔
再利用CSR檔去建立出一個https可以使用的keystore
然後iOS手機要先至https下載CSR憑證
就可以跳過無法連結xxx.xxx.xxx.xxx的問題
好 以為這樣就很順利了
但what the fuxk!!!
為啥又出現
Unable to download App
xxx not be download at this time
(繁中:無法下載應用程序此時無法安裝xxx xx ”)
為了以上的問題 我煩惱了三天
為了in house下載煩惱了四天
所以一個星期就過了....
後來發現一件很蠢的問題
就是手機裡有原本App的profile檔
也就是之前實機測試裝上去的
把他砍了 重新執行下載
就能夠順利安裝了…
in house的資料是不多 且apple一直在改變
像我最無法安裝時 有查到以下的 解法
Targets → Select your target
→ Build Settings
→ Code Signing Resource Rules Path
加入 $(SDKROOT)/ResourceRules.plist
但我加入還是不能
但這應該都是憑證的問題
也可以參考以下教學網址試試
2015年11月5日 星期四
ios Singleton
UserInfoManagerCenter.h
#import <Foundation/Foundation.h>
@interface UserInfoManagerCenter : NSObject
@property (nonatomic,strong) NSString *name;
@property (nonatomic,strong) NSNumber *age;
+(instancetype)managerCenter;
@end
UserInfoManagerCenter.m
#import "UserInfoManagerCenter.h"
static UserInfoManagerCenter *center = nil;
@implementation UserInfoManagerCenter
+(instancetype)managerCenter{
static dispatch_once_t predicate;
// 避免產生競爭現像
dispatch_once(&predicate, ^{
center = (UserInfoManagerCenter *)@"UserInfoManagerCenter";
center = [[UserInfoManagerCenter alloc] init];
});
// 防止子類別使用
NSString *classString = NSStringFromClass([self class]);
// 使用方法的class名字與UserInfoManagerCenter不同 就crash
if( [classString isEqualToString:@"UserInfoManagerCenter"] == NO ){
// crash
NSParameterAssert(nil);
}
return center;
}
-(instancetype)init{
NSString *string = (NSString*)center;
if( [string isKindOfClass:[NSString class]] == YES && [string isEqualToString:@"UserInfoManagerCenter"]){
self = [super init];
if( self){
// 防止子類別使用
NSString *classString = NSStringFromClass([self class]);
// 使用方法的class名字與UserInfoManagerCenter不同 就crash
if( [classString isEqualToString:@"UserInfoManagerCenter"] == NO ){
// crash
NSParameterAssert(nil);
}
}
return self;
}else{
return nil;
}
}
@end
使用
UserInfoManagerCenter *center = [UserInfoManagerCenter managerCenter];
NSLog(@"%@",center.name);
2015年10月30日 星期五
iOS開發者帳號購買價格功能表參考
自從iOS Xcode 7開始,
你不需新購買Developer 帳號就可以直接發佈在實機測試App
可是你還是需有一組Apple ID
但有些功能是有限制的
可以參考下表
2015年9月23日 星期三
Swift Call Objective-C方式
iOS裡要如何呼叫Objective-C的語法呢
Swift會透過一個Bridge去呼叫Objective-C
首先先建立一個Swift的iOS Project
再建立一個Objective語法的檔案 叫做Member
會產生Member.h 與Member.m
當建立後 會跳出這個畫面
這樣就可以對Objective-C的屬性做存取囉!
Swift會透過一個Bridge去呼叫Objective-C
首先先建立一個Swift的iOS Project
再建立一個Objective語法的檔案 叫做Member
會產生Member.h 與Member.m
當建立後 會跳出這個畫面
若有產生就按Yes
沒有產生就別擔心 可以手動建立
沒產生的話就手動建立一個檔名為
swiftCallObjCTest-Bridging-Header.h的檔案
swiftCallObjCTest為你的專案名稱 自行修改
若自行新增的使用者 要去Build Setting檢查一下有沒有新增這項檔案
再來在Member.h新增objective-c的語法
#import <Foundation/Foundation.h>
@interface Member : NSObject
@property (nonatomic,strong) NSString *name;
@end
接下來再切到AppDelegate.swift的檔案
到func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool 裡面
加入
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
var member: Member = Member()
member.name = "James"
println("member name:\(member.name)")
return true
}
這樣就可以對Objective-C的屬性做存取囉!
2015年4月18日 星期六
XCode6.3惱人的bug
升到XCode 6.3發現一個惱人的Bug
明明就有一隻手機是ios 8.1.2版
project設定 iOS Deployment Target 為 8.0版本
照理說8.0以上的手機都要可以發佈至實機上(以正確的憑證狀況下),
但升到XCode6.3 卻無法傳app至8.1.2、8.2 的iOS手機
而iOS 8.3的手機卻可以!!
不可能要我把所有裝置都升級到8.3
這個bug 是你無法選擇你的裝置,
會出現 ineligible Devices.
明明就有一隻手機是ios 8.1.2版
project設定 iOS Deployment Target 為 8.0版本
照理說8.0以上的手機都要可以發佈至實機上(以正確的憑證狀況下),
但升到XCode6.3 卻無法傳app至8.1.2、8.2 的iOS手機
而iOS 8.3的手機卻可以!!
不可能要我把所有裝置都升級到8.3
這個bug 是你無法選擇你的裝置,
會出現 ineligible Devices.
後來找到解法!!!!
只要你到Product→Destionation→選擇你的裝置
左上角就會直接跳到你的手機,就可以發佈了.....|||||||
2015年3月23日 星期一
解決Xcode外掛無法使用問題
解決xcode下外掛無法使用
到以下目錄
~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/
找到你要的外掛 打開套件內容
選擇info.plist檔,
於DVTPluginCompatibilityUIDs加入
XCodde 6.3.2
E969541F-E6F9-4D25-8158-72DC3545A6C6
XCode 6.3
9F75337B-21B4-4ADC-B558-F9CADF7073A7
Xcode 6.2
A16FF353-8441-459E-A50C-B071F53F51B7
Xcode 6GM:
C4A681B0-4A26-480E-93EC-1218098B9AA0
到以下目錄
~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/
找到你要的外掛 打開套件內容
選擇info.plist檔,
於DVTPluginCompatibilityUIDs加入
XCodde 6.3.2
E969541F-E6F9-4D25-8158-72DC3545A6C6
並執行
find ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins -name Info.plist -maxdepth 3 | xargs -I{} defaults write {} DVTPlugInCompatibilityUUIDs -array-add `defaults read /Applications/Xcode.app/Contents/Info DVTPlugInCompatibilityUUID`
XCode 6.3
9F75337B-21B4-4ADC-B558-F9CADF7073A7
Xcode 6.2
A16FF353-8441-459E-A50C-B071F53F51B7
Xcode 6GM:
C4A681B0-4A26-480E-93EC-1218098B9AA0
2015年3月12日 星期四
2015年3月2日 星期一
UIContainer View呼叫Parent ViewController屬性與傳值
UIContainer VIew 傳值給ParentViewController
主要是選擇使用delegate的方式,
在ParentViewController.h
ParentUIViewController .m 檔
而在 ChildViewController.h 要宣告定義好protocol讓UIViewController能夠處理你要他做的事情
然後.m檔去呼叫delegate方法
這樣就可以透過container view controller去傳值給parentviewcontroller
而還有夠簡易的方式是
直接由container view controller去修改parent view controller的值
例如
以上是由container view 呼叫 parent view的屬性
主要是選擇使用delegate的方式,
在ParentViewController.h
#import
#import "ChildViewController.h"
@interface ViewController : UIViewController<ChildViewControllerDelegate>
@property (weak, nonatomic) IBOutlet UITextField *parentTF;
@end
ParentUIViewController .m 檔
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:@"mySegue"])
{
ChildViewController *cVC = segue.destinationViewController;
cVC.delegate = self;
}
}
-(void) done:(NSString *)someText andChildBtn:(UIButton *)childBtn
{
self.parentTF.text = someText;
[childBtn setTitle:@"changed" forState:UIControlStateNormal];
[self.view setBackgroundColor:[UIColor darkGrayColor]];
}
@end
而在 ChildViewController.h 要宣告定義好protocol讓UIViewController能夠處理你要他做的事情
#import <UIKit/UIKit.h>
// 傳到到另個 ViewController ,所以自己要先定義protocol
@protocol ChildViewControllerDelegate <NSObject>
-(void)done:(NSString*)someText andChildBtn:(UIButton*)childBtn;
@end
@interface ChildViewController : UIViewController
@property(nonatomic,assign) id<ChildViewControllerDelegate> delegate;
@property (weak, nonatomic) IBOutlet UIButton *passValueBtn;
@property (weak, nonatomic) IBOutlet UITextField *childTF;
- (IBAction)passValueAction:(id)sender;
@end
然後.m檔去呼叫delegate方法
#import "ChildViewController.h"
@implementation ChildViewController
- (IBAction)passValueAction:(id)sender {
[self.delegate done:self.childTF.text andChildBtn:self.passValueBtn];
}
@end
這樣就可以透過container view controller去傳值給parentviewcontroller
而還有夠簡易的方式是
直接由container view controller去修改parent view controller的值
例如
((ViewController*)self.parentViewController).lb.text =[NSString stringWithFormat:@"%ld",indexPath.row];
以上是由container view 呼叫 parent view的屬性
2015年2月12日 星期四
Objective-C 字串比較
一般自定常數的方法有兩種,
1. 在header(.h)檔
FOUNDATION_EXPORT NSString * const MY_NAME;
FOUNDATION_EXPORT NSString * const MY_GIRLFRIEND_NAME;
於.m檔
NSString * const MY_NAME = @"James";
NSString * const MY_GIRLFRIEND_NAME = @"Stella";
2. 另一種定義常數的方法為:
#define MY_NAM @"James"
#define MY_GIRLFRIEND_NAME @"Stella"
這兩種方法在檢查字串時,第一種可以使用(StringInstance == MY_NAME )來比較,
而使用define則是使用([StringInstance isEqualToString:MY_NAME]) 來比較。
第一種直接比較是使用pointer address,第二種比較則是比較每個字元是否相等。
1. 在header(.h)檔
FOUNDATION_EXPORT NSString * const MY_NAME;
FOUNDATION_EXPORT NSString * const MY_GIRLFRIEND_NAME;
於.m檔
NSString * const MY_NAME = @"James";
NSString * const MY_GIRLFRIEND_NAME = @"Stella";
2. 另一種定義常數的方法為:
#define MY_NAM @"James"
#define MY_GIRLFRIEND_NAME @"Stella"
這兩種方法在檢查字串時,第一種可以使用(StringInstance == MY_NAME )來比較,
而使用define則是使用([StringInstance isEqualToString:MY_NAME]) 來比較。
第一種直接比較是使用pointer address,第二種比較則是比較每個字元是否相等。
2015年1月26日 星期一
gen_entitlements.py: No such file or directory實機報錯
今天要把別的廠商的專案進行測試
但拿到專案檔一直無法傳到手機上,
以為是憑證哪出了問題,但後來發現不是!
錯誤訊息部份如下
line 4: /Applications/Xcode.app/Contents/Developer/iphoneentitlements/gen_entitlements.py: No such file or directory
但拿到專案檔一直無法傳到手機上,
以為是憑證哪出了問題,但後來發現不是!
錯誤訊息部份如下
line 4: /Applications/Xcode.app/Contents/Developer/iphoneentitlements/gen_entitlements.py: No such file or directory
後來發現這個是之前公司在作假憑證的run script出了問題
只要到build phase裡刪除 run script
再使用正確的debug憑證去發佈至手機即可
2014年12月9日 星期二
啟用Watch App Simulator
目前測試 apple 最新的 apple watch 可以透過XCode 6.2 beta版
apple watch的project是要綁在手機上的專案,
所以watch app其實只是手機app的延伸,
若你今天要啟用apple watch simulator的話,
只要在xcode的target選擇watch app
然後按下compile
模擬器就會跑出來囉!
若你發現只有手機模擬器出現的話,
你可以在模擬器的工具列
Hardware→External Displays→選到最下方的Apple Watch
這樣Apple watch的simulator就會跑出來囉!
apple watch的project是要綁在手機上的專案,
所以watch app其實只是手機app的延伸,
若你今天要啟用apple watch simulator的話,
只要在xcode的target選擇watch app
然後按下compile
模擬器就會跑出來囉!
若你發現只有手機模擬器出現的話,
你可以在模擬器的工具列
Hardware→External Displays→選到最下方的Apple Watch
這樣Apple watch的simulator就會跑出來囉!
2014年9月15日 星期一
2014年8月9日 星期六
Xcode trace 方法名稱
為了避免方法名稱修改
在NSLog內的字串也要修改會造成麻煩
可以直接寫
這樣就可以trace method 的名稱
在NSLog內的字串也要修改會造成麻煩
可以直接寫
NSLog(@"%@", NSStringFromSelector(_cmd));
_cmd在objective-c都為一個SEL這樣就可以trace method 的名稱
2014年7月28日 星期一
UIWebview 的javascript與ios objective-c互動傳參數(Ⅱ)
繼4個月前的一篇【UIWebview 的javascript與ios objective-c互動傳參數】
有人問到要如何從objective-c呼叫網頁的function並回傳值
以下為沒有傳參數的方法,
傳參數給網頁的function請看
【UIWebview 的javascript與ios objective-c互動傳參數】 此篇
若要從objective-c去呼叫網頁javascript並回傳值的話
有兩種作法
一種就是再用function去呼叫丟objective-c內的的function
此方法較複雜也較麻煩 此方法可用前篇 在網頁呼叫callObjFunction的function
這是其中一種作法。
Objective-c程式關鍵部份:
這樣就可以看見log有I will return from js web的字樣
發文附圖:
有人問到要如何從objective-c呼叫網頁的function並回傳值
以下為沒有傳參數的方法,
傳參數給網頁的function請看
【UIWebview 的javascript與ios objective-c互動傳參數】 此篇
若要從objective-c去呼叫網頁javascript並回傳值的話
有兩種作法
一種就是再用function去呼叫丟objective-c內的的function
此方法較複雜也較麻煩 此方法可用前篇 在網頁呼叫callObjFunction的function
這是其中一種作法。
另種作法就最單純簡單
就直接在javascript使用return 就可以傳回到objective-c內
例:
webview的程式碼:
<!DOCTYPE html>
<html>
<head>
<script>
function callObjFunction()
{
return "I will return from js web";
}
</script>
</head>
<body>
</body>
</html>
Objective-c程式關鍵部份:
NSString *str = [_theWebview stringByEvaluatingJavaScriptFromString: [NSString stringWithFormat:@"callObjFunction()"]];
NSLog(@"str:%@", str);
這樣就可以看見log有I will return from js web的字樣
發文附圖:
範例程式: GitHub
2014年7月17日 星期四
推薦XCode外掛套件 - ColorSense-for-Xcode
ColorSense-for-Xcode 為一款XCode的顏色選擇套件,
~/Library/Application Support/Developer/Shared/Xcode/Plug-ins
加入外掛
目前官網說明在 OS X 10.8 with Xcode 4.4.1 and 4.5.的環境測試過
而我是在OS X 10.9.4 withXCode 5.1 and Xcode 6 Beta3 測試皆可以使用。
只要打入[UIColor 後面就會跳出顏色面版讓你選擇
不用再自行輸入色彩代碼
如圖
安裝使用方式
只要下載官網專案檔
使用xcode開啟專案 compile 成功後
程式會自動在你的
加入外掛
目前官網說明在 OS X 10.8 with Xcode 4.4.1 and 4.5.的環境測試過
而我是在OS X 10.9.4 withXCode 5.1 and Xcode 6 Beta3 測試皆可以使用。
2014年6月12日 星期四
navigation pushViewController返回方式
若目前有
A(Root) → B → C → D
四個UIViewController,
每個都是使用navigation 的 push的做action,
今天你在B、C或D 要點擊按鈕回到A(Root)
在按鈕事件下
就可以回到A的Root。
返回某個指定的UIViewController 採用index定位的話,
就下
若要用class name去指定跳到的UIViewController
這樣就可以返回你想要返回的地方囉~
A(Root) → B → C → D
四個UIViewController,
每個都是使用navigation 的 push的做action,
今天你在B、C或D 要點擊按鈕回到A(Root)
在按鈕事件下
[self.navigationController popToRootViewController]
就可以回到A的Root。
返回某個指定的UIViewController 採用index定位的話,
就下
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:2] animated:YES];
若要用class name去指定跳到的UIViewController
for (UIViewController *controller in self.navigationController.viewControllers) {
if ([controller isKindOfClass:[你要跳到的UIViewController的class名稱 class]]) {
[self.navigationController popToViewController:controller animated:YES];
}
}
這樣就可以返回你想要返回的地方囉~
2014年5月28日 星期三
Apple開發者帳號 統編申請方式
若公司要購買開發者帳號,但需公司統編附在發票上的話,
申請的流程如下:
申請的流程如下:
1. 先刷卡附款。
2. 附款成功後,獲得訂單編號。
3. 打電話與台灣客服聯繫 0800-020-021 ,選擇國語 按4
告知需要開的統一編號,與發票需打的公司名字,
只要把需求跟台灣客服說他們就會幫我們處理。
所以不用擔心網頁上沒有可以輸入統編的問題~
2014年4月23日 星期三
GoogleMap API error - [animateToCameraPosition... ]
今天要再用map時一直出現下面錯誤
[GMSMapView animateToCameraPosition:]: unrecognized selector sent to instance
Code與官網一樣
最後發現
原來是少加了
-ObjC
這樣就可以順利發佈了
訂閱:
文章 (Atom)













