【问题标题】:MultiBranding the same source code without using xcodeMultiBranding 相同的源代码而不使用 xcode
【发布时间】:2016-11-17 04:59:53
【问题描述】:

我有一个应用程序,我想将它标记为具有不同 UI 的 3 个不同应用程序。

我不想直接使用 Xcode

到目前为止,我发现了很多解决方案,说创建不同的目标并像这样拖放图像

但我打算在 Xcode 之外做这个品牌推广工作

帮帮我!

【问题讨论】:

    标签: ios jenkins build branding


    【解决方案1】:

    现在我们可以在不打开 Xcode 的情况下构建代码

    品牌推广UI、构建设置和功能

    • 用户界面
      • 应用程序图标和其他图标
      • iTunes 艺术作品
    • 构建设置
      • 应用名称
      • 包标识符
      • 配置文件
      • 代码签名身份
    • 功能性
      • 品牌特定 URL(登录、注销、资源获取等...)

    使用终端

    Branding.sh

       #Author: Durai Amuthan(h.duraiamuthan@gmail.com)
    #This is to achieve multiple branding of an iOS app by configuring the variables below
    
    #************ Configuring the brand starts ************
    
    #Directory path where .xcworkspace or .xcodeproj exists
    PathOfProjectDirectory=/Users/Shared/Jenkins/Documents/JenkinsTestNuu/New/
    
    #Path where info.plist exists
    PathOfInfoPlist=$PathOfProjectDirectory/XxYyZz
    
    #Path to icons where new iTunesArtwork and application icon exixts
    #Note: Make sure proper naming conventions of file has been followed
    PathOfNewIcons=/Users/Shared/Jenkins/Documents/icons-two
    
    #Path to asset resource where you have kept your application icon.
    PathOfAppIconSet=$PathOfProjectDirectory/XxYyZz/Icon.xcassets/AppIcon.appiconset
    
    #Path where do you want the .app file has to be kept
    PathToApp=/Users/Shared/Jenkins/Documents/JenkinsTestNuu/app
    
    #Path where do you want the .ipa file has to kept
    PathToIpa=/Users/Shared/Jenkins/Documents/JenkinsTestNuu/ipa
    
    #Cocoapods project or project that involves more than one modules are scheme based
    isWorkspaceBased=true
    
    #Path of the Project (.xcodeproj) - applicable for workspace(.xcworkspace) based project
    PathofProjectFile=$PathOfProjectDirectory/XxYyZz.xcodeproj
    
    #Path of the Workspace (.xcworkspace)
    PathofWorkspaceFile=$PathOfProjectDirectory/XxYyZz.xcworkspace
    
    #Name of the target - applicable only for non-workspace(.xcodeproj)  based projects
    Target=XxYyZz
    
    #Scheme of the iOS app
    Scheme=XxYyZz
    
    #To ascertain Cocoapods has been used or not
    isCocoaPodsBased=true
    
    #Configuration of the app (Debug -(Development) or Release(Adhoc or Distribution))
    Config=Release
    
    #For giving access to signing idetity found in KeyChain
    LoginKeychainPath=/Users/Shared/Jenkins/Library/Keychains/login.keychain
    LoginKeyChainPassword=xxyyzz
    
    #Name of the code signing identity.You can find the name in Keychain or xcode build setting
    CodeSigningIdentity='iPhone Distribution: Xx Yy Zz Limited (3Z5MHUYJ2L)'
    
    #Path of the provisioning profile
    PathToMobileProvision=/Users/Shared/Jenkins/Desktop/BrandingTest.mobileprovision
    
    #UUID value found inside Provisioning profile has to be given
    #Do not forget to install provisiong profile in the system
    ProvisioningProfileIdentity=6e6506e9-8233-4886-9084-zf21e8f8bbae
    
    #Bundle identifier of the app
    BundleIdentifier=com.xxyy.zz
    
    #AppVersion of the app
    AppVersion=2.2.2
    
    #App Name
    Appname=Two
    
    #************ Configuring the brand ends ************
    
    #** Creatting the build based on configuration starts **
    
    cd $PathOfInfoPlist
    echo "****************** Setting App Name ******************"
    /usr/libexec/PlistBuddy -c "Set :CFBundleName $Appname" info.plist
    /usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $Appname" info.plist
    echo "app name has been set as $Appname"
    
    cd $PathOfProjectDirectory
    echo "****************** Setting AppVersion ******************"
    /usr/bin/agvtool new-marketing-AppVersion $AppVersion
    /usr/bin/agvtool new-AppVersion -all $AppVersion
    
    echo "****************** Changing app icons & iTunes Artwork ******************"
    cp -R $PathOfNewIcons/*.png $PathOfAppIconSet
    echo "App icons has been changed at $PathOfNewIcons"
    cp -R $PathOfNewIcons/iTunesArtwork@2x $PathOfProjectDirectory/XxYyZz
    cp -R $PathOfNewIcons/iTunesArtwork $PathOfProjectDirectory/XxYyZz
    echo "iTunesArtwork has been changed at $PathOfProjectDirectory"
    
    #Unlock login keychain
    security unlock-keychain -p $LoginKeyChainPassword $LoginKeychainPath
    if $isCocoaPodsBased == 'true'
    then
    echo "****************** Installing Cocoapods **********************"
    /usr/local/bin/pod install
    echo "Cocoapods has been installed"
    fi
    
    echo "****************** Creating .app ******************"
    if $isWorkspaceBased == 'true'
    then
    /usr/bin/xcodebuild -scheme $Scheme -workspace $PathofWorkspaceFile -configuration $Config clean build CONFIGURATION_BUILD_DIR=$PathToApp "CODE_SIGN_IDENTITY=$CodeSigningIdentity" "PRODUCT_BUNDLE_IDENTIFIER=$BundleIdentifier" "PROVISIONING_PROFILE=$ProvisioningProfileIdentity"
    else
    /usr/bin/xcodebuild -target $Target -project $PathofProjectFile -configuration $Config clean build CONFIGURATION_BUILD_DIR=$PathToApp "CODE_SIGN_IDENTITY=$CodeSigningIdentity" "PRODUCT_BUNDLE_IDENTIFIER=$BundleIdentifier" "PROVISIONING_PROFILE=$ProvisioningProfileIdentity"
    fi
    echo ".app has been generated at $PathToApp"
    
    echo "****************** Creating .ipa *******************"
    /usr/bin/xcrun -sdk iphoneos PackageApplication -v $PathToApp/XxYyZz.app -o $PathToIpa/$Appname.ipa --embed $PathToMobileProvision --sign "$CodeSigningIdentity"
    echo "$Appname.ipa has been generated at $PathToIpa"
    
    #** Creatting the build based on configuration ends **
    

    该文件具有自我描述性,您可以轻松理解。 只需在文件中配置变量的值并像下面这样调用它

    sh Branding.sh
    

    仅供参考:

    如果您想更改除 App Icon 和 iTunesArtwork 之外的其他图标 使用cp 命令,例如

    cp path/to/source path/to/destination
    

    要了解更多信息,请cp man

    使用上述文件,您可以为 UI 和构建设置进行品牌推广

    对于功能性品牌,您必须保留

    • 品牌特定网址

    • 与品牌相关的其他输入

    在单独的 plist 文件中,以便在构建应用程序时也可以根据各自的品牌进行更改

    在编码方面,您可以自定义您的应用程序以像这样从 plist 中读取值

    函数定义:

    func getPlistFile()->Dictionary<String,AnyObject>? {
            var dictPlistFile:Dictionary<String,AnyObject>?
            if let path = NSBundle.mainBundle().pathForResource("plistfile", ofType: "plist") {
                if let dictValue = NSDictionary(contentsOfFile: path) as? Dictionary<String, AnyObject> {
                    dictPlistFile=dictValue
                }
            }
            return dictPlistFile
        }
    

    函数调用:

    var Value=getPlistFile()?["Key"]
    

    您可以在构建应用程序时使用 PlistBuddy 根据品牌更改键的值

    这里是语法

    /usr/libexec/PlistBuddy -c "Set :Key Value" plistfile.plist
    

    使用 Jenkins

    我们可以在jenkins中有效地重用这里的shell脚本

    1.您必须使用 Add Parameter 参数化 jenkins 中的 shell 脚本中的所有变量...就像下面的屏幕截图中我为这样的一个变量所做的那样你必须为所有其他人做这件事

    2.在Build Step

    中选择Execute shell

    3.复制根据配置创建构建开始根据配置创建构建结束之间的脚本并将其粘贴到执行壳牌

    注意:

    • 资源规则

      在通过非xcode接口构建和打包应用程序时,某些版本的Xcode的ResourceRules存在一个已知错误。

      因此,它必须运行一次才能在 xcode 中停用对 资源规则 路径的验证。资源规则路径是已弃用的功能,并且苹果不接受带有资源规则的应用程序,但是如果我们在不使用 Xcode 的情况下构建应用程序,则会出现验证错误说资源规则尚未找到,以反驳我们必须只运行一次脚本.

    xcode_fix_PackageApplicationResourceRules.sh

    #!/bin/sh
    # A script to patch xcrun PackageInstallation so that it doesn't use the deprecated --resource-rules
    # See "Do not use the --resource-rules flag or ResourceRules.plist. They have been obsoleted and will be rejected."
    #   under https://developer.apple.com/library/mac/technotes/tn2206/_index.html#//apple_ref/doc/uid/DTS40007919-CH1-TNTAG205
    # Reported as Apple bug #19384243
    # 
    # should be run as a user who can modify the PackageApplication file
    
    xcodedir=$1
    
    function usage {
            # FIXME we cannot parse args properly because 2 are optional...
            echo "USAGE: $0 xcodedir"
            echo "  xcodedir: an install dir like /Application/Xcode6.1.1.app"
    }
    
    if [[ $# -ne 1 ]]; then
            echo "ERROR: invalid number of arguments"
            usage
            exit -1 
    fi
    
    pi="$xcodedir/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/PackageApplication"
    piorig="$piOrig"
    
    if [[ ! -f "$pi" ]]; then
        echo "$pi file not found. Invalid argument ?"
        usage
        exit -1
    fi
    
    grep resource-rules "$pi" 
    if [[ $? -ne 0 ]]; then
        echo "PackageApplication doesn't use resource-rules. Skipping"
        exit 0
    fi
    
    if [[ -f "$piorig" ]]; then
        echo "Backup file $piorig already exist. Aborting"
        exit -1
    fi
    
    perl  -p -i'Orig' -e 'BEGIN{undef $/;} s/,resource-rules(.*sign}).*ResourceRules.plist"/$1/smg' "$pi" 
    echo $?
    
    • 解锁钥匙串

      每当您在终端中运行 Branding.sh 时,它都会提示用户名和密码作为其访问 系统钥匙串

      每当您在 jenkins 中运行作业时,您都会收到“不允许用户交互”错误

      所以要解决这个问题,您必须按照以下步骤操作

      • 打开钥匙串访问
      • 右键单击私钥
      • 选择“获取信息”
      • 选择“访问控制”选项卡
      • 点击“允许所有应用程序访问此项目”
      • 点击“保存更改”
      • 输入您的密码
    • 配置文件

      如果您收到“未找到匹配的配置文件”,请确保您已双击并通过 Xcode 安装它。

      安装后,您会在 ~/Library/MobileDevice/Provisioning Profiles/

      中看到 UUID.mobileprovision

      此 UUID 是移动配置中的值,表示已安装配置文件。

    希望对你有帮助

    【讨论】:

    • 毫无疑问,这个脚本非常适合每个资源彼此相似的品牌。但是当不同的品牌有不同的本地化支持时,它就会失败。例如品牌 A 支持英语,品牌 B 支持英语和法语,那么我们不能修改这两个品牌的 xcode 项目文件。你有什么解决办法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-06
    • 1970-01-01
    相关资源
    最近更新 更多