diff --git a/README.md b/README.md
index 3b79135..230d1d9 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,32 @@
-# SwiftExceptionCatcher
\ No newline at end of file
+# SwiftExceptionCatcher
+
+[
](https://RedRoma.tech)
+
+`SwiftExceptionCatcher` allows Swift Code to catch exceptions thrown from Objective-C code.
+
+This is useful when using Thrift libraries, where it is perfectly normal for code to throw `NSException` types.
+
+
+# Cocoapods
+```xml
+pod 'SwiftExceptionCatcher', :git => 'https://github.com/RedRoma/SwiftExceptionCatcher.git'
+```
+
+# API
+Simply wrap the code-in-play in the `tryOp` function call.
+
+```js
+var object: SomeObjectThatThrows
+...
+do {
+ try tryOp() { object.act() }
+}
+catch let ex is AromaException {
+ print("Aroma Failed: \(ex")
+}
+catch let ex {
+ print("Exception: \(ex")
+}
+
+```
diff --git a/SwiftExceptionCatcher.podspec b/SwiftExceptionCatcher.podspec
new file mode 100644
index 0000000..d63053d
--- /dev/null
+++ b/SwiftExceptionCatcher.podspec
@@ -0,0 +1,18 @@
+Pod::Spec.new do |spec|
+ spec.name = "SwiftExceptionCatcher"
+ spec.module_name = 'SwiftExceptionCatcher'
+ spec.version = "1.0"
+ spec.summary = "Catch NSException with Swift"
+ spec.homepage = "https://github.com/RedRoma/SwiftExceptionCatcher"
+ spec.license = "Code is Licensed under Apache 2.0"
+ spec.author = { "SirWellington" => "wellington@redroma.tech" }
+ spec.source =
+ {
+ :path => "SwiftExceptionCatcher/SwiftExceptionCatcher/"
+ }
+ spec.source_files = "SwiftExceptionCatcher/SwiftExceptionCatcher/*.{h,m,swift}"
+ # spec.resources = 'Pod/Assets/*'
+
+ spec.platform = :ios, '8.0', :osx, '10.8'
+ spec.requires_arc = false
+end
diff --git a/SwiftExceptionCatcher/SwiftExceptionCatcher.xcodeproj/project.pbxproj b/SwiftExceptionCatcher/SwiftExceptionCatcher.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..e085efc
--- /dev/null
+++ b/SwiftExceptionCatcher/SwiftExceptionCatcher.xcodeproj/project.pbxproj
@@ -0,0 +1,433 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ DE683D8E1CB380180072F98A /* SwiftExceptionCatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = DE683D8D1CB380180072F98A /* SwiftExceptionCatcher.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ DE683D951CB380180072F98A /* SwiftExceptionCatcher.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DE683D8A1CB380180072F98A /* SwiftExceptionCatcher.framework */; };
+ DE683D9A1CB380180072F98A /* SwiftExceptionCatcherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE683D991CB380180072F98A /* SwiftExceptionCatcherTests.swift */; };
+ DE683DA81CB380320072F98A /* SwiftExceptionCatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = DE683DA51CB380320072F98A /* SwiftExceptionCatcher.m */; };
+ DE683DA91CB380320072F98A /* SwiftExceptionCatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE683DA61CB380320072F98A /* SwiftExceptionCatcher.swift */; };
+ DE683DAD1CB38EFB0072F98A /* Throwing.m in Sources */ = {isa = PBXBuildFile; fileRef = DE683DAC1CB38EFB0072F98A /* Throwing.m */; };
+ DE683DAF1CB3902D0072F98A /* Throwing.h in Headers */ = {isa = PBXBuildFile; fileRef = DE683DAB1CB38EB80072F98A /* Throwing.h */; settings = {ATTRIBUTES = (Public, ); }; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ DE683D961CB380180072F98A /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = DE683D811CB380180072F98A /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = DE683D891CB380180072F98A;
+ remoteInfo = SwiftExceptionCatcher;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ DE683D8A1CB380180072F98A /* SwiftExceptionCatcher.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftExceptionCatcher.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ DE683D8D1CB380180072F98A /* SwiftExceptionCatcher.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwiftExceptionCatcher.h; sourceTree = ""; };
+ DE683D8F1CB380180072F98A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ DE683D941CB380180072F98A /* SwiftExceptionCatcherTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SwiftExceptionCatcherTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ DE683D991CB380180072F98A /* SwiftExceptionCatcherTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftExceptionCatcherTests.swift; sourceTree = ""; };
+ DE683D9B1CB380180072F98A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ DE683DA51CB380320072F98A /* SwiftExceptionCatcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SwiftExceptionCatcher.m; sourceTree = ""; };
+ DE683DA61CB380320072F98A /* SwiftExceptionCatcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftExceptionCatcher.swift; sourceTree = ""; };
+ DE683DAB1CB38EB80072F98A /* Throwing.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Throwing.h; sourceTree = ""; };
+ DE683DAC1CB38EFB0072F98A /* Throwing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Throwing.m; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ DE683D861CB380180072F98A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ DE683D911CB380180072F98A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ DE683D951CB380180072F98A /* SwiftExceptionCatcher.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ DE683D801CB380180072F98A = {
+ isa = PBXGroup;
+ children = (
+ DE683D8C1CB380180072F98A /* SwiftExceptionCatcher */,
+ DE683D981CB380180072F98A /* SwiftExceptionCatcherTests */,
+ DE683D8B1CB380180072F98A /* Products */,
+ );
+ sourceTree = "";
+ };
+ DE683D8B1CB380180072F98A /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ DE683D8A1CB380180072F98A /* SwiftExceptionCatcher.framework */,
+ DE683D941CB380180072F98A /* SwiftExceptionCatcherTests.xctest */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ DE683D8C1CB380180072F98A /* SwiftExceptionCatcher */ = {
+ isa = PBXGroup;
+ children = (
+ DE683D8D1CB380180072F98A /* SwiftExceptionCatcher.h */,
+ DE683DA51CB380320072F98A /* SwiftExceptionCatcher.m */,
+ DE683DA61CB380320072F98A /* SwiftExceptionCatcher.swift */,
+ DE683D8F1CB380180072F98A /* Info.plist */,
+ );
+ path = SwiftExceptionCatcher;
+ sourceTree = "";
+ };
+ DE683D981CB380180072F98A /* SwiftExceptionCatcherTests */ = {
+ isa = PBXGroup;
+ children = (
+ DE683D991CB380180072F98A /* SwiftExceptionCatcherTests.swift */,
+ DE683D9B1CB380180072F98A /* Info.plist */,
+ DE683DAB1CB38EB80072F98A /* Throwing.h */,
+ DE683DAC1CB38EFB0072F98A /* Throwing.m */,
+ );
+ path = SwiftExceptionCatcherTests;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ DE683D871CB380180072F98A /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ DE683D8E1CB380180072F98A /* SwiftExceptionCatcher.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ DE683DAE1CB390240072F98A /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ DE683DAF1CB3902D0072F98A /* Throwing.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ DE683D891CB380180072F98A /* SwiftExceptionCatcher */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = DE683D9E1CB380180072F98A /* Build configuration list for PBXNativeTarget "SwiftExceptionCatcher" */;
+ buildPhases = (
+ DE683D851CB380180072F98A /* Sources */,
+ DE683D861CB380180072F98A /* Frameworks */,
+ DE683D871CB380180072F98A /* Headers */,
+ DE683D881CB380180072F98A /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = SwiftExceptionCatcher;
+ productName = SwiftExceptionCatcher;
+ productReference = DE683D8A1CB380180072F98A /* SwiftExceptionCatcher.framework */;
+ productType = "com.apple.product-type.framework";
+ };
+ DE683D931CB380180072F98A /* SwiftExceptionCatcherTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = DE683DA11CB380180072F98A /* Build configuration list for PBXNativeTarget "SwiftExceptionCatcherTests" */;
+ buildPhases = (
+ DE683D901CB380180072F98A /* Sources */,
+ DE683DAE1CB390240072F98A /* Headers */,
+ DE683D911CB380180072F98A /* Frameworks */,
+ DE683D921CB380180072F98A /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ DE683D971CB380180072F98A /* PBXTargetDependency */,
+ );
+ name = SwiftExceptionCatcherTests;
+ productName = SwiftExceptionCatcherTests;
+ productReference = DE683D941CB380180072F98A /* SwiftExceptionCatcherTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ DE683D811CB380180072F98A /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastSwiftUpdateCheck = 0730;
+ LastUpgradeCheck = 0730;
+ ORGANIZATIONNAME = "RedRoma, Inc.";
+ TargetAttributes = {
+ DE683D891CB380180072F98A = {
+ CreatedOnToolsVersion = 7.3;
+ };
+ DE683D931CB380180072F98A = {
+ CreatedOnToolsVersion = 7.3;
+ };
+ };
+ };
+ buildConfigurationList = DE683D841CB380180072F98A /* Build configuration list for PBXProject "SwiftExceptionCatcher" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = DE683D801CB380180072F98A;
+ productRefGroup = DE683D8B1CB380180072F98A /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ DE683D891CB380180072F98A /* SwiftExceptionCatcher */,
+ DE683D931CB380180072F98A /* SwiftExceptionCatcherTests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ DE683D881CB380180072F98A /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ DE683D921CB380180072F98A /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ DE683D851CB380180072F98A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ DE683DA81CB380320072F98A /* SwiftExceptionCatcher.m in Sources */,
+ DE683DA91CB380320072F98A /* SwiftExceptionCatcher.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ DE683D901CB380180072F98A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ DE683D9A1CB380180072F98A /* SwiftExceptionCatcherTests.swift in Sources */,
+ DE683DAD1CB38EFB0072F98A /* Throwing.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ DE683D971CB380180072F98A /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = DE683D891CB380180072F98A /* SwiftExceptionCatcher */;
+ targetProxy = DE683D961CB380180072F98A /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ DE683D9C1CB380180072F98A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
+ 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;
+ 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;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.3;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
+ };
+ name = Debug;
+ };
+ DE683D9D1CB380180072F98A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
+ 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";
+ 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;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.3;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
+ };
+ name = Release;
+ };
+ DE683D9F1CB380180072F98A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
+ CLANG_ENABLE_MODULES = YES;
+ DEFINES_MODULE = YES;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ EMBEDDED_CONTENT_CONTAINS_SWIFT = YES;
+ INFOPLIST_FILE = SwiftExceptionCatcher/Info.plist;
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = tech.redroma.SwiftExceptionCatcher;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ };
+ name = Debug;
+ };
+ DE683DA01CB380180072F98A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
+ CLANG_ENABLE_MODULES = YES;
+ DEFINES_MODULE = YES;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ EMBEDDED_CONTENT_CONTAINS_SWIFT = YES;
+ INFOPLIST_FILE = SwiftExceptionCatcher/Info.plist;
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = tech.redroma.SwiftExceptionCatcher;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ };
+ name = Release;
+ };
+ DE683DA21CB380180072F98A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
+ CLANG_ENABLE_MODULES = YES;
+ INFOPLIST_FILE = SwiftExceptionCatcherTests/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = tech.redroma.SwiftExceptionCatcherTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = SwiftExceptionCatcherTests/Throwing.h;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ };
+ name = Debug;
+ };
+ DE683DA31CB380180072F98A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
+ CLANG_ENABLE_MODULES = YES;
+ INFOPLIST_FILE = SwiftExceptionCatcherTests/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = tech.redroma.SwiftExceptionCatcherTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = SwiftExceptionCatcherTests/Throwing.h;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ DE683D841CB380180072F98A /* Build configuration list for PBXProject "SwiftExceptionCatcher" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ DE683D9C1CB380180072F98A /* Debug */,
+ DE683D9D1CB380180072F98A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ DE683D9E1CB380180072F98A /* Build configuration list for PBXNativeTarget "SwiftExceptionCatcher" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ DE683D9F1CB380180072F98A /* Debug */,
+ DE683DA01CB380180072F98A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ };
+ DE683DA11CB380180072F98A /* Build configuration list for PBXNativeTarget "SwiftExceptionCatcherTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ DE683DA21CB380180072F98A /* Debug */,
+ DE683DA31CB380180072F98A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = DE683D811CB380180072F98A /* Project object */;
+}
diff --git a/SwiftExceptionCatcher/SwiftExceptionCatcher.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/SwiftExceptionCatcher/SwiftExceptionCatcher.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..2660e47
--- /dev/null
+++ b/SwiftExceptionCatcher/SwiftExceptionCatcher.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/SwiftExceptionCatcher/SwiftExceptionCatcher/Info.plist b/SwiftExceptionCatcher/SwiftExceptionCatcher/Info.plist
new file mode 100644
index 0000000..d3de8ee
--- /dev/null
+++ b/SwiftExceptionCatcher/SwiftExceptionCatcher/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/SwiftExceptionCatcher/SwiftExceptionCatcher/SwiftExceptionCatcher.h b/SwiftExceptionCatcher/SwiftExceptionCatcher/SwiftExceptionCatcher.h
new file mode 100644
index 0000000..59ee724
--- /dev/null
+++ b/SwiftExceptionCatcher/SwiftExceptionCatcher/SwiftExceptionCatcher.h
@@ -0,0 +1,26 @@
+//
+// SwiftExceptionCatcher.h
+// SwiftExceptionCatcher
+//
+// Created by Juan Wellington Moreno on 4/4/16.
+// Copyright © 2016 RedRoma, Inc. All rights reserved.
+//
+
+#ifndef SwiftExceptionCatcher
+#define SwiftExceptionCatcher
+
+#import
+#import
+
+//! Project version number for SwiftExceptionCatcher.
+FOUNDATION_EXPORT double SwiftExceptionCatcherVersionNumber;
+
+//! Project version string for SwiftExceptionCatcher.
+FOUNDATION_EXPORT const unsigned char SwiftExceptionCatcherVersionString[];
+
+// In this header, you should import all the public headers of your framework using statements like #import
+
+
+void tryOperation(void(^tryBlock)(), void(^catchBlock)(NSException *e));
+
+#endif
\ No newline at end of file
diff --git a/SwiftExceptionCatcher/SwiftExceptionCatcher/SwiftExceptionCatcher.m b/SwiftExceptionCatcher/SwiftExceptionCatcher/SwiftExceptionCatcher.m
new file mode 100644
index 0000000..4e3ec24
--- /dev/null
+++ b/SwiftExceptionCatcher/SwiftExceptionCatcher/SwiftExceptionCatcher.m
@@ -0,0 +1,20 @@
+//
+// TryOperation.m
+// SwiftExceptionCatcher
+//
+// Created by Juan Wellington Moreno on 4/4/16.
+// Copyright © 2016 RedRoma, Inc. All rights reserved.
+//
+
+#import
+#import "SwiftExceptionCatcher.h"
+
+void tryOperation(void (^tryBlock)(), void(^catchBlock)(NSException *e)) {
+
+ @try {
+ tryBlock();
+ }
+ @catch (NSException *exception) {
+ catchBlock(exception);
+ }
+}
diff --git a/SwiftExceptionCatcher/SwiftExceptionCatcher/SwiftExceptionCatcher.swift b/SwiftExceptionCatcher/SwiftExceptionCatcher/SwiftExceptionCatcher.swift
new file mode 100644
index 0000000..c4c84a3
--- /dev/null
+++ b/SwiftExceptionCatcher/SwiftExceptionCatcher/SwiftExceptionCatcher.swift
@@ -0,0 +1,53 @@
+//
+// TryOperation.swift
+// SwiftExceptionCatcher
+//
+// Created by Juan Wellington Moreno on 4/4/16.
+// Copyright © 2016 RedRoma, Inc. All rights reserved.
+//
+
+import Foundation
+
+
+/**
+ * This Extension adds the ability to catch NSException Types in Swift.
+ */
+extension NSException : ErrorType {
+ public var _domain: String { return "tech.redroma.SwiftExceptionCatcher" }
+ public var _code: Int { return 0 }
+}
+
+/**
+ This class wraps Operations that may throw NSException types and catches them in a safe way
+ Primarily designed to overcome Swift's exception-handling limitations.
+
+ - parameter operation: This operation may throw an Objective-C NSException type and must be safely wrapped.
+*/
+public func tryOp(operation: (() throws -> T)) throws -> T {
+
+ var result: T?
+ var error: NSException?
+
+ let theTry: () -> () = {
+ do {
+ result = try operation()
+ } catch let ex {
+ error = ex as? NSException
+ }
+ return
+ }
+
+ let theCatch: (NSException!) -> () = { ex in
+ error = ex
+ }
+
+ tryOperation(theTry, theCatch)
+
+ if let result = result {
+ return result
+ } else if let ex = error {
+ throw ex
+ } else {
+ throw NSException(name: "Unknown", reason: "Error Occured performing Operation", userInfo: nil)
+ }
+}
diff --git a/SwiftExceptionCatcher/SwiftExceptionCatcherTests/Info.plist b/SwiftExceptionCatcher/SwiftExceptionCatcherTests/Info.plist
new file mode 100644
index 0000000..ba72822
--- /dev/null
+++ b/SwiftExceptionCatcher/SwiftExceptionCatcherTests/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/SwiftExceptionCatcher/SwiftExceptionCatcherTests/SwiftExceptionCatcherTests.swift b/SwiftExceptionCatcher/SwiftExceptionCatcherTests/SwiftExceptionCatcherTests.swift
new file mode 100644
index 0000000..a3c982c
--- /dev/null
+++ b/SwiftExceptionCatcher/SwiftExceptionCatcherTests/SwiftExceptionCatcherTests.swift
@@ -0,0 +1,76 @@
+//
+// SwiftExceptionCatcherTests.swift
+// SwiftExceptionCatcherTests
+//
+// Created by Juan Wellington Moreno on 4/4/16.
+// Copyright © 2016 RedRoma, Inc. All rights reserved.
+//
+
+import XCTest
+@testable import SwiftExceptionCatcher
+
+class SwiftExceptionCatcherTests: XCTestCase {
+
+ override func setUp() {
+ super.setUp()
+ // Put setup code here. This method is called before the invocation of each test method in the class.
+ }
+
+ override func tearDown() {
+ // Put teardown code here. This method is called after the invocation of each test method in the class.
+ super.tearDown()
+ }
+
+ func testWhenThrows() {
+
+ do {
+ try tryOp() {
+ Throwing.functionThatThrows()
+ }
+ XCTFail("Expected Exception")
+ }
+ catch {
+ //Test Passed
+ }
+ }
+
+ func testWhenNotThrows() {
+ do {
+ try tryOp() { Throwing.functionNotThrowing() }
+ }
+ catch let ex {
+ XCTFail("Unexpected Exception: \(ex)")
+ }
+ }
+
+ func testWhenSwiftThrows() {
+ do {
+ try tryOp() { try self.somethingThatMightThrow(true) }
+ XCTFail("Expected Exception")
+ }
+ catch {
+
+ }
+ }
+
+ func testWhenSwiftNotThrows() {
+ do {
+ try tryOp() { try self.somethingThatMightThrow(false) }
+ }
+ catch let ex {
+ XCTFail("Unexpected Exception: \(ex)")
+ }
+ }
+
+
+ private func somethingThatMightThrow(shouldThrow: Bool = true) throws {
+
+ if shouldThrow {
+ throw NSException(name: "Test", reason: "Because", userInfo: nil)
+ }
+ else {
+ print("Not Throwing")
+ }
+ }
+
+}
diff --git a/SwiftExceptionCatcher/SwiftExceptionCatcherTests/Throwing.h b/SwiftExceptionCatcher/SwiftExceptionCatcherTests/Throwing.h
new file mode 100644
index 0000000..aba57b4
--- /dev/null
+++ b/SwiftExceptionCatcher/SwiftExceptionCatcherTests/Throwing.h
@@ -0,0 +1,23 @@
+//
+// Throwing.h
+// SwiftExceptionCatcher
+//
+// Created by Juan Wellington Moreno on 4/4/16.
+// Copyright © 2016 RedRoma, Inc. All rights reserved.
+//
+
+#ifndef Throwing_h
+#define Throwing_h
+
+#import
+
+@interface Throwing : NSObject
+
++ (void) functionThatThrows;
+
++ (void) functionNotThrowing;
+
+
+@end
+
+#endif /* Throwing_h */
diff --git a/SwiftExceptionCatcher/SwiftExceptionCatcherTests/Throwing.m b/SwiftExceptionCatcher/SwiftExceptionCatcherTests/Throwing.m
new file mode 100644
index 0000000..417486c
--- /dev/null
+++ b/SwiftExceptionCatcher/SwiftExceptionCatcherTests/Throwing.m
@@ -0,0 +1,24 @@
+//
+// Throwing.m
+// SwiftExceptionCatcher
+//
+// Created by Juan Wellington Moreno on 4/4/16.
+// Copyright © 2016 RedRoma, Inc. All rights reserved.
+//
+
+#import
+#import "Throwing.h"
+
+@implementation Throwing
+
++ (void) functionThatThrows
+{
+ @throw [NSException exceptionWithName:@"Test" reason:@"" userInfo:nil];
+}
+
++ (void) functionNotThrowing
+{
+
+}
+
+@end
\ No newline at end of file