E Writing Swift Applications Using the iOS Client SDK

You can also use the Oracle Mobile Cloud Service iOS client SDK with Swift applications.

Here are the general steps you take to work with Swift and the client SDK, using Xcode as your IDE:

  1. Add the bridging header files.

  2. Add the SDK header files and libraries.

  3. Add the Objective-C linker flag.

  4. Compile and link your app using the iOS client SDK as you would any other iOS project in Xcode.

Note:

Using the SDK with Swift has all the same dependencies as using the SDK with Objective-C. For the list of dependencies, see iOS SDK Dependencies.

For more information on how to work effectively with Swift and Objective-C, see Apple’s documentation: https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html.

Adding the Bridging Header File

You need to use a bridging header file to import the header files of the Objective-C public classes that your Swift app calls. All of the available public classes in the MCS client SDK can be found in the SDK’s include folder.

To create a bridging header file in Xcode:

  1. Select File > New... > File... and then from iOS/Source choose Header file using the .h icon. You can give the bridging header file any name you choose.
    Depending on the SDK classes that your app uses, the contents should look something like the following:
    #ifndef GettingStartedSwift_Bridging_Header_h
    #define GettingStartedSwift_Bridging_Header_h
    
    #import "OMCCore.h"
    #import "OMCAuthorization.h"
    #import "OMCMobileBackend.h"
    #import "OMCMobileBackendManager.h"
    #import "OMCServiceProxy.h"
    #import "OMCUser.h"
    
    #import "OMCStorage.h"
    #import "OMCMobileBackend+OMC_Storage.h"
    #import "OMCStorageCollection.h"
    #import "OMCStorageObject.h"
    
    #import "OMCSynchronization.h"
    #import "OMCMobileBackend+OMC_Synchronization.h"
    #import "OMCFetchObjectCollectionBuilder.h"
    #import "OMCMobileResource.h"
    #import "OMCSyncGlobals.h"
    
    #import "OMCAnalytics.h"
    #import "OMCMobileBackend+OMC_Analytics.h"
    
    #import "OMCNotifications.h"
    #import "OMCMobileBackend+OMC_Notifications.h"
    
    #import "OMCLocation.h"
    #import "OMCMobileBackend+OMC_Location.h"
    
    
    #endif /* GettingStartedSwift_Bridging_Header_h */
  2. After you have created the header file, note the location of the file in the Build Settings for the Objective-C Bridging Header setting.
    It’s best to keep the header location specified relative to the project, rather than as an absolute path, in case the project is shared.

Adding the SDK Headers and Libraries to a Swift App

The set of headers and libraries you add depends upon which of the client SDK’s static libraries you include in your app. At a minimum, you need the libOMCCore.a and libIDMMobileSDK.a libraries.

To add the SDK headers and libraries:
  1. Download and unzip the SDK, as described in iOS Applications.
  2. From the location where you’ve unzipped the SDK files, drag the libraries and header files you want into your Swift project in Xcode.

    Note:

    The contents of the SDK libraries are hierarchically arranged by category, so you’ll need to drag over entire folders to preserve the includes of other headers.
  3. Under the Build Phases settings, add the static libraries plus the iOS frameworks required by the IDM library to the Link with Binary Libraries phase.
  4. Add the header files to your search path. Under the project settings, configure the Header Search Paths to include the location of the parent directory of the SDK folders, that is, the parent directory of libOMCCore.a, libIDMMobileSDK.a, and so on. Be sure to use a relative path to the project.
  5. Edit the bridging header file to include the header files you’ll actually need for your code.
    This means that you'll also need to add headers that are used by the class you wish to use.
    For example, to make sure that all the methods of OMCAuthorization.h are accessible, you’d also need to add OMAuthView.h, OMCUser.h and OMDefinitions.h. Without these files in the bridging header file, some methods and properties of OMCAuthorization won’t be visible, and the compiler won’t warn you with errors.

Using SDK Objects in Swift Apps

The rules for converting from Objective-C to Swift are well described in the Apple documentation. For general information on the relationship and usage of these two languages together, be sure you look there.

Watch out for the following:

  • The auto-complete feature of the Code Editor in Xcode generally works well enough to get you the mappings. However, sometimes it puts the a label in the first parameter that isn’t supposed to be there. Watch for it if you’re using auto-complete.

  • When Objective-C init methods come over to Swift, they take on native Swift initializer syntax. This means the init prefix is sliced off and becomes a keyword to indicate that the method is an initializer. See the Apple documentation for complete details.

  • Pay special attention to the ! and ? optional parameter specifications, as well as any parametrized types in the declarations. The optional types are auto-determined by the compiler when mapping Objective-C to Swift.

You should be able to compile and run your mobile app using Swift and the MCS client SDK on both the Xcode Simulator and an actual device.

Here’s an example of Objective-C and the comparable Swift code that uses the MCS client SDK.

The following Objective-C code to register a device token for Push notifications:

// Get notifications sdk object
OMCNotifications* notifications = [[appDelegate myMobileBackend] notifications];

// Register device token with MCS server using notifications sdk
[notifications registerForNotifications:[appDelegate getDeviceTokenData]
 
			onSuccess:^(NSHTTPURLResponse *response) {
								  
				NSLog(@"Device token registered successfully on MCS server");
								  
				dispatch_async(dispatch_get_main_queue(), ^{
					// Update UI here
				}) ;
			}
 
		onError:^(NSError *error) {
									
			NSLog(@"Error: %@", error.localizedDescription);
									
			dispatch_async(dispatch_get_main_queue(), ^{
				// Update UI here
			}) ;
		}];

might be written in the following way in Swift:

@IBAction func registerForPushNotifications() {
	
	// Get notifications sdk object
	let notifications = appDelegate.myMobileBackend().notifications();
	
	// Get device token first, and assign it here
	let deviceTokenData:NSData! = nil;
	
	// Register device token with MCS server using notifications sdk
	notifications.registerForNotifications(deviceTokenData, onSuccess: { (response:NSHTTPURLResponse!) in
		
		NSLog("Device token registered successfully on MCS server");
		
		dispatch_async(dispatch_get_main_queue()) {
			// Update UI here
		}
		
	}) { (error) in
		
		print("Error: %@", error.localizedDescription);
	};
}