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 files
// # import "ILSwift-Swift.h"
// Import classes via code
@class ILSwiftBean;


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 inInterface 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 UIKit
enum 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 UIKit
enum 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 UIKit
class ILLoginController: ILLoginSuperController {
     override func loginButtonPressed (sender: AnyObject!) {
         ILHTTPRequest.requestLogin (self.userNameField.text, password: self.passwordField.text) {(state)-> (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.






Http://www.cocoachina.com/swift/20150608/12025.html



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.