我们可以在Xcode 4中导入.apparchive包

时间:2011-02-20 21:37:34

标签: xcode ios archive

在Xcode 3中,应用程序存档在.apparchive文件夹中。

在Xcode 4中,应用程序现在存档在.xcarchive包中。

有没有办法在.xcarchive包中转换.apparchive文件夹或用Xcode 4打开.apparchive文件夹?

3 个答案:

答案 0 :(得分:11)

Dave Dunkin的剧本很棒,但在某些情况下我错过了图标和版本。下面是稍微调整过的脚本版本。 您需要安装MacRuby,可在此处获取:http://www.macruby.org/downloads.html

#!/System/Library/PrivateFrameworks/MacRuby.framework/Versions/A/usr/bin/macrub‌​y

framework 'Cocoa'
require 'date'
require 'fileutils'

Dir.glob(Dir.home() + '/Library/Application Support/Developer/Shared/Archived Applications/*.apparchive').each { |apparchivePath|

  print "Found archive at #{apparchivePath}... "

  archiveInfo = NSDictionary.dictionaryWithContentsOfURL(NSURL.fileURLWithPath(apparchivePath + '/ArchiveInfo.plist')) 

  name = archiveInfo['XCUserProvidedName'] || archiveInfo['XCApplicationName']
  appFilename = archiveInfo['XCApplicationFilename']
  appPath = 'Applications/' + appFilename
  archiveDate = archiveInfo['XCArchivedDate']
  xcarchivePath = Dir.home() + '/Library/Developer/Xcode/Archives/' + archiveDate.strftime('%Y-%m-%d') + '/' + name + ' ' + archiveDate.strftime('%m-%d-%y %I.%M %p') + '.xcarchive'
  appVersion = archiveInfo['CFBundleVersion']
  iconPaths = archiveInfo['XCInfoPlist']['CFBundleIconFiles']
  if not iconPaths
    iconPaths = appPath + '/' + archiveInfo['XCInfoPlist']['CFBundleIconFile']
  else
    iconPaths = archiveInfo['XCInfoPlist']['CFBundleIconFiles'].collect { |f| appPath + '/' + f }
  end

  if File.directory?(xcarchivePath)
    puts 'skipping'
  else
    puts 'importing'
    FileUtils.mkdir_p(xcarchivePath)

    xcarchiveInfo = {
      'ApplicationProperties' => {
        'ApplicationPath' => appPath,
        'CFBundleIdentifier' => archiveInfo['CFBundleIdentifier'],
        'CFBundleShortVersionString' => appVersion,
        'IconPaths' => iconPaths
      },
      'ArchiveVersion' => 1,
      'CreationDate' => archiveDate,
      'Name' => name,
      'SchemeName' => archiveInfo['XCApplicationName']
    }
    if archiveInfo.has_key?('XCUserProvidedComment')
      xcarchiveInfo['Comment'] = archiveInfo['XCUserProvidedComment']
    end
    xcarchiveInfo.writeToURL(NSURL.fileURLWithPath(xcarchivePath + '/Info.plist'), atomically:false)

    FileUtils.mkdir_p(xcarchivePath + '/Products/Applications')
    FileUtils.cp_r(apparchivePath + '/' + appFilename, xcarchivePath + '/Products/Applications')
    FileUtils.mkdir_p(xcarchivePath + '/dSYMs')
    FileUtils.cp_r(apparchivePath + '/' + appFilename + '.dSYM', xcarchivePath + '/dSYMs')
  end
}

答案 1 :(得分:5)

这是我写给我的MacRuby脚本。

#!/usr/local/bin/macruby

framework 'Cocoa'
require 'date'
require 'fileutils'

