ios - 如何从子项目调用函数

标签 ios swift xcode

我想在主 Xcode 项目上按 UIButton 并运行项目列表中的子项目。 这可能吗 ? 这是我从 MainViewController 到我的主项目的代码:

import UIKit

class MainViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

    }
    @IBAction func playSubproject(_ sender: UIButton) {

        // here I want to run the SubProject O2App.xcodeproj
        // More exactly I want to run a method from that subproject which is in ViewController.swift and is named startUnity().
    }
}

这是我的 ViewController 子项目的代码:

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var backgroundImageView: UIImageView!


    override func viewDidLoad() {
        super.viewDidLoad()
        backgroundImageView.isHidden = false
        if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
            appDelegate.startUnity()

            NotificationCenter.default.addObserver(self, selector: #selector(handleUnityReady), name: NSNotification.Name("UnityReady"), object: nil)
            NotificationCenter.default.addObserver(self, selector: #selector(handleUnityPlayHologram(_:)), name: NSNotification.Name("UnityPlayHologram"), object: nil)
        }
    }
}

这是来自子项目的 AppDelegate,其中我有函数 startUnity。如果可能的话,我想将此 startUnity 函数调用到我的主项目中。这是代码:

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    var application: UIApplication?

    @objc var currentUnityController: UnityAppController!

    var isUnityRunning = false

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        self.application = application
        unity_init(CommandLine.argc, CommandLine.unsafeArgv)

        currentUnityController = SVFUnityPluginAppController()
        currentUnityController.application(application, didFinishLaunchingWithOptions: launchOptions)

        // first call to startUnity will do some init stuff, so just call it here and directly stop it again
        startUnity()
        stopUnity()

        return true
    }

    func applicationWillResignActive(_ application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.

        if isUnityRunning {
            currentUnityController.applicationWillResignActive(application)
        }
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.

        if isUnityRunning {
            currentUnityController.applicationDidEnterBackground(application)
        }
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.

        if isUnityRunning {
            currentUnityController.applicationWillEnterForeground(application)
        }
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.

        if isUnityRunning {
            currentUnityController.applicationDidBecomeActive(application)
        }
    }

    func applicationWillTerminate(_ application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.

        if isUnityRunning {
            currentUnityController.applicationWillTerminate(application)
        }
    }

    public func startUnity() {
        if !isUnityRunning {
            isUnityRunning = true
            currentUnityController.applicationDidBecomeActive(application!)
        }
    }

    public func stopUnity() {
        if isUnityRunning {
            currentUnityController.applicationWillResignActive(application!)
            isUnityRunning = false
        }
    }
}

这是我的主项目和子项目的屏幕截图:

Structure

编辑:

在我的 MainProject 中,我进入“build设置”,并在“标题搜索路径”中使用以下代码行设置子项目中所有类的路径: $(inherited) "$(SRCROOT)/O2App​​/O2App​​/Unity""$(SRCROOT)/O2App​​/O2App​​/Unity/Classes""$(SRCROOT)/O2App​​/O2App​​/Unity/Classes/Unity""$(SRCROOT)/O2App​​/O2App​​/Unity/Classes/Native""$(SRCROOT)/O2App​​/O2App​​/Unity/Libraries""$(SRCROOT)/O2App​​/O2App​​/Unity/Libraries/libil2cpp/include"。现在,在 MainViewController 中,我导入 O2App​​,现在我可以访问所有这些类。但是当我尝试从该类调用方法时,出现错误。 这是我按下按钮时尝试在函数中执行的操作:

@IBAction func playSubproject(_ sender: UIButton) {
        ViewController().viewDidLoad()
    }

这是错误:

Undefined symbols for architecture arm64:
  "type metadata accessor for O2App.ViewController", referenced from:
      RGA_MainProject.MainViewController.playSubproject(__ObjC.UIButton) -> () in MainViewController.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

最佳答案

您需要在子项目中创建一个框架。然后,您可以在主项目中导入该框架并运行子项目中的代码。这是您问题的答案。

仅供引用。我发现您正在与 Unity 打交道。好消息 - 可以将 Unity 嵌入到框架中,并且通常您的思考方式是正确的。坏消息 - 您的实现存在错误并且总体上很复杂。这个问题无法涵盖这个主题。

关于ios - 如何从子项目调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52298478/

相关文章:

c++ - 当包含它的对象不改变时,这个成员变量的地址如何在 objective-c 中改变?

iphone - 我无法在 iPhone 上创建联系人群组,该如何解决?

ios - 方法 "min()"和 "max()"中内置的 Swift 4 数组是否适用于字符串数组?

iOS归档应用面临的问题

Swift 从函数中获取值

xcode - 此应用程序的包标识符与其代码签名标识符不匹配

ios - Xcode:在项目构建时发出 "file xxx.png is missing from working copy"

ios - Swift:JSONEcoder EXC_BAD_ACCESS

iOS "Exploding image"动画

ios - 带有 Apple Watch 的 Cordova 应用程序无法在 Apple Store 上载(有多个 bundle 与 CFBundleIdentifier 冲突)