'Get the main app bundle from within extension

Is it possible to get the containing app's NSBundle from within an app extension? I would like to get the main app's display name, not the extension's display name.



Solution 1:[1]

Building upon @phatblat's answer, here is a solution which is less likely to break from file structure changes.

extension Bundle {
    /// Return the main bundle when in the app or an app extension.
    static var app: Bundle {
        var components = main.bundleURL.path.split(separator: "/")
        var bundle: Bundle?

        if let index = components.lastIndex(where: { $0.hasSuffix(".app") }) {
            components.removeLast((components.count - 1) - index)
            bundle = Bundle(path: components.joined(separator: "/"))
        }

        return bundle ?? main
    }
}

Solution 2:[2]

Use this extensions and you'll be able to get the main bundle from target extensions:

extension Bundle {
    
    func getBundleName() -> String {
        var finalBundleName = Bundle.main.bundleIdentifier ?? "unknow"
        if(SwiftUtils.isRunningOnExtension()){
            _ = finalBundleName.replaceRegex(#"\.\w+$"#)
        }
        return finalBundleName
    }
}

extension String {

    public mutating func replaceRegex(_ pattern: String, replaceWith: String = "") -> Bool {
        do {
            let regex = try NSRegularExpression(pattern: pattern, options: NSRegularExpression.Options.caseInsensitive)
            let range = NSMakeRange(0, self.count)
            self = regex.stringByReplacingMatches(in: self, options: [], range: range, withTemplate: replaceWith)
            return true
        } catch {
            return false
        }
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 cnotethegr8
Solution 2 Rafael Setragni