Swift basic syntax I believe you have seen a lot, here is the most complete information :swift official website, here is talking about swift2.2. There’s an interesting quote on the Internet:

C, C++, Objective, Swift but like four of the seven calabash boys, the seven calabash boys are the best, but it takes all seven brothers to get rid of them

I. Establishment project

Select Create Brideing Header

Here I drew a picture myself in keyNote

Of course, the example without the demo is completely rogue, so you can look at the demo appendix on the last page later, click to download it, and post the code here

M: in OSMOView.

@implementation OSMOView- (void) print
{
    NSLog(@"testXXX");
}
Copy the code

M: in ViewController.

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    XXSwiftViewController *swiftVC = [[XXSwiftViewController alloc] init];
    [swiftVC printOSMOView];
}
Copy the code

In XXSwiftViewController:

class XXSwiftViewController: UIViewController{ override init(nibName nibNameOrNil: String? , bundle nibBundleOrNil:NSBundle?). {super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) } required init? (coder:NSCoder) {
        super.init(coder: coder) printOSMOView(); } func printOSMOView() -> Void { let osmoView:OSMOView = OSMOView() osmoView.print(); }}Copy the code

Interaction with Objective-C apis

1. Initialization

In the oc:

- (instancetype)init;
- (instancetype)initWithFrame:(CGRect)frame
                        style:(UITableViewStyle)style;
Copy the code

In swift:

init() { / *... * / }
init(frame: CGRect, style: UITableViewStyle) { / *... * / }
Copy the code

