IOS企業(yè)版版本更新以及推送pem的生成

發(fā)布新版本時需要注意的問題:

1.XCODE工程修改版本號。
2.打包后领跛,替換服務(wù)器中IPA文件肺魁。
3.修改ios_update.php文件,里面的版本號隔节,更新內(nèi)容鹅经。
4.修改push.php中推送的內(nèi)容寂呛。

推送需要準(zhǔn)備的東西:

開發(fā)P12 、 開發(fā)推送證書
推送P12 瘾晃、發(fā)布推送證書

開發(fā)推送證書的命令

需要的兩個文件aps_development.cer贷痪、Push.p12

1.openssl x509 -in aps_development.cer -inform der -out PushChatCert.pem
2.openssl pkcs12 -nocerts -out PushChatKey.pem -in Push.p12
3.cat PushChatCert.pem PushChatKey.pem > ck.pem
4、telnet gateway.sandbox.push.apple.com 2195
5. openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert PushChatCert.pem -key PushChatKey.pem

發(fā)布推送證書的命令

需要的兩個文件 aps_production.cer 蹦误、Push.p12(和開發(fā)的不同)

openssl x509 -in aps_production.cer  -inform der -out PushChatCert.pem
openssl pkcs12 -nocerts -out PushChatKey.pem -in Push.p12
cat PushChatCert.pem PushChatKey.pem > ck.pem
telnet gateway.push.apple.com 2195 
openssl s_client -connect gateway.push.apple.com:2195 -cert PushChatCert.pem -key PushChatKey.pem

推送IOS端代碼

#pragma mark - 推送設(shè)置   // Register for Push Notitications, if running iOS 8
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
        
        UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert |  UIUserNotificationTypeBadge | UIUserNotificationTypeSound);
        
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        [application registerForRemoteNotifications];
    } else {
        // Register for Push Notifications before iOS 8
        
        [application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |  UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)];
    }
}

-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
    
    NSString* newToken = [[[NSString stringWithFormat:@"%@",deviceToken]
                           stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]] stringByReplacingOccurrencesOfString:@" " withString:@""];
    NSLog(@"nsdata:%@\n 字符串token: %@",deviceToken, newToken);// 獲取device token
    // 上傳devicetoken
    [_netUtils requestContentWithUrl:DEVICE_TOKEN para:@{@"appleID": newToken} withSuccessBlock:^(id returnData) {
        NSLog(@"%@",returnData);
    } withFailureBlock:^(NSError *error) {
        NSLog(@"%@",error);
    }];
    
}
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
    NSLog(@"RegistFail%@",error);
  
}

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
    // 處理推送消息
    NSLog(@"收到推送消息:%@",[[userInfo objectForKey:@"aps"] objectForKey:@"alert"]);
    if (application.applicationIconBadgeNumber > 0) {
        application.applicationIconBadgeNumber  = 0;
    }
}

IOS端檢查更新代碼

-(void)getUpdate:(updateBlock)completonBlock  // 檢查更新
{
    __unsafe_unretained NetUtils *netUtil = self;// 防止循環(huán)應(yīng)用
    
    [netUtil GetContentWithUrl:UPDATE_URL withSuccessBlock:^(id returnData) {
       
        if ([returnData[@"verCode"] isEqualToString:kVersion_Coding]) {
            // 不用更新
            
        }
        else{
            // 提示更新
            UIAlertView *testView = [[UIAlertView alloc] bk_initWithTitle:@"有新版本" message:returnData[@"content"]];
            
            [testView bk_addButtonWithTitle:@"取消" handler:^{
            }];
            [testView bk_addButtonWithTitle:@"更新" handler:^{
                [[UIApplication sharedApplication] openURL:[NSURL URLWithString:IPAURL]];

            }];
            [testView show];
            
        }
     
    } withFailureBlock:^(NSError *error) {
        //NSLog(@"%@",error);
    }];
}


服務(wù)器端代碼:

db.php


<?php

class DB{
    public $link;
    public $error_state;
    function __construct(){
    
        $dbname = 'rUCqINjvmzQMBxMhDzeb';

        $host = 'sqld.duapp.com';
        $port = 4050;
        $user = 'vcoDM9nG8wswSdMTHj7YYsvV';//用戶名(api key)
        $pwd = 'OrpEsFYYu8nTC3VONGTjQGUjEu3y0EQU';//密碼(secret key)
        
        $this->link = @mysql_connect("{$host}:{$port}",$user,$pwd,true);
        if(!$this->link) {
            die("Connect Server Failed: " . mysql_error());
        }
        /*連接成功后立即調(diào)用mysql_select_db()選中需要連接的數(shù)據(jù)庫*/
        if(!mysql_select_db($dbname,$this->link)) {
            die("Select Database Failed: " . mysql_error($this->link));
        }
        mysql_query("SET NAMES 'UTF8'");
    }
  
    public function db_insert($sql)
    {
        $ret = mysql_query($sql,$this->link);
        if(!$ret){
            $this->error_state = 1;
        }
        return $ret;
    }
    
    
    public function db_select($sql)
    {   
        return db_insert($sql);
    }
  
    public function db_delete($sql)
    {
        return db_insert($sql);
    }
  
    //查詢后返回數(shù)組
    public function db_array($sql)
    {
        $arr = mysql_query($sql,$this->link);
        $result = array();
        while ($arrTemp = @mysql_fetch_assoc($arr)) {
            $result[] = $arrTemp ;
        }
        return $result;     
    }
  
  // 關(guān)閉連接數(shù)據(jù)庫
    public function closeDB()
    {
        mysql_close($this->link);
    }
  
  
    //事物處理 
    //開始事物
    public function db_start_substance()
    {
        mysql_query("BEGIN" ,$this->link);
        $this->error_state = 0;
    }
    //提交事物/回滾事物
    public function db_commit_substance()
    {
        if($this->error_state == 1){
            mysql_query("ROLLBACK",$this->link);
        }else{
            mysql_query("COMMIT",$this->link);
        }
        return $this->error_state;
    }
 
}

?>

存儲IOS設(shè)備的device token

 
<?php
// 查重
require_once "db.php";

$appleID =  $_REQUEST['appleID'];
if($appleID==""){
    exit("kongkong");
}
$db_obj = new DB();
$sqlApple = "select * from appleDevice where appleID = '$appleID'";
$sqlResult = $db_obj->db_array($sqlApple);
if($sqlResult){
   exit("exit");
}else{
  $sql = "insert into appleDevice (appleID) values ('$appleID') ";
  $result = $db_obj->db_insert($sql);
 if($result){
    $arr  = array('result' => 'success' );
    echo json_encode($arr);
  }else{
    $arr  = array('result' => 'fail' );
    echo json_encode($arr);

}
}

?>

檢查更新代碼

<?php
//  http://weixin.jsptz.com/map/app/ipa/location.ipa 
// ipa下載地址
$arr = array('verName'=>'app','verCode'=>'1.0.10','content'=>'活動詳情展示劫拢。');
echo json_encode($arr);
?>

發(fā)布推送的代碼

 <?php
// 發(fā)布地址:gateway.push.apple.com:2195

 // 測試通過
require_once "db.php";
 
$db_obj = new DB();
$sql = "select appleID from appleDevice ";
$result = $db_obj->db_array($sql);
 
$countArray = count($result); 
 
$passphrase = 'zhaojian';
$message = '生產(chǎn)-推送-測試!'; 
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
$fp = stream_socket_client(
    'ssl://gateway.push.apple.com:2195', $err,
    $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);

if (!$fp)
    exit("Failed to connect: $err $errstr" . PHP_EOL);
 
echo 'Connected to APNS' . PHP_EOL;
 
$body['aps'] = array(
    'alert' => $message,
    'sound' => 'default'
    );
 
$payload = json_encode($body);

 for($i = 0; $i < $countArray; $i++)
{
    $deviceToken = $result[$i]['appleID'];
   
    $msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
 
    $result1 = fwrite($fp, $msg, strlen($msg));
     
    if (!$result1){
        echo  $deviceToken . 'Message not delivered' . PHP_EOL;
    }
    else
    {
     echo  $deviceToken . 'Message successfully delivered' . PHP_EOL;
    }
  }
    fclose($fp);   

?>

服務(wù)端下載地址代碼down.html


        <script type="text/javascript">
            /*
             * 智能機(jī)瀏覽器版本信息:
             *
             */
            var browser = {
                versions: function() {
                    var u = navigator.userAgent, app = navigator.appVersion;
                    return {//移動終端瀏覽器版本信息 
                        trident: u.indexOf('Trident') > -1, //IE內(nèi)核
                        presto: u.indexOf('Presto') > -1, //opera內(nèi)核
                        webKit: u.indexOf('AppleWebKit') > -1, //蘋果强胰、谷歌內(nèi)核
                        gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, //火狐內(nèi)核
                        mobile: !!u.match(/AppleWebKit.*Mobile.*/) || !!u.match(/AppleWebKit/), //是否為移動終端
                        ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios終端
                        android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, //android終端或者uc瀏覽器
                        iPhone: u.indexOf('iPhone') > -1 || u.indexOf('Mac') > -1, //是否為iPhone或者QQHD瀏覽器
                        iPad: u.indexOf('iPad') > -1, //是否iPad
                        webApp: u.indexOf('Safari') == -1 //是否web應(yīng)該程序舱沧,沒有頭部與底部
                    };
                }(),
                language: (navigator.browserLanguage || navigator.language).toLowerCase()
            }

            if (browser.versions.ios || browser.versions.iPhone || browser.versions.iPad) {
                //window.location='itms-services://?action=download-manifest&url=http://zhangshangxindai.duapp.com/app/ipa/Loan.php';
                window.location="itms-services://?action=download-manifest&url=https://zhangshangxindai.duapp.com/Travel/ios_app/Travel.plist";         
            }
            else if (browser.versions.android) {
                window.location="http://zhangshangxindai.duapp.com/app/apk/zhangshangxindai.apk";
            }
 
        </script>

down.html指向plist的地址,plist指向ipa的地址偶洋。
plist需要放在支持https的服務(wù)器上熟吏,down.html、ipa可以放在http/https上

參考:

http://blog.csdn.net/IOS_CaoMuJieBing/article/details/18043557
http://blog.csdn.net/showhilllee/article/details/8631734

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末玄窝,一起剝皮案震驚了整個濱河市牵寺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌恩脂,老刑警劉巖帽氓,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異俩块,居然都是意外死亡黎休,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進(jìn)店門玉凯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來势腮,“玉大人,你說我怎么就攤上這事壮啊〖稻ǎ” “怎么了撑蒜?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵歹啼,是天一觀的道長。 經(jīng)常有香客問我座菠,道長狸眼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任浴滴,我火速辦了婚禮拓萌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘升略。我一直安慰自己微王,他們只是感情好屡限,可當(dāng)我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著炕倘,像睡著了一般钧大。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上罩旋,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天啊央,我揣著相機(jī)與錄音,去河邊找鬼涨醋。 笑死瓜饥,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的浴骂。 我是一名探鬼主播乓土,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼靠闭!你這毒婦竟也來了帐我?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤愧膀,失蹤者是張志新(化名)和其女友劉穎拦键,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體檩淋,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡芬为,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蟀悦。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片媚朦。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖日戈,靈堂內(nèi)的尸體忽然破棺而出询张,到底是詐尸還是另有隱情,我是刑警寧澤浙炼,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布份氧,位于F島的核電站,受9級特大地震影響弯屈,放射性物質(zhì)發(fā)生泄漏蜗帜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一资厉、第九天 我趴在偏房一處隱蔽的房頂上張望厅缺。 院中可真熱鬧,春花似錦、人聲如沸湘捎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽窥妇。三九已至且叁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間秩伞,已是汗流浹背逞带。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留纱新,地道東北人展氓。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像脸爱,于是被迫代替她去往敵國和親遇汞。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內(nèi)容