1

I am a fan of the guard statements using Swift.

One thing I haven't fully understand is how (or even if) to use it inside a function that expect return value.

Simple example:

func refreshAudioMix() -> AVPlayerItem? {
   guard let originalAsset = rootNC.lastAssetLoaded else {
         return nil
   }
   let asset = originalAsset.copy() as! AVAsset
   ..... return AVPlayerItem ....
}

The issue with this approach is that I need to check the returned value each time. I am trying to understand if am I approaching this correctly or maybe even guard not needed here at all.

Thank you!

Nikhil Manapure
  • 3,748
  • 2
  • 30
  • 55
Roi Mulia
  • 5,626
  • 11
  • 54
  • 105
  • You are using `guard` correctly, but "The issue with this approach is that I need to check the returned value each time." = ?? Please explain by eg. – Nikhil Manapure Sep 14 '17 at 11:21
  • In your sample you are using guard correctly, just know that you can return an optional value in this function. – Damien Sep 14 '17 at 11:39
  • Did you see [`guard` vs `if let`](https://stackoverflow.com/questions/32256834/swift-guard-vs-if-let/39263210#39263210)? – mfaani Sep 14 '17 at 13:19
  • @NikhilManapure Guard expect return call inside the "else" statement, if my using guard inside a "void" function it's enough. Tho, for times my function return a value ( eg : -> Int, -> UIView). I'll need to return nil inside the guard "else" statement, than every time i'll be calling this function, i'll need to check again for nil or actual value, which is the "guard" initial idea.. That's why I was thinking that I might not use it correctly. What do you think? – Roi Mulia Sep 14 '17 at 13:21
  • 1
    @Honey Your linked helped me a lot. Thank you. – Roi Mulia Sep 14 '17 at 13:27

1 Answers1

3

I'd say the use of guard isn't wrong. When the objects you're manipulating have a probability of being nil, it seems fair that you return an optional value.

There's one other way (at least, but I don't see others right now) to handle that: write that your function can throw an error and throw it when you find nil in an optional value in a guard statement. You can even create errors so it's easily readable. You can read more about it here

sample :

enum CustomError: Error {
    case errorOne
    case errorTwo
    case errorThree
}

func refreshAudioMix() throws -> AVPlayerItem {
   guard let originalAsset = rootNC.lastAssetLoaded else {
         throw CustomError.errorOne
   }
   let asset = originalAsset.copy() as! AVAsset
   ..... return AVPlayerItem ....
}
Damien
  • 3,322
  • 3
  • 19
  • 29
  • 1
    Throwing an error instead of returning `nil` is quite a bad idea. Handling a throwing function requires more boilerplate code than handling an optional and throwing an error doesn't add any extra meaning. – Dávid Pásztor Sep 14 '17 at 15:31
  • Yet it does exist and is presented like that in Apple documentation, depends on what having a nil value means in your code. To me it can add an extra meaning, dealing with optional is pretty common everywhere in our apps, so I'd say it depends on the case. – Damien Sep 15 '17 at 09:12
  • Could you please show the part of documentation you are referring to? I am pretty sure Apple doesn't encourage people to add extra complexity to their code by throwing an error instead of using one of the numerous built in methods for handling optionals. – Dávid Pásztor Sep 15 '17 at 09:13
  • look at the link in my answer – Damien Sep 15 '17 at 16:16
  • Either I don't see what you're talking about or you're misunderstanding something in the documentation. I can only see Apple mention converting errors to optionals, while you are talking about it the other way around... – Dávid Pásztor Sep 15 '17 at 17:16
  • guard let item = inventory[name] else { throw VendingMachineError.invalidSelection }; isn't it an optional chaining ? that call an error when the value is nil ? I didn't say Apple told developers to use that method for optionals, I just said it existed and Apple use it in their Documentation. Bye, don't even respond to the comment – Damien Sep 18 '17 at 08:00