使用带 Chrome 的脚本桥强制解包错误

Force unwrap error using the Scripting Bridge with Chrome

我正在尝试使用 Apple 的 Scripting Bridge 与 Google Chrome 进行交互。我从

中的代码开始

我已经使用 sdefsdp 命令创建了 .h 文件。

我已经包含了文件并创建了桥接 header 并在桥接 header 中导入了 chrome 的 header 文件。但问题在于在 Swift 中使用 header。代码很旧,Swift 变化很大。

我的 Swift 文件:

import Cocoa
import ScriptingBridge


var chromeObject = SBApplication.init(bundleIdentifier: "com.google.Chrome")! as AnyObject

print(chromeObject.closeable)

我收到一条错误消息

fatal error: unexpectedly found nil while unwrapping an Optional value

我做错了什么?

来自 SBApplication.init?(bundleIdentifier:) 的文档:

Return Value

An initialized shared instance of an SBApplication subclass that represents a target application with the bundle identifier of ident. Returns nil if no such application can be found or if the application does not have a scripting interface.

你应该在强制展开之前检查 init 方法 returns 一个实例,例如:

if let chromeObject = SBApplication.init(bundleIdentifier: "com.google.Chrome") as? AnyObject {
    print(chromeObject.closeable)
}

SBApplicationreturns申请object。您可以在 .h 文件中看到不同的 interface

@interface ChromeApplication : SBApplication
@interface ChromeWindow : SBObject <ChromeGenericMethods>
@interface ChromeApplication (ChromiumSuite)
@interface ChromeTab : SBObject <ChromeGenericMethods>
@interface ChromeBookmarkFolder : SBObject <ChromeGenericMethods>
@interface ChromeBookmarkItem : SBObject <ChromeGenericMethods>

所以,SBApplicationreturns你ChromeApplication。您可以调用 ChromeApplication 中定义的任何属性。自己试试吧。你不会得到任何错误。

问题是您调用的 closeableChromeWindow 的一部分。

来自 Apple Documentation:

AppleScript and Objects

AppleScript is an object-oriented language. When you write, compile, and execute scripts, everything you work with is an object. An object is an instantiation of a class definition, which can include properties and actions. AppleScript defines classes for the objects you most commonly work with, starting with the top-level script object, which is the overall script you are working in.

..............

.....................

最主要的是,

What Is in a Script Object

When you enter AppleScript statements in script window in Script Editor, you are working in a top-level script object. All script object definitions follow the same syntax, except that a top-level script object does not have statements marking its beginning and end.

A script object can contain the following:

Property definitions (optional): A property is a labeled container in which to store a value.

An explicit run handler (optional): A run handler contains statements AppleScript executes when the script is run. (For more information, see run Handlers.)

An implicit run handler (optional): An implicit run handler consists of any statements outside of any contained handlers or script objects.

Additional handlers (optional): A handler is the equivalent of a subroutine. (For details, see About Handlers.)

Additional script objects (optional): A script object can contain nested script objects, each of which is defined just like a top-level script object, except that a nested script object is bracketed with statements that mark its beginning and end. (For details, see Script Objects.)

所以,简单来说,Application 是一个包含 Window 的 object,它是一个包含 Tab object 的 object .....

您需要从 Application 中检索 Window object/element 才能使用 closeable

每个 interface 中应该有 SBElementArray。你需要得到它。

示例,

// The application's top-level scripting object.
@interface ChromeApplication : SBApplication

- (SBElementArray<ChromeWindow *> *) windows;

@property (copy, readonly) NSString *name;  // The name of the application.
@property (readonly) BOOL frontmost;  // Is this the frontmost (active) application?
@property (copy, readonly) NSString *version;  // The version of the application.

- (void) open:(NSArray<NSURL *> *)x;  // Open a document.
- (void) quit;  // Quit the application.
- (BOOL) exists:(id)x;  // Verify if an object exists.

@end

您应该检索 - (SBElementArray<ChromeWindow *> *) windows; 以使用 closable。同样在 windows 中,您有制表符数组等

例如,在 AppleScript 中获取 URL 和每个选项卡的标题:

tell application "Google Chrome"

    set a to ""
    repeat with w in windows
        repeat with t in tab in w  // Getting tab object from window
            set a to a & linefeed & title of t & " -URL: " & URL of t
        end repeat
    end repeat

end tell

Swift 中的等价物是:

import Cocoa
import ScriptingBridge


var chromeObject: AnyObject = SBApplication.init(bundleIdentifier: "com.google.Chrome")!

var f = chromeObject.windows() // get the windows from application
for i in f!
{
    var t = (i as AnyObject).tabs() // get the tabs from windows
    for j in t!
    {
        print(((j as AnyObject).title as String) + " -URL: " + ((j as AnyObject).url as String))
    }
}

希望对您有所帮助!