Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the Framework version in iOS using Swift

This is likely not limited to iOS Universal Frameworks but all xxx.framework files. However I can't seem to find documentation on how to get the current version and build of a framework within the client application. Within an app you'd use something like:

    NSString *name = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"];
    NSString *build = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
    NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];

That would give you the current information stored in the Info.plist for the app. But how to we find that information for a framework. And in my case, specifically an embedded framework.

like image 635
Ryan Poolos Avatar asked Jul 02 '14 18:07

Ryan Poolos


3 Answers

Here's a solution that does work with Universal Frameworks. Just replace SomeFrameworkClass with a class from the desired framework.

if let sdkVersion = Bundle(for: SomeFrameworkClass.self).infoDictionary?["CFBundleShortVersionString"] {
    // sdkVersion is available here
}
like image 199
picciano Avatar answered Nov 15 '22 00:11

picciano


I have found that Apple's new Cocoa Touch frameworks supported in Xcode 6, offer an easy answer to this problem. In the default header file created for you, something like Framework.h, you'll see two constants declared for you. These are defined later presumably at runtime by internal framework logic. But I have confirmed they're pulled from the plist for the framework.

//! Project version number for LocalSearch.
FOUNDATION_EXPORT double FrameworkVersionNumber;

//! Project version string for LocalSearch.
FOUNDATION_EXPORT const unsigned char FrameworkVersionString[];
like image 44
Ryan Poolos Avatar answered Nov 15 '22 01:11

Ryan Poolos


Let's say Foo is a class from the given framework, you can use something like :

NSDictionary *infoDictionary = [[NSBundle bundleForClass: [Foo class]] infoDictionary]; 

NSString *name = [infoDictionary valueForKey:(__bridge NSString*)kCFBundleNameKey];
NSString *version = [infoDictionary valueForKey:(__bridge NSString*)kCFBundleVersionKey];

NSLog(@"%@ version %@", name, version);

In Swift :

// `Foo` is a type defined in the framework
if  let infos = Bundle(for: Foo.self).infoDictionary,
    let name = infos[kCFBundleNameKey as String],
    let version = infos[kCFBundleVersionKey as String] {     
        print("Using \(name) version \(version)")

        if let shortVersion = infos["CFBundleShortVersionString"] as? String {
            print("Short version : " + shortVersion)
        }
    }

Note : For some reason, "CFBundleShortVersionString" is not defined in a constant, cf Is there a constant defined for CFBundleShortVersionString in iOS/MacOS framework

like image 32
Axel Guilmin Avatar answered Nov 15 '22 02:11

Axel Guilmin