It all starts with init(, and then you put parameters init to make it even more uniform

2. Instantiate the object

In the oc:

UITableView *myTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
Copy the code

In swift:

let myTableView: UITableView = UITableView(frame: CGRectZero, style: .Grouped)
Copy the code

Without alloc and init, Swift does a better job of using the factory method, mapping it directly to swift’s initialization method:

In the oc:

UIColor *color = [UIColor colorWithRed:0.5 green:0.0 blue:0.5 alpha:1.0];
Copy the code

In swift:

let color = UIColor(red: 0.5, green: 0.0, blue: 0.5, alpha: 1.0)
Copy the code

3. Access properties

In the oc:

[UIColor darkGrayColor];
textfield.text = @"test";
Copy the code

In swift:

UIColor.darkGrayColor()
myTextField.text = "Hello world"
Copy the code

When you get or set a property, you write only the name of the property, no parentheses. But note that darkGrayColor contains a parenthesis. This is because darkGrayColor is a class method of UIColor, not a property

4. Usage

In the oc:

[myTableView insertSubview:mySubview atIndex:2];
Copy the code

In swift:

myTableView.insertSubview(mySubview, atIndex: 2)
myTableView.layoutIfNeeded() // No parameters
Copy the code

Properties and methods are a purpose that () follows through

5. Id compatibility

5.1 Basic Usage

Swift contains a protocol type called AnyObject, which represents any type of object, like an ID in Objective-C. You can also call any Objective-C method and access any property without casting. This includes objective-C compatible methods marked with the @objc attribute, in Swift:

var myObject: AnyObject = UITableViewCell()
myObject = NSDate()

let futureDate = myObject.dateByAddingTimeInterval(10)
let timeSinceNow = myObject.timeIntervalSinceNow
Copy the code

Note: crash!

myObject.characterAtIndex(5)
// crash, myObject doesn't respond to that method
Copy the code

Because the exact type is only known at runtime in objects of type AnyObject, it is easy to write unsafe code. Also, in contrast to Objective-C, if you call a method or property that doesn’t exist in Anyobject, you get a runtime error. For example, the following code does not produce a compilation error, but does have undefined method errors at run time. You can eliminate the error with Optional

let myCount = myObject.count let myChar = myObject.characterAtIndex? (5)
print("\(myCount),\(myChar)") / / the nil nil
Copy the code
5.2 Downward Transformation

You can test this optional value to determine whether the conversion was successful

let userDefaults = NSUserDefaults.standardUserDefaults()
let lastRefreshDate: AnyObject? = userDefaults.objectForKey("LastRefreshDate")
if let date = lastRefreshDate as? NSDate {
    print("\(date.timeIntervalSinceReferenceDate)")}Copy the code

Note: the crash

let date = lastRefreshDate as! NSDate
Copy the code

as! If it’s not of the right type, then crash, remember if it’s not of the right type it’s better to use as?

6. The Extension expansion

Extension Objective-C Category in Swift is similar. Extension extends the behavior of existing classes, structures, and enumerations, including those defined in Objective-C. You can define an Extension on a system framework or on your own custom type. Simply import the corresponding module and refer to the same class, structure, and enumeration names you have in Objective-C.

extension UIBezierPath {
    convenience init(triangleSideLength: Float, origin: CGPoint) {
        self.init()
        let squareRoot = Float(sqrt(3.0))
        let altitude = (squareRoot * triangleSideLength) / 2
        moveToPoint(origin)
        addLineToPoint(CGPoint(x: CGFloat(triangleSideLength), y: origin.x))
        addLineToPoint(CGPoint(x: CGFloat(triangleSideLength) / 2, y: CGFloat(altitude)))
        closePath()
    }
}
protocol SomeProtocol {
    var mustBeSettable: Int { get set }
}

extension CGRect:SomeProtocol {
    var area: CGFloat {
        return width * height
    }
    var mustBeSettable: Int { get{ return 10} set{} }
    
}
func testExtern() -> Void {
    let testPath:UIBezierPath = UIBezierPath.init(triangleSideLength: 1.0, origin: CGPointMake(5.10))
    print("\(testPath)")
    
    let rect = CGRect(x: 0.0, y: 0.0, width: 10.0, height: 50.0)
    let area = rect.area
    print("\(area)")}"UIBezierPath: 0x7f9e44857b90; <MoveTo {5.10}>,
 <LineTo {1.5}>,
 <LineTo {0.5.0.86602538824081421}>,
 <Close>
500.0
Copy the code

7. Closure

Function closure: block, in OC:

void (^completionBlock)(NSData *, NSError*) = ^ (NSData *data, NSError *error) {/ *... * /}
Copy the code

In swift:

func testConclusure() -> Void {
    let completionBlock: (String, NSError?). -> Void = {str, errorin
        print("\(str)")
    }
    completionBlock("5".nil)}Copy the code

8. @objC changes the method exposed to OC, etc

For example, in swift now we write:

@objc(Color)
enum AppColor: Int {
    @objc(Red)
    case KRedColor
    
    @objc(Black)
    case KBlackColor
}

@objc(GameSwfitItem)
class Apple:NSObject{
    @objc(color)
    var appColor: AppColor = .KRedColor
    
    @objc(swiftName)
    var name: String
    
    @objc(initSwift:)
    init(name:String){
        self.name = name
    }
}
Copy the code

In the ‘project name -swift.h’ we see this:

SWIFT_CLASS_NAMED("Apple")
@interface GameSwfitItem : NSObject
@property (nonatomic.copy) NSString * _Nonnull swiftName;
- (nonnull instancetype)initSwift:(NSString * _Nonnull)name OBJC_DESIGNATED_INITIALIZER;
@end
Copy the code

9. Lightweight paradigm

In the oc:

@property NSArray<NSDate *>* dates;
@property NSSet<NSString *>* words;
@property NSDictionary<KeyType: NSURL *, NSData *>* cachedData;
Copy the code

In swift:

var dates: [NSDate]
var words: Set<String>
var cachedData: [NSURL: NSData]
Copy the code

10. #selector

1. Add ‘Target’ to the object

import UIKit
class MyViewController: UIViewController {
    let myButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50)) override init(nibName nibNameOrNil: String? , bundle nibBundleOrNil:NSBundle?). {super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        
        let action = #selector(MyViewController.tappedButton(_:))
        myButton.addTarget(self, action: action, forControlEvents: .TouchUpInside)
    }
    
    func tappedButton(sender: UIButton!). { print("tapped button") } required init? (coder:NSCoder) {
        super.init(coder: coder)
    }
}
Copy the code

