15

I am getting the following error when trying to archive my build on XCode:

/Users/AppDelegate.swift:18:9: 'guard' body may not fall through, consider using 'return' or 'break' to exit the scope

It is a little frustrating, because it is the exact code that Google Analytics (I just copied/pasted) suggests you to put in appdelegate to set-up their analytics. Also, it only occurs when archiving my build. It does not occur when just running my code in the simulator.

Would appreciate if anyone had some ideas.

EDIT: I also tried placing a break or continue after the assert, but I got an error...Something about it not being a loop.

import UIKit
import Firebase

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        FIRApp.configure()

        //Google Analytics
        guard let gai = GAI.sharedInstance() else {
            assert(false, "Google Analytics not configured correctly")
        }
        gai.tracker(withTrackingId: "xxxxxxxxxxx")
        // Optional: automatically report uncaught exceptions.
        gai.trackUncaughtExceptions = true

        // Optional: set Logger to VERBOSE for debug information.
        // Remove before app release.
        gai.logger.logLevel = .verbose;


        return true
    }
user2411290
  • 631
  • 2
  • 10
  • 33
  • 1
    See https://stackoverflow.com/a/29149643/1187415 for an explanation why the error occurs only for the "Archive" build and not for a "Debug" build. – Martin R Jun 27 '17 at 18:21
  • 2
    You should use `assertionFailure` instead of `assert(false,...)`, although unfortunately, `assertionFailure` doesn't return `Never`, which would satisfy a guard statement's requirement of exiting scope. – Alexander Jun 27 '17 at 18:22
  • 1
    @Alexander: Also assertionFailure is ignored in "-O" builds, in contrast to fatalError(). – Martin R Jun 27 '17 at 18:25
  • 1
    @MartinR Interesting. Can you think of a use case in which `assertionFailure` is preferable? – Alexander Jun 27 '17 at 18:44
  • 2
    You probably want the released application to run even if Google Analytics could not be initialized. – Martin R Jun 27 '17 at 18:49

1 Answers1

33

guard let function needs to exit the current scope of your gai variable. So you need to modify your code to

guard let gai = GAI.sharedInstance() else {
    assert(false, "Google Analytics not configured correctly")
    return true//Base on your function return type, it may be returning something else
}

Here is the document:

The else clause of a guard statement is required, and must either call a function marked with the noreturn attribute or transfer program control outside the guard statement’s enclosing scope using one of the following statements:

return break continue throw

Fangming
  • 24,551
  • 6
  • 100
  • 90
  • 1
    Unexpected non-void return value in void function – Abhishek Mitra Dec 19 '17 at 14:40
  • 2
    @AbhishekMitra You just need to exit current scope. The return type is based on your function return type. if your function is not returning anything, then just do `return` – Fangming Jan 19 '18 at 12:50