Swift Project compatibility Objective-c issues Summary

Source: Internet
Author: User
Tags unsupported uikit

This article is a contribution article, one leaf (blog)
Welcome to the original article or translation to us, the way of submission: [email protected] or on the homepage click on the "Submission of explosive material"

First, solve the problem

The SWIFT project requires the use of packaged OBJECTIVE-C components and third-party libraries, and Apple offers solutions that handle most of the daily needs, but not as perfect, with many problems in the process of mixing. This article summarizes Swift-compatible objective-c issues to help you better use Swift, with the following table of contents:

1. Swift calls OBJECTIVE-C code

2. Objective-c Invoke Swift code

3. Swift compatible Xib/storyboard

4. Objective-c Smart Call to incompatible swift methods

5. Multi-target compilation error resolution

6. Third-party class library support

second, the basic mixed programming

Swift and Objective-c's code calls each other, not as convenient as objective-c and C + +, and requires some additional configuration work. Whether Swift calls Objective-c or Objective-c calls Swift,xcode requires two steps in processing:

2.1 Swift calls objective-c code

Xcode calls the OBJECTIVE-C code for swift, with the exception of macro definitions, which are relatively well supported.

2.1.1 First step in using Objetvie-c

Tell Xcode, which objective-c class to use, create a new. h header file, the file name can be arbitrarily taken, it is recommended to use the "project name-bridging-header.h" command format.


Tips

Swift's iOS project, create the class file in Xcode6, by default automatically selects the file under the OS X tag, you must select the file under the iOS tag, otherwise the grammar intelligence hint will not work, and the serious result will cause the packing error.

2.1.2 The second step, target is configured so that the created header file takes effect

When you set the objective-c bridging Header , the path is configured correctly, for example: a file named "ilswift-bridging-header.h" is created, stored in the root directory of the Ilswift project folder, the following is the wording:

Ilswift/ilswift-bridging-header.h

Of course, in a new project, create a objective-c class directly, and Xcode will prompt you to:

Directly Select Yes, if you accidentally click the other buttons, you can follow the steps above to add step by step.

2.2 objective-c Calling Swift code

2.2.1 Objective-c calling Swift code two steps

The first step tells Xcode which classes need to be used (automatic processing of classes that inherit from NSObject, this step is not required), and the keyword @objc (className) to mark

Import UIKIT@OBJC (Ilwritebyswift) class Ilwritebyswift {var name:string! Class Func newinstance (), Ilwritebyswift {return Ilwritebyswift ()}}

The second step introduces the header file, the Xcode header file naming rules for

$ (swift_module_name)-swift.h

Examples are as follows:

#import "Ilswift-swift.h"

Tips

Unclear swift_module_name can be viewed through the following steps

2.2.2 Not found $ (swift_module_name)-swift.h

1. If you encounter this problem, follow the steps below to perform a routine check

    • OK import swift_module_name)-swift.h header file name is correct

    • Swift_module_name)-swift.h was not rebuilt after clean, executed xcode->product->build

2. header file loop

In mixed programming projects, because of the simultaneous use of both languages, the following requirements often arise: in the case of the Swift project, a class objectvie-c write is required, and the Class A uses some of the functions of Swift, the loop of the header file, which causes the compiler not to properly build the $ (swift_ module_name)-swift.h, when you encounter this problem, do the following with the. h file

Delete the following header file//#import "ilswift-swift.h"//Import class @class Ilswiftbean by code;

At the top of the objevtive-c. m file, add

#import "Ilswift-swift.h"

the use of undecalared identifier error appears or the method is not found, as follows:

There are several possible reasons for this:

    • The Swift class used is not inherited from NSObject, and the keyword can be added

    • Swift_module_name)-swift.h No real-time updates, xcode->product->build

    • This swift file uses a type or syntax that is not supported by OBJECTIVE-C, such as private

There are some problems not found in the method, Xcode no Smart tip:

    • This method uses a type or syntax that is not supported by objective-c

The type of conversion not supported by Apple's official

    • 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

Third, Xib/storyboard support

Swift projects encounter two different issues when using Xib/storyboard

    • Xib: Do not load view content

    • Storyboard: class file not found

3.1 xib do not load view content

When creating Uiviewcontroller, the Xib file is selected by default, and when Xib is consistent with the class file name, it can be instantiated with the following code:

Let controller = Ilviewcontroller ()

Operation, the interface is not a thing, xib is not loaded. Workaround, precede the class with @objc (class name), for example:

Import UIKIT@OBJC (Ilviewcontroller) class Ilviewcontroller:uiviewcontroller {}

Tips:

Uiviewcontroller that are created in storyboard, do not require @objc (class name) and can be kept compatible

3.2 Storyboard Cannot find a class file

The Swift language introduces the module concept and, when converted by keyword @objc (class name), causes the following two types of errors because Storboard does not update the module property in a timely manner:

3.2.1 The Swift class or Objective-c class marked with @objc (class name) may have an error:

2015-06-02 11:27:42.626 ilswift[2431:379047] Unknown class _ttc7ilswift33ilnotfindswifttagbyobjccontroller in Interface Builder file.

Workaround, press, select Blank in module, direct enter

3.2.2 Swift class with no @objc (class name) tag

2015-06-02 11:36:29.788 ilswift[2719:417490] Unknown class Ilnotfindswiftcontroller in Interface Builder file.

Workaround, press, select the correct module

3. The cause of the above error: After setting the storyboard, directly in the class file, add or remove the @objc (class name) keyword, causing the module property in storyboard is not automatically updated, so a more general solution is that Let storyboard automatically update the module as follows:

3.3 Error Simulation demo download

In order to be able to get a clearer understanding of the solution process, the above error has been simulated, want to try to solve the above problems of students can directly download the demo

Iv. Objective-c Smart calls to incompatible swift methods

When you invoke a method in the Swift class in Objective-c, you will encounter a situation where the corresponding method cannot be found because some swift syntax does not support the conversion, as follows:

import uikitenum httpstate {    case succed, failed,  networkerror, servererror, others}class ilhttprequest: nsobject {     class func requestlogin (username: string, password: string, callback:   (state: httpstate)  ->  (Void))  {         Dispatch_async (Dispatch_get_global_queue (0, 0), {  ()  -> Void in             nsthread.sleepfortimeinterval (3)              dispatch_async (Dispatch_get_main_queue (), {  ()  -> Void in                 callback (state: httpstate.succed)              })          })     }} 

The corresponding $ (swift_module_name)-swift.h file is:

Swift_class ("_ttc12ilswifttests13ilhttprequest") @interface ilhttprequest:nsobject-(swift_nullability (nonnull) instancetype) init Objc_designated_initializer; @end

As can be seen from the above header file, the method Requestlogin uses the unsupported Swift enumeration, the conversion method is automatically ignored, there are two ways to skillfully solve similar problems:

4.1 Packaging with supported Swift syntax

In the swift file, add a compatible wrapper method Wraprequestlogin, note that incompatible types or syntax cannot be used in this method

Import uikitenum httpstate: int {    case succed = 0,  Failed = 1, NetworkError = 2, ServerError = 3, Others  = 4}class ilhttprequest: nsobject {    class func  Requestlogin (username: string, password: string, callback:  (state: HTTPState)  ->  (Void))  {        dispatch_async (dispatch_get_ Global_queue (0, 0), {  ()  -> Void in             nsthread.sleepfortimeinterval (3)              dispatch_async (Dispatch_get_main_queue (), {  ()  -> Void in                 callback (state :  httpstate.succed)              })          })     }    class func wraprequestlogin (userName:  String, password: String, callback:  (State: int)  ->  (Void))  {         self.requestlogin (Username, password: password)  {  (state)  ->  (Void)  in             callback (State: state.rawvalue)         }     }}

The corresponding $ (swift_module_name)-swift.h file is:

Swift_class ("_ttc12ilswifttests13ilhttprequest") @interface ilhttprequest:nsobject+ (void) Wraprequestlogin: ( NSString * __nonnull) userName Password: (nsstring * __nonnull) password callback: (void (^ __nonnull) (Nsinteger)) callback ;-(Swift_nullability (nonnull) instancetype) init Objc_designated_initializer; @end

At this point, we can use the wrapping method directly in the Objective-c Wraprequestlogin

4.2 Using inheritance wisely

With inheritance you can support all swift types, the primary functionality is implemented in OBJECTIVE-C, and unsupported syntax is called in the Swift file, for example, Illoginsupercontroller as the parent class

@interface Illoginsupercontroller:uiviewcontroller@property (Weak, nonatomic) Iboutlet Uitextfield *userNameField;@ Property (weak, nonatomic) Iboutlet Uitextfield *passwordfield;-(ibaction) loginbuttonpressed: (ID) sender; @end/////// @implementation illoginsupercontroller-(ibaction) Loginbuttonpressed: (ID) sender{} @end

Create Swift file, inherit from Illoginsupercontroller, call those unsupported syntax in this swift file

Import Uikitclass Illogincontroller:illoginsupercontroller {override func loginbuttonpressed (sender:anyobject!)            {Ilhttprequest.requestlogin (Self.userNameField.text, Password:self.passwordField.text) {(state) and (Void) in Specific business Logic}}}

Five, multiple target compilation error resolution

There are some compilation errors when using multiple target

5.1 Use of undeclared type

This type of error is because the currently running target cannot find a file that must be compiled. Add the file to target, support ilswifttests target below, select the check box before ilswifttests


5.2 does not has a member named

This type of error may be caused by the following two reasons, the workaround is as follows:

1. This method comes from the parent class, and the parent class file is not added to the current target

2. This method comes from the extension, and the extension is not added to the current target

Tips

If the check finds that all class files have been accurately added to target, but compiled or not, focus on checking that the bridge file is set correctly, and adding the corresponding header file to the bridge file. It is recommended that all target bridging files be directed to the same file, if not specifically requested. For the settings of the bridging file, refer to 2.1

Vi. third-party class library support

The Swift project canceled precompiled files, and some third-party objective-c libraries did not import the necessary frameworks (such as Uikit) to cause compilation errors

6.1 Cocoapods cannot find the. o File

In the Cocoapods project, some of the. o files for some class libraries are not found, leading to the following two types of errors:

    • A compilation error exists in the class library itself

    • Swift does not pre-compile, uikit, etc. not imported

Add the code file from this library file directly to the project, compile, and resolve the error.

6.2 Jsonmodel Support

Some simple features of Jsonmodel can be used in swift, and some complex data models recommend the use of Objevtive-c

Import UIKIT@OBJC (Illoginbean) public class Illoginbean:jsonmodel {var useravatarurl:nsstring?    var userphone:nsstring! var uid:nsstring!}

Tips

When Swift uses the Jsonmodel framework, the field can only be a support type in nsfoundation, and the newly added string, Int, array, and so on under swift cannot be used

6.3 Friends League statistics

The referenced from error is present in the introduction of the Friends League statistics SDK in the SWIFT project:

workaround, find other Linker Flags, add-lz

Vii. Overview

Most mature third-party frameworks are now written using objective-c, which inevitably involves mixed programming in two languages during development, with a number of strange problems. Because the unknown has the value of exploration, Swift's simplicity and speed, can greatly advance the development progress. So from today onwards, bold start to try.

Swift Project compatibility Objective-c issues Summary

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.