2.performSelector / respondsToSelector

let string: NSString = "Hello, Cocoa!"
let selector = #selector(NSString.lowercaseStringWithLocale(_:))
let locale = NSLocale.currentLocale()
if let result = string.performSelector(selector, withObject: locale) {
    print(result.takeUnretainedValue())
}
// Prints "hello, cocoa!"
Copy the code

If there’s no response to Selector at this point, it’s going to crash

let array: NSArray = ["delta"."alpha"."zulu"]
    
// Not a compile-time error because NSDictionary has this selector.
let selector = #selector(NSDictionary.allKeysForObject(_:))
    
if array.respondsToSelector(selector){
    array.performSelector(selector)
}
Copy the code

Write Swift classes using objective-C features

1. The agreement, the Class

class XXTableViewController: UIViewController.UITableViewDelegate.UITableViewDataSource{
    
    lazy var tableView: UITableView! = {
        var tableView = UITableView(frame: CGRectZero, style: UITableViewStyle.Grouped)
        tableView.delegate = self
        tableView.dataSource = self
        tableView.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "Cell")
        return tableView
    }()
    
    //MARK: UITableViewDelegate
    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }
    
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }
    
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) - >UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
        return cell
    }
}
Copy the code

Lazy: in oc

@property (nonatomic.copy) NSString *testString;

// ClassA.m
- (NSString *)testString {
     if(! _testString) { _testString =@"Hello";
        NSLog(@" Output on first access only");
     }
     return _testString;
}
Copy the code

In swift:

class ClassA {
    lazy var str: String = {
        let str = "Hello"
        print("Output on first access only")
        return str
    }()
}
Copy the code

Deeper understanding:

let data = 1..3.
let result = data.lazy.map {
    (i: Int) -> Int in
    print("Processing \(I)")
    return i * 2
}

print("Prepare the results of the interview")
for i in result {
    print("Result of operation \(I)")
}

print("Operation complete") run result at this time:// Prepare the results of the visit
// Process 1
// The result after the operation is 2
// Process 2
// The result of the operation is 4
// Process 3
// The result after the operation is 6
// The operation is complete
Copy the code

4. Points needing attention in the mixture of OC/Swift

1. Object comparison

Object comparison: in pure swift with == judgment

class TodoItem {
    let uuid: String
    var title: String
    
    init(uuid: String, title: String) {
        self.uuid = uuid
        self.title = title
    }
}

extension TodoItem: Equatable {
    
}

func ==(lhs: TodoItem, rhs: TodoItem) -> Bool {
    return lhs.uuid == rhs.uuid
}
Reference: / / : http://swifter.tips/equal/
Copy the code

If you compare it to an OC object, you still need to override the isEqual method

class TodoItemOC :NSObject{
    let uuid: String
    var title: String
    
    init(uuid: String, title: String) {
        self.uuid = uuid
        self.title = title
    }
    
    override func isEqual(object: AnyObject?) -> Bool {
        return true; }}Copy the code

2. Type compatibility

2.1 Whether to inherit NSObject or OC classes

When you define a Swift class that inherits from NSObject or another Objective-C class, that class is automatically objective-C compliant. All of this is done for you by the Swift compiler. In the Persion. Swift in:

class Person: NSObject {
    var name : String
    var age : Int
    
    // Overrides the NSObject constructor
    override init() {
        name = "testname"
        age = 0
    }
    
    func printName() -> Void {
        print("\(name)")}}Copy the code

In the oc:

