how to use the Objective-C CommonCrypto library in a swift app in xcode?

I need help on using xcode and specifically using Objective-C libraries in swift. Im trying to use sha256 hashing code but swift doesn't recognize the code and I cant figure out the correct way to do an import or use a swift bridging header to get the code to work.

Replies

The best way to do this, at least in my experience, is to write a small Objective-C wrapper for the CommonCrypto functionality you need and then use that wrapper from your Swift code. Pasted in below is an example of this from a test project of mine.

There are other choices here:

  • You can include

    <CommonCrypto/CommonCrypto.h>
    in your bridging header and then call it from Swift directly.
  • You can cook up your own module map for Common Crypto.

However, I think the approach outline below represents a good balance between minimising your Objective-C code and avoiding extra complexity in the tools.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

In my bridging header:

#import "SecurityHelpers.h"

In my

SecurityHelpers.h
:
@import Foundation;

typedef NS_ENUM(NSInteger, SecDigestAlgorithm) {
    SecDigestAlgorithmSHA1, 
    SecDigestAlgorithmSHA224, 
    SecDigestAlgorithmSHA256, 
    SecDigestAlgorithmSHA384, 
    SecDigestAlgorithmSHA512 
};

/*! Returns a digest of the specified data.
 *  \param algorithm The digest algorithm to use.
 *  \param data The data to digest.
 *  \returns A digest of that data.
 */

extern NSData * SecCreateDigest(SecDigestAlgorithm algorithm, NSData * data);

In my

SecurityHelpers.m
:
#import "SecurityHelpers.h"

#include <CommonCrypto/CommonCrypto.h>

extern NSData * SecCreateDigest(SecDigestAlgorithm algorithm, NSData * data) {
    NSUInteger size;
    unsigned char *(*digester)(const void *data, CC_LONG len, unsigned char *md);
    NSMutableData * digest;

    switch (algorithm) {
        case SecDigestAlgorithmSHA1:   size = CC_SHA1_DIGEST_LENGTH;   digester = CC_SHA1;   break;
        case SecDigestAlgorithmSHA224: size = CC_SHA224_DIGEST_LENGTH; digester = CC_SHA224; break;
        case SecDigestAlgorithmSHA256: size = CC_SHA256_DIGEST_LENGTH; digester = CC_SHA256; break;
        case SecDigestAlgorithmSHA384: size = CC_SHA384_DIGEST_LENGTH; digester = CC_SHA384; break;
        case SecDigestAlgorithmSHA512: size = CC_SHA512_DIGEST_LENGTH; digester = CC_SHA512; break;
        default:
            abort();
    }

    digest = [[NSMutableData alloc] initWithLength:size];
    digester(data.bytes, (CC_LONG) data.length, digest.mutableBytes);

    return digest;
}

In my Swift code:

let content: Data = …
let messageDigest = SecCreateDigest(.SHA256, content)