CartoDB / mobile-ios-samples

iOS mobile app with CARTO Mobile SDK
BSD 2-Clause "Simplified" License
30 stars 12 forks source link

Storyboard support using Swift #13

Closed randyhbh closed 7 years ago

randyhbh commented 7 years ago

Hi, I have reviewed the examples of ios and noticed that they do not use the storyboard, this means that the whole design of the app has to be done in code. Thanks in advance.

Nikituh commented 7 years ago

The samples do not use storyboard, but by no means do you have to write your app in code. HelloMap.Objective-C uses a storyboard-based implementation and our documentation features a Getting Started section where the map view is initialized in a storyboard.

randyhbh commented 7 years ago

Try to reproduce the example of objective-c in the introduction section with Swift, also check the HelloMap.Swift looking for this approximation, but without luck. This is the error that the compiler gives me: Could not convert value of type 'GLKView' (0x1eb4af8) to 'NTMapView' (0x732bfc). Any suggestion. Thanks in advance

Nikituh commented 7 years ago

Unfortunately I cannot reproduce your issue. It worked fine by exactly following the iOS guide. What Swift version are you doing? Could you perhaps share your source code?

On a completely unrelated note, have you considered writing your views in code as well? I once wrote a blog post on the perils of being a mobile developer, here's an abstract concerning the storyboard:

In short, Storyboards are Apple’s preffered approach to writing views. It’s a drag-and-drop interface of buttons and labels that you connect to the controller, where you actually start writing code.

And already we see a huge flaw in the concept: I need to manually connect my views to a controller, create reference objects that I can use in my controller to update that storyboard. This is the definition of a clusterfuck. Sure, you can see your views before you start debugging your application, but the interface is slow, complex and the extra layer of abstraction just creates more confusion than it solves.

Also, when your application becomes more complex, the more complex and slow your storyboard interfance becomes. It’s not very scalable.

Another argument would be merge conflicts. I have no idea what’s happening there behind the scenes, but just opening a file changes its configuration file, and the structure of it is unbearable -- meaning that it becomes a nightmare when several developers need to touch the same storyboard.

I mentioned the drag-and-drop interface and the speed, but there’s more to this: it’s laggy and it’s mouse-only. Writing views in code is literally faster.

To sum up, ironically, I can set up a complex view in code much faster and cleaner than if I did it with the interface builder.

randyhbh commented 7 years ago

Hi, thanks for your reply, I'm using XCode 8.2.1, I'm not sure which version of Swift, but I think it's version 3.0.1. Here is my source code https://github.com/RandyHBH/cartodb-ios-map-example.git, I am very glad to see that you can help me, help is very well received.

About writing my views in code, the truth is that I have considered it, but I am relatively new and I am still learning, but I will take very into account your opinion and if you could leave the link to your blog post, it would be of great help.

Nikituh commented 7 years ago

The blog's currently not active, so I cannot really link the entire post. Either way, your problem was with how you initialize your storyboard. What you're doing is basically using a storyboard, but then still initializing your views in code.

window?.rootViewController = UINavigationController(rootViewController: ViewController());
window?.makeKeyAndVisible();

You're currently pushing a custom controller that's not really connected to any storyboard. So, yes, your view object won't be a NTMapView. If you change your view logic to:

self.mapView = NTMapView()
view = mapView

...you'll have a functional MapView :). Because then you initialize it purely in code and then set contentview as your mapView object.

Alternatively, if you just remove the following the lines from AppDelegate.swift, it'll work as well:

window?.rootViewController = UINavigationController(rootViewController: ViewController());
window?.makeKeyAndVisible();

Just delete them, no need to replace with anything. Then it'll properly initialize your app from the storyboard and you'll be able to set your mapView object as:

self.mapView = view as! NTMapView
randyhbh commented 7 years ago

Regards The first approach worked well, but the alternative with the storyboard does not, I follow the steps:

self.mapView = view as! NTMapView