//
// Squirrel.m
// XXSwiftUseOC
//
// Created by tomxiang on 7/30/16.
// Copyright © 2016 Tomxiang. All rights reserved.
//

#import "Squirrel.h"
#import "XXSwiftUseOC-Swift.h"

@implementation Squirrel- (void) print{
    Person *person = [[Person alloc] init];
    [person printName];
}
@end
Copy the code

3. swift/C++

There is a sentence on apple’s website: You cannot import C++ code directly into Swift. Instead, create an objective-C or C wrapper for C++ code. Need to use OC or C packaging

1. Swift call c
//
// CFile.c
// XXSwiftUseOC
//
// Created by tomxiang on 8/4/16.
// Copyright © 2016 Tomxiang. All rights reserved.
//

#include <stdio.h>
void testc()
{
    printf("CFile\n");
}
Copy the code
2. Swift call c + +

H:

#ifndef junk_h
#define junk_h

class A
{
public:
    A(int);
    int getInt();
private:
    int m_Int;
};

#endif /* junk_h */
Copy the code

In the.cpp:

#include "junk.h"

A::A(int _i) : m_Int(_i) {}

int A::getInt() { return m_Int; }

extern "C" int getIntFromCPP()
{
    // Create an instance of A, defined in
    // the library, and call getInt() on it:
    return A(1234).getInt();
}
Copy the code

– bridging – the Header:


#import "Squirrel.h"

void testc();

int getIntFromCPP();
Copy the code

When everything is done, it can be called smoothly

4. The localization

If it’s a SWIFT project, you can do this

let format = NSLocalizedString("Hello, %@!", comment: "Hello, {given name}!")
let name = "Mei"
let greeting = String(format: format, arguments: [name])
print(greeting)
Copy the code

If the project is not swift, the oc macro conversion is required

+ (NSString*) GET_LOCALIZED_TEXT:(NSString*)inputKey COMMENT:(NSString*)comment; + (NSString*) GET_LOCALIZED_TEXT:(NSString*)inputKey COMMENT:(NSString*)comment {
    return NSLocalizedString(inputKey, comment);
}
Copy the code

5. The macro

There are no macros in Swift, so in pure Swift:

class Constants {
    static let BEZEL_COLOR = UIColor.init(red: 0, green: 0, blue: 0, alpha:0.8)
    static let TEXT_COLOR = UIColor.init(red: 1, green: 1, blue: 1, alpha: 1)
    static let MARGIN: CGFloat = 15.0
}
hud.bezelView.color = Constants.BEZEL_COLOR
Copy the code

In mixed-use projects:

#define ContinuousViewWidth  190
#define ContinuousViewHeight 60

@interface OSMODefineSwitch : NSObject+ (CGFloat) OSMO_ICON_WIDTH_SWIFT;
Copy the code

6. CoreFoundation

Swifter.tips/Toll-Free/is pretty complete. CFRelease,CFRetain, and CFFundation objects are now ARC objects. One exception is for non-system CF apis (such as those written by you or by a third party), since there is no mandatory mechanism for them to follow Cocoa’s naming conventions, it is not possible to do automatic memory management. Import these APIS that return CF objects into Swift and their type will be Unmanaged if you do not explicitly use the above annotation to specify memory management

// CFGetSomething() -> Unmanaged<Something>
// CFCreateSomething() -> Unmanaged<Something>
// Both are not annotated, and are created in Create

let unmanaged = CFGetSomething()
let something = unmanaged.takeUnretainedValue()
// The type of something is something

let unmanaged = CFCreateSomething()
let something = unmanaged.takeRetainedValue()

/ / to use something

// Because the value is retained, release after use
unmanaged.release()
Copy the code

Keep in mind that these are only used in rare cases without annotations, and you don’t need to care if you just call the system’s CF API and don’t write your own CF API

5. Data types

1. The string

To allow string conversions, simply import the Foundation framework

class XXCocoaSwift: NSObject {
    
