Skip to content

Commit

Permalink
Improved ObjC interop utils
Browse files Browse the repository at this point in the history
  • Loading branch information
Alkenso committed Mar 19, 2022
1 parent 91271f7 commit 00ce562
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 30 deletions.
46 changes: 42 additions & 4 deletions Sources/SwiftConvenience/ObjC Bridging/ObjC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,54 @@
import Foundation
@_implementationOnly import SwiftConvenienceObjC


extension NSException {
public static func catching(_ body: () -> Void) -> NSException? {
scbridge_catching(body)
public static func catching<R>(_ body: () -> R) -> NSExceptionResult<R> {
var result: NSExceptionResult<R>!
if let exception = SwiftConvenienceObjC.nsException_catching({
let value = body()
result = .success(value)
}) {
result = .exception(exception)
}
return result
}
}


extension NSXPCConnection {
public var auditToken: audit_token_t {
scbridge_auditToken
SwiftConvenienceObjC.nsxpcConnection_auditToken(self)
}
}

public enum NSExceptionResult<Success> {
case success(Success)
case exception(NSException)
}

extension NSExceptionResult {
public var success: Success? {
if case let .success(value) = self {
return value
} else {
return nil
}
}

public var exception: NSException? {
if case let .exception(value) = self {
return value
} else {
return nil
}
}

public func mapToResult<Failure: Error>(exceptionTransform: (NSException) -> Failure) -> Result<Success, Failure> {
switch self {
case .success(let success):
return .success(success)
case .exception(let exception):
return .failure(exceptionTransform(exception))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public extension Process {
proc.standardOutput = standardOutPipe.fileHandleForWriting
proc.standardError = standardErrPipe.fileHandleForWriting

if let exception = NSException.catching({ proc.launch() }) {
if let exception = NSException.catching({ proc.launch() }).exception {
return (
ENOENT,
"",
Expand Down
11 changes: 3 additions & 8 deletions Sources/SwiftConvenienceObjC/SwiftConvenienceObjC.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,11 @@

NS_ASSUME_NONNULL_BEGIN

@interface NSException (SwiftConvenience)
@interface SwiftConvenienceObjC : NSObject

+ (nullable instancetype)scbridge_catching:(void(NS_NOESCAPE ^)(void))block;
+ (nullable NSException *)NSException_catching:(void(NS_NOESCAPE ^)(void))block;

@end


@interface NSXPCConnection (SwiftConvenience)

@property (nonatomic, readonly) audit_token_t scbridge_auditToken;
+ (audit_token_t)NSXPCConnection_auditToken:(NSXPCConnection *)connection;

@end

Expand Down
20 changes: 7 additions & 13 deletions Sources/SwiftConvenienceObjC/SwiftConvenienceObjC.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,13 @@

#import "SwiftConvenienceObjC.h"

@interface NSXPCConnection (SwiftConveniencePrivate)
@property (nonatomic, readonly) audit_token_t auditToken;
@end

@implementation NSException (SwiftConvenience)
@implementation SwiftConvenienceObjC

+ (nullable instancetype)scbridge_catching:(void(NS_NOESCAPE ^)(void))block
+ (nullable NSException *)NSException_catching:(void(NS_NOESCAPE ^)(void))block
{
@try
{
Expand All @@ -38,18 +41,9 @@ + (nullable instancetype)scbridge_catching:(void(NS_NOESCAPE ^)(void))block
}
}

@end


@interface NSXPCConnection (SwiftConveniencePrivate)
@property (nonatomic, readonly) audit_token_t auditToken;
@end

@implementation NSXPCConnection (SwiftConvenience)

- (audit_token_t)scbridge_auditToken
+ (audit_token_t)NSXPCConnection_auditToken:(NSXPCConnection *)connection
{
return self.auditToken;
return connection.auditToken;
}

@end
25 changes: 21 additions & 4 deletions Tests/SwiftConvenienceTests/ObjCTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,28 @@ import XCTest


class ObjCTests: XCTestCase {
func test_catchNSException() throws {
let exception = NSException.catching {
func test_catchNSException_success() throws {
let result = NSException.catching {
return 10
}
switch result {
case .success(let value):
XCTAssertEqual(value, 10)
case .exception:
XCTFail()
}
}

func test_catchNSException_exception() throws {
let result = NSException.catching {
NSException(name: .genericException, reason: "Just", userInfo: nil).raise()
}
XCTAssertEqual(exception?.name, .genericException)
XCTAssertEqual(exception?.reason, "Just")
switch result {
case .success:
XCTFail()
case .exception(let exception):
XCTAssertEqual(exception.name, .genericException)
XCTAssertEqual(exception.reason, "Just")
}
}
}

0 comments on commit 00ce562

Please sign in to comment.