ios开发企业版plist发布In-House简单记录

本文详细介绍了如何使用企业账号将iOS应用发布到公司内部的过程,包括解决XCode6后不再自动生成的plist文件问题及存放plsit文件的HTTPS服务器配置。特别指出在iOS8设备上的安装限制与解决方案,以及正确配置bundle-identifier的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这几天帮一家公司将ios应用通过企业账号发布到公司内部,具体过程可以参考这个:http://blog.youkuaiyun.com/pang040328/article/details/40924737,这里讲的很详细了,感谢这位博主!

这里只写两点,一个是XCode6后不再自动生成的plist文件的文件内容;另一个是存放plsit文件的https服务器怎么办。

  • 原始plist文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<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>THE URL FOR YOUR IPA: ex: http://go.com/appname.ipa</string>
				</dict>
				<dict>
					<key>kind</key>
					<string>full-size-image</string>
					<key>needs-shine</key>
					<true/>
					<key>url</key>
					<string>THE URL FOR INSTALLATION @2x ICON: ex: http://go.com/Icon@2x.png</string>
				</dict>
				<dict>
					<key>kind</key>
					<string>display-image</string>
					<key>needs-shine</key>
					<true/>
					<key>url</key>
					<string>THE URL FOR INSTALLATION ICON: ex: http://go.com/Icon.png</string>
				</dict>
			</array>
			<key>metadata</key>
			<dict>
				<key>bundle-identifier</key>
				<string>YOUR BUNDLE ID (Take it from your Xcode Project)</string>
				<key>bundle-version</key>
				<string>1.2.3 Your app version</string>
				<key>kind</key>
				<string>software</string>
				<key>title</key>
				<string>The Title To Present To The User installing the app</string>
			</dict>
		</dict>
	</array>
</dict>
</plist>

我在刚开始测试时,没有指定<full-size-image>和<display-image>段的图片地址,导致应用在ios6和ios7设备上可以安装,但ios8设备上可以下载无法安装,大家可以注意一下这个问题;

另外<bundle-identifier>段,这里的注释是“输入你的BUNDLE ID(可以从XCODE的工程中获取)”。但我输入的是potal中完整的APPID,形如"X6J85AD.com.xx.xx"这样,也可以正常下载和安装。

  • plist存放位置

plist下载必须使用https协议,要么就花钱买个SSL证书给网站添加https支持,

不想花钱的可以使用OSChina的代码托管。

访问https://git.oschina.net,添加一个项目;然后用git或svn客户端将plsit文件提交到版本库中;最后在浏览器中访问项目中的plsit文件,查看原始数据,即可获得plsit的https下载地址。



