diff --git a/olm.podspec b/olm.podspec
new file mode 100644
index 0000000..6e366d2
--- /dev/null
+++ b/olm.podspec
@@ -0,0 +1,98 @@
+#
+# Be sure to run `pod spec lint olm.podspec' to ensure this is a
+# valid spec and to remove all comments including this before submitting the spec.
+#
+# To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html
+# To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
+#
+
+Pod::Spec.new do |s|
+
+ # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
+ #
+ # These will help people to find your library, and whilst it
+ # can feel like a chore to fill in it's definitely to your advantage. The
+ # summary should be tweet-length, and the description more in depth.
+ #
+
+ s.name = "olm"
+ s.version = "0.1.0"
+ s.summary = "olm"
+
+ # This description is used to generate tags and improve search results.
+ # * Think: What does it do? Why did you write it? What is the focus?
+ # * Try to keep it short, snappy and to the point.
+ # * Write the description between the DESC delimiters below.
+ # * Finally, don't worry about the indent, CocoaPods strips it!
+ s.description = <<-DESC
+ DESC
+
+ s.homepage = "http://EXAMPLE/olm"
+ # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"
+
+
+ # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
+ #
+ # Licensing your code is important. See http://choosealicense.com for more info.
+ # CocoaPods will detect a license file if there is a named LICENSE*
+ # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
+ #
+
+ s.license = "MIT (example)"
+ # s.license = { :type => "MIT", :file => "FILE_LICENSE" }
+
+
+ # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
+ #
+ # Specify the authors of the library, with email addresses. Email addresses
+ # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also
+ # accepts just a name if you'd rather not provide an email address.
+ #
+ # Specify a social_media_url where others can refer to, for example a twitter
+ # profile URL.
+ #
+
+ s.author = { "Chris Ballinger" => "chrisballinger@gmail.com" }
+ # Or just: s.author = "Chris Ballinger"
+ # s.authors = { "Chris Ballinger" => "chrisballinger@gmail.com" }
+ # s.social_media_url = "http://twitter.com/Chris Ballinger"
+
+ # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
+ #
+ # If this Pod runs only on iOS or OS X, then specify the platform and
+ # the deployment target. You can optionally include the target after the platform.
+ #
+
+ # s.platform = :ios
+ # s.platform = :ios, "5.0"
+
+ # When using multiple platforms
+ # s.ios.deployment_target = "5.0"
+ # s.osx.deployment_target = "10.7"
+ # s.watchos.deployment_target = "2.0"
+ # s.tvos.deployment_target = "9.0"
+
+
+ # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
+ #
+ # Specify the location from where the source should be retrieved.
+ # Supports git, hg, bzr, svn and HTTP.
+ #
+
+ s.source = { :git => "http://EXAMPLE/olm.git", :tag => "0.0.1" }
+
+
+ # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
+ #
+ # CocoaPods is smart about how it includes source code. For source files
+ # giving a folder will include any swift, h, m, mm, c & cpp files.
+ # For header files it will include any header in the folder.
+ # Not including the public_header_files will make all headers public.
+ #
+
+ s.source_files = ["include/olm/*.hh","src/*.cpp"]
+ s.public_header_files = "include/olm/olm.hh"
+
+ s.library = "c++"
+ s.xcconfig = { 'HEADER_SEARCH_PATHS' => '$(PODS_ROOT)/olm/include $(PODS_ROOT)/olm/lib $(PODS_ROOT)/../../include $(PODS_ROOT)/../../lib' }
+end
diff --git a/xcode/OLMKit/Info.plist b/xcode/OLMKit/Info.plist
new file mode 100644
index 0000000..d3de8ee
--- /dev/null
+++ b/xcode/OLMKit/Info.plist
@@ -0,0 +1,26 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ $(CURRENT_PROJECT_VERSION)
+ NSPrincipalClass
+
+
+
diff --git a/xcode/OLMKit/OLMAccount.h b/xcode/OLMKit/OLMAccount.h
new file mode 100644
index 0000000..a2923f9
--- /dev/null
+++ b/xcode/OLMKit/OLMAccount.h
@@ -0,0 +1,41 @@
+//
+// OLMAccount.h
+// olm
+//
+// Created by Chris Ballinger on 4/8/16.
+//
+//
+
+#import
+#import "OLMSerializable.h"
+
+@class OLMSession;
+
+@interface OLMAccount : NSObject
+
+/** Creates new account */
+- (instancetype) initNewAccount;
+
+/** public identity keys. base64 encoded in "curve25519" and "ed25519" keys */
+- (NSDictionary*) identityKeys;
+
+/** signs message with ed25519 key for account */
+- (NSString*) signMessage:(NSData*)messageData;
+
+/** Public parts of the unpublished one time keys for the account */
+- (NSDictionary*) oneTimeKeys;
+
+- (BOOL) removeOneTimeKeysForSession:(OLMSession*)session;
+
+/** Marks the current set of one time keys as being published. */
+- (void) markKeysAsPublished;
+
+/** The largest number of one time keys this account can store. */
+- (NSUInteger) maxOneTimeKeys;
+
+/** Generates a number of new one time keys. If the total number of keys stored
+ * by this account exceeds -maxOneTimeKeys then the old keys are
+ * discarded. */
+- (void) generateOneTimeKeys:(NSUInteger)numberOfKeys;
+
+@end
diff --git a/xcode/OLMKit/OLMAccount.m b/xcode/OLMKit/OLMAccount.m
new file mode 100644
index 0000000..4561a37
--- /dev/null
+++ b/xcode/OLMKit/OLMAccount.m
@@ -0,0 +1,229 @@
+//
+// OLMAccount.m
+// olm
+//
+// Created by Chris Ballinger on 4/8/16.
+//
+//
+
+#import "OLMAccount.h"
+#import "OLMAccount_Private.h"
+#import "OLMSession.h"
+#import "OLMSession_Private.h"
+#import "OLMUtility.h"
+
+@import Security;
+
+@implementation OLMAccount
+
+- (void) dealloc {
+ olm_clear_account(_account);
+ free(_account);
+}
+
+- (BOOL) initializeAccountMemory {
+ size_t accountSize = olm_account_size();
+ _account = malloc(accountSize);
+ NSParameterAssert(_account != nil);
+ if (!_account) {
+ return NO;
+ }
+ _account = olm_account(_account);
+ NSParameterAssert(_account != nil);
+ if (!_account) {
+ return NO;
+ }
+ return YES;
+}
+
+- (instancetype) init {
+ self = [super init];
+ if (!self) {
+ return nil;
+ }
+ BOOL success = [self initializeAccountMemory];
+ if (!success) {
+ return nil;
+ }
+ return self;
+}
+
+- (instancetype) initNewAccount {
+ self = [self init];
+ if (!self) {
+ return nil;
+ }
+ size_t randomLength = olm_create_account_random_length(_account);
+ NSMutableData *random = [OLMUtility randomBytesOfLength:randomLength];
+ size_t accountResult = olm_create_account(_account, random.mutableBytes, random.length);
+ if (accountResult == olm_error()) {
+ const char *error = olm_account_last_error(_account);
+ NSLog(@"error creating account: %s", error);
+ return nil;
+ }
+ return self;
+}
+
+- (size_t) maxOneTimeKeys {
+ return olm_account_max_number_of_one_time_keys(_account);
+}
+
+
+/** public identity keys */
+- (NSDictionary*) identityKeys {
+ size_t identityKeysLength = olm_account_identity_keys_length(_account);
+ uint8_t *identityKeysBytes = malloc(identityKeysLength);
+ if (!identityKeysBytes) {
+ return nil;
+ }
+ size_t result = olm_account_identity_keys(_account, identityKeysBytes, identityKeysLength);
+ if (result == olm_error()) {
+ const char *error = olm_account_last_error(_account);
+ NSLog(@"error getting id keys: %s", error);
+ free(identityKeysBytes);
+ return nil;
+ }
+ NSData *idKeyData = [NSData dataWithBytesNoCopy:identityKeysBytes length:identityKeysLength freeWhenDone:YES];
+ NSError *error = nil;
+ NSDictionary *keysDictionary = [NSJSONSerialization JSONObjectWithData:idKeyData options:0 error:&error];
+ if (error) {
+ NSLog(@"Could not decode JSON: %@", error.localizedDescription);
+ }
+ return keysDictionary;
+}
+
+- (NSDictionary*) oneTimeKeys {
+ size_t otkLength = olm_account_one_time_keys_length(_account);
+ uint8_t *otkBytes = malloc(otkLength);
+ if (!otkBytes) {
+ return nil;
+ }
+ size_t result = olm_account_one_time_keys(_account, otkBytes, otkLength);
+ if (result == olm_error()) {
+ const char *error = olm_account_last_error(_account);
+ NSLog(@"error getting id keys: %s", error);
+ free(otkBytes);
+ }
+ NSData *otk = [NSData dataWithBytesNoCopy:otkBytes length:otkLength freeWhenDone:YES];
+ NSError *error = nil;
+ NSDictionary *keysDictionary = [NSJSONSerialization JSONObjectWithData:otk options:0 error:&error];
+ if (error) {
+ NSLog(@"Could not decode JSON: %@", error.localizedDescription);
+ }
+ return keysDictionary;
+}
+
+
+- (void) generateOneTimeKeys:(NSUInteger)numberOfKeys {
+ size_t randomLength = olm_account_generate_one_time_keys_random_length(_account, numberOfKeys);
+ NSMutableData *random = [OLMUtility randomBytesOfLength:randomLength];
+ size_t result = olm_account_generate_one_time_keys(_account, numberOfKeys, random.mutableBytes, random.length);
+ if (result == olm_error()) {
+ const char *error = olm_account_last_error(_account);
+ NSLog(@"error generating keys: %s", error);
+ }
+}
+
+- (BOOL) removeOneTimeKeysForSession:(OLMSession *)session {
+ NSParameterAssert(session != nil);
+ if (!session) {
+ return nil;
+ }
+ size_t result = olm_remove_one_time_keys(self.account, session.session);
+ if (result == olm_error()) {
+ const char *error = olm_session_last_error(session.session);
+ NSAssert(NO, @"olm_remove_one_time_keys error: %s", error);
+ return NO;
+ }
+ return YES;
+}
+
+#pragma mark OLMSerializable
+
+/** Initializes from encrypted serialized data. Will throw error if invalid key or invalid base64. */
+- (instancetype) initWithSerializedData:(NSString*)serializedData key:(NSData*)key error:(NSError**)error {
+ self = [self init];
+ if (!self) {
+ return nil;
+ }
+ NSParameterAssert(key.length > 0);
+ NSParameterAssert(serializedData.length > 0);
+ if (key.length == 0 || serializedData.length == 0) {
+ if (error) {
+ *error = [NSError errorWithDomain:@"org.matrix.olm" code:0 userInfo:@{NSLocalizedDescriptionKey: @"Bad length."}];
+ }
+ return nil;
+ }
+ NSMutableData *pickle = [serializedData dataUsingEncoding:NSUTF8StringEncoding].mutableCopy;
+ size_t result = olm_unpickle_account(_account, key.bytes, key.length, pickle.mutableBytes, pickle.length);
+ if (result == olm_error()) {
+ const char *olm_error = olm_account_last_error(_account);
+ NSString *errorString = [NSString stringWithUTF8String:olm_error];
+ if (error && errorString) {
+ *error = [NSError errorWithDomain:@"org.matrix.olm" code:0 userInfo:@{NSLocalizedDescriptionKey: errorString}];
+ }
+ return nil;
+ }
+ return self;
+}
+
+/** Serializes and encrypts object data, outputs base64 blob */
+- (NSString*) serializeDataWithKey:(NSData*)key error:(NSError**)error {
+ NSParameterAssert(key.length > 0);
+ size_t length = olm_pickle_account_length(_account);
+ NSMutableData *pickled = [NSMutableData dataWithLength:length];
+ size_t result = olm_pickle_account(_account, key.bytes, key.length, pickled.mutableBytes, pickled.length);
+ if (result == olm_error()) {
+ const char *olm_error = olm_account_last_error(_account);
+ NSString *errorString = [NSString stringWithUTF8String:olm_error];
+ if (error && errorString) {
+ *error = [NSError errorWithDomain:@"org.matrix.olm" code:0 userInfo:@{NSLocalizedDescriptionKey: errorString}];
+ }
+ return nil;
+ }
+ NSString *pickleString = [[NSString alloc] initWithData:pickled encoding:NSUTF8StringEncoding];
+ return pickleString;
+}
+
+#pragma mark NSSecureCoding
+
++ (BOOL) supportsSecureCoding {
+ return YES;
+}
+
+#pragma mark NSCoding
+
+- (id)initWithCoder:(NSCoder *)decoder {
+ NSString *version = [decoder decodeObjectOfClass:[NSString class] forKey:@"version"];
+
+ NSError *error = nil;
+
+ if ([version isEqualToString:@"1"]) {
+ NSString *pickle = [decoder decodeObjectOfClass:[NSString class] forKey:@"pickle"];
+ NSData *key = [decoder decodeObjectOfClass:[NSData class] forKey:@"key"];
+
+ self = [self initWithSerializedData:pickle key:key error:&error];
+ }
+
+ NSParameterAssert(error == nil);
+ NSParameterAssert(self != nil);
+ if (!self) {
+ return nil;
+ }
+
+ return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)encoder {
+ NSData *key = [OLMUtility randomBytesOfLength:32];
+ NSError *error = nil;
+ NSString *pickle = [self serializeDataWithKey:key error:&error];
+ NSParameterAssert(pickle.length > 0 && error == nil);
+
+ [encoder encodeObject:pickle forKey:@"pickle"];
+ [encoder encodeObject:key forKey:@"key"];
+ [encoder encodeObject:@"1" forKey:@"version"];
+}
+
+
+@end
diff --git a/xcode/OLMKit/OLMAccount_Private.h b/xcode/OLMKit/OLMAccount_Private.h
new file mode 100644
index 0000000..4eb3e2b
--- /dev/null
+++ b/xcode/OLMKit/OLMAccount_Private.h
@@ -0,0 +1,15 @@
+//
+// OLMAccount_Private.h
+// olm
+//
+// Created by Chris Ballinger on 4/8/16.
+//
+//
+
+@import olm;
+
+@interface OLMAccount()
+
+@property (nonatomic) OlmAccount *account;
+
+@end
\ No newline at end of file
diff --git a/xcode/OLMKit/OLMKit.h b/xcode/OLMKit/OLMKit.h
new file mode 100644
index 0000000..745af43
--- /dev/null
+++ b/xcode/OLMKit/OLMKit.h
@@ -0,0 +1,23 @@
+//
+// OLMKit.h
+// OLMKit
+//
+// Created by Chris Ballinger on 4/8/16.
+//
+//
+
+#import
+
+//! Project version number for OLMKit.
+FOUNDATION_EXPORT double OLMKitVersionNumber;
+
+//! Project version string for OLMKit.
+FOUNDATION_EXPORT const unsigned char OLMKitVersionString[];
+
+// In this header, you should import all the public headers of your framework using statements like #import
+
+
+#import "OLMAccount.h"
+#import "OLMSession.h"
+#import "OLMMessage.h"
+#import "OLMUtility.h"
\ No newline at end of file
diff --git a/xcode/OLMKit/OLMMessage.h b/xcode/OLMKit/OLMMessage.h
new file mode 100644
index 0000000..97c748f
--- /dev/null
+++ b/xcode/OLMKit/OLMMessage.h
@@ -0,0 +1,28 @@
+//
+// OLMMessage.h
+// olm
+//
+// Created by Chris Ballinger on 4/8/16.
+//
+//
+
+#import
+
+/*
+ from olm.hh
+ static const size_t OLM_MESSAGE_TYPE_PRE_KEY = 0;
+ static const size_t OLM_MESSAGE_TYPE_MESSAGE = 1;
+ */
+typedef NS_ENUM(NSInteger, OLMMessageType) {
+ OLMMessageTypePreKey = 0,
+ OLMMessageTypeMessage = 1
+};
+
+@interface OLMMessage : NSObject
+
+@property (nonatomic, copy, readonly, nonnull) NSString *ciphertext;
+@property (readonly) OLMMessageType type;
+
+- (nullable instancetype) initWithCiphertext:(nonnull NSString*)ciphertext type:(OLMMessageType)type;
+
+@end
diff --git a/xcode/OLMKit/OLMMessage.m b/xcode/OLMKit/OLMMessage.m
new file mode 100644
index 0000000..d0cfb41
--- /dev/null
+++ b/xcode/OLMKit/OLMMessage.m
@@ -0,0 +1,24 @@
+//
+// OLMMessage.m
+// olm
+//
+// Created by Chris Ballinger on 4/8/16.
+//
+//
+
+#import "OLMMessage.h"
+
+@implementation OLMMessage
+
+- (nullable instancetype) initWithCiphertext:(nonnull NSString*)ciphertext type:(OLMMessageType)type {
+ NSParameterAssert(ciphertext != nil);
+ self = [super init];
+ if (!self) {
+ return nil;
+ }
+ _ciphertext = [ciphertext copy];
+ _type = type;
+ return self;
+}
+
+@end
diff --git a/xcode/OLMKit/OLMSerializable.h b/xcode/OLMKit/OLMSerializable.h
new file mode 100644
index 0000000..b4b115a
--- /dev/null
+++ b/xcode/OLMKit/OLMSerializable.h
@@ -0,0 +1,19 @@
+//
+// OLMSerializable.h
+// olm
+//
+// Created by Chris Ballinger on 4/8/16.
+//
+//
+
+#import
+
+@protocol OLMSerializable
+
+/** Initializes from encrypted serialized data. Will throw error if invalid key or invalid base64. */
+- (instancetype) initWithSerializedData:(NSString*)serializedData key:(NSData*)key error:(NSError**)error;
+
+/** Serializes and encrypts object data, outputs base64 blob */
+- (NSString*) serializeDataWithKey:(NSData*)key error:(NSError**)error;
+
+@end
diff --git a/xcode/OLMKit/OLMSession.h b/xcode/OLMKit/OLMSession.h
new file mode 100644
index 0000000..c209564
--- /dev/null
+++ b/xcode/OLMKit/OLMSession.h
@@ -0,0 +1,34 @@
+//
+// OLMSession.h
+// olm
+//
+// Created by Chris Ballinger on 4/8/16.
+//
+//
+
+#import
+#import "OLMSerializable.h"
+#import "OLMAccount.h"
+#import "OLMMessage.h"
+
+@interface OLMSession : NSObject
+
+- (instancetype) initOutboundSessionWithAccount:(OLMAccount*)account theirIdentityKey:(NSString*)theirIdentityKey theirOneTimeKey:(NSString*)theirOneTimeKey;
+
+- (instancetype) initInboundSessionWithAccount:(OLMAccount*)account oneTimeKeyMessage:(NSString*)oneTimeKeyMessage;
+
+- (instancetype) initInboundSessionWithAccount:(OLMAccount*)account theirIdentityKey:(NSString*)theirIdentityKey oneTimeKeyMessage:(NSString*)oneTimeKeyMessage;
+
+- (NSString*) sessionIdentifier;
+
+- (BOOL) matchesInboundSession:(NSString*)oneTimeKeyMessage;
+
+- (BOOL) matchesInboundSessionFrom:(NSString*)theirIdentityKey oneTimeKeyMessage:(NSString *)oneTimeKeyMessage;
+
+/** UTF-8 plaintext -> base64 ciphertext */
+- (OLMMessage*) encryptMessage:(NSString*)message;
+
+/** base64 ciphertext -> UTF-8 plaintext */
+- (NSString*) decryptMessage:(OLMMessage*)message;
+
+@end
diff --git a/xcode/OLMKit/OLMSession.m b/xcode/OLMKit/OLMSession.m
new file mode 100644
index 0000000..119079f
--- /dev/null
+++ b/xcode/OLMKit/OLMSession.m
@@ -0,0 +1,261 @@
+//
+// OLMSession.m
+// olm
+//
+// Created by Chris Ballinger on 4/8/16.
+//
+//
+
+#import "OLMSession.h"
+#import "OLMUtility.h"
+#import "OLMAccount_Private.h"
+#import "OLMSession_Private.h"
+@import olm;
+
+@implementation OLMSession
+
+- (void) dealloc {
+ olm_clear_session(_session);
+ free(_session);
+}
+
+- (BOOL) initializeSessionMemory {
+ size_t size = olm_session_size();
+ _session = malloc(size);
+ NSParameterAssert(_session != nil);
+ if (!_session) {
+ return NO;
+ }
+ _session = olm_session(_session);
+ NSParameterAssert(_session != nil);
+ if (!_session) {
+ return NO;
+ }
+ return YES;
+}
+
+- (instancetype) init {
+ self = [super init];
+ if (!self) {
+ return nil;
+ }
+ BOOL success = [self initializeSessionMemory];
+ if (!success) {
+ return nil;
+ }
+ return self;
+}
+
+- (instancetype) initWithAccount:(OLMAccount*)account {
+ self = [self init];
+ if (!self) {
+ return nil;
+ }
+ NSParameterAssert(account != nil && account.account != NULL);
+ if (account == nil || account.account == NULL) {
+ return nil;
+ }
+ _account = account;
+ return self;
+}
+
+- (instancetype) initOutboundSessionWithAccount:(OLMAccount*)account theirIdentityKey:(NSString*)theirIdentityKey theirOneTimeKey:(NSString*)theirOneTimeKey {
+ self = [self initWithAccount:account];
+ if (!self) {
+ return nil;
+ }
+ NSMutableData *random = [OLMUtility randomBytesOfLength:olm_create_outbound_session_random_length(_session)];
+ NSData *idKey = [theirIdentityKey dataUsingEncoding:NSUTF8StringEncoding];
+ NSData *otKey = [theirOneTimeKey dataUsingEncoding:NSUTF8StringEncoding];
+ size_t result = olm_create_outbound_session(_session, account.account, idKey.bytes, idKey.length, otKey.bytes, otKey.length, random.mutableBytes, random.length);
+ if (result == olm_error()) {
+ const char *error = olm_session_last_error(_session);
+ NSAssert(NO, @"olm_create_outbound_session error: %s", error);
+ return nil;
+ }
+ return self;
+}
+
+- (instancetype) initInboundSessionWithAccount:(OLMAccount*)account oneTimeKeyMessage:(NSString*)oneTimeKeyMessage {
+ self = [self initWithAccount:account];
+ if (!self) {
+ return nil;
+ }
+ NSMutableData *otk = [NSMutableData dataWithData:[oneTimeKeyMessage dataUsingEncoding:NSUTF8StringEncoding]];
+ size_t result = olm_create_inbound_session(_session, account.account, otk.mutableBytes, oneTimeKeyMessage.length);
+ if (result == olm_error()) {
+ const char *error = olm_session_last_error(_session);
+ NSAssert(NO, @"olm_create_inbound_session error: %s", error);
+ return nil;
+ }
+ return self;
+}
+
+- (instancetype) initInboundSessionWithAccount:(OLMAccount*)account theirIdentityKey:(NSString*)theirIdentityKey oneTimeKeyMessage:(NSString*)oneTimeKeyMessage {
+ self = [self initWithAccount:account];
+ if (!self) {
+ return nil;
+ }
+ NSData *idKey = [theirIdentityKey dataUsingEncoding:NSUTF8StringEncoding];
+ NSMutableData *otk = [NSMutableData dataWithData:[oneTimeKeyMessage dataUsingEncoding:NSUTF8StringEncoding]];
+ size_t result = olm_create_inbound_session_from(_session, account.account, idKey.bytes, idKey.length, otk.mutableBytes, otk.length);
+ if (result == olm_error()) {
+ const char *error = olm_session_last_error(_session);
+ NSAssert(NO, @"olm_create_inbound_session_from error: %s", error);
+ return nil;
+ }
+ return self;
+}
+
+- (NSString*) sessionIdentifier {
+ size_t length = olm_session_id_length(_session);
+ NSMutableData *idData = [NSMutableData dataWithLength:length];
+ if (!idData) {
+ return nil;
+ }
+ size_t result = olm_session_id(_session, idData.mutableBytes, idData.length);
+ if (result == olm_error()) {
+ const char *error = olm_session_last_error(_session);
+ NSAssert(NO, @"olm_session_id error: %s", error);
+ return nil;
+ }
+ NSString *idString = [[NSString alloc] initWithData:idData encoding:NSUTF8StringEncoding];
+ return idString;
+}
+
+- (OLMMessage*) encryptMessage:(NSString*)message {
+ size_t messageType = olm_encrypt_message_type(_session);
+ size_t randomLength = olm_encrypt_random_length(_session);
+ NSMutableData *random = [OLMUtility randomBytesOfLength:randomLength];
+ NSData *plaintextData = [message dataUsingEncoding:NSUTF8StringEncoding];
+ size_t ciphertextLength = olm_encrypt_message_length(_session, plaintextData.length);
+ NSMutableData *ciphertext = [NSMutableData dataWithLength:ciphertextLength];
+ if (!ciphertext) {
+ return nil;
+ }
+ size_t result = olm_encrypt(_session, plaintextData.bytes, plaintextData.length, random.mutableBytes, random.length, ciphertext.mutableBytes, ciphertext.length);
+ if (result == olm_error()) {
+ const char *error = olm_session_last_error(_session);
+ NSAssert(NO, @"olm_encrypt error: %s", error);
+ return nil;
+ }
+ NSString *ciphertextString = [[NSString alloc] initWithData:ciphertext encoding:NSUTF8StringEncoding];
+ OLMMessage *encryptedMessage = [[OLMMessage alloc] initWithCiphertext:ciphertextString type:messageType];
+ return encryptedMessage;
+}
+
+- (NSString*) decryptMessage:(OLMMessage*)message {
+ NSParameterAssert(message != nil);
+ NSData *messageData = [message.ciphertext dataUsingEncoding:NSUTF8StringEncoding];
+ if (!messageData) {
+ return nil;
+ }
+ NSMutableData *mutMessage = messageData.mutableCopy;
+ size_t maxPlaintextLength = olm_decrypt_max_plaintext_length(_session, message.type, mutMessage.mutableBytes, mutMessage.length);
+ if (maxPlaintextLength == olm_error()) {
+ const char *error = olm_session_last_error(_session);
+ NSAssert(NO, @"olm_decrypt_max_plaintext_length error: %s", error);
+ return nil;
+ }
+ // message buffer is destroyed by olm_decrypt_max_plaintext_length
+ mutMessage = messageData.mutableCopy;
+ NSMutableData *plaintextData = [NSMutableData dataWithLength:maxPlaintextLength];
+ size_t plaintextLength = olm_decrypt(_session, message.type, mutMessage.mutableBytes, mutMessage.length, plaintextData.mutableBytes, plaintextData.length);
+ if (plaintextLength == olm_error()) {
+ const char *error = olm_session_last_error(_session);
+ NSAssert(NO, @"olm_decrypt error: %s", error);
+ return nil;
+ }
+ plaintextData.length = plaintextLength;
+ NSString *plaintext = [[NSString alloc] initWithData:plaintextData encoding:NSUTF8StringEncoding];
+ return plaintext;
+}
+
+#pragma mark OLMSerializable
+
+/** Initializes from encrypted serialized data. Will throw error if invalid key or invalid base64. */
+- (instancetype) initWithSerializedData:(NSString*)serializedData key:(NSData*)key error:(NSError**)error {
+ self = [self init];
+ if (!self) {
+ return nil;
+ }
+ NSParameterAssert(key.length > 0);
+ NSParameterAssert(serializedData.length > 0);
+ if (key.length == 0 || serializedData.length == 0) {
+ if (error) {
+ *error = [NSError errorWithDomain:@"org.matrix.olm" code:0 userInfo:@{NSLocalizedDescriptionKey: @"Bad length."}];
+ }
+ return nil;
+ }
+ NSMutableData *pickle = [serializedData dataUsingEncoding:NSUTF8StringEncoding].mutableCopy;
+ size_t result = olm_unpickle_session(_session, key.bytes, key.length, pickle.mutableBytes, pickle.length);
+ if (result == olm_error()) {
+ const char *olm_error = olm_session_last_error(_session);
+ NSString *errorString = [NSString stringWithUTF8String:olm_error];
+ if (error && errorString) {
+ *error = [NSError errorWithDomain:@"org.matrix.olm" code:0 userInfo:@{NSLocalizedDescriptionKey: errorString}];
+ }
+ return nil;
+ }
+ return self;
+}
+
+/** Serializes and encrypts object data, outputs base64 blob */
+- (NSString*) serializeDataWithKey:(NSData*)key error:(NSError**)error {
+ NSParameterAssert(key.length > 0);
+ size_t length = olm_pickle_session_length(_session);
+ NSMutableData *pickled = [NSMutableData dataWithLength:length];
+ size_t result = olm_pickle_session(_session, key.bytes, key.length, pickled.mutableBytes, pickled.length);
+ if (result == olm_error()) {
+ const char *olm_error = olm_session_last_error(_session);
+ NSString *errorString = [NSString stringWithUTF8String:olm_error];
+ if (error && errorString) {
+ *error = [NSError errorWithDomain:@"org.matrix.olm" code:0 userInfo:@{NSLocalizedDescriptionKey: errorString}];
+ }
+ return nil;
+ }
+ NSString *pickleString = [[NSString alloc] initWithData:pickled encoding:NSUTF8StringEncoding];
+ return pickleString;
+}
+
+#pragma mark NSSecureCoding
+
++ (BOOL) supportsSecureCoding {
+ return YES;
+}
+
+#pragma mark NSCoding
+
+- (id)initWithCoder:(NSCoder *)decoder {
+ NSString *version = [decoder decodeObjectOfClass:[NSString class] forKey:@"version"];
+
+ NSError *error = nil;
+
+ if ([version isEqualToString:@"1"]) {
+ NSString *pickle = [decoder decodeObjectOfClass:[NSString class] forKey:@"pickle"];
+ NSData *key = [decoder decodeObjectOfClass:[NSData class] forKey:@"key"];
+
+ self = [self initWithSerializedData:pickle key:key error:&error];
+ }
+
+ NSParameterAssert(error == nil);
+ NSParameterAssert(self != nil);
+ if (!self) {
+ return nil;
+ }
+
+ return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)encoder {
+ NSData *key = [OLMUtility randomBytesOfLength:32];
+ NSError *error = nil;
+ NSString *pickle = [self serializeDataWithKey:key error:&error];
+ NSParameterAssert(pickle.length > 0 && error == nil);
+
+ [encoder encodeObject:pickle forKey:@"pickle"];
+ [encoder encodeObject:key forKey:@"key"];
+ [encoder encodeObject:@"1" forKey:@"version"];
+}
+
+@end
diff --git a/xcode/OLMKit/OLMSession_Private.h b/xcode/OLMKit/OLMSession_Private.h
new file mode 100644
index 0000000..d906b14
--- /dev/null
+++ b/xcode/OLMKit/OLMSession_Private.h
@@ -0,0 +1,16 @@
+//
+// OLMSession_Private.h
+// olm
+//
+// Created by Chris Ballinger on 4/13/16.
+//
+//
+
+@import olm;
+
+@interface OLMSession()
+
+@property (nonatomic) OlmSession *session;
+@property (nonatomic, strong) OLMAccount *account;
+
+@end
\ No newline at end of file
diff --git a/xcode/OLMKit/OLMUtility.h b/xcode/OLMKit/OLMUtility.h
new file mode 100644
index 0000000..8acbf40
--- /dev/null
+++ b/xcode/OLMKit/OLMUtility.h
@@ -0,0 +1,15 @@
+//
+// OLMUtility.h
+// olm
+//
+// Created by Chris Ballinger on 4/8/16.
+//
+//
+
+#import
+
+@interface OLMUtility : NSObject
+
++ (NSMutableData*) randomBytesOfLength:(NSUInteger)length;
+
+@end
diff --git a/xcode/OLMKit/OLMUtility.m b/xcode/OLMKit/OLMUtility.m
new file mode 100644
index 0000000..5dbe644
--- /dev/null
+++ b/xcode/OLMKit/OLMUtility.m
@@ -0,0 +1,25 @@
+//
+// OLMUtility.m
+// olm
+//
+// Created by Chris Ballinger on 4/8/16.
+//
+//
+
+#import "OLMUtility.h"
+
+@implementation OLMUtility
+
++ (NSMutableData*) randomBytesOfLength:(NSUInteger)length {
+ NSMutableData *randomData = [NSMutableData dataWithLength:length];
+ if (!randomData) {
+ return nil;
+ }
+ int result = SecRandomCopyBytes(kSecRandomDefault, randomData.length, randomData.mutableBytes);
+ if (result != 0) {
+ return nil;
+ }
+ return randomData;
+}
+
+@end
diff --git a/xcode/OLMKitTests/Info.plist b/xcode/OLMKitTests/Info.plist
new file mode 100644
index 0000000..ba72822
--- /dev/null
+++ b/xcode/OLMKitTests/Info.plist
@@ -0,0 +1,24 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ BNDL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+
+
diff --git a/xcode/OLMKitTests/OLMKitTests.m b/xcode/OLMKitTests/OLMKitTests.m
new file mode 100644
index 0000000..c76d636
--- /dev/null
+++ b/xcode/OLMKitTests/OLMKitTests.m
@@ -0,0 +1,161 @@
+//
+// OLMKitTests.m
+// OLMKitTests
+//
+// Created by Chris Ballinger on 4/8/16.
+//
+//
+
+#import
+@import OLMKit;
+
+@interface OLMKitTests : XCTestCase
+
+@end
+
+@implementation OLMKitTests
+
+- (void)setUp {
+ [super setUp];
+ // Put setup code here. This method is called before the invocation of each test method in the class.
+}
+
+- (void)tearDown {
+ // Put teardown code here. This method is called after the invocation of each test method in the class.
+ [super tearDown];
+}
+
+- (void)testAliceAndBob {
+ OLMAccount *alice = [[OLMAccount alloc] initNewAccount];
+ OLMAccount *bob = [[OLMAccount alloc] initNewAccount];
+ [bob generateOneTimeKeys:5];
+ NSDictionary *bobIdKeys = bob.identityKeys;
+ NSString *bobIdKey = bobIdKeys[@"curve25519"];
+ NSDictionary *bobOneTimeKeys = bob.oneTimeKeys;
+ NSParameterAssert(bobIdKey != nil);
+ NSParameterAssert(bobOneTimeKeys != nil);
+ __block NSString *bobOneTimeKey = nil;
+ NSDictionary *bobOtkCurve25519 = bobOneTimeKeys[@"curve25519"];
+ [bobOtkCurve25519 enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
+ bobOneTimeKey = obj;
+ }];
+ XCTAssert([bobOneTimeKey isKindOfClass:[NSString class]]);
+
+ OLMSession *aliceSession = [[OLMSession alloc] initOutboundSessionWithAccount:alice theirIdentityKey:bobIdKey theirOneTimeKey:bobOneTimeKey];
+ NSString *message = @"Hello!";
+ OLMMessage *aliceToBobMsg = [aliceSession encryptMessage:message];
+
+ OLMSession *bobSession = [[OLMSession alloc] initInboundSessionWithAccount:bob oneTimeKeyMessage:aliceToBobMsg.ciphertext];
+ NSString *plaintext = [bobSession decryptMessage:aliceToBobMsg];
+ XCTAssertEqualObjects(message, plaintext);
+ BOOL success = [bob removeOneTimeKeysForSession:bobSession];
+ XCTAssertTrue(success);
+}
+
+- (void) testBackAndForth {
+ OLMAccount *alice = [[OLMAccount alloc] initNewAccount];
+ OLMAccount *bob = [[OLMAccount alloc] initNewAccount];
+ [bob generateOneTimeKeys:1];
+ NSDictionary *bobIdKeys = bob.identityKeys;
+ NSString *bobIdKey = bobIdKeys[@"curve25519"];
+ NSDictionary *bobOneTimeKeys = bob.oneTimeKeys;
+ NSParameterAssert(bobIdKey != nil);
+ NSParameterAssert(bobOneTimeKeys != nil);
+ __block NSString *bobOneTimeKey = nil;
+ NSDictionary *bobOtkCurve25519 = bobOneTimeKeys[@"curve25519"];
+ [bobOtkCurve25519 enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
+ bobOneTimeKey = obj;
+ }];
+ XCTAssert([bobOneTimeKey isKindOfClass:[NSString class]]);
+
+ OLMSession *aliceSession = [[OLMSession alloc] initOutboundSessionWithAccount:alice theirIdentityKey:bobIdKey theirOneTimeKey:bobOneTimeKey];
+ NSString *message = @"Hello I'm Alice!";
+ OLMMessage *aliceToBobMsg = [aliceSession encryptMessage:message];
+
+ OLMSession *bobSession = [[OLMSession alloc] initInboundSessionWithAccount:bob oneTimeKeyMessage:aliceToBobMsg.ciphertext];
+ NSString *plaintext = [bobSession decryptMessage:aliceToBobMsg];
+ XCTAssertEqualObjects(message, plaintext);
+ BOOL success = [bob removeOneTimeKeysForSession:bobSession];
+ XCTAssertTrue(success);
+
+ NSString *msg1 = @"Hello I'm Bob!";
+ NSString *msg2 = @"Isn't life grand?";
+ NSString *msg3 = @"Let's go to the opera.";
+
+ OLMMessage *eMsg1 = [bobSession encryptMessage:msg1];
+ OLMMessage *eMsg2 = [bobSession encryptMessage:msg2];
+ OLMMessage *eMsg3 = [bobSession encryptMessage:msg3];
+
+ NSString *dMsg1 = [aliceSession decryptMessage:eMsg1];
+ NSString *dMsg2 = [aliceSession decryptMessage:eMsg2];
+ NSString *dMsg3 = [aliceSession decryptMessage:eMsg3];
+ XCTAssertEqualObjects(msg1, dMsg1);
+ XCTAssertEqualObjects(msg2, dMsg2);
+ XCTAssertEqualObjects(msg3, dMsg3);
+
+
+}
+
+- (void) testAccountSerialization {
+ OLMAccount *bob = [[OLMAccount alloc] initNewAccount];
+ [bob generateOneTimeKeys:5];
+ NSDictionary *bobIdKeys = bob.identityKeys;
+ NSDictionary *bobOneTimeKeys = bob.oneTimeKeys;
+
+ NSData *bobData = [NSKeyedArchiver archivedDataWithRootObject:bob];
+
+ OLMAccount *bob2 = [NSKeyedUnarchiver unarchiveObjectWithData:bobData];
+ NSDictionary *bobIdKeys2 = bob2.identityKeys;
+ NSDictionary *bobOneTimeKeys2 = bob.oneTimeKeys;
+
+ XCTAssertEqualObjects(bobIdKeys, bobIdKeys2);
+ XCTAssertEqualObjects(bobOneTimeKeys, bobOneTimeKeys2);
+}
+
+- (void) testSessionSerialization {
+ OLMAccount *alice = [[OLMAccount alloc] initNewAccount];
+ OLMAccount *bob = [[OLMAccount alloc] initNewAccount];
+ [bob generateOneTimeKeys:1];
+ NSDictionary *bobIdKeys = bob.identityKeys;
+ NSString *bobIdKey = bobIdKeys[@"curve25519"];
+ NSDictionary *bobOneTimeKeys = bob.oneTimeKeys;
+ NSParameterAssert(bobIdKey != nil);
+ NSParameterAssert(bobOneTimeKeys != nil);
+ __block NSString *bobOneTimeKey = nil;
+ NSDictionary *bobOtkCurve25519 = bobOneTimeKeys[@"curve25519"];
+ [bobOtkCurve25519 enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
+ bobOneTimeKey = obj;
+ }];
+ XCTAssert([bobOneTimeKey isKindOfClass:[NSString class]]);
+
+ OLMSession *aliceSession = [[OLMSession alloc] initOutboundSessionWithAccount:alice theirIdentityKey:bobIdKey theirOneTimeKey:bobOneTimeKey];
+ NSString *message = @"Hello I'm Alice!";
+ OLMMessage *aliceToBobMsg = [aliceSession encryptMessage:message];
+
+ OLMSession *bobSession = [[OLMSession alloc] initInboundSessionWithAccount:bob oneTimeKeyMessage:aliceToBobMsg.ciphertext];
+ NSString *plaintext = [bobSession decryptMessage:aliceToBobMsg];
+ XCTAssertEqualObjects(message, plaintext);
+ BOOL success = [bob removeOneTimeKeysForSession:bobSession];
+ XCTAssertTrue(success);
+
+ NSString *msg1 = @"Hello I'm Bob!";
+ NSString *msg2 = @"Isn't life grand?";
+ NSString *msg3 = @"Let's go to the opera.";
+
+ OLMMessage *eMsg1 = [bobSession encryptMessage:msg1];
+ OLMMessage *eMsg2 = [bobSession encryptMessage:msg2];
+ OLMMessage *eMsg3 = [bobSession encryptMessage:msg3];
+
+ NSData *aliceData = [NSKeyedArchiver archivedDataWithRootObject:aliceSession];
+ OLMSession *alice2 = [NSKeyedUnarchiver unarchiveObjectWithData:aliceData];
+
+ NSString *dMsg1 = [alice2 decryptMessage:eMsg1];
+ NSString *dMsg2 = [alice2 decryptMessage:eMsg2];
+ NSString *dMsg3 = [alice2 decryptMessage:eMsg3];
+ XCTAssertEqualObjects(msg1, dMsg1);
+ XCTAssertEqualObjects(msg2, dMsg2);
+ XCTAssertEqualObjects(msg3, dMsg3);
+}
+
+
+@end
diff --git a/xcode/Podfile b/xcode/Podfile
new file mode 100644
index 0000000..7bd8189
--- /dev/null
+++ b/xcode/Podfile
@@ -0,0 +1,6 @@
+# Uncomment this line to define a global platform for your project
+platform :ios, '8.0'
+# Uncomment this line if you're using Swift
+use_frameworks!
+
+pod 'olm', :path => '../olm.podspec'
\ No newline at end of file
diff --git a/xcode/Podfile.lock b/xcode/Podfile.lock
new file mode 100644
index 0000000..4639dc0
--- /dev/null
+++ b/xcode/Podfile.lock
@@ -0,0 +1,14 @@
+PODS:
+ - olm (0.1.0)
+
+DEPENDENCIES:
+ - olm (from `../olm.podspec`)
+
+EXTERNAL SOURCES:
+ olm:
+ :path: "../olm.podspec"
+
+SPEC CHECKSUMS:
+ olm: ba8c1a7ca04486ec1ad958ec9feef73c0939ae27
+
+COCOAPODS: 0.39.0
diff --git a/xcode/olm.xcodeproj/project.pbxproj b/xcode/olm.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..6c6fa32
--- /dev/null
+++ b/xcode/olm.xcodeproj/project.pbxproj
@@ -0,0 +1,561 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ D9401CDC1CBF10BD003DD078 /* OLMSession_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = D9401CDB1CBF10BD003DD078 /* OLMSession_Private.h */; };
+ D976E4411CB852E000F5C124 /* OLMKit.h in Headers */ = {isa = PBXBuildFile; fileRef = D976E4401CB852E000F5C124 /* OLMKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ D976E4481CB852E000F5C124 /* OLMKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D976E43E1CB852E000F5C124 /* OLMKit.framework */; };
+ D976E44D1CB852E000F5C124 /* OLMKitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D976E44C1CB852E000F5C124 /* OLMKitTests.m */; };
+ D976E4571CB8536500F5C124 /* OLMAccount.h in Headers */ = {isa = PBXBuildFile; fileRef = D976E4551CB8536500F5C124 /* OLMAccount.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ D976E4581CB8536500F5C124 /* OLMAccount.m in Sources */ = {isa = PBXBuildFile; fileRef = D976E4561CB8536500F5C124 /* OLMAccount.m */; };
+ D976E45B1CB8538300F5C124 /* OLMSession.h in Headers */ = {isa = PBXBuildFile; fileRef = D976E4591CB8538300F5C124 /* OLMSession.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ D976E45C1CB8538300F5C124 /* OLMSession.m in Sources */ = {isa = PBXBuildFile; fileRef = D976E45A1CB8538300F5C124 /* OLMSession.m */; };
+ D976E45F1CB8538E00F5C124 /* OLMUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = D976E45D1CB8538E00F5C124 /* OLMUtility.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ D976E4601CB8538E00F5C124 /* OLMUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = D976E45E1CB8538E00F5C124 /* OLMUtility.m */; };
+ D976E4621CB860E200F5C124 /* OLMSerializable.h in Headers */ = {isa = PBXBuildFile; fileRef = D976E4611CB860E200F5C124 /* OLMSerializable.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ D976E4651CB8674900F5C124 /* OLMMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = D976E4631CB8674900F5C124 /* OLMMessage.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ D976E4661CB8674900F5C124 /* OLMMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = D976E4641CB8674900F5C124 /* OLMMessage.m */; };
+ D976E4681CB8787D00F5C124 /* OLMAccount_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = D976E4671CB8696100F5C124 /* OLMAccount_Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ DE4C8FA4266B10FC69A1C762 /* Pods.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 235C5A0B708438C11BCE552C /* Pods.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ D976E4491CB852E000F5C124 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = D9679C4D1C87B53E007F67AA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = D976E43D1CB852E000F5C124;
+ remoteInfo = OLMKit;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 0A0809C67039D4BDCE9CE9AF /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; };
+ 235C5A0B708438C11BCE552C /* Pods.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 81B8A7B31F3BA6548ACC45DE /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; };
+ D9401CDB1CBF10BD003DD078 /* OLMSession_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OLMSession_Private.h; sourceTree = ""; };
+ D976E43E1CB852E000F5C124 /* OLMKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OLMKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ D976E4401CB852E000F5C124 /* OLMKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OLMKit.h; sourceTree = ""; };
+ D976E4421CB852E000F5C124 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ D976E4471CB852E000F5C124 /* OLMKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OLMKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ D976E44C1CB852E000F5C124 /* OLMKitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OLMKitTests.m; sourceTree = ""; };
+ D976E44E1CB852E000F5C124 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ D976E4551CB8536500F5C124 /* OLMAccount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OLMAccount.h; sourceTree = ""; };
+ D976E4561CB8536500F5C124 /* OLMAccount.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OLMAccount.m; sourceTree = ""; };
+ D976E4591CB8538300F5C124 /* OLMSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OLMSession.h; sourceTree = ""; };
+ D976E45A1CB8538300F5C124 /* OLMSession.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OLMSession.m; sourceTree = ""; };
+ D976E45D1CB8538E00F5C124 /* OLMUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OLMUtility.h; sourceTree = ""; };
+ D976E45E1CB8538E00F5C124 /* OLMUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OLMUtility.m; sourceTree = ""; };
+ D976E4611CB860E200F5C124 /* OLMSerializable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OLMSerializable.h; sourceTree = ""; };
+ D976E4631CB8674900F5C124 /* OLMMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OLMMessage.h; sourceTree = ""; };
+ D976E4641CB8674900F5C124 /* OLMMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OLMMessage.m; sourceTree = ""; };
+ D976E4671CB8696100F5C124 /* OLMAccount_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OLMAccount_Private.h; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ D976E43A1CB852E000F5C124 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ DE4C8FA4266B10FC69A1C762 /* Pods.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ D976E4441CB852E000F5C124 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D976E4481CB852E000F5C124 /* OLMKit.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ C125031A628591D7E1C25FD8 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 235C5A0B708438C11BCE552C /* Pods.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+ D9679C4C1C87B53E007F67AA = {
+ isa = PBXGroup;
+ children = (
+ D96991B7CDE3F0F8C3A52C54 /* Pods */,
+ D976E43F1CB852E000F5C124 /* OLMKit */,
+ D976E44B1CB852E000F5C124 /* OLMKitTests */,
+ C125031A628591D7E1C25FD8 /* Frameworks */,
+ D976E43E1CB852E000F5C124 /* OLMKit.framework */,
+ D976E4471CB852E000F5C124 /* OLMKitTests.xctest */,
+ );
+ sourceTree = "";
+ };
+ D96991B7CDE3F0F8C3A52C54 /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ 0A0809C67039D4BDCE9CE9AF /* Pods.debug.xcconfig */,
+ 81B8A7B31F3BA6548ACC45DE /* Pods.release.xcconfig */,
+ );
+ name = Pods;
+ sourceTree = "";
+ };
+ D976E43F1CB852E000F5C124 /* OLMKit */ = {
+ isa = PBXGroup;
+ children = (
+ D976E4631CB8674900F5C124 /* OLMMessage.h */,
+ D976E4641CB8674900F5C124 /* OLMMessage.m */,
+ D976E4401CB852E000F5C124 /* OLMKit.h */,
+ D976E4611CB860E200F5C124 /* OLMSerializable.h */,
+ D976E4551CB8536500F5C124 /* OLMAccount.h */,
+ D976E4671CB8696100F5C124 /* OLMAccount_Private.h */,
+ D976E4561CB8536500F5C124 /* OLMAccount.m */,
+ D976E4591CB8538300F5C124 /* OLMSession.h */,
+ D9401CDB1CBF10BD003DD078 /* OLMSession_Private.h */,
+ D976E45A1CB8538300F5C124 /* OLMSession.m */,
+ D976E45D1CB8538E00F5C124 /* OLMUtility.h */,
+ D976E45E1CB8538E00F5C124 /* OLMUtility.m */,
+ D976E4421CB852E000F5C124 /* Info.plist */,
+ );
+ path = OLMKit;
+ sourceTree = "";
+ };
+ D976E44B1CB852E000F5C124 /* OLMKitTests */ = {
+ isa = PBXGroup;
+ children = (
+ D976E44C1CB852E000F5C124 /* OLMKitTests.m */,
+ D976E44E1CB852E000F5C124 /* Info.plist */,
+ );
+ path = OLMKitTests;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ D976E43B1CB852E000F5C124 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D9401CDC1CBF10BD003DD078 /* OLMSession_Private.h in Headers */,
+ D976E45B1CB8538300F5C124 /* OLMSession.h in Headers */,
+ D976E4681CB8787D00F5C124 /* OLMAccount_Private.h in Headers */,
+ D976E4651CB8674900F5C124 /* OLMMessage.h in Headers */,
+ D976E4621CB860E200F5C124 /* OLMSerializable.h in Headers */,
+ D976E45F1CB8538E00F5C124 /* OLMUtility.h in Headers */,
+ D976E4571CB8536500F5C124 /* OLMAccount.h in Headers */,
+ D976E4411CB852E000F5C124 /* OLMKit.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ D976E43D1CB852E000F5C124 /* OLMKit */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = D976E44F1CB852E000F5C124 /* Build configuration list for PBXNativeTarget "OLMKit" */;
+ buildPhases = (
+ 5DFDEA7662CDB902F5544BBD /* Check Pods Manifest.lock */,
+ D976E4391CB852E000F5C124 /* Sources */,
+ D976E43A1CB852E000F5C124 /* Frameworks */,
+ D976E43B1CB852E000F5C124 /* Headers */,
+ D976E43C1CB852E000F5C124 /* Resources */,
+ DC41A6806320B8867B32F48B /* Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = OLMKit;
+ productName = OLMKit;
+ productReference = D976E43E1CB852E000F5C124 /* OLMKit.framework */;
+ productType = "com.apple.product-type.framework";
+ };
+ D976E4461CB852E000F5C124 /* OLMKitTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = D976E4521CB852E000F5C124 /* Build configuration list for PBXNativeTarget "OLMKitTests" */;
+ buildPhases = (
+ D976E4431CB852E000F5C124 /* Sources */,
+ D976E4441CB852E000F5C124 /* Frameworks */,
+ D976E4451CB852E000F5C124 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ D976E44A1CB852E000F5C124 /* PBXTargetDependency */,
+ );
+ name = OLMKitTests;
+ productName = OLMKitTests;
+ productReference = D976E4471CB852E000F5C124 /* OLMKitTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ D9679C4D1C87B53E007F67AA /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0730;
+ TargetAttributes = {
+ D976E43D1CB852E000F5C124 = {
+ CreatedOnToolsVersion = 7.3;
+ };
+ D976E4461CB852E000F5C124 = {
+ CreatedOnToolsVersion = 7.3;
+ };
+ };
+ };
+ buildConfigurationList = D9679C501C87B53E007F67AA /* Build configuration list for PBXProject "olm" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = D9679C4C1C87B53E007F67AA;
+ productRefGroup = D9679C4C1C87B53E007F67AA;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ D976E43D1CB852E000F5C124 /* OLMKit */,
+ D976E4461CB852E000F5C124 /* OLMKitTests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ D976E43C1CB852E000F5C124 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ D976E4451CB852E000F5C124 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 5DFDEA7662CDB902F5544BBD /* Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Check Pods Manifest.lock";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
+ showEnvVarsInLog = 0;
+ };
+ DC41A6806320B8867B32F48B /* Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Copy Pods Resources";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ D976E4391CB852E000F5C124 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D976E4661CB8674900F5C124 /* OLMMessage.m in Sources */,
+ D976E4581CB8536500F5C124 /* OLMAccount.m in Sources */,
+ D976E45C1CB8538300F5C124 /* OLMSession.m in Sources */,
+ D976E4601CB8538E00F5C124 /* OLMUtility.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ D976E4431CB852E000F5C124 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D976E44D1CB852E000F5C124 /* OLMKitTests.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ D976E44A1CB852E000F5C124 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = D976E43D1CB852E000F5C124 /* OLMKit */;
+ targetProxy = D976E4491CB852E000F5C124 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ D9679C511C87B53E007F67AA /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ENABLE_TESTABILITY = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ };
+ name = Debug;
+ };
+ D9679C521C87B53E007F67AA /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ };
+ name = Release;
+ };
+ D976E4501CB852E000F5C124 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 0A0809C67039D4BDCE9CE9AF /* Pods.debug.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ CURRENT_PROJECT_VERSION = 1;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ DEFINES_MODULE = YES;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ INFOPLIST_FILE = OLMKit/Info.plist;
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ IPHONEOS_DEPLOYMENT_TARGET = 9.3;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = io.ballinger.OLMKit;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = iphoneos;
+ SKIP_INSTALL = YES;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
+ };
+ name = Debug;
+ };
+ D976E4511CB852E000F5C124 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 81B8A7B31F3BA6548ACC45DE /* Pods.release.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ CURRENT_PROJECT_VERSION = 1;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DEFINES_MODULE = YES;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ INFOPLIST_FILE = OLMKit/Info.plist;
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ IPHONEOS_DEPLOYMENT_TARGET = 9.3;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ MTL_ENABLE_DEBUG_INFO = NO;
+ PRODUCT_BUNDLE_IDENTIFIER = io.ballinger.OLMKit;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = iphoneos;
+ SKIP_INSTALL = YES;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
+ };
+ name = Release;
+ };
+ D976E4531CB852E000F5C124 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ INFOPLIST_FILE = OLMKitTests/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.3;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = io.ballinger.OLMKitTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = iphoneos;
+ };
+ name = Debug;
+ };
+ D976E4541CB852E000F5C124 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ INFOPLIST_FILE = OLMKitTests/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.3;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ MTL_ENABLE_DEBUG_INFO = NO;
+ PRODUCT_BUNDLE_IDENTIFIER = io.ballinger.OLMKitTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = iphoneos;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ D9679C501C87B53E007F67AA /* Build configuration list for PBXProject "olm" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D9679C511C87B53E007F67AA /* Debug */,
+ D9679C521C87B53E007F67AA /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ D976E44F1CB852E000F5C124 /* Build configuration list for PBXNativeTarget "OLMKit" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D976E4501CB852E000F5C124 /* Debug */,
+ D976E4511CB852E000F5C124 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ D976E4521CB852E000F5C124 /* Build configuration list for PBXNativeTarget "OLMKitTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D976E4531CB852E000F5C124 /* Debug */,
+ D976E4541CB852E000F5C124 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = D9679C4D1C87B53E007F67AA /* Project object */;
+}
diff --git a/xcode/olm.xcodeproj/xcshareddata/xcschemes/OLMKit.xcscheme b/xcode/olm.xcodeproj/xcshareddata/xcschemes/OLMKit.xcscheme
new file mode 100644
index 0000000..eee8c5e
--- /dev/null
+++ b/xcode/olm.xcodeproj/xcshareddata/xcschemes/OLMKit.xcscheme
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xcode/olm.xcodeproj/xcshareddata/xcschemes/OLMKitTests.xcscheme b/xcode/olm.xcodeproj/xcshareddata/xcschemes/OLMKitTests.xcscheme
new file mode 100644
index 0000000..300e62c
--- /dev/null
+++ b/xcode/olm.xcodeproj/xcshareddata/xcschemes/OLMKitTests.xcscheme
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xcode/olm.xcworkspace/contents.xcworkspacedata b/xcode/olm.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..3c8fe35
--- /dev/null
+++ b/xcode/olm.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+