Dir.glob(Dir.home() + '/Library/Application Support/Developer/Shared/Archived Applications/*.apparchive').each { |apparchivePath|

  print "Found archive at #{apparchivePath}... "

  archiveInfo = NSDictionary.dictionaryWithContentsOfURL(NSURL.fileURLWithPath(apparchivePath + '/ArchiveInfo.plist')) 

  name = archiveInfo['XCUserProvidedName'] || archiveInfo['XCApplicationName']
  appFilename = archiveInfo['XCApplicationFilename']
  appPath = 'Applications/' + appFilename
  archiveDate = archiveInfo['XCArchivedDate']
  xcarchivePath = Dir.home() + '/Library/Developer/Xcode/Archives/' + archiveDate.strftime('%Y-%m-%d') + '/' + name + ' ' + archiveDate.strftime('%m-%d-%y %I.%M %p') + '.xcarchive'

  if File.directory?(xcarchivePath)
    puts 'skipping'
  else
    puts 'importing'
    FileUtils.mkdir_p(xcarchivePath)

    xcarchiveInfo = {
      'ApplicationProperties' => {
        'ApplicationPath' => appPath,
        'CFBundleIdentifier' => archiveInfo['CFBundleIdentifier'],
        'IconPaths' => archiveInfo['XCInfoPlist']['CFBundleIconFiles'].collect { |f| appPath + '/' + f }
      },
      'ArchiveVersion' => 1,
      'CreationDate' => archiveDate,
      'Name' => name,
      'SchemeName' => archiveInfo['XCApplicationName']
    }
    if archiveInfo.has_key?('XCUserProvidedComment')
      xcarchiveInfo['Comment'] = archiveInfo['XCUserProvidedComment']
    end
    xcarchiveInfo.writeToURL(NSURL.fileURLWithPath(xcarchivePath + '/Info.plist'), atomically:false)

    FileUtils.mkdir_p(xcarchivePath + '/Products/Applications')
    FileUtils.cp_r(apparchivePath + '/' + appFilename, xcarchivePath + '/Products/Applications')
    FileUtils.mkdir_p(xcarchivePath + '/dSYMs')
    FileUtils.cp_r(apparchivePath + '/' + appFilename + '.dSYM', xcarchivePath + '/dSYMs')
  end
}

答案 2 :(得分:3)

我只是手工做了一个,所以这绝对是可能的,但是对于超过一两个而言是乏味的。有一点时间,有人可以写一个脚本来做这件事。

.xcarchive个捆绑包只是目录,就像它们之前的.apparchive个捆绑包一样。较新的格式移动了一些内容并简化了顶级Info.plist

Xcode 3将档案存储在~/Library/Application Support/Developer/Shared/Archived Applications中。各个归档捆绑包被命名为GUID。每个内容都是ArchiveInfo.plist,实际的.app捆绑和.dSYM捆绑。

Xcode 4将档案存储在~/Library/Developer/Xcode/Archives中,分隔到以创建档案的日期命名的文件夹中。在每个日期文件夹中是.xcarchive包,使用可读名称而不是GUID。其中包括Info.plistProducts所在的.app文件夹以及用于保存dSYMs个捆绑包的.dSYM文件夹。

.apparchive复制到.xcarchive的快捷方式:

  1. 使用创建存档的日期创建一个新文件夹。
  2. .apparchive的内容复制到新文件夹中以.xcarchive结尾的新文件夹中。
  3. cd到新的.xcarchive文件夹中。从现在开始,一切都与此相关。
  4. 创建ProductsdSYMs个文件夹。
  5. .app捆绑包移至Products
  6. .dSYM捆绑包移至dSYMs
  7. 删除旧的ArchiveInfo.plist文件。
  8. 创建一个看起来像这样的新Info.plist,替换为适当的。
  9. (结束列表,以便StackOverflow正确格式化XML ...)

    <?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>ApplicationProperties</key>
        <dict>
            <key>ApplicationPath</key>
            <string>AppBundleName.app</string>
            <key>CFBundleIdentifier</key>
            <string>com.example.app-id</string>
            <key>IconPaths</key>
            <array>
                <string>AppBundleName.app/Icon.png</string>
                <string>AppBundleName.app/Icon-Small.png</string>
            </array>
        </dict>
        <key>ArchiveVersion</key>
        <real>1</real>
        <key>CreationDate</key>
        <date>2010-12-15T15:10:34Z</date> <!-- this is a GMT time stamp -->
        <key>Name</key>
        <string>AppName</string>
        <key>SchemeName</key>
        <string>AppName</string>
    </dict>
    </plist>