0

I would like to use the Microsoft's offline data sync framework in a native iOS project. This framework is written in objective-c but I use swift. I implemented my own local data store therefore I had to implement a protocol from the framework. There is a method in the protocol what looks like the following way:

-(nullable NSDictionary *) readTable:(nonnull NSString *)table
                      withItemId:(nonnull NSString *)itemId
                         orError:(NSError * __nullable * __nullable)error;

When I implement the protocol I got this in swift:

func readTable(_ table: String, withItemId itemId: String) throws -> [AnyHashable: Any] {
    fatalError("readTable(table:itemId:) has not been implemented")
}

The problem with that is the return type cannot be nullable because of the orError parameter. In obc it is good because if there is an error in the method the orError param won't be null and the return type of the method can be nil. But in swift the return type cannot be nil because of the method definition. It should throw an error in this case but I must return a nil becuse the framework does not handle any errors.

My question is how can I implement this protocol so this method returns a nil instead of throw an error?

UPDATE

I know it is not the best solution what I'm looking for that's why I asked. I'm going to add more details.

So there is the protocol what I've mentioned above. In the objc MS framework there is a class what calls my swift class what implements this protocol. This method has to retrieve a line from the local database by its id. According to the original objc MS implementation this method return a nil if it does not find any row by id and set an error message in the orError parameter and thus the original code - what called this method - can run onward. But when the MS class calls my class I cannot return a nil because of my swift implementation. I have to throw an error if I didn't find the row by id but in this case the execustion of the caller method gets stuck - because of the error - but according to the original objc code it should run onward without error. Here is a code snippet from the caller class:

// Check to see if this item already exists
                NSString *itemId = itemToSave[MSSystemColumnId];
                NSDictionary *result = [self.dataSource readTable:table withItemId:itemId orError:&error];
                if (error == nil) {
                    if (result == nil) {
                        [self.dataSource upsertItems:@[itemToSave] table:table orError:&error];
                    } else {
                        error = [self errorWithDescription:@"This item already exists."
                                              andErrorCode:MSSyncTableInvalidAction];
                    }
                }

I hope my problem got a little bit clear. Do you have any idea how can I solve that?

ambri
  • 23
  • 4
  • In Objective-C an error is indicated by returning nil. In Swift an error is indicated by throwing an error. So what is the problem? – Possibly helpful: https://stackoverflow.com/q/34786115/1187415. – Martin R Dec 17 '18 at 08:24
  • Why? The pattern to `throw` an error on failure and return a non-optional on success is very convenient. – vadian Dec 17 '18 at 08:25
  • Thank you for your answer. I've updated my post with further information. – ambri Dec 17 '18 at 09:30

0 Answers0