Create great enterprise apps: A chat with Box's Aaron Levie
App Store & Distribution 入门 26m

打造出色的企业级应用:与 Box CEO Aaron Levie 对谈

Create great enterprise apps: A chat with Box's Aaron Levie

2020年6月24日

在 Apple 官方观看视频

一句话判断

这不是一场技术 Session,而是一场关于”如何用 Apple 平台重塑企业软件”的理念对谈——如果你在做 B2B 或企业内部应用,Aaron Levie 的洞察会让你重新思考产品策略。

这场 Session 讲了什么

这是一场非传统的 Session——Apple 的工程师与 Box CEO Aaron Levie 进行了一场关于企业应用开发理念的对谈。Box 是一家云内容管理和文件分享平台,拥有大量企业用户,其 iOS/macOS 应用是企业级应用的优秀范例。

对谈的核心议题围绕三个方向:企业应用为什么需要”消费级体验”、Apple 平台的新技术如何改变企业软件的开发方式、以及远程办公趋势下企业应用的机会。

Aaron Levie 反复强调了一个观点:企业用户也是消费者。他们在生活中习惯了 Uber、Instagram、Apple Music 的体验,回到工作中却要忍受笨重的企业软件。Box 的策略是把消费级应用的体验质量带到企业场景中——流畅的动画、直觉性的操作、美观的界面。这不仅仅是”好看”,而是直接影响生产力。

Session 还讨论了 Apple 在 2020 年推出的多个企业相关新特性:改进的 MDM(移动设备管理)API、新增的 Managed Apple ID 功能、Apple Business Manager 的增强,以及 Device Enrollment 和 Content Distribution 的改进。这些底层基础设施让企业应用的部署和管理更加流畅。

值得深挖的点

企业应用的”消费化”趋势

Aaron Levie 指出,企业软件正在经历一次”消费化”浪潮。用户不再接受”因为是企业软件所以丑是正常的”这种借口。好的企业应用应该像消费应用一样注重 UI/UX,同时在安全性和合规性上满足企业要求。Box 的做法是在设计阶段就邀请非技术人员参与测试,确保任何人都能直觉性地使用。

远程办公带来的新需求

2020 年的远程办公潮让企业应用的需求发生了根本变化。以前企业软件假设用户在公司网络内、使用公司设备;现在需要支持任何网络环境、任何设备、任何地点。Session 讨论了如何利用 Apple 的安全框架(如 Data Protection、Keychain、Network Extension)来确保远程场景下的数据安全。

代码片段

// 企业应用中的 MDM 配置检查
import ManagedSettings
import Foundation

class EnterpriseConfigManager {
    
    // 检查应用是否通过 MDM 管理
    func checkMDMEnrollment() {
        // 检查 Managed Configuration
        if let managedConfig = UserDefaults.standard.dictionary(forKey: "com.apple.configuration.managed") {
            print("应用通过 MDM 管理")
            applyEnterprisePolicies(managedConfig)
        } else {
            print("非托管环境")
            applyDefaultSettings()
        }
    }
    
    func applyEnterprisePolicies(_ config: [String: Any]) {
        // 应用企业策略
        if let requireVPN = config["requireVPN"] as? Bool, requireVPN {
            enforceVPNConnection()
        }
        
        if let maxFileShareSize = config["maxFileShareSizeMB"] as? Int {
            FileManager.shared.maxShareSize = maxFileShareSize * 1024 * 1024
        }
        
        // 企业水印配置
        if let showWatermark = config["showWatermark"] as? Bool, showWatermark {
            DocumentViewer.shared.enableWatermark = true
        }
    }
    
    func enforceVPNConnection() {
        // 检查 VPN 状态并提示
        let vpnManager = NEVPNManager.shared()
        if vpnManager.connection.status != .connected {
            showVPNRequiredAlert()
        }
    }
}
// 企业级安全文件操作
import Foundation

class SecureDocumentManager {
    
    // 使用文件保护 API 确保数据安全
    func saveDocument(data: Data, name: String) throws -> URL {
        let documentsDir = FileManager.default.urls(
            for: .documentDirectory, in: .userDomainMask
        ).first!
        let fileURL = documentsDir.appendingPathComponent(name)
        
        // 写入文件时启用完整保护
        try data.write(to: fileURL, options: .completeFileProtection)
        // 设备锁定时文件不可访问
        
        return fileURL
    }
    
    // 检查 Data Protection 状态
    func checkDataProtectionStatus() {
        let path = NSSearchPathForDirectoriesInDomains(
            .documentDirectory, .userDomainMask, true
        ).first!
        
        do {
            let attributes = try FileManager.default.attributesOfFileSystem(
                forPath: path
            )
            if let protection = attributes[.protectionKey] as? FileProtectionType {
                print("文件保护级别: \(protection)")
            }
        } catch {
            print("检查失败: \(error)")
        }
    }
}
// 企业应用的审计日志
import os

class AuditLogger {
    static let shared = AuditLogger()
    let logger = Logger(
        subsystem: "com.enterprise.app",
        category: "Audit"
    )
    
    func logFileAccess(fileName: String, action: String) {
        logger.info("文件访问审计: \(action) - \(fileName, privacy: .private)")
        // 企业合规要求:记录所有敏感数据的访问行为
    }
    
    func logLoginAttempt(success: Bool, userId: String) {
        if success {
            logger.info("用户登录成功: \(userId, privacy: .private)")
        } else {
            logger.warning("用户登录失败: \(userId, privacy: .private)")
        }
    }
    
    func logDataExport(dataType: String, count: Int) {
        logger.notice("数据导出: \(dataType), \(count) 条记录")
    }
}

最佳实践

  • 企业应用同样需要遵循 Apple 的 Human Interface Guidelines——不要因为是 B2B 就降低设计标准
  • 使用 Managed Configuration 让 IT 管理员通过 MDM 远程配置应用行为
  • 为所有敏感操作(文件访问、数据导出、登录)实现审计日志,满足合规要求
  • 利用 Data Protection API 确保本地文件在设备锁定时不可访问
  • 测试时使用 Apple Business Manager 配置真实的 MDM 环境,不要只在个人设备上测试

还有什么值得关注

  • Apple Business Manager 在 2020 年支持了自定义应用分发——企业可以将私有应用只分发给自己的员工
  • Managed Apple ID 现在支持与企业的 Identity Provider(如 Okta、Azure AD)联合,实现 SSO
  • Session 提到 Box 正在利用 Apple Silicon 的 ML 能力做设备端的内容分类和敏感数据检测
WWDC 2020