SoFunction
Updated on 2025-04-11

Swift using data types in Cocoa

As part of Objective-C interoperability (interoperability), Swift provides a fast and efficient way to handle Cocoa data types.

Swift will automatically convert some Objective-C types to Swift types and convert Swift types to Objective-C types. There are also some data types that are interoperable in Objective-C and Swift. Those convertible data types or data types that have interoperability are called bridged data types. For example, in Swift, you can pass an Array value to a method that requires an NSArray object. You can also convert a bridged type and a copy of it. When you use as to convert bridged types or those provided by constants and variables, Swift bridges their data types.

Swift also provides a simple and convenient override method to connect Foundation data types. In the later Swift language, you can feel nature and unity in its syntax.

String

Swift will automatically convert in String and NSString types. This means that where you can use NSString objects, you can use a Swift-based String type instead, and doing so will have the characteristics of their data type, interpolation of String type, APIs based on Swift, and a wider range of application of NSString classes. Therefore, you hardly have to use the NSString class in your code anymore. In fact, when Swift connects to Objective-C APIs, it replaces all NSString types with String types. When you use the Swift class in your Objective-C code, the accessed API replaces all String types with NSString types.

To allow string conversion, just connect to Foundation. For example, you call capitalizedString-a method of the NSString class in a Swift string. After that, Swift will automatically convert the String into an NSString object and call the method. This method even returns a Swift String type because it is replaced on access.

Copy the codeThe code is as follows:

import Foundation
let greeting = "hello, world!"
let capitalizedGreeting =
// capitalizedGreeting: String = Hello, World!

If you really need to use an NSString object, you can use a Swift String value and convert it. The String type can always be converted from an NSString object to a Swift String value, so there is no need to use an optional type converter (as?). You can also create an NSString object by defining constants and variables in a string.

Copy the codeThe code is as follows:

import Foundation
let myString: NSString = "123"
if let integerValue = (myString as String).toInt()){
    println("\(myString) is the integer \(integerValue)")
}

Localization

In Objective-C, a macro of the NSLocalizedString class is commonly used to locate a string. The macros of this collection include NSLocalizedStringFromTableInBundle and NSLocalizedStringWithDefaultValue. In Swift, only one function can be used to implement the same function as the entire NSLocalizedString set, that is, NSLocalizedString(key:tableName:bundle:value:comment:). The NSLocalizedString function provides a default value for tableName, bundle and value parameters, respectively. You can replace the macro with it.

number

Swift will automatically convert the determined numeric types Int and Float to NSNumber. Such a conversion allows you to create an NSNumber based on one of the types:

Copy the codeThe code is as follows:

let n = 42
let m: NSNumber = n

You can also pass a value of type Int, for example to a parameter that requires type NSNumber. It is also important to note that NSNumber can contain many different types, so you cannot pass it to a single Int value.

The types listed below will be automatically converted to NSNumber:

Copy the codeThe code is as follows:
Int
UInt
Float
Double
Bool

Class collection

Swift will automatically convert NSArray and NSDictionary classes to equivalent classes in Swift. This means you will benefit from Swift's powerful algorithms and unique syntax to handle collections - mutually convertible Foundation and Swift collection types.

Array

Swift will automatically convert in Array and NSArray types. When you convert from a Swift array to an NSArray object, the converted array is an array of type AnyObject[]. If an object is an instance of the Objective-C or Swift class, or if the object can be converted to another type, then the object belongs to an object of type AnyObject. You can convert any NSArray object into a Swift array because all Objective-C objects are of AnyObject type. Because of this, the Swift compiler replaces the NSArray class with AnyObject[] when connecting to Objective-C APIs.

When you convert an NSArray object to a Swift array, you can also cast the array to a specific type. Unlike converting from an NSArray class to AnyObject[], converting from an object of type AnyObject to an explicit type does not guarantee success. Since the compiler does not know until runtime whether AnyObject's object can be cast to a specific type, converting from AnyObject[] to SomeType[] returns an optional value. For example, if you know that a Swift array only contains instances of the UIView class (or a subclass of the UIView class), you can cast an array element of type AnyObject into a UIView object. If the element in the Swift array is not an object of type UIView at runtime, the conversion will return nil.

Copy the codeThe code is as follows:

let swiftyArray = foundationArray as AnyObject[]
if let downcastedSwiftArray = swiftArray as? UIView[] {
    // downcastedSwiftArray contains only UIView objects
}

You can also cast NSArray objects in a for loop to a specific type of Swift array:

Copy the codeThe code is as follows:

for aView: UIView! in foundationArray {
     // aView is of type UIView
}

Note: This conversion is a cast, and if the conversion is unsuccessful, an error message will be generated at runtime.

When you convert from a Swift array to an NSArray object, the elements in the Swift array must belong to AnyObject. For example, a Swift array of type Int[] contains elements of an Int structure. The Int type is not an instance of a class, but because the Int type is converted to the NSNumber class, the Int type belongs to the AnyObject type. So you can convert a Swift array of type Int[] into an NSArray object. If an element in the Swift array does not belong to the AnyObject type, an error will occur at runtime.