Give me this error

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[GLKViewController loadView] loaded the "BYZ-38-t0r-view-8bC-Xf-vdC" nib but didn't get a GLKView.'
*** First throw call stack:
(
    0   CoreFoundation                      0x03b64bf2 __exceptionPreprocess + 194
    1   libobjc.A.dylib                     0x0361de66 objc_exception_throw + 52
    2   CoreFoundation                      0x03bd6f85 +[NSException raise:format:] + 133
    3   GLKit                               0x01e434ed -[GLKViewController loadView] + 327
    4   UIKit                               0x02082ae9 -[UIViewController loadViewIfRequired] + 188
    5   UIKit                               0x0208350d -[UIViewController view] + 29
    6   UIKit                               0x01f2995f -[UIWindow addRootViewControllerViewIfPossible] + 72
    7   UIKit                               0x01f2a0a7 -[UIWindow _setHidden:forced:] + 335
    8   UIKit                               0x01f2a53f -[UIWindow _orderFrontWithoutMakingKey] + 30
    9   UIKit                               0x01f3f0bc -[UIWindow makeKeyAndVisible] + 64
    10  UIKit                               0x01eac1fe -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 5053
    11  UIKit                               0x01eb30a4 -[UIApplication _runWithMainScene:transitionContext:completion:] + 2004
    12  UIKit                               0x01ed47d5 __84-[UIApplication _handleApplicationActivationWithScene:transitionContext:completion:]_block_invoke.3129 + 53
    13  UIKit                               0x01eafcc2 -[UIApplication workspaceDidEndTransaction:] + 172
    14  FrontBoardServices                  0x0a2431a5 __37-[FBSWorkspace clientEndTransaction:]_block_invoke_2 + 59
    15  FrontBoardServices                  0x0a242cc5 __40-[FBSWorkspace _performDelegateCallOut:]_block_invoke + 49
    16  FrontBoardServices                  0x0a26c66c __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 23
    17  FrontBoardServices                  0x0a26c4cd -[FBSSerialQueue _performNext] + 166
    18  FrontBoardServices                  0x0a26c8ad -[FBSSerialQueue _performNextFromRunLoopSource] + 52
    19  FrontBoardServices                  0x0a26bcc7 FBSSerialQueueRunLoopSourceHandler + 29
    20  CoreFoundation                      0x03b03edf __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
    21  CoreFoundation                      0x03ae7fa7 __CFRunLoopDoSources0 + 519
    22  CoreFoundation                      0x03ae7434 __CFRunLoopRun + 1124
    23  CoreFoundation                      0x03ae6d5b CFRunLoopRunSpecific + 395
    24  CoreFoundation                      0x03ae6bbb CFRunLoopRunInMode + 123
    25  UIKit                               0x01eae33b -[UIApplication _run] + 542
    26  UIKit                               0x01eb4ff3 UIApplicationMain + 148
    27  WeGoCuba                            0x00043111 main + 145
    28  libdyld.dylib                       0x04893799 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)

I'm doing something wrong, I'm missing something. Thanks for your help

Nikituh commented 7 years ago

If you look closely at the documentation, you'll notice that we haven't set a custom module that's "Inherited From Target". The Module is none, you have WeGoCuba there. If you remove it, it will run correctly. It's because GLKView is not part of your module.

Screenshot: https://carto.com/docs/img/layout/mobile/xcode_storyboard.aa785d73.jpg

randyhbh commented 7 years ago

Regards, sorry the delay in replying is that due to the uracan Irma my country suffered great damage and the electric fluid was affected. About the error I solved it, thank you very much.

I have other questions, should I open another issue?

Thank you very much in advance.

Nikituh commented 7 years ago

Gosh, I hope you're alright! No problem, glad I could help, and sure, you can always open another issue.

jaakla commented 7 years ago

@RandyHBH I wish you good strength to fight with the Irma disaster damages! A comment about our samples - if you find questions/bugs/suggestions in our specific sample, then post as new issues. If you have any other questions about SDK in general (how to do something), then better channel would be posting to stackoverflow with carto-mobile tag