1

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?

mdmb
  • 4,833
  • 7
  • 42
  • 90
  • Is this for the bundle identifier of your own app? Why so complicated? Have a look at [Obtain bundle identifier programatically in Swift?](http://stackoverflow.com/questions/25897086/obtain-bundle-identifier-programatically-in-swift). – Martin R Feb 27 '16 at 18:41
  • It's not. It's a bundle of another app. That is why I'm not using .mainBundle().bundleIdentifier on NSBundle. – mdmb Feb 27 '16 at 18:43
  • Then what about `NSBundle(path: ...).bundleIdentifier` ? – Martin R Feb 27 '16 at 18:45
  • What the heck! Really? That simple? Thank you very (!) much! – mdmb Feb 27 '16 at 18:46

2 Answers2

4

If you are trying to get it programmatically , you can use below line of code :

Objective-C:

NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];

Swift 3.0:

let bundleIdentifier =  Bundle.main.bundleIdentifier

(Updated for latest swift It will work for both iOS and Mac apps.)

For More Info, Check here :

Apple Docs: https://developer.apple.com/documentation/foundation/bundle#//apple_ref/occ/instm/NSBundle/bundleIdentifier

thedp
  • 8,350
  • 16
  • 53
  • 95
Ash
  • 5,525
  • 1
  • 40
  • 34
2

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")
}
Community
  • 1
  • 1
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • Wow, you even thought about the more complicated (and not necessary) code! Thanks a lot! – mdmb Feb 28 '16 at 00:38