Dhyaan
Dhyaan

Reputation: 111

Swift's "if let" equivalent in Objective C

What would be "if let" equivalent in Objective C? The example snippet I want to convert to Objective C is below;

if let pfobjects = images as? [PFObject] {
    if pfobjects.count > 0 {
        var imageView: PFImageView = PFImageView()
        imageView.file = pfobjects[0] as! PFFile
        imageView.loadInBackground()
    }
}

Upvotes: 9

Views: 8963

Answers (5)

ReDetection
ReDetection

Reputation: 3196

You want three things simultaneously. Let's split them:

  1. variable as? OtherType is possible, but erases type, because it returns id. Implementation is as easy as a category on NSObject class, so it becomes NSArray *array = [jsonDict[@"objects"] ifKindOfClass:NSArray.class].

Implementation

@interface NSObject (OptionalDowncast)
- (id)ifKindOfClass:(__unsafe_unretained Class)clazz;
@end
@implementation NSObject (OptionalDowncast)
- (id)ifKindOfClass:(__unsafe_unretained Class)clazz {
    return [self isKindOfClass:clazz] ? self : nil;
}
@end
  1. if let is also possible in Objective-C if type is known, so it cannot be combined with previous thing. Easiest way is: for(NSArray *array = [self getItems]; array != nil; array = nil) { ... }, but if you want to use else branch, it gets a bit more complex. I have made SwiftyObjC pod for that, please take a look
  2. Check generic template is not possible during type cast in Objective-C, thus you can cast to NSArray, but you can't cast to NSArray<PFObject>

I don't see iterations over your array: With all that being said, I think best example is (assuming images is an array already):

for(PFFile *file = [images.firstObject ifKindOfClass:PFFile.class]; file != nil; file = nil) {
  imageView.file = file;
  [imageView loadInBackground];
}

If you need to also iterate over it:

for(id object in images) {
  for(PFFile *file = [object ifKindOfClass:PFFile.class]; file != nil; file = nil) {
     //operate on file
  }
} 

Upvotes: 0

G. Veronika
G. Veronika

Reputation: 230

You can use something like this:

NSArray<PFObject *> *pfobjects;
if ([images isKindOfClass: [NSArray<PFObject> class]] && (pfobjects = images)) {
    // your code here
}

Upvotes: 0

93sauu
93sauu

Reputation: 4117

You can use Objective-C++ in place of Objective-C. In this you can use the next define:

#define let const auto

Note: it is not the same exactly (Swift has wrapped values, ...) but it makes the work easier.

And through of this define you can use it of this way:

if (let pfobjects = images) {
    if (pfobjects.count > 0 {
        let imageView = [[PFImageView alloc] init];
        imageView.file = pfobjects[0];
        imageView loadInBackground();
    }
}

To convert your Objective-C class in Objective-C++ class you only must change the extension of implementation file of .m to .mm

Upvotes: -3

malhal
malhal

Reputation: 30689

You can use NSPredicate to verify the array contains only instances of PFObject:

NSPredicate *p = [NSPredicate predicateWithFormat:@"self isKindOfClass: %@", [PFObject class]];
NSInteger numberThatArePFObjects = [images filteredArrayUsingPredicate:p].count;
if(numberThatArePFObjects && numberThatArePFObjects == images.count){
    // certain that images only contains instances of PFObject.
}

If however you weren't working with an array but a single object then it is simpler:

if([image isKindOfClass:[PFObject class]]){
    // certain that image is a valid PFObject.
}

Or if you wanted a new variable:

PFObject* obj = nil;
if([image isKindOfClass:[PFObject class]] && (obj = image)){
    // certain that obj is a valid PFObject.
}

Upvotes: 1

rob mayoff
rob mayoff

Reputation: 385860

There's no direct equivalent to if let in Objective-C, because if let does Swift-specific things (unwrapping optionals and rebinding identifiers) that don't have direct equivalents in Objective-C.

Here's a nearly equivalent of your Swift code:

if (images != nil) {
    NSArray<PFObject *> *pfobjects = (id)images;
    if (pfobjects.count > 0) {
        PFImageView *imageView = [[PFImageView alloc] init];
        assert([pfobjects[0] isKindOfClass:[PFFile class]]);
        imageView.file = (PFFile *)pfobjects[0];
        [imageView loadInBackground];
    }
}

But this Objective-C code won't verify that images only contains instances of PFObject, and should successfully create an image view as long as pfobjects[0] is a PFFile. Your Swift code will do nothing (create no image view) if images contains any non-PFObject elements.

Upvotes: 7

Related Questions