您的位置:首页 > 移动开发 > Objective-C

Swift and Objective-C in the Same Project

2015-01-29 12:09 417 查看


Swift and Objective-C in the Same Project

Swift’s compatibility with Objective-C lets you create a project that contains files written in either language. You can use this feature, called mix
and match, to write apps that have a mixed-language codebase. Using mix and match, you can implement part of your app’s functionality using the latest Swift features and seamlessly incorporate it back into your existing Objective-C codebase.


Mix and Match Overview

Objective-C and Swift files can coexist in a single project, whether the project was originally an Objective-C or Swift project. You can simply add a file of the other language directly to an existing project. This natural workflow makes creating mixed-language
app and framework targets as straightforward as creating an app or framework target written in a single language.

The process for working with mixed-language targets differs slightly depending on whether you’re writing an app or a framework. The general import model for working with both languages within the same target is depicted below and described in more detail in
the following sections.




Importing Code from Within the Same App Target

If you’re writing a mixed-language app, you may need to access your Objective-C code from Swift and your Swift code from Objective-C. The process described in this section applies to non-framework targets.


Importing Objective-C into Swift

To import a set of Objective-C files in the same app target as your Swift code, you rely on an Objective-C bridging header to expose
those files to Swift. Xcode offers to create this header file when you add a Swift file to an existing Objective-C app, or an Objective-C file to an existing Swift app.



If you accept, Xcode creates the header file along with the file you were creating, and names it by your product module name followed by adding
"-Bridging-Header.h"
.
(You’ll learn more about the product module name later, in Naming
Your Product Module.)

Alternatively, you can create a bridging header yourself by choosing File > New > File > (iOS or OS X) > Source > Header File.

You’ll need to edit the bridging header file to expose your Objective-C code to your Swift code.

To import Objective-C code into Swift from the same target

In your Objective-C bridging header file, import every Objective-C header you want to expose to Swift. For example:

OBJECTIVE-C

#import
"XYZCustomCell.h"


#import
"XYZCustomView.h"


#import
"XYZCustomViewController.h"


Under Build Settings, make sure the Objective-C Bridging Header build setting under Swift Compiler - Code Generation has a path to the header.

The path should be relative to your project, similar to the way your Info.plist path is specified in Build Settings. In most cases, you should not need to modify this setting.

Any public Objective-C headers listed in this bridging header file will be visible to Swift. The Objective-C functionality will be available in any Swift file within that target automatically, without any import statements. Use your custom Objective-C code
with the same Swift syntax you use with system classes.

SWIFT

let

myCell =
XYZCustomCell()


myCell.subtitle
=
"A custom cell"



Importing Swift into Objective-C

When you import Swift code into Objective-C, you rely on an Xcode-generated header file to expose those files to Objective-C. This automatically
generated file is an Objective-C header that declares the Swift interfaces in your target. It can be thought of as an umbrella header for your Swift code. The name of this header is your product module name followed by adding
"-Swift.h"
.
(You’ll learn more about the product module name later, in Naming
Your Product Module.)

By default, the generated header contains interfaces for Swift declarations marked with the
public
modifier.
It also contains those marked with the
internal
modifier
if your app target has an Objective-C bridging header. Declarations marked with the
private
modifier
do not appear in the generated header. Private declarations are not exposed to Objective-C unless they are explicitly marked with
@IBAction
,
@IBOutlet
,
or
@objc
as well. For
more information on access-level modifiers, see Access
Control in The
Swift Programming Language.

You don’t need to do anything special to create the generated header file—just import it to use its contents in your Objective-C code. Note that the Swift interfaces in the generated header include references to all of the Objective-C types used in them. If
you use your own Objective-C types in your Swift code, make sure to import the Objective-C headers for those types before importing the Swift generated header into the Objective-C
.m
file
you want to access the Swift code from.

To import Swift code into Objective-C from the same target

Import the Swift code from that target into any Objective-C
.m
file
within that target using this syntax and substituting the appropriate name:

OBJECTIVE-C

#import
"ProductModuleName-Swift.h"


The Swift files in your target will be visible in Objective-C
.m
files
containing this import statement. For information on using Swift from Objective-C code, see Using
Swift from Objective-C.

Import into Swift
Import into Objective-C
Swift code
No import statement
#import "ProductModuleName-Swift.h"

Objective-C code
No import statement; Objective-C bridging header required
#import "Header.h"


Importing Code from Within the Same Framework Target

If you’re writing a mixed-language framework, you may need to access your Objective-C code from Swift and your Swift code from Objective-C.


Importing Objective-C into Swift

To import a set of Objective-C files in the same framework target as your Swift code, you’ll need to import those files into the Objective-C umbrella header for the framework.

To import Objective-C code into Swift from the same framework

Under Build Settings, in Packaging, make sure the Defines Module setting for that framework target is set to Yes.

In your umbrella header file, import every Objective-C header you want to expose to Swift. For example:

OBJECTIVE-C

#import
<XYZ/XYZCustomCell.h>


#import
<XYZ/XYZCustomView.h>


#import
<XYZ/XYZCustomViewController.h>


Swift will see every header you expose publicly in your umbrella header. The contents of the Objective-C files in that framework will be available in any Swift file within that framework target automatically, without any import statements. Use your custom Objective-C
code with the same Swift syntax you use with system classes.

SWIFT

let

myCell =
XYZCustomCell()


myCell.subtitle
=
"A custom cell"



Importing Swift into Objective-C

To import a set of Swift files in the same framework target as your Objective-C code, you don’t need to import anything into the umbrella header for the framework. Instead, import the Xcode-generated header file for your Swift code into any Objective-C
.m
file
you want to use your Swift code from.

