首页 > 解决方案 > 使用 Objective-C 无法识别的新构建系统构建的 Swift 框架

问题描述

当我将我的 Swift 框架集成到一个 Objective-C 项目中时,在使用 Xcode 的新构建系统后,该项目无法识别框架中的公共类名和 api。

当我去构建项目时,我收到“使用未声明的标识符‘SampleClassName’错误。

我更新了我的 Swift 5 框架的构建脚本以使用 Xcode 的新构建系统。构建脚本创建一个胖二进制文件,可以导入任何 Xcode 项目(我们提供了一个剥离未使用的架构运行脚本)以删除未使用的拱门。

我尝试了以下方法来解决这个问题,但没有成功:-设置项目构建设置'定义模块'->是-我尝试明确说明要构建哪些架构-设置'始终嵌入 Swift 标准库'->是

这就是我定义我们的公共课程的方式

open class SampleClassName: NSObject {

  // a public class definition within my framework
  @objc public static fun run() -> Bool { ... }

}

我们的 {ProjectName}.h 文件实现

//! Project version number for SampleProject.
FOUNDATION_EXPORT double SampleProjectVersionNumber;

//! Project version string for SampleProject.
FOUNDATION_EXPORT const unsigned char SampleProjectVersionString[];

// In this header, you should import all the public headers of your framework using statements like #import <SampleProject/PublicHeader.h>

我们的 {ProjectName}-Bridging-Header.h 实现

#include "SystemUtils.h"
#import <CommonCrypto/CommonCrypto.h>

这是我用来创建胖二进制文件的 ruby​​ 构建脚本。

#!/usr/bin ruby

require 'open3'
require 'optparse'
require 'plist'

PROJECT_DIR        = Dir.pwd
PROJECT_NAME       = 'SampleProject'

BUILD_DIR          = PROJECT_DIR+'/'+PROJECT_NAME
DERIVED_DATA       = 'DerivedData'
FRAMEWORK_NAME     = 'SampleProjectFramework'
OUTPUT_NAME        = 'SampleFramework'
UNIVERSAL_BUILD    = 'Release-universal'
WORKSPACE_DIR      = '..'

def run(command)
  puts command
  stdin, stdout, stderr = Open3.popen3(command)
  out = stdout.readlines
  puts out
  err = stderr.readlines
  [out.to_s, err.to_s]
end

def clean_build
  Dir.chdir("#{PROJECT_NAME}")
  run("rm -rf build")
  Dir.chdir("..")
end

def clean_deriveddata
  Dir.chdir("#{PROJECT_NAME}")
  run("rm -rf #{DERIVED_DATA}")
end

def create_universaldir
  Dir.chdir("#{BUILD_DIR}")
  run("mkdir #{DERIVED_DATA}")
  Dir.chdir("#{DERIVED_DATA}")
  run("mkdir #{UNIVERSAL_BUILD}")
  Dir.chdir("#{PROJECT_DIR}")
end

def create_ios(architecture)
  Dir.chdir("#{BUILD_DIR}")
  command = "xcodebuild -workspace SampleProject.xcworkspace -scheme #{FRAMEWORK_NAME} ONLY_ACTIVE_ARCH=NO -configuration Release -sdk #{architecture} BUILD_DIR=#{BUILD_DIR}/#{DERIVED_DATA} BUILD_ROOT=#{BUILD_DIR}/#{DERIVED_DATA} -UseNewBuildSystem=YES OTHER_SWIFT_FLAGS='-D RELEASE -D EXLUDE_PROXY -D NOIDFA' build"

  run(command)
  Dir.chdir('..')
end

def copy_structure
  run("cp -R #{BUILD_DIR}/#{DERIVED_DATA}/Release-iphoneos/#{FRAMEWORK_NAME}.framework #{BUILD_DIR}/#{DERIVED_DATA}/#{UNIVERSAL_BUILD}/")
end

def copy_swift_modules
  swift_simulator_modules_dir = "#{BUILD_DIR}/#{DERIVED_DATA}/Release-iphonesimulator/#{FRAMEWORK_NAME}.framework/Modules/#{FRAMEWORK_NAME}.swiftmodule/."
  command =
  "if [ -d #{swift_simulator_modules_dir} ]; then
    cp -R #{swift_simulator_modules_dir} #{BUILD_DIR}/#{DERIVED_DATA}/#{UNIVERSAL_BUILD}/#{FRAMEWORK_NAME}.framework/Modules/#{FRAMEWORK_NAME}.swiftmodule
  fi"
  run(command)
end

def create_universal_binary
  command = "lipo -create -output '#{BUILD_DIR}/#{DERIVED_DATA}/#{UNIVERSAL_BUILD}/#{FRAMEWORK_NAME}.framework/#{FRAMEWORK_NAME}' '#{BUILD_DIR}/#{DERIVED_DATA}/Release-iphonesimulator/#{FRAMEWORK_NAME}.framework/#{FRAMEWORK_NAME}' '#{BUILD_DIR}/#{DERIVED_DATA}/Release-iphoneos/#{FRAMEWORK_NAME}.framework/#{FRAMEWORK_NAME}'"
  run(command)
end

def copy_to_project
  command = "cp -R '#{BUILD_DIR}/#{DERIVED_DATA}/#{UNIVERSAL_BUILD}/#{FRAMEWORK_NAME}.framework' '#{BUILD_DIR}'"
end

def put_title(message, sep = "-")
  total_message =  "#{(sep * 10)} #{message} #{(sep * 10)}"

  puts "\n\n\n"
  puts sep * total_message.length
  puts total_message
  puts sep * total_message.length
end


def main
  put_title 'Cleaning build'
  clean_build

  put_title 'Cleaning DerivedData'
  clean_deriveddata

  put_title 'Creating Universal Directory'
  create_universaldir

  put_title 'Creating iOS device version'
  create_ios('iphoneos')

  put_title 'Creating iOS simulator version'
  create_ios('iphonesimulator')

  put_title 'Copying framework structure to the Universal build'
  copy_structure

  put_title 'Copying Swift Modules'
  copy_swift_modules

  put_title 'Creating Universal Binary'
  create_universal_binary

 put_title 'Copy to project dir'
 copy_to_project
end

if __FILE__ == $0
  main
end

现在导致“使用未声明的标识符错误”的主要变化是切换到新的构建系统。

我希望公共类能够被 Objective-C 项目文件识别。不幸的是,我不知道为什么他们没有被认可。

标签: iosobjective-cswiftxcodeframeworks

解决方案


推荐阅读