Skip to content

Instantly share code, notes, and snippets.

@lemonkey
Last active June 9, 2017 18:39
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lemonkey/637e855e0ba118a50218 to your computer and use it in GitHub Desktop.
Save lemonkey/637e855e0ba118a50218 to your computer and use it in GitHub Desktop.
Swift 2 and Objective-C Interoperability Review

Using Swift 2 and Objective-C classes within frameworks, apps and unit tests

Normal Usage:

  • Swift into Obj-C:
    • Within framework or app:
      • Because the auto generated Swift interface header "Objective-C Generated Interface Header" SWIFT_OBJC_INTERFACE_HEADER_NAME for a framework target is part of the framework’s public interface, only Swift declarations marked with the public modifier for classes or structs marked with @objc appear in this header for a framework target.
        • Framework:
          • #import <ProductName/ProductModuleName-Swift.h>
          • This could go in the Framework’s prefix PCH file if used as a local dev pod, otherwise not recommended (reserve PCH for things that don’t change often like UIKit, etc.)
          • Note: You can still use Swift methods and properties that are marked with the internal modifier from within the ObjC part of your framework, as long they are declared within a Swift class that inherits from an ObjC class.
        • App:
          • #import “ProductModuleName-Swift.h”
          • Shouldn’t go in the app’s prefix PCH file since these Swift classes could change often.
    • Outside framework:
      • If only public Swift classes/structs from framework are needed:
        • #import <ProductName/ProductModuleName-Swift.h>
      • If both Obj-C and Swift classes/structs from framework are needed:
        • @import FrameworkName;
  • Obj-C into Swift:
    • Within framework:
      • Framework umbrella header must have a system import for each Obj-C class needed (double quote import won’t work):
        • #import <ProductName/ClassName.h>
        • Note that using bridging headers with framework targets is unsupported.
    • Within app:
      • "Objective-C Bridging Header" SWIFT_OBJC_BRIDGING_HEADER created when first Swift class was added to the app (or created manually and set in the build settings) must include an import for each Obj-C class that needs to be visible to all Swift classes (in import in Swift class is needed).
        • #import “Classname.h”
    • Outside framework:
      • import FrameworkName
  • Swift into Swift:
    • Within framework or app:
      • Nothing needs to be done as long as Swift class or struct is public.
    • Outside framework:
      • import FrameworkName
  • Obj-C into Obj-C:
    • Within framework or app:
      • #import “Classname.h”
    • Outside framework:
      • If all Obj-C classes that exist in the Framework’s umbrella header are needed:
        • @import FrameworkName;
      • If only certain Obj-C classes in the Framework’s umbrella header are needed:
        • @import FrameworkName.Classname;
        • Note: #import “Classname.h” should continue to work depending on the framework headers search path for your build settings. System import #import <FrameworkName/Classname.h> shouldn't be necessary.

Unit Tests:

  • Swift tests:
    • Obj-C and Swift classes:
      • From Framework:
        • import FrameworkName
      • From main app:
          1. Main app must enable testability, modules and have product module name set
          1. @testable import MainAppProductModuleName
  • Obj-C tests:
    • Swift classes:
      • From Framework:
        • @import FrameworkName;
      • From main app:
          1. Main app must enable modules and have a product module name set
          1. Test target HEADER_SEARCH_PATHS must include path for test host target’s auto generated swift interface header file:
          1. #import “MainAppProductModuleName-Swift.h”
        • Note: recommended that test classes that need to test main app Swift classes be written in Swift. Apple doesn’t officially support Obj-C test classes accessing Swift classes from the test host.
    • Obj-C classes:
      • From Framework:
        • Same as Swift (@import FrameworkName;)
      • From main app:
        • #import “Classname.h”

Resources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment