Search code examples
swiftcocoafoundation

Getting bundle identifier in Swift


I'm trying to get bundleID using app's directory and I'm getting an error: EXC_BAD_ACCESS(code=1, address=0xd8)

application.directory! is a String

let startCString = (application.directory! as NSString).UTF8String //Type: UnsafePointer<Int8>
let convertedCString = UnsafePointer<UInt8>(startCString) //CFURLCreateFromFileRepresentation needs <UInt8> pointer
let length = application.directory!.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)
let dir = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, convertedCString, length, false)
let bundle = CFBundleCreate(kCFAllocatorDefault, dir)
let result = CFBundleGetIdentifier(bundle)

and I get this error on the result line.

What am I doing wrong here?


Solution

  • One potential problem with your code is that the pointer obtained in

    let startCString = (application.directory! as NSString).UTF8String //Type: UnsafePointer<Int8>
    

    is valid only as long as the temporary NSString exists. But that conversion to a C string can be done "automatically" by the compiler (compare String value to UnsafePointer<UInt8> function parameter behavior), so a working version should be

    let dir = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, path, Int(strlen(path)), false)
    let bundle = CFBundleCreate(kCFAllocatorDefault, dir)
    let result = CFBundleGetIdentifier(bundle)
    

    But you can simply create a NSBundle from a given path and obtain its identifier:

    let ident = NSBundle(path: path)!.bundleIdentifier!
    

    Full example with added error checking:

    let path = "/Applications/TextEdit.app"
    
    if let bundle = NSBundle(path: path) {
        if let ident = bundle.bundleIdentifier {
            print(ident) // com.apple.TextEdit
        } else {
            print("bundle has no identifier")
        }
    } else {
        print("bundle not found")
    }