The simplest enterprise certificate deployment application! In house improvements! Free HTTPS!

Time:2019-11-30

⚠ due to Sina server upgrade, the length of directory and file name is limited, so the implementation mode is changed

brief introduction

iOSPlatform release application, want to bypassAppStoreThe best wayIn-HouseReleased (due to incomplete coverage of jailbreak users, jailbreak mode is generally not considered).
Web searchIn-HouseThere are many tutorials about how to apply for enterprise certificate and how to apply for enterprise certificateipaI won’t repeat if the bag is signed. Two links are attached at the end of the article. You can have a look at the children’s shoes you don’t know.

If you didIn-HouseDeployment, you should know that you need to prepare a*.plistThe file is uploaded to the server and from theiOS7And later, this file must be deployed inHTTPSThe server can be installed normally. This step is very error prone and cannot be deployed successfully.

Error reason:

  • Wrong signature or packaging.

  • It’s because I don’t know about the configuration file, and I don’t know where the error is.

  • No conditional deploymentHTTPSThe server

The easiest way (uploadipaPackage tohttpServer, calling ajsMethod)

  • The installation page introduces thisJS

<script></script>
  • Called at the location of the Install buttonopenInstallURLMethod, you can use any HTML tag!

<div onclick="openInstallURL({
    'title': 'I am the app title',
    'ipa'     : 'http://www.xxx.com/app.ipa', 
    'version' : '1.0',
    'ident'   : 'cn.xxx.xxx', 
    'icon': '}); "> click Install < / div >
  • Parameter description

parameter Explain Remarks
title Title Safari pop up the title of the installation prompt
ipa Have a guess IPA package requires you to upload it to your own server, and then fill in the URL that can be downloaded to this IPA package. You can useHTTPAgreement!
version Guess again. ⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠
ident App unique identifier You can configure theBundle IdentifierSee him next.
icon Install icons during load If you pass in an empty string, there is a default icon:The simplest enterprise certificate deployment application! In house improvements! Free HTTPS!

Demo

  • Students who are not familiar with HTML can use the following code directly. The style has been written and saved as*.htmlFile can

<html>
<head>
  <meta name="generator" content="HTML Tidy for Mac OS X (vers 31 October 2006 - Apple Inc. build 15.12), see www.w3.org" />
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  < title > app test < / Title >
  <link rel="stylesheet" href="http://iosinstall.sinaapp.com/plist/ios-install.css">
  <script></script>
</head>
<body>
  < H5 style = "text align: Center; color: red; padding: 20px;" > note! The following packages are for testing only! <br/></h5>
  <install-btn onclick="openInstallURL({
    'title': 'I am the title', 
      'ipa'     : 'http://www.xxx.com/ipa/xxxx.ipa', 
      'version'    : '1.0',
      'ident'   : 'com.xxx.xxx', 
      'icon': '}); "> click on me to install < / install BTN >
</body>
</html>

If you want to provide these entirely yourself, please look at the following.

Realization principle

I used to solveIn-HouseIn order to solve the problem of deployment, many detours have been takenHTTPSUsing private certificates, usingDropboxThe HTTPS service of GitHub, or the HTTPS service of GitHub, are all feasible, but they all have different degrees of troubles, so today’s post comes.

Implementation logic: according to their own software requirements, clients transfer to the server, and the server dynamically generates*.plistBecauseiOSWill detect*.plistThe URL of cannot have parameters, so use theBase64After encryption is added to the URL path, the server intercepts the parameters in the path and decrypts them to obtain the parameters. Because of the particularity of path change, it is necessary to configure the redirection of the server.
This way, you don’t need to configure every new application once*.plistPapers!
What I’m offering now*.plistRun in Sina cloud stable and fast, can rest assured use!

  • jsImplementation logic: collect parameters, encrypt them into Base64 strings, and insert them into the access URL.

// http://iosinstall.sinaapp.com/plist/ios-install.js
var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var base64DecodeChars = new Array(
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
    -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
    -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);
    
//Base64 encoding method
function base64encode(str) {
    var out, i, len;
    var c1, c2, c3;
    len = str.length;
    i = 0;
    out = "";
    while(i < len) {
        c1 = str.charCodeAt(i++) & 0xff;
        if(i == len) {
            out += base64EncodeChars.charAt(c1 >> 2);
            out += base64EncodeChars.charAt((c1 & 0x3) << 4);
            out += "==";
            break;
        }
        c2 = str.charCodeAt(i++);
        if(i == len) {
            out += base64EncodeChars.charAt(c1 >> 2);
            out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
            out += base64EncodeChars.charAt((c2 & 0xF) << 2);
            out += "=";
            break;
        }
        c3 = str.charCodeAt(i++);
        out += base64EncodeChars.charAt(c1 >> 2);
        out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
        out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6));
        out += base64EncodeChars.charAt(c3 & 0x3F);
    }
    return out;
}

//Calculate hash value
var I64BIT_TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-'.split('');
function hash(input){
 var hash = 5381;
 var i = input.length - 1;
  
 if(typeof input == 'string'){
  for (; i > -1; i--)
   hash += (hash << 5) + input.charCodeAt(i);
 }
 else{
  for (; i > -1; i--)
   hash += (hash << 5) + input[i];
 }
 var value = hash & 0x7FFFFFFF;
  
 var retValue = '';
 do{
  retValue += I64BIT_TABLE[value & 0x3F];
 }
 while(value >>= 6);
  
 return retValue;
}

/**
  Demo:
  Var info = {'title': 'I am the title', // APP name 
                'ipa'        : 'http://www.xxx.com/ipa/xxx.ipa', // ipa url 
                'version'    : '1.0',
                'ident'        : 'cn.xxx.xxx', 
                'icon'        : '' // icon url
  };
  openInstallURL(info);
 */
function openInstallURL(info) {
    if (info.ident == null || info.ident.length == 0) {
        info.ident = 'cn.ineva.cn';
    }
    if (info.icon == null || info.icon.length == 0) {
        info.icon = 'http://iosinstall.sinaapp.com/plist/ios-install.png';
    }
    if (info.version == null || info.version.length == 0) {
        info.version = '1.0.0';
    }
    
    var json = JSON.stringify(info)
    var base64String = base64encode(encodeURI(json)).replace(/\=/g, "");
    var fileName = hash(base64String)
    var s = 128;
    var count = Math.ceil( base64String.length / s);
    var path = "";
    //Because Sina has restrictions on the length of linked file names and directories, JSON data is separated by '/'
    for (var i = 0; i < count; i++) {
        var l = s;
        if (i == count - 1) {
            l = base64String.length - i * s;
        }
        path += "/" + base64String.substr( i * s, l);
    }
    var url = 'https://iosinstall.sinaapp.com/plist' + path + "/" + fileName + ".plist";
    window.self.location = 'itms-services://?action=download-manifest&url=' + url;
}
  • Server PHP implementation: intercept parameters from URL, and use parameters to splice well*.plistThe content of the document, the spliced content will be returned as the document.

<?php
    
    $pathItems = explode('/', $_SERVER["REQUEST_URI"]);
    
    if ( count($pathItems) < 4 ) {
        return;
    }

    $base64Data = "";
    $fileName = "ios-install.plist";
    for ( $i = 2; $i < count($pathItems); $i++ )
    {
        if ( $i == count($pathItems) - 1 ) {
            $fileName = $pathItems[$i];
        } else {
            $base64Data .= $pathItems[$i];
        }
    }
    
    $jsonString = urldecode(base64_decode($base64Data));
    
    $obj = json_decode($jsonString);
    
    $ipa = $obj->ipa;
    $icon = $obj->icon;
    $ident = $obj->ident;
    $version = $obj->version;
    $title = $obj->title;

$data =
'<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>items</key>
<array>
<dict>
<key>assets</key>
<array>
<dict>
<key>kind</key>
<string>software-package</string>
<key>url</key>
<string>'.$ipa.'</string>
</dict>
<dict>
<key>kind</key>
<string>display-image</string>
<key>needs-shine</key>
<true/>
<key>url</key>
<string>'.$icon.'</string>
</dict>
</array>
<key>metadata</key>
<dict>
<key>bundle-identifier</key>
<string>'.$ident.'</string>
<key>bundle-version</key>
<string>'.$version.'</string>
<key>kind</key>
<string>software</string>
<key>title</key>
<string>'.$title.'</string>
</dict>
</dict>
</array>
</dict>
</plist>';
    
    $file_size = strlen($data);
    
    ob_clean();
    header("Content-type:application/octet-stream");
    header("Server:nginx/1.4.4");
    header("Content-type:text/plain");
    header("Accept-Ranges:bytes");
    header("Accept-Length:".$file_size);
    header("Content-Disposition: attachment; filename=".$fileName);

    echo $data;
            

Release by other means (suitable for open source projects)

I developed a project to read Korean comics, which can be installed by opening a link with Safari on my mobile phone: http://qzs21.github.io/icomic/
If you are interested, you can take a look at this project,GitHub is used for code and installation package release and deployment(under the master branch is the project code, and the GH pages branch is the code of the installation page): https://github.com/qzs21/icomic

Related recommendations

Very detailedIn-HouseDeployment tutorial: http://blog.csdn.net/yangxt/article/details/7998762
utilizeGithubOfHTTPSService deployment: http://my.oschina.net/qixiaobo025/blog/321050

Recommended Today

Swift advanced (XV) extension

The extension in swift is somewhat similar to the category in OC Extension can beenumeration、structural morphology、class、agreementAdd new features□ you can add methods, calculation attributes, subscripts, (convenient) initializers, nested types, protocols, etc What extensions can’t do:□ original functions cannot be overwritten□ you cannot add storage attributes or add attribute observers to existing attributes□ cannot add parent […]