XZ_Python uses Python to write Xcode interface packaging scripts

    After each update of our project, we need to make more than 100 enterprise packages. The number of enterprise packages has been increasing all the time. Before, we had to make them manually. It takes about a day to make so many packages. . . .

    Now it only takes about 16 minutes to type more than 100 packages. The difference between our enterprise packages is that each enterprise package has different user names and user mobile phone numbers, and other configurations are the same. Therefore, the idea is: create a plist in the project, Write all the user names and mobile phone numbers of all enterprise packages in it, and when you need it, just go to it and pick it up. When packaging, only one .xcarchive package is generated, and then the plist file of the project is modified, re-signed and then packaged for output.

   The idea of ​​packaging is the same as the idea of ​​packaging using the command line, you can check the article XZ_iOS Packaging using the terminal command line

  Implementation of the packaging function

   The following is the main code to implement the packaging function:

# compile command
archivePath = outputPath + "/" + scheme + ".xcarchive"
# The path of the info.plist file in the compiled app
infoPath = archivePath + "/Products/Applications/" + scheme + ".app/info.plist"
# execute compile command
buildCommand = "xcodebuild archive -project " + projectpath + " -scheme " + scheme + " -archivePath " + archivePath
output = os.system(buildCommand)
# Modify the plist file
for n in idList:
    pl = readPlist(infoPath)
    # Modify the corresponding business data
    pl["LocalUserID"] = n
    writePlist(pl, infoPath)
codeSignPlistPath = outputPath + "/DistributionSummary.plist"
    appPath = archivePath + "/Products/Applications/" + scheme + ".app"
    codesignCommand = "codesign -f -s " + teamName + " --entitlements " + codeSignPlistPath + " " + appPath
    print("Execute the signature command: " + codesignCommand)
output = os.system(codesignCommand)
if output == 0:
    print("====================Project <<" + n + ">> Successfully re-signed, in the process of packaging ========== ==========")
# Export the plist file required by the ipa package
    exportPlistPath = outputPath + "/" + "ExportOptions.plist"
    exportPath = outputPath + "/" + n
    exportCommand = "xcodebuild -exportArchive -archivePath " + archivePath + " -exportPath " + exportPath + " -exportOptionsPlist " + exportPlistPath
    print("Execute packaging command: " + exportCommand)
    result = os.system(exportCommand)
    if result == 0:
      print("====================Project <<" + n + ">> Export successfully!!!============ ========")
#Rename and move all ipa packages to 'all ipa packages' folder
    else:
      print("====================Project <<" + n + ">> Re-signature failed, please check DistributionSummary.plist file ======= ============")

output folder of the ipa package

The user can select the output folder, if not selected, a folder will be created automatically. If the user does not choose a folder themselves, create a default folder for the packaged output:

# Determine if the folder exists, if it exists, delete it and create it again
if os.path.exists(outputPath + "/all ipa packages"):
    shutil.rmtree(outputPath + "/all ipa packages") #delete the folder and the contents of the folder
# Move all ipa packages to a unified folder
    os.makedirs(outputPath + "/all ipa packages")

Implementation of interface packaging interface

The user can choose the project path, the recommender form, the recommender package output path, and the plist path that needs to be replaced

# Recommender excel sheet path
label1 = tk.Label(root,text="Recommender excel sheet path:").grid(row = 0, column = 0)
tk.Entry(root, textvariable = excelFile).grid(row = 0, column = 1)

button1 = tk.Button(root, text = "路径选择", command = selectExcelFile).grid(row = 0, column = 2, padx = 10, pady = 5)

# project path
tk.Label(root,text = "Project path:").grid(row = 1, column = 0)
tk.Entry(root, textvariable = projectFile).grid(row = 1, column = 1)
tk.Button(root, text = "路径选择", command = selectProjectFile).grid(row = 1, column = 2, padx = 10, pady = 5)

# ipa package output path
tk.Label(root,text = "ipa package output path:").grid(row = 2, column = 0)
tk.Entry(root, textvariable = outputPath).grid(row = 2, column = 1)
tk.Button(root, text = "Path selection", command = selectPath).grid(row = 2, column = 2, padx = 10, pady = 5)

# info.plist path
tk.Label(root, text = "registerPhone.plist路径:").grid(row = 3, column = 0)
tk.Entry(root, textvariable = infoPlistPath).grid(row = 3, column = 1)
tk.Button(root, text = "Path selection", command = selectInfoPlistPath).grid(row = 3, column = 2, padx = 10, pady = 5)

# Modify the plist of the recommender list, get the recommender userid and pack it
tk.Button(root, text = "开始打包", command = lambda:judgePath(excelFile.get(), projectFile.get(), outputPath.get(), infoPlistPath.get())).grid(row = 4, column = 0, pady = 10)

The interface effect achieved is as follows:


When the user selects the path, only the current type of file is optional

For example, if the user needs to select Excel, other folders or other types of files are not selectable:

# Select the path to the referrer package
def selectExcelFile():
    filename = askopenfilename(filetypes=[('Excel', '*.xls *.xlsx'), ('All Files', '*')])
    excelFile.set(filename)

# project path
def selectProjectFile():
    filename = askopenfilename(filetypes = [('PROJECT', '*.xcodeproj .xcworkspace'), ('All Files', '*')])
    projectFile.set(filename)

# Select the path of the recommender package ==> You can not select it, if you do not select the path, a "generated ipa package" will be generated on the desktop to store the ipa package by default
def selectPath():
    path_ = askdirectory()
    if path_ != '':
        outputPath.set(path_)
    else:
        outputPath.set("")

# registerPhone.plist path
def selectInfoPlistPath():
    plistPath = askopenfilename(filetypes = [('INFOPLIST', '*.plist'), ('All Files', '*')])
    infoPlistPath.set(plistPath)

Automatically read the data in the Excel file into the plist file

After the user selects the path to the Excel file, the data in the Excel file is automatically read into the created plist file

# Get recommender userid: excel path, project path, output path
def packPkg(excelFile, projectFile, outputPath, infoPlistPath):
    print("The recommender's excel address is", excelFile)
    print("ipa package address is", projectFile)
    print("IPA's output address is", outputPath)
    print("The output address of infoPlistPath is", infoPlistPath)
    
    # get output path
    outputPath = createPlist(outputPath)
    
    # read table
    excel_data = xlrd.open_workbook(excelFile)
    # Take out the first sheet data of Excel
    table_one = excel_data.sheet_by_index(0) # Get the content of the sheet according to the sheet index
    # The total number of rows in the table
    lines = table_one.nrows
    cols = table_one.ncols
    print ("The total number of lines in the table: ",lines)
    print ("The total number of columns in the table:",cols)
    last_output_dir = ''
    
    idList = []
    infoPlist = []
    
    for i in range(0,lines):
        # Get the data of a row in the excel table
        row_values = table_one.row_values(i)
        tuijianren_id = str(int(row_values[0]))
        
        tuijianren_phone = str(int(row_values[1]))
        
        dict = {"fmuserid": tuijianren_id, "fmmobile": tuijianren_phone}
        
        idList.append(tuijianren_id)
        # Convert the data in the Excel table into an array
        infoPlist.append(dict)
        
    # delete old plist data, import new
    plist = readPlist(infoPlistPath)
    print ("The original plist is: ", plist)
    writePlist(infoPlist, infoPlistPath)

    print ("============The created list is: ",idList)
    print ("The list of mobile phone numbers read is: ", infoPlist)
    plist = readPlist(infoPlistPath)
    print ("The modified list is: ", plist)

    if len(idList) == lines:
        # call packager
        beginToPackage(projectFile, outputPath, idList)
    else:
        print("Failed to read Excel")

Modify the name of the ipa package

Change the name of the ipa package to be the same as the name of the upper folder

def changeFileName(exportPath, outputPath):
    if not os.path.isdir(exportPath):
        return False
    if os.path.isdir(exportPath):
        fileName = os.path.basename(exportPath)
        pathOld = exportPath + "/rzjrapp.ipa"
        print ("Get file name: ",fileName)
        pathNew = exportPath + "/app" + fileName + ".ipa"
        os.rename(pathOld , pathNew)

        #The folder to be moved
        pathMoved = outputPath + "/all ipa packages"
        shutil.move (pathNew, pathMoved)

Package the script into an executable

XZ_Python packages Python scripts into executable files

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325893735&siteId=291194637
Recommended