Pretend to write a preface

Background: Large SDKS with a long history, objective-C of course. Of course, there is no problem with this, and it serves tens of millions of users every day, but unfortunately Apple released a StoreKit2, it is normal that Apple dad should release a lot of apis every year. Unfortunately, it only supports Swift writing, and I expect this API will only become the norm, so swiftization is urgent.

Result: Midnight writing

Tips: The example code of this article has been uploaded to Github and is attached in (below).

Compilation environment: Xcode13.0 Swift5.5 ARM64

Please let me know in the comments section.

A,OC calls Swift within the SDK

| Create two Swift files

import UIKit

@objc(TESTSWIFT)
@objcMembers
public
class TestSwift: NSObject {
    public static func run(a) -> Void {
        print("(#fileID): (#function)")
        TestSwift2.run()
    }
}


//TestSwift2.swift


class TestSwift2: NSObject {
    static func run(a) -> Void {
        print("(#fileID): (#function)")}}Copy the code

Explain:

  • The main purpose of @objc is to change the name of the class.

  • @objcMembers: Use the objcMembers modifier before the name of the class. The system will automatically add @objc to all methods of this class, exposing the OC.

  • Public is intended for exposure to external OC callers.

| Call the Swift class in OC

#import "TestOC.h"
#import "TestOC2.h"
#import <SWSDK/SWSDK-Swift.h>
@implementation TestOC

+ (void) run  {
    NSLog(@ "TestOC: outside the SDK put OC class");
    [TESTSWIFT run];
    [TestOC2 run];
}

@end
Copy the code
  • Here the main operation is #import

    , all OC calls Swift must import this header file, to facilitate the import, we can add this header file in the PCH file.

  • You can see that the Swift inner classes don’t need @objc, @objcMembers, public, etc.

Let’s compare the file structure changes before and after joining Swift

. / / no Swift├ ─ ─ Headers │ ├ ─ ─ SWSDK. H │ └ ─ ─ TestOC. H ├ ─ ─ the Info. The plist ├ ─ ─ Modules │ └ ─ ─module.├ ── ├── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ─ ./ / Swift increase├ ─ ─ Headers │ ├ ─ ─ SWSDK - Swift. H │ ├ ─ ─ SWSDK. H │ └ ─ ─ TestOC. H ├ ─ ─ the Info. The plist ├ ─ ─ Modules │ ├ ─ ─ SWSDK. Swiftmodule │ │ ├ ─ ─ . │ └ ─ ─module.├ ── ├── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ─Copy the code
/ / SWSDK - Swift. H file
SWIFT_CLASS_NAMED("TestSwift")
@interface TESTSWIFT : NSObject
+ (void)run;
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end
Copy the code
  • Added swsdK-swift. h and swsdK. swiftModule directories. PS: Swiftmodule folder can be used only when the simulator and the real machine are merged.

  • Swsdk-swift.h is mainly used to facilitate internal OC calls. There is no Build Phases public drag for Headers, which is automatic.

  • Swsdk. swiftModule: Public interface definition file.


Question: Why did SWsdK-swift. h become external?

Let’s take a look at the moduleMap file before and after

framework module SWSDK { 
  umbrella header "SWSDK.h"

  export *
  module * { export*}}// SwsdK. Swift added after joining Swift
module SWSDK.Swift {
    header "SWSDK-Swift.h"
    requires objc
}
Copy the code

| SwSDK-swift. h can be called internally and placed in Headers by moduleMap, so it is logical to call swsdK-swift. h explicitly from external projects.

Called in appdelegate.h#import "AppDelegate.h"
//#import <SWSDK/SWSDK.h>
#import <SWSDK/SWSDK-Swift.h>
@interface AppDelegate(a)
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// [TestOC run];
    [TESTSWIFT run];
    return YES;
}

/ / output
SWSDK/TestSwift.swift: run()
SWSDK/TestSwift2.swift: run()
Copy the code

| So external classes can also call Swift normally by adding the #import

header file.

In the next article we will cover the module-based method of Swift calling OC within the SDK

Swift integration in Objective-C SDK (part 2)