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) 要如下:

 
<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

改成

dl.dropboxusercontent.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);