YapDatabase icon indicating copy to clipboard operation
YapDatabase copied to clipboard

Proposed API change: Using wrapper objects instead of inout parameters

Open chrisballinger opened this issue 8 years ago • 2 comments

After our Swift 3 transition we ran into problems with our inout parameters to getSectionChanges:rowChanges.

- (void)getSectionChanges:(NSArray<YapDatabaseViewSectionChange *> **)sectionChangesPtr
               rowChanges:(NSArray<YapDatabaseViewRowChange *> **)rowChangesPtr
         forNotifications:(NSArray *)notifications
             withMappings:(YapDatabaseViewMappings *)mappings

I'm wondering if in a future Yap API change, we could return a wrapper object instead.

NS_ASSUME_NONNULL_BEGIN
@interface OTRSectionRowChanges : NSObject
@property (nonatomic, strong, readonly) NSArray<YapDatabaseViewSectionChange *> *sectionChanges;
@property (nonatomic, strong, readonly) NSArray<YapDatabaseViewRowChange *> *rowChanges;
@end

@interface YapDatabaseViewConnection (ChatSecure)

- (OTRSectionRowChanges*) otr_getSectionRowChangesForNotifications:(NSArray<NSNotification*> *)notifications
                                                      withMappings:(YapDatabaseViewMappings *)mappings;
@end

@interface OTRSectionRowChanges()
- (instancetype) initWithSectionChanges:(NSArray<YapDatabaseViewSectionChange *> *)sectionChanges rowChanges:(NSArray<YapDatabaseViewRowChange *> *) rowChanges;
@end

@implementation OTRSectionRowChanges

- (instancetype) initWithSectionChanges:(NSArray<YapDatabaseViewSectionChange *> *)sectionChanges rowChanges:(NSArray<YapDatabaseViewRowChange *> *) rowChanges {
    NSParameterAssert(sectionChanges != nil);
    NSParameterAssert(rowChanges != nil);
    if (self = [super init]) {
        _sectionChanges = sectionChanges;
        _rowChanges = rowChanges;
    }
    return self;
}

@end

@implementation YapDatabaseViewConnection (ChatSecure)

- (OTRSectionRowChanges*) otr_getSectionRowChangesForNotifications:(NSArray<NSNotification*> *)notifications
                                                      withMappings:(YapDatabaseViewMappings *)mappings {
    NSParameterAssert(notifications != nil);
    NSParameterAssert(mappings != nil);
    NSArray *sc = nil;
    NSArray *rc = nil;
    [self getSectionChanges:&sc rowChanges:&rc forNotifications:notifications withMappings:mappings];
    if (!sc) {
        sc = @[];
    }
    if (!rc) {
        rc = @[];
    }
    OTRSectionRowChanges *src = [[OTRSectionRowChanges alloc] initWithSectionChanges:sc rowChanges:rc];
    return src;
}

@end
NS_ASSUME_NONNULL_END

This results in nice simple Swift code, instead of having to mess with optionals, AutoreleasingMutablePointers, and NSArray/Array bridging:

let src = databaseView.otr_getSectionRowChanges(for: notifications, with: mappings)

chrisballinger avatar Feb 24 '17 21:02 chrisballinger

Good idea - would also be a natural place to fix #387, since this object can transform the changes on initialization.

joelekstrom avatar Sep 07 '17 10:09 joelekstrom

For Swift 2.0 and later your '.h' should conatains NS_SWIFT_NAME and look something like following:

#import <YapDatabase/YapDatabaseViewConnection.h>

NS_ASSUME_NONNULL_BEGIN

@interface OTRSectionRowChanges : NSObject
@property (nonatomic, strong, readonly) NSArray<YapDatabaseViewSectionChange *> *sectionChanges;
@property (nonatomic, strong, readonly) NSArray<YapDatabaseViewRowChange *> *rowChanges;
@end

@interface YapDatabaseViewConnection (ChatSecure)

- (OTRSectionRowChanges*) otr_getSectionRowChangesForNotifications:(NSArray<NSNotification*> *)notifications
                                                      withMappings:(YapDatabaseViewMappings *)mappings
                                                    NS_SWIFT_NAME(otr_getSectionRowChanges(notifications:mappings:));
@end

@interface OTRSectionRowChanges()
- (instancetype) initWithSectionChanges:(NSArray<YapDatabaseViewSectionChange *> *)sectionChanges rowChanges:(NSArray<YapDatabaseViewRowChange *> *) rowChanges;
@end

NS_ASSUME_NONNULL_END

CTiPKA avatar Feb 25 '18 21:02 CTiPKA