我有一个包含 3 个目标的 iOS Xcode 项目 - AppTarget、Lib1 和 Lib2。
等级制度:
为了获得上述结构,我必须添加、删除文件引用并设置依赖项。
当我运行 AppTarget 时,构建成功后会出现以下弹出窗口,

将上述错误粘贴为文本,
Details
Executable Path is a Directory
Domain: DVTMachOErrorDomain
Code: 5
Recovery Suggestion: /Users/<user_name>/Library/Developer/Xcode/DerivedData/<project_name>-bnytgzvocmpwyuajjxxjivpkymui/Build/Products/Debug-iphonesimulator/<project_name>.app is not a valid path to an executable file.
User Info: {
DVTErrorCreationDateKey = "2022-11-03 08:04:49 +0000";
}
Run Code Online (Sandbox Code Playgroud)
我不知道为什么会发生这种情况。我没有弄乱 Xcode->Preferences->Location 选项卡中的默认可执行路径。
有一个苹果论坛帖子描述了类似的错误(不一样)。解决方案是检查旧文件的引用,这些文件现在不存在。我已经验证了所有 3 个目标的目标 -> 构建阶段 -> …
我一直在研究 SwiftUI 并从这个WWDC20 视频中了解应用程序、场景和视图。我试图通过一个示例应用程序来理解这些概念,该应用程序显示电影列表并帮助预订电影。
iOS和iPadOS SwiftUI项目有以下App:
@main
struct HelloIOSSwiftUIApp: App {
// Attach the app delegate to the swiftUI app
@UIApplicationDelegateAdaptor
var appDelegate: AppDelegate
var body: some Scene {
MovieListScene()
}
}
Run Code Online (Sandbox Code Playgroud)
从上面的代码可以推断出HelloIOSSwiftUIApp有一个名为MovieListScene的场景。因此,要向应用程序添加新场景,
@main
struct HelloIOSSwiftUIApp: App {
// Attach the app delegate to the swiftUI app
@UIApplicationDelegateAdaptor
var appDelegate: AppDelegate
var body: some Scene {
MovieListScene()
BookMovieScene()
.handlesExternalEvents(matching: ["book movie"])
}
}
Run Code Online (Sandbox Code Playgroud)
现在声明了两个场景,SwiftUI 启动应用程序并显示第一个场景的内容。
在上面的两个示例中,应用程序的场景都是在编译时声明的。那么,如何动态地向应用程序添加/删除新场景呢?我想从配置文件中读取一些数据并决定是否应显示特定场景。我怎样才能实现这种行为?或者应用程序应该在编译时声明所有可能的场景(如上所示)?
我知道 SwiftUI 视图可以通过使用@State、@StateObject和@ObservedObject属性@Published包装器在运行时更新。SwiftUI 视图是其状态的函数......因此更新状态可以更改视图。我怎样才能对场景做同样的事情?
我一直在研究 iOS 中的后台执行。其中一种方法是无声通知。
无声通知(又名后台推送)可用于将应用程序从挂起状态唤醒并更新内容。从 Xcode 11.4 开始,可以模拟常规用户通知,如此处所述。然后,从 Xcode 14 开始,那些拥有 Apple Silicon Mac 笔记本电脑的用户将能够从 APNS 本身向模拟器发送通知......太棒了。
但这篇文章是关于无声通知的。
使用的 .apns 文件是,
{
"Simulator Target Bundle": "com.example.IOSBackgroundExec",
"aps": {
"content-available": 1
}
}
Run Code Online (Sandbox Code Playgroud)
在项目设置中,“签名和功能”选项卡下启用“远程通知”,并添加推送通知。无声通知不需要用户许可。
当应用程序被唤醒时,应该调用以下委托方法。
// Handling silent remote notification
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
NSLog(AppDelegate.TAG + "application(_:didReceiveRemoteNotification:fetchCompletionHandler:)")
// Some work
completionHandler(.newData)
}
Run Code Online (Sandbox Code Playgroud)
问题):
此外,如果您启用了远程通知后台模式,系统会启动您的应用程序(或将其从挂起状态唤醒),并在远程通知到达时将其置于后台状态。但是,如果用户强制退出,系统不会自动启动您的应用程序。
环境:Xcode 14.2、iOS 模拟器 16.x
background-process push-notification ios ios-simulator swift
从后台线程,当UI需要更新时,需要使用async(execute:)函数发布到DispatchQueue.main,如下所示:
static func executeInUIThread(_ uiThreadFunc: @escaping (Any?) -> Void, _ parms: Any?) {
DispatchQueue.main.async {
// Update UI
uiThreadFunc(parms)
}
}
Run Code Online (Sandbox Code Playgroud)
可以访问闭包内部的uiThreadFuncand ,因为闭包从其“周围上下文”捕获变量。parms
但可以说,我不喜欢 lambda 风格(在 swift 中称为闭包)编程。我怎样才能在不关闭的情况下做到这一点?
我尝试了以下操作:
static func executeInUIThread(_ uiThreadFunc: @escaping (Any?) -> Void, _ parms: Any?) {
let workItem = DispatchWorkItem(block: EventLoopMgr.InternalExecuteInUIThread)
DispatchQueue.main.async(execute: workItem)
}
private static func InternalExecuteInUIThread() {
// How to execute the uiThreadfunc? This block doesn't take any parameters.
}
Run Code Online (Sandbox Code Playgroud)
它不起作用,因为初始化 DispatchWorkItem 时的块不带参数。因此,我无法通过uiThreadFunc …
我有一个带有三个目标的 iOS SwiftUI 应用程序 - 一个应用程序目标和 2 个静态库(如下所示)
Project Workspace
--AppTarget
----(some files)
--EntryPoint (static library)
---- <Struct conforming to App protocol>.swift
---- AppDelegate.swift
---- (other files)
--Experience (static library)
---- ContentView.swift
---- (other files)
Run Code Online (Sandbox Code Playgroud)
由于某些原因,层次结构定义如下:
// AppTarget depends on EntryPoint and Experience
AppTarget -> EntryPoint, Experience
// Experience depends on EntryPoint
Experience -> EntryPoint
Run Code Online (Sandbox Code Playgroud)
EntryPoint 库具有应用程序的入口点,即符合应用程序协议的结构体。body 属性必须是一个 Scene,其中必须包含一个 View。问题是,View 是在 Experience 中定义的...并且因为 Experience 依赖于 EntryPoint,所以我无法将 Experience 标记为 EntryPoint 的依赖项并执行以下操作
import Experience
Run Code Online (Sandbox Code Playgroud)
在 EntryPoint 目标中,因为这会导致循环依赖错误。
SwiftUI 期望场景内的视图在编译时已知。
问题:
@main …Run Code Online (Sandbox Code Playgroud) 我有一个后台线程执行任务,完成后,UI 应该更新。要更新 UI,我需要 UI 线程来执行我的函数,其中包含更新 UI 的代码。
Qt 有QMetaObject::invokeMethod((QObject *context, Functor function, Qt::ConnectionType type = Qt::AutoConnection, FunctorReturnType *ret = nullptr)方法。根据文档,Qt 在创建的线程中调用函子或函数上下文指针,但也可以使用 lambda 来实现(如下所示)。
// QtApplicationWrapper::sApp is of type QGuiApplication
// pFunc - pointer to a function
// pFuncParms - argument of type void *
QMetaObject::invokeMethod (QtApplicationWrapper::sApp,
[=] {
pFunc (pFuncParms);
},
Qt::QueuedConnection);
Run Code Online (Sandbox Code Playgroud)
上面的代码有效。但假设我不想使用 lambda 或函子。
pFunc 可以直接传递给 QMetaObject::invokeMethod ,如下所示:
QMetaObject::invokeMethod (QtApplicationWrapper::sApp,
pFunc,
Qt::QueuedConnection);
Run Code Online (Sandbox Code Playgroud)
但我不知道如何传递参数。上面的代码仅适用于不带参数的函数。
如何在 UI 线程中调用 pFunc 及其参数?