You can also create an NSArray object from a Swift array. When you define a constant or variable as an NSArray object and assign an array to it as an instance variable, Swift will create an NSArray object instead of a Swift array.

Copy the codeThe code is as follows:

let schoolSupplies: NSArray = ["Pencil", "Eraser", "Notebkko"]
// schoolSupplies is an NSArray object containing NSString objects

In the example above, the Swift array contains three String strings. Due to the conversion from String type to NSString class, the array literal is converted into an NSArray object and is successfully assigned to the schoolSupplies variable.

When you use Swift classes or protocols in Objective-C code, the accessed API replaces all Swift arrays of all types with NSArray. If you pass an NSArray object to Swift's API and ask the array element to be a new type, an error will be generated at runtime. If the Swift API returns a Swift array that cannot be converted to NSArray type, an error will also occur.

Foundation data types

Swift also provides a simple and convenient override method to connect data types defined in the Foundation framework. Use override methods in NSSize and NSPoint, and in the remaining Swift languages, you can feel nature and unity in its syntax. For example, you can use the following syntax to create a structure of NSSize type:

Copy the codeThe code is as follows:

let size = NSSize(width: 20, height: 40)

Override methods also allow you to call Foundation's structure functions in a natural way.

Copy the codeThe code is as follows:

let rect = NSRect(x: 50, y: 50, width: 100, height: 100)
let width = // equivalent of NSWidth(rect)
let maxX = // equivalent of NSMaxY(rect)

Swift can convert NSUInteger and NSInteger to Int type. These types will become Int types in Foundation APIs. Int is often used as coherent as possible in Swift, and the UInt type is always available when you require an unsigned integer type.

Foundation function

In Swift, NSLog can output information on the system console. You can use this function like the syntax format you used in Objective-C.

Copy the codeThe code is as follows:

NSLog("%.7f", pi)  // Logs "3.1415927" to the console

At the same time, Swift also provides output functions like print and println. The character interpolation mechanism that is mostly attributed to Swift makes these functions simple, rough and multi-effect. These functions do not output information on the system console, but are available when calling is required.

The NSAssert function no longer exists in Swift, but instead is the assert function.

Core Foundation

The Core Foundation type in Swift is a mature class. When memory management comments appear, Swift automatically manages the memory of the Core Foundation object, including the Core Foundation object you instantiated. In Swift, you can freely transform Fundation and Core Foundation types. If you want to convert to the Bridge Foundation type first, you can also bridge some toll-free bridged Core Foundation types to the Swift standard library type.

Redefine the type

When Swift imports a Core Foundation type, the compiler remaps the imported type name. The compiler removes the Ref from the end of each type name, because all Swift classes are reference types, so the suffix is ​​redundant.

The CFTypeRef type in Core Foundation remaps the Anyobject type. So the CFTypeRef you used before is now time to switch to AnyObject.

Memory management object

In Swift, the Core Foundation object returned from annotated APIs can be automatically memory-managed - you no longer need to call your own CFRetain, CFRelease, or CFAutorelease functions. If you return a Core Foundation object from your own C function and Objective-C method, you need to comment the object with CF_RETURNS_RETAINED or CF_RETURNS_NOT_RETAINED. When these APIs are included in Swift code, the compiler automatically calls memory management at compile time. If you only call annotated APIs that do not indirectly return the Core Foundation object, you can now skip the rest of this section. Otherwise, let's continue to learn about the unmanaged Core Foundation object.

Unmanaged objects

When Swift imports unannotated APIs, the compiler will not automatically host the returned Core Foundation object. Swift encloses these returned Core Foundation objects in a Unmanaged<T> structure. Objects that return indirectly to the Core Foundation are also unmanaged. For example, here is an unannotated C function:

Copy the codeThe code is as follows:

CFStringRef StringByAddingTwoStrings(CFStringRef string1, CFStringRef string2)

Here is how Swift is imported:

Copy the codeThe code is as follows:

func StringByAddingTwoStrings(CFString!, CFString!) -> Unmanaged<CFString>!

Suppose you receive an unmanaged object from unannotated APIs, and before using it, you must convert it into a memory-managed object. In this regard, Swift can help you manage memory without doing it yourself. At the same time, the Unmanaged<T> structure also provides two methods to convert an unmanaged object into a memory-managed object-takeUnretainedValue() method and takeRetainedValue() method. These two methods return the original, non-enclosed object type. You can choose which method is more appropriate based on the unretained or retained objects returned by the APIs you actually call.

For example, suppose there is a C function here, which will not release the CFString object before returning the value. Before using this object, you use the takeUnretainedValue() function to convert it into an object that can be managed in memory.

Copy the codeThe code is as follows:

let memoryManagedResult = StringByAddingTwoStrings(str1, str2).takeUnretainedValue()
// memoryManagedResult is a memory managed CFString

You can also use the retain(), release() and autorelease() methods in an unmanaged object, but this approach is not worth recommending.