    let myString: NSString = "123"
    override init() {
        super.init()
        self.testNSString()
    }
    
    func testNSString() -> Void {
        if let integerValue = Int(myString as String) {
            print("\(myString) is the integer \(integerValue)")}}}//print 123 is the integer 123
Copy the code

2. The numerical

Swift automatically converts the identified numeric type to NSNumber

Int
UInt
Float
Double
Bool
Copy the code

3. Collection classes

Swift automatically converts the NSArray, NSSet, and NSDictionary classes to their Swift equivalents: Array, Set, and Dictionary

1. Array
@property NSArray<NSDate *>* dates;
- (NSArray<NSDate *> *)datesBeforeDate:(NSDate *)date;
- (void)addDatesParsedFromTimestamps:(NSArray<NSString *> *)timestamps;
Copy the code

In swift:

var dates: [NSDate]
func datesBeforeDate(date: NSDate) - > [NSDate]
func addDatesParsedFromTimestamps(timestamps: [String])
Copy the code
2. Set
@property NSSet<NSString *>* words;
- (NSSet<NSString *> *)wordsMatchingPredicate:(NSPredicate *)predicate;
- (void)removeWords:(NSSet<NSString *> *)words;
Copy the code

So, to Swift, it looks like this:

var words: Set<String>
func wordsMatchingPredicate(predicate: NSPredicate) -> Set<String>
func removeWords(words: Set<String>)
Copy the code
3. NSDictionary
@property NSDictionary<NSURL *, NSData *>* cachedData;
- (NSDictionary<NSURL *, NSNumber *> *)fileSizesForURLsWithSuffix:(NSString *)suffix;
- (void)setCacheExpirations:(NSDictionary<NSURL *, NSDate *> *)expirations;
Copy the code

So, converting to SWIFT is:

var cachedData: [NSURL: NSData]
func fileSizesForURLsWithSuffix(suffix: String) -> [NSURL: NSNumber]
func setCacheExpirations(expirations: [NSURL: NSDate])
Copy the code

4. The enumeration

@objc public enum CustomError: Int, ErrorType {
    case A, B, C
}
Copy the code

Otherwise, oc will not be able to apply the swift enumeration

typedef SWIFT_ENUM(NSInteger, CustomError) {
  CustomErrorA = 0,
  CustomErrorB = 1,
  CustomErrorC = 2};static NSString * _Nonnull const CustomErrorDomain = @"XXSwiftUseOC.CustomError";
Copy the code

Vi. Real-time display of playground

1. It is recommended to refer to directory 2, official documentation. Here are a bit of XCPlaygroundPage. CurrentPage. LiveView Settings

//: Playground - noun: a place where people can play
import UIKit
import XCPlayground

var str = "Hello world"

XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

/ / 1. Images
let image:UIImage = UIImage(named: "1.png")!

//2.uibutton
let button = UIButton(frame: CGRectMake(0.0.100.100))
button.backgroundColor = UIColor.redColor()
button.layer.cornerRadius = 10
button.layer.borderWidth = 2


//3. Function Click on the editor's show display mode to change its viewing mode
var j = 2
for i in 0  ..< 5{
    j += i*j
}

//4.add color
let imageView = UIImageView(image:UIImage(named:"1.png"))


//5.view
// Second display method
XCPlaygroundPage.currentPage.liveView = imageView

let customView = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 400))
customView.backgroundColor = UIColor.whiteColor()
//XCPlaygroundPage.currentPage.liveView = customView

/ / 5. Animation
Copy the code

Vii. Reference catalogue

PlayGround official 3.Using Swift with Cocoa and Objective-C (Swift 2.2) 4.15 Tips to Become a Better Swift Developer 5.Using Swift with Cocoa and Objective-C Chinese version 6.Swift project compatible objective-C issues summary 7. Swiftgg 8.CoreFoundation points to note 9. Swift2.2 Chinese version

8. Demo download

1.Demo