mamaral / Onboard

An iOS framework to easily create a beautiful and engaging onboarding experience with only a few lines of code.
MIT License
6.46k stars 765 forks source link

Xcode 8, Swift 3, crash #150

Closed Geeroz closed 8 years ago

Geeroz commented 8 years ago

After update to Xcode 8 I got this crash.

* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_SwiftValue setDelegate:]: unrecognized selector sent to instance 0x60000024d9b0' * First throw call stack: (

0   CoreFoundation                      0x000000010f03a34b __exceptionPreprocess + 171
1   libobjc.A.dylib                     0x000000010ea5521e objc_exception_throw + 48
2   CoreFoundation                      0x000000010f0a9f34 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
3   CoreFoundation                      0x000000010efbfc15 ___forwarding___ + 1013
4   CoreFoundation                      0x000000010efbf798 _CF_forwarding_prep_0 + 120
5   Onboard                             0x000000010df85289 -[OnboardingViewController generateView] + 2121
6   Onboard                             0x000000010df83f7b -[OnboardingViewController viewDidLoad] + 171
7   UIKit                               0x000000010faa306d -[UIViewController loadViewIfRequired] + 1258
8   UIKit                               0x000000010faa34a0 -[UIViewController view] + 27
9   UIKit                               0x000000010f96d045 -[UIWindow addRootViewControllerViewIfPossible] + 71
10  UIKit                               0x000000010f96d796 -[UIWindow _setHidden:forced:] + 293
11  UIKit                               0x000000010f9810a9 -[UIWindow makeKeyAndVisible] + 42
12  UIKit                               0x000000010f8fa259 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4818
13  UIKit                               0x000000010f9003b9 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1731
14  UIKit                               0x000000010f8fd539 -[UIApplication workspaceDidEndTransaction:] + 188
15  FrontBoardServices                  0x00000001142e976b __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
16  FrontBoardServices                  0x00000001142e95e4 -[FBSSerialQueue _performNext] + 189
17  FrontBoardServices                  0x00000001142e996d -[FBSSerialQueue _performNextFromRunLoopSource] + 45
18  CoreFoundation                      0x000000010efdf311 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
19  CoreFoundation                      0x000000010efc459c __CFRunLoopDoSources0 + 556
20  CoreFoundation                      0x000000010efc3a86 __CFRunLoopRun + 918
21  CoreFoundation                      0x000000010efc3494 CFRunLoopRunSpecific + 420
22  UIKit                               0x000000010f8fbdb6 -[UIApplication _run] + 434
23  UIKit                               0x000000010f901f34 UIApplicationMain + 159
24  FirstCard                           0x000000010bbe9d3f main + 111
25  libdyld.dylib                       0x0000000111b3268d start + 1
26  ???                                 0x0000000000000001 0x0 + 1

)

Here is the code that I use to create Onboarding in AppDelegate.swift

` func generateOnBoardViewController()-> OnboardingViewController { print("(#function)") // Initialize onboarding view controller // var onboardingVC = OnboardingViewController() let icon = UIImage(named: "empty-biz") let firstPage = OnboardingContentViewController.content(withTitle: "Welcome", body: "Welcome message", image: icon, buttonText: nil) { }

    let secondPage = OnboardingContentViewController.content(withTitle: "Hello", body: "Body", image: icon, buttonText: nil) {
    }
    let thirdPage = OnboardingContentViewController.content(withTitle: "Start now.", body: "Sign up now it's easy.", image: icon, buttonText: nil) {
        self.switchToSignupOrLoginViewControllers()
    }

    let bg = UIImage(named: "onboard-bg")
    let onboardingVC = OnboardingViewController.init(backgroundImage: bg, contents: [firstPage, secondPage, thirdPage])
    return onboardingVC!

}`

Then I check if user is login, if not replace the rootViewController with this code

self.window?.rootViewController = generateOnBoardViewController()

I have try so many init method of OnboardingViewController but none of them works. Any suggestion?

vite7 commented 8 years ago

The same error in my situation.

Here is the code:

    let page1 = OnboardingContentViewController(title: "", body: "ONBOARDING1".l, image:        UIImage(named: "onboarding-page-1"), buttonText: "NEXT".l) { () -> Void in

    }

    let page2 = OnboardingContentViewController(title: "", body: "ONBOARDING2".l, image: UIImage(named: "onboarding-page-2"), buttonText: "NEXT".l) { () -> Void in

    }

    let page3 = OnboardingContentViewController(title: "", body: "ONBOARDING3".l, image: UIImage(named: "onboarding-page-3"), buttonText: "NEXT".l) { () -> Void in

    }

    let page4 = OnboardingContentViewController(title: "", body:"ONBOARDING4".l, image: UIImage(named: "onboarding-page-4"), buttonText: "ONBOARDING_GO".l, actionBlock: { (controller) -> Void in
        controller?.dismiss(animated: true, completion: { 

        })
    })

    let pages = [page1, page2, page3, page4]

    for page in pages {
        page?.bodyLabel.font = UIFont.systemFont(ofSize: 18)
        page?.iconImageView.contentMode = .scaleToFill
        page?.topPadding = 1
        page?.underTitlePadding = -200
        page?.iconWidth = viewController.view.bounds.width
        page?.iconHeight = viewController.view.bounds.height
        page?.actionButton.titleLabel?.font = UIFont.systemFont(ofSize: 14)
        page?.movesToNextViewController = true
    }

    let onboardingVC = OnboardingViewController(backgroundImage: UIImage(named: "onboarding-background"), contents: pages)
    onboardingVC?.shouldMaskBackground = false
    onboardingVC?.modalTransitionStyle = .crossDissolve

    viewController.present(onboardingVC!, animated: true, completion: nil)` 
mamaral commented 8 years ago

I haven't look at swift for Onboard since like Swift 1.2 so I'm assuming there'll need to be a decent amount of changes, but haven't had any time to look into it. Feel free to debug and open a pull request if you're able, otherwise it may be a bit until I support Swift 3.

vite7 commented 8 years ago

Okay. I'll try to fix it. Thank's for your response.

Derekhie commented 8 years ago

vite7, any luck finding the solution for this issue?

vite7 commented 8 years ago

I was used this in one of my projects, so I need to fix it anyway. I'll make a pull request when its done.

On Sep 18, 2016, at 6:59 PM, Derekhie notifications@github.com wrote:

vite7, any luck finding the solution for this issue?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

Derekhie commented 8 years ago

Thanks vite7

ebba-enappstudio commented 8 years ago

Same problem for me! Thanks vite7!

vin-the-dev commented 8 years ago

Same Problem here too Thanks @vite7

phatmann commented 8 years ago

@vite7 Any fix yet?

phatmann commented 8 years ago

I have the fix. Each of the pages is actually an Optional because (1) the initializer is imported into Swift as a failable initializer and (2) Swift3 will not force unwrap an Optional until it has to do so. So just add ! at the end of your page initializers. For example:

let firstPage = OnboardingContentViewController.content(withTitle: "Welcome", body: "Welcome message", image: icon, buttonText: nil) {
}!

OR

... contents: [page1!, page2!, page3!] ...
phatmann commented 8 years ago

So to "fix" this issue we just need to update the README. I will submit a PR for this.

phatmann commented 8 years ago

So, PR #154 fixes the issue so that OnboardingContentViewController instances are no longer optional values. Until this change is merged, use the workaround above and force unwrap these instances.

mamaral commented 8 years ago

v2.3.1 was just pushed and should be available shortly.