<think>好的,用户之前询问了关于不需要发布到应用商店的APP开发方案,现在他进一步要求“技术操作方案”。我需要先回顾之前的对话,看看已经提供了哪些信息,避免重复。 用户之前得到的回答涵盖了私有化部署、合规调整、核心技术、安全方案、应用场景和注意事项。现在用户可能想要更具体的技术步骤,比如如何实际搭建分发渠道、实现热更新或者安全验证等。 我需要判断用户的具体需求。他可能是一个开发者或企业技术人员,希望直接实施这些方案。因此,需要分步骤详细说明技术操作,比如Android和iOS的分发方法、热更新的配置、安全措施的实现等。 还要注意用户可能关心的合规问题,尤其是在中国,隐私和数据安全的法律要求。需要确保技术方案中提到相关合规措施,比如签名验证、权限控制、数据加密等。 可能需要补充代码示例和具体命令,方便用户直接复制使用。例如,如何生成企业签名的APK,配置TestFlight,或者使用Bugly进行热更新。 另外,用户可能对特定平台(如鸿蒙)有疑问,之前的回答提到了鸿蒙需要适配.hap,这里可能需要进一步说明如何操作。 最后,结构要清晰,分步骤讲解,每个技术点都有对应的实现方法,并强调注意事项,确保用户操作时不会遗漏关键点。</think>以下是无需应用商店发布的APP技术操作方案详解,分为核心实施步骤与关键代码实现: --- ### 一、安卓私有化分发体系搭建 #### 1. 签名证书配置 ```bash # 生成企业专用签名密钥 keytool -genkey -v -keystore enterprise.jks -keyalg RSA -keysize 2048 -validity 10000 -alias enterprise_key # 获取证书指纹(SHA256) keytool -list -v -keystore enterprise.jks | grep SHA256 ``` #### 2. 构建定制安装包 ```gradle // build.gradle配置多渠道打包 flavorDimensions "deploy" productFlavors { enterprise { dimension "deploy" manifestPlaceholders = [CHANNEL: "enterprise"] signingConfig signingConfigs.enterprise // 指向企业签名配置 } } // 添加版本元数据 android { defaultConfig { resValue "string", "build_authority", "com.yourcompany.installer" } } ``` #### 3. 安装器自更新机制 ```kotlin // 实现APK静默更新 fun silentUpdate(apkFile: File) { val intent = Intent(Intent.INSTALL_PACKAGE).apply { data = FileProvider.getUriForFile(context, "com.yourcompany.installer", apkFile) flags = Intent.FLAG_GRANT_READ_URI_PERMISSION } startActivity(intent) } ``` --- ### 二、iOS企业级部署方案 #### 1. 企业证书申请流程 ```markdown 1. 登录Apple开发者账号 2. 选择「Certificates, Identifiers & Profiles」 3. 创建类型为「In-House」的Distribution Certificate 4. 生成.mobileprovision描述文件(有效期3年) ``` #### 2. 分发页面搭建 ```html <!-- 企业安装引导页 --> <!DOCTYPE html> <html> <body> <a href="itms-services://?action=download-manifest&url=https://yourdomain.com/app.plist"> <button>安装企业应用</button> </a> </body> </html> ``` #### 3. 安装验证逻辑 ```swift // 验证企业证书有效性 func verifyEnterpriseCertificate() { guard let certData = Bundle.main.embeddedProvisioningProfile else { return } let plist = try! PropertyListSerialization.propertyList(from: certData, options: [], format: nil) guard let dict = plist as? [String: Any], dict["ProvisionsAllDevices"] as? Bool == true else { exitApplication() // 非企业证书强制退出 } } ``` --- ### 三、动态功能加载方案 #### 1. Android动态功能模块(DFM) ```java // 动态加载支付模块 private void loadPaymentModule() { SplitInstallManager splitInstallManager = SplitInstallManagerFactory.create(this); SplitInstallRequest request = SplitInstallRequest.newBuilder() .addModule("payment_module") .build(); splitInstallManager.startInstall(request) .addOnSuccessListener(sessionId -> initPaymentSDK()); } ``` #### 2. iOS按需资源下载 ```swift // 使用On-Demand Resources let tags = NSSet(array: ["level1_assets"]) let request = NSBundleResourceRequest(tags: tags as! Set<String>) request.beginAccessingResources { error in if error == nil { let assetPath = request.bundle.path(forResource: "texture", ofType: "png") } } ``` --- ### 四、安全防护实施 #### 1. 防二次打包检测 ```java // 检查签名证书指纹 public static boolean checkSign(Context context) { try { Signature[] sigs = context.getPackageManager() .getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES).signatures; String currentSign = calculateSHA256(sigs[0].toByteArray()); return currentSign.equals("预设指纹"); } catch (Exception e) { return false; } } ``` #### 2. 运行时环境检测 ```java // Root检测与模拟器检测 public static boolean isUnsafeEnvironment() { if (checkRoot() || checkEmulator()) { triggerSelfDestruction(); // 触发自毁逻辑 return true; } return false; } ``` --- ### 五、热更新合规实现 #### 1. Android热修复框架集成 ```yaml # Tinker配置示例 tinker: applyMapping: "build/outputs/mapping.txt" buildConfig: keepDexApply: false tinkerId: "1.0.3" loader: - com.tencent.tinker.loader.* dex: loaderPattern: ["tinker/*"] ``` #### 2. iOS差量更新方案 ```swift // 使用JSPatch合规方案 JSPatch.start(withAppKey: "your_app_key") JSPatch.sync() // 从私有服务器获取更新 JSPatch.setupCallback { (error) in if error != nil { rollbackToLastStableVersion() } } ``` --- ### 六、设备授权管理系统 #### 1. 设备指纹生成 ```kotlin // 生成唯一设备ID fun generateDeviceId(): String { val androidId = Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID) val buildInfo = Build.FINGERPRINT + Build.BOARD + Build.BRAND return sha256Hash(androidId + buildInfo) } ``` #### 2. 离线授权验证 ```java // 基于RSA的时间锁验证 public boolean validateLicense(String license) { RSAPublicKey publicKey = loadPublicKey(); String decrypted = RSAUtils.decrypt(license, publicKey); long timestamp = Long.parseLong(decrypted.split("|")[1]); return System.currentTimeMillis() < timestamp; } ``` --- ### 关键实施建议: 1. **网络隔离策略**:使用`NetworkSecurityConfig`强制HTTPS通信 ```xml <!-- network_security_config.xml --> <network-security-config> <domain-config cleartextTrafficPermitted="false"> <domain includeSubdomains="true">yourcompany.com</domain> </domain-config> </network-security-config> ``` 2. **日志安全处理**:自动过滤敏感信息 ```kotlin fun sanitizeLog(message: String): String { val patterns = listOf( Regex("\\b[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{4}\\b"), // 银行卡号 Regex("\\b[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[0-9Xx]\\b") // 身份证号 ) return patterns.fold(message) { acc, regex -> acc.replace(regex, "***FILTERED***") } } ``` 是否需要深入说明以下内容: 1. 企业MDM(移动设备管理)系统对接方案 2. 跨平台代码混淆的进阶配置 3. 私有化推送服务搭建(基于MQTT协议)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值