Because the generated header for a framework target is part of the framework’s public interface, only declarations marked with the
public
modifier
appear in the generated header for a framework target. You can still use Swift methods and properties that are marked with the
internal
modifier
from within the Objective-C part of your framework, as long they are declared within a class that inherits from an Objective-C class. For more information on access-level modifiers, see Access
Control in The
Swift Programming Language.

To import Swift code into Objective-C from the same framework

Under Build Settings, in Packaging, make sure the Defines Module setting for that framework target is set to Yes.

Import the Swift code from that framework target into any Objective-C
.m
file
within that framework target using this syntax and substituting the appropriate names:

OBJECTIVE-C

#import
<ProductName/ProductModuleName-Swift.h>


The Swift files in your framework target will be visible in Objective-C
.m
files
containing this import statement. For information on using Swift from Objective-C code, see Using
Swift from Objective-C.

Import into Swift
Import into Objective-C
Swift code
No import statement
#import <ProductName/ProductModuleName-Swift.h>

Objective-C code
No import statement; Objective-C umbrella header required
#import "Header.h"


Importing External Frameworks

You can import external frameworks that have a pure Objective-C codebase, a pure Swift codebase, or a mixed-language codebase. The process for importing an external framework is the same whether the framework is written in a single language or contains files
from both languages. When you import an external framework, make sure the Defines Module build setting for the framework you’re importing is set to Yes.

You can import a framework into any Swift file within a different target using the following syntax:

SWIFT

import

FrameworkName


You can import a framework into any Objective-C
.m
file
within a different target using the following syntax:

OBJECTIVE-C

@import

FrameworkName;


Import into Swift
Import into Objective-C
Any language framework
import FrameworkName

@import FrameworkName;


Using Swift from Objective-C

Once you import your Swift code into Objective-C, use regular Objective-C syntax for working with Swift classes.

OBJECTIVE-C

MySwiftClass

*swiftObject

=
[[MySwiftClass

alloc]

init];


[swiftObject

swiftMethod];


A Swift class or protocol must be marked with the
@objc
attribute
to be accessible and usable in Objective-C. This attribute tells the compiler that this piece of Swift code can be accessed from Objective-C. If your Swift class is a descendant of an Objective-C class, the compiler automatically adds the
@objc
attribute
for you. For more information, see Swift
Type Compatibility.

You’ll have access to anything within a class or protocol that’s marked with the
@objc
attribute
as long as it’s compatible with Objective-C. This excludes Swift-only features such as those listed here:

Generics

Tuples

Enumerations defined in Swift

Structures defined in Swift

Top-level functions defined in Swift

Global variables defined in Swift

Typealiases defined in Swift

Swift-style variadics

Nested types

Curried functions

For example, a method that takes a generic type as an argument or returns a tuple will not be usable from Objective-C.

To avoid cyclical references, don’t import Swift into an Objective-C header file. Instead, you can forward declare a Swift class to use it in an Objective-C header. Note that you cannot subclass a Swift class in Objective-C.

To reference a Swift class in an Objective-C header file

Forward declare the Swift class you’re using:

OBJECTIVE-C

//
MyObjcClass.h


@class

MySwiftClass;


@interface

MyObjcClass :
NSObject


-

(MySwiftClass

*)returnSwiftObject;


/*
... */


@end



Naming Your Product Module

The name of the Xcode-generated header for Swift code, and the name of the Objective-C bridging header that Xcode creates for you, are generated from your product module name. By default, your product module name is the same as your product name. However, if
your product name has any non-alphanumeric characters, such as a period (
.
),
they are replaced with an underscore (
_
)
in your product module name. If the name begins with a number, the first number is replaced with an underscore.

You can also provide a custom name for the product module name, and Xcode will use this when naming the bridging and generated headers. To do this, change the Product Module Name build setting.


Troubleshooting Tips and Reminders

Treat your Swift and Objective-C files as the same collection of code, and watch out for naming collisions.

If you’re working with frameworks, make sure the Defines Module build setting under Packaging is set to Yes.

If you’re working with the Objective-C bridging header, make sure the Objective-C Bridging Header build setting under Swift Compiler - Code Generation has a path to the header that’s relative to your project. The path must be directly to the file itself, not
just to the directory that it’s in.

Xcode uses your product module name—not your target name—when naming the Objective-C bridging header and the generated header for your Swift code. For information on product module naming, see Naming
Your Product Module.

To be accessible and usable in Objective-C, a Swift class must be a descendant of an Objective-C class or it must be marked
@objc
.

When you bring Swift code into Objective-C, remember that Objective-C won’t be able to translate certain features that are specific to Swift. For a list, see Using
Swift from Objective-C.

If you use your own Objective-C types in your Swift code, make sure to import the Objective-C headers for those types before importing the Swift generated header into the Objective-C
.m
file
you want to use your Swift code from.

Swift declarations marked with the
private
modifier
do not appear in the generated header. Private declarations are not exposed to Objective-C unless they are explicitly marked with
@IBAction
,
@IBOutlet
,
or
@objc
as well.

For app targets, declarations marked with the
internal
modifier
appear in the generated header if the app target has an Objective-C bridging header.

For framework targets, only declarations with the
public
modifier
appear in the generated header. You can still use Swift methods and properties that are marked with the
internal
modifier
from within the Objective-C part of your framework, as long they are declared within a class that inherits from an Objective-C class. For more information on access-level modifiers, see Access
Control in The
Swift Programming Language.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