简体   繁体   English

有没有办法检测扩展是否在 iPad vs iPhone 上运行

[英]Is there a way to detect if extension is running on iPad vs iPhone

I am porting an extension from Chrome/Firefox to Safari on iOS.我正在将扩展从 Chrome/Firefox 移植到 iOS 上的 Safari。 When the extension popup comes up there are two different behaviors on Safari on iOS.当扩展弹出窗口出现时,在 iOS 上的 Safari 上有两种不同的行为。 On iPhone it comes up as a full screenwidth menu from the bottom of the screen.在 iPhone 上,它从屏幕底部以全屏宽度菜单的形式出现。 On iPad it behaves like Safari on MacOS and the popup comes down from the extension icon in the toolbar and is dynamically sized.在 iPad 上,它的行为与 MacOS 上的 Safari 类似,并且弹出窗口从工具栏中的扩展图标向下弹出并动态调整大小。

I would like to detect these two different cases in my javascript code.我想在我的 javascript 代码中检测这两种不同的情况。 In the former case I want to refrain from setting the popup window width (since that causes problems) in the latter case I do want to set the width (in the same way that I do in Chrome etc).在前一种情况下,我想避免设置弹出窗口 window 宽度(因为这会导致问题),在后一种情况下,我确实想设置宽度(就像我在 Chrome 等中所做的那样)。

I don't know for sure if it is a case of detecting iPad vs iPhone (but I would be interested in knowing how to do that).我不确定是否是检测 iPad 与 iPhone 的情况(但我有兴趣知道如何做到这一点)。 There could be an iPhone with a large enough screen size that would cause it to use the latter behavior.可能有一个屏幕尺寸足够大的 iPhone 会导致它使用后一种行为。

While figuring out macOS vs iOS is fairly simple through using browser.runtime.getPlatformInfo() , determining iOS vs iPadOS is more difficult.虽然通过使用browser.runtime.getPlatformInfo()来确定 macOS 与 iOS 相当简单,但确定 iOS 与 iPadOS 更困难。

When the extension popup comes up there are two different behaviors on Safari on iOS.当扩展弹出窗口出现时,在 iOS 上的 Safari 上有两种不同的行为。 On iPhone it comes up as a full screenwidth menu from the bottom of the screen.在 iPhone 上,它从屏幕底部以全屏宽度菜单的形式出现。 On iPad it behaves like Safari on MacOS and the popup comes down from the extension icon in the toolbar and is dynamically sized.在 iPad 上,它的行为与 MacOS 上的 Safari 类似,并且弹出窗口从工具栏中的扩展图标向下弹出并动态调整大小。

Keep in mind that on iPadOS the popup can also show up as it does on iOS when the browser is in split view.请记住,在 iPadOS 上,当浏览器处于拆分视图时,弹出窗口可以像在 iOS 上一样显示。 Because of this it's important to track window resize events and to test the popup in and out of split view, across all of the split view sizes.因此,跟踪window 调整大小事件并在所有拆分视图大小中测试弹出窗口进出拆分视图非常重要。

The only complete solution I've found is using a combination of Swift, Javascript and CSS.我发现的唯一完整解决方案是使用 Swift、Javascript 和 CSS 的组合。

Swift side Swift侧

In your WebExtension, or wherever you like, you could create a simple function that returns which platform you're on.在您的 WebExtension 或任何您喜欢的地方,您可以创建一个简单的 function 来返回您所在的平台。 I use this over browser.runtime.getPlatformInfo() since the latter can't discern iOS vs iPadOS.我在browser.runtime.getPlatformInfo()上使用它,因为后者无法辨别 iOS 与 iPadOS。 Something like:就像是:

func getPlatform() -> String {
    var platform:String
    #if os(iOS)
        if UIDevice.current.userInterfaceIdiom == .pad {
            platform = "ipados"
        }
        else {
            platform = "ios"
        }
    #elseif os(macOS)
        platform = "macos"
    #endif
    return platform
}

In order to communicate with the swift side of you application, you'll need to use native messaging from the javascript side - and put the appropriate message handlers on your swift side.为了与应用程序的 swift 端进行通信,您需要使用来自 javascript 端的本机消息传递- 并将适当的消息处理程序放在 swift 端。

background.js背景.js


browser.runtime.sendNativeMessage({name: "getPlatformFromSwiftSide"}, response => {
    if (response.platform === "ipados") {
        ...
    } else if (response.platform === "ios") {
        ...
    }
});

SafariWebExtensionHandler.swift SafariWebExtensionHandler.swift

class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling {
    func beginRequest(with context: NSExtensionContext) {
        let item = context.inputItems[0] as? NSExtensionItem
        let message = item?.userInfo?[SFExtensionMessageKey] as? [String: Any]
        guard let name = message?["name"] as? String else {return}
        let response = NSExtensionItem()
        if name == "getPlatformFromSwiftSide" {
            let platform = getPlatform()
            response.userInfo = [SFExtensionMessageKey: ["platform": platform]]
        }
        context.completeRequest(returningItems: [response], completionHandler: nil)
    }
}


At this point you can distinguish between iPadOS and iOS .此时您可以区分 iPadOS 和 iOS However you still have the issue of whether or not the browser is in split view or not.但是,您仍然存在浏览器是否处于拆分视图中的问题。 As mentioned, for certain sizes in split view, the popup on iPadOS is laid out differently and you must account for this.如前所述,对于拆分视图中的某些尺寸,iPadOS 上的弹出窗口布局不同,您必须考虑到这一点。

Currently I am unaware of any methods to easily determine this, outside of CSS media queries or Javascript matchMedia calls.目前,除了 CSS 媒体查询或 Javascript matchMedia调用之外,我不知道有任何方法可以轻松确定这一点。

Further, calling window from the popup (or using media queries in the popup context) won't indicate the browser's size, but rather the popups.此外,从弹出窗口调用window (或在弹出窗口上下文中使用媒体查询)不会指示浏览器的大小,而是指示弹出窗口。 Since we wan't to know the browser size to determine how to size the popup, the only reliable way I know of accomplishing this is by using browser.tabs.sendMessage , send a message to the content script requesting the browser window size.由于我们不知道浏览器大小来确定如何调整弹出窗口的大小,因此我知道的唯一可靠方法是使用browser.tabs.sendMessage ,向内容脚本发送一条消息,请求浏览器window大小。


All of this seems more complicated than it need be, but I know of no other alternatives currently.所有这一切似乎都比它需要的复杂,但我目前不知道其他选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM