iOS Static Framework

iOS Static Framework

This is old fashion way, but simple way.

These days, xcframework is latest technology and easy to integrate.

But if the target library is written by Objective-C, still static framework is useful. Legacy Dynamic framework needs to strip simulator module. (This is troublesome)

Steps

  1. Create “static library” project from XCode
  2. Write Codes (Objective-C)
  3. Add Info.plist to Project root
  4. Add Target “Aggregate”
  5. Add Run Script

Code Examle

#import "SampleKit.h"

@implementation SampleKit

+ (Boolean) isiPad {
    return YES;
}

@end
#import <Foundation/Foundation.h>

@interface SampleKit : NSObject

+ (Boolean) isiPad;

@end

Support only one method for public

Info.plist

This is an example for static framework

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleDevelopmentRegion</key>
	<string>English</string>
	<key>CFBundleExecutable</key>
	<string>SampleKit</string>
	<key>CFBundleIdentifier</key>
	<string>com.daiji110.samplekit</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>SampleKit</string>
	<key>CFBundlePackageType</key>
	<string>FMWK</string>
	<key>CFBundleShortVersionString</key>
	<string>1.0</string>
	<key>CFBundleVersion</key>
	<string>1</string>
</dict>
</plist>

Run Script

# Environment Variables
FRAMEWORK_NAME=${PROJECT_NAME}
FRAMEWORK_VERSION=A
FRAMEWORK_VERSION_NUMBER=1.0
FRAMEWORK_BUILD_PATH="${SRCROOT}/build/${CONFIGURATION}-framework"
FRAMEWORK_DIR="${FRAMEWORK_BUILD_PATH}/${FRAMEWORK_NAME}.framework"
FRAMEWORK_PACKAGE_NAME="${FRAMEWORK_NAME}.${FRAMEWORK_VERSION_NUMBER}.zip"

# Clean directories
rm -rf "${FRAMEWORK_BUILD_PATH}"

# Build simulator and device binaries.
xcodebuild -project ${PROJECT_NAME}.xcodeproj -sdk iphonesimulator${IPHONEOS_DEPLOYMENT_TARGET} -target "${PROJECT_NAME}" -configuration ${CONFIGURATION} 
xcodebuild -project ${PROJECT_NAME}.xcodeproj -sdk iphoneos${IPHONEOS_DEPLOYMENT_TARGET} -target "${PROJECT_NAME}" -configuration ${CONFIGURATION} 

# create framework directories.
mkdir -p ${FRAMEWORK_DIR}
mkdir -p ${FRAMEWORK_DIR}/Versions
mkdir -p ${FRAMEWORK_DIR}/Versions/${FRAMEWORK_VERSION}
mkdir -p ${FRAMEWORK_DIR}/Versions/${FRAMEWORK_VERSION}/Resources
mkdir -p ${FRAMEWORK_DIR}/Versions/${FRAMEWORK_VERSION}/Headers

# create symlinks
ln -s "Versions/${FRAMEWORK_VERSION}" ${FRAMEWORK_DIR}/Versions/Current
ln -s "Versions/Current/Headers" ${FRAMEWORK_DIR}/Headers
ln -s "Versions/Current/Resources" ${FRAMEWORK_DIR}/Resources
ln -s "Versions/Current/${FRAMEWORK_NAME}" ${FRAMEWORK_DIR}/${FRAMEWORK_NAME}

# create the universal library
lipo ${SRCROOT}/build/${CONFIGURATION}-iphoneos/lib${FRAMEWORK_NAME}.a ${SRCROOT}/build/${CONFIGURATION}-iphonesimulator/lib${FRAMEWORK_NAME}.a -create -output "${FRAMEWORK_DIR}/Versions/Current/${FRAMEWORK_NAME}"

# copy files
cp ${SRCROOT}/build/${CONFIGURATION}-iphoneos/include/SampleKit/*.h ${FRAMEWORK_DIR}/Headers/
cp Info.plist ${FRAMEWORK_DIR}/Resources

# zip
cd ${FRAMEWORK_BUILD_PATH}
zip -ry ${FRAMEWORK_PACKAGE_NAME} $(basename $FRAMEWORK_DIR)


Framework

Framework will create under build file. If you need release, please change Schema.

After running script, you can see framework under build/Release-framework/

Let’s try from Swift App

Let’s use this Static Framework from Swift App

Copy Framework into app project

You can copy framework folder into application project.

Please check Framework list. And this Framework should be embed.

Create Objective-C Bridge and Set as Bridge Header

For XCode 11, “Swift Compiler – General” -> Objective-C Bridging Header

Set header path.

Header Example (SimpleKitApp-Bridging-Header.h)

#ifndef SimpleKitApp_Bridge_Header_h
#define SimpleKitApp_Bridge_Header_h
#import <SampleKit/SampleKit.h>

#endif /* SimpleKitApp_Bridge_Header_h */

Now, it’s ready to use

Call an Objective-C(in Framework) method from Swift

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        NSLog("%d", SampleKit.isiPad())  // Can call
    }
}

Ref

iOS
スポンサーリンク
Professional Programmer2

コメント