Skip to content

Commit

Permalink
Merge pull request #150 from sharplet/as-swift-error-bridging
Browse files Browse the repository at this point in the history
Support Swift bridging for RACSignalError using NS_ERROR_ENUM
  • Loading branch information
sharplet authored Jan 7, 2019
2 parents 5f2817f + 7b150ab commit a621018
Show file tree
Hide file tree
Showing 16 changed files with 222 additions and 63 deletions.
5 changes: 3 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
language: objective-c
osx_image: xcode9
osx_image: xcode10
before_install: true
install: true
branches:
Expand All @@ -24,7 +24,7 @@ matrix:
env:
- XCODE_SDK=appletvsimulator
- XCODE_ACTION="build-for-testing test-without-building"
- XCODE_DESTINATION="platform=tvOS Simulator,name=Apple TV 1080p"
- XCODE_DESTINATION="platform=tvOS Simulator,name=Apple TV 4K"
- xcode_scheme: ReactiveObjC-watchOS
env:
- XCODE_SDK=watchsimulator
Expand Down Expand Up @@ -55,6 +55,7 @@ matrix:
env:
- JOB=CARTHAGE-watchOS
- script:
- gem install cocoapods --pre
- pod repo update --silent
- pod lib lint ReactiveObjC.podspec
env:
Expand Down
2 changes: 1 addition & 1 deletion Cartfile.resolved
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
github "Quick/Nimble" "v7.0.2"
github "Quick/Nimble" "v7.3.1"
github "Quick/Quick" "v1.2.0"
github "jspahrsummers/xcconfigs" "3d9d99634cae6d586e272543d527681283b33eb0"
2 changes: 1 addition & 1 deletion Carthage/Checkouts/Nimble
Submodule Nimble updated 105 files
161 changes: 134 additions & 27 deletions ReactiveObjC.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions ReactiveObjC/Deprecations+Removals.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// Deprecations+Removals.swift
// ReactiveObjC
//
// Created by Adam Sharp on 26/12/18.
// Copyright © 2018 GitHub. All rights reserved.
//

@available(*, deprecated, renamed: "RACSignalError.notEnabled")
public let RACCommandErrorNotEnabled = RACCommandError.notEnabled.rawValue

@available(*, deprecated, renamed: "RACSignalError.methodSwizzlingRace")
public let RACSelectorSignalErrorMethodSwizzlingRace = RACSelectorSignalError.methodSwizzlingRace

@available(*, deprecated, renamed: "RACSignalError.noMatchingCase")
public let RACSignalErrorNoMatchingCase = RACSignalError.noMatchingCase.rawValue

@available(*, deprecated, renamed: "RACSignalError.timedOut")
public let RACSignalErrorTimedOut = RACSignalError.timedOut.rawValue
2 changes: 1 addition & 1 deletion ReactiveObjC/NSObject+RACAppKitBindings.m
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ - (instancetype)initWithTarget:(id)target bindingName:(NSString *)bindingName op

@weakify(self);

void (^cleanUp)() = ^{
void (^cleanUp)(void) = ^{
@strongify(self);

id target = self.target;
Expand Down
2 changes: 1 addition & 1 deletion ReactiveObjC/NSObject+RACKVOWrapper.m
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ - (RACDisposable *)rac_observeKeyPath:(NSString *)keyPath options:(NSKeyValueObs

BOOL isObject = attributes->objectClass != nil || strstr(attributes->type, @encode(id)) == attributes->type;
BOOL isProtocol = attributes->objectClass == NSClassFromString(@"Protocol");
BOOL isBlock = strcmp(attributes->type, @encode(void(^)())) == 0;
BOOL isBlock = strcmp(attributes->type, @encode(void(^)(void))) == 0;
BOOL isWeak = attributes->weak;

// If this property isn't actually an object (or is a Class object),
Expand Down
16 changes: 9 additions & 7 deletions ReactiveObjC/NSObject+RACSelectorSignal.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@
NS_ASSUME_NONNULL_BEGIN

/// The domain for any errors originating from -rac_signalForSelector:.
extern NSString * const RACSelectorSignalErrorDomain;
extern NSErrorDomain const RACSelectorSignalErrorDomain;

/// -rac_signalForSelector: was going to add a new method implementation for
/// `selector`, but another thread added an implementation before it was able to.
///
/// This will _not_ occur for cases where a method implementation exists before
/// -rac_signalForSelector: is invoked.
extern const NSInteger RACSelectorSignalErrorMethodSwizzlingRace;
typedef NS_ERROR_ENUM(RACSelectorSignalErrorDomain, RACSelectorSignalError) {
/// -rac_signalForSelector: was going to add a new method implementation for
/// `selector`, but another thread added an implementation before it was able to.
///
/// This will _not_ occur for cases where a method implementation exists before
/// -rac_signalForSelector: is invoked.
RACSelectorSignalErrorMethodSwizzlingRace = 1,
};

@interface NSObject (RACSelectorSignal)

Expand Down
3 changes: 1 addition & 2 deletions ReactiveObjC/NSObject+RACSelectorSignal.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@
#import <objc/message.h>
#import <objc/runtime.h>

NSString * const RACSelectorSignalErrorDomain = @"RACSelectorSignalErrorDomain";
const NSInteger RACSelectorSignalErrorMethodSwizzlingRace = 1;
NSErrorDomain const RACSelectorSignalErrorDomain = @"RACSelectorSignalErrorDomain";

static NSString * const RACSignalForSelectorAliasPrefix = @"rac_alias_";
static NSString * const RACSubclassSuffix = @"_RACSelectorSignal";
Expand Down
2 changes: 1 addition & 1 deletion ReactiveObjC/RACBlockTrampoline.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ - (instancetype)initWithBlock:(id)block {
+ (id)invokeBlock:(id)block withArguments:(RACTuple *)arguments {
NSCParameterAssert(block != NULL);

RACBlockTrampoline *trampoline = [[self alloc] initWithBlock:block];
RACBlockTrampoline *trampoline = [(RACBlockTrampoline *)[self alloc] initWithBlock:block];
return [trampoline invokeWithArguments:arguments];
}

Expand Down
8 changes: 5 additions & 3 deletions ReactiveObjC/RACCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@
NS_ASSUME_NONNULL_BEGIN

/// The domain for errors originating within `RACCommand`.
extern NSString * const RACCommandErrorDomain;
extern NSErrorDomain const RACCommandErrorDomain;

/// -execute: was invoked while the command was disabled.
extern const NSInteger RACCommandErrorNotEnabled;
typedef NS_ERROR_ENUM(RACCommandErrorDomain, RACCommandError) {
/// -execute: was invoked while the command was disabled.
RACCommandErrorNotEnabled = 1,
};

/// A `userInfo` key for an error, associated with the `RACCommand` that the
/// error originated from.
Expand Down
4 changes: 1 addition & 3 deletions ReactiveObjC/RACCommand.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,9 @@
#import "RACSignal+Operations.h"
#import <libkern/OSAtomic.h>

NSString * const RACCommandErrorDomain = @"RACCommandErrorDomain";
NSErrorDomain const RACCommandErrorDomain = @"RACCommandErrorDomain";
NSString * const RACUnderlyingCommandErrorKey = @"RACUnderlyingCommandErrorKey";

const NSInteger RACCommandErrorNotEnabled = 1;

@interface RACCommand () {
// Atomic backing variable for `allowsConcurrentExecution`.
volatile uint32_t _allowsConcurrentExecution;
Expand Down
2 changes: 1 addition & 1 deletion ReactiveObjC/RACDisposable.m
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ - (instancetype)initWithBlock:(void (^)(void))block {
}

+ (instancetype)disposableWithBlock:(void (^)(void))block {
return [[self alloc] initWithBlock:block];
return [(RACDisposable *)[self alloc] initWithBlock:block];
}

- (void)dealloc {
Expand Down
17 changes: 9 additions & 8 deletions ReactiveObjC/RACSignal+Operations.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@
NS_ASSUME_NONNULL_BEGIN

/// The domain for errors originating in RACSignal operations.
extern NSString * const RACSignalErrorDomain;

/// The error code used with -timeout:.
extern const NSInteger RACSignalErrorTimedOut;

/// The error code used when a value passed into +switch:cases:default: does not
/// match any of the cases, and no default was given.
extern const NSInteger RACSignalErrorNoMatchingCase;
extern NSErrorDomain const RACSignalErrorDomain;

typedef NS_ERROR_ENUM(RACSignalErrorDomain, RACSignalError) {
/// The error code used with -timeout:.
RACSignalErrorTimedOut = 1,
/// The error code used when a value passed into +switch:cases:default: does not
/// match any of the cases, and no default was given.
RACSignalErrorNoMatchingCase = 2,
};

@interface RACSignal<__covariant ValueType> (Operations)

Expand Down
7 changes: 2 additions & 5 deletions ReactiveObjC/RACSignal+Operations.m
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,7 @@
#import <libkern/OSAtomic.h>
#import <objc/runtime.h>

NSString * const RACSignalErrorDomain = @"RACSignalErrorDomain";

const NSInteger RACSignalErrorTimedOut = 1;
const NSInteger RACSignalErrorNoMatchingCase = 2;
NSErrorDomain const RACSignalErrorDomain = @"RACSignalErrorDomain";

// Subscribes to the given signal with the given blocks.
//
Expand Down Expand Up @@ -331,7 +328,7 @@ - (RACSignal *)bufferWithTime:(NSTimeInterval)interval onScheduler:(RACScheduler
RACSerialDisposable *timerDisposable = [[RACSerialDisposable alloc] init];
NSMutableArray *values = [NSMutableArray array];

void (^flushValues)() = ^{
void (^flushValues)(void) = ^{
@synchronized (values) {
[timerDisposable.disposable dispose];

Expand Down
33 changes: 33 additions & 0 deletions ReactiveObjCTests/RACSwiftBridgingSpec.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import Quick
import Nimble
import ReactiveObjC

final class RACSwiftBridgingSpec: QuickSpec {
override func spec() {
describe("RACCommandError") {
it("bridges RACCommandErrorNotEnabled to a Swift error code") {
let error: Error = NSError(domain: RACCommandErrorDomain, code: 1)
expect(RACCommandError.notEnabled ~= error).to(beTrue())
}
}

describe("RACSelectorSignalError") {
it("bridges RACSelectorSignalErrorMethodSwizzlingRace to a Swift error code") {
let error: Error = NSError(domain: RACSelectorSignalErrorDomain, code: 1)
expect(RACSelectorSignalError.methodSwizzlingRace ~= error).to(beTrue())
}
}

describe("RACSignalError") {
it("bridges RACSignalErrorTimedOut to a Swift error code") {
let error: Error = NSError(domain: RACSignalErrorDomain, code: 1)
expect(RACSignalError.timedOut ~= error).to(beTrue())
}

it("bridges RACSignalErrorNoMatchingCase to a Swift error code") {
let error: Error = NSError(domain: RACSignalErrorDomain, code: 2)
expect(RACSignalError.noMatchingCase ~= error).to(beTrue())
}
}
}
}

0 comments on commit a621018

Please sign in to comment.