Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building a LEGO ® app with CocoaPods

Artheyn
January 19, 2017

Building a LEGO ® app with CocoaPods

How to architecture a mobile app into reusable bricks linked together with CocoaPods.

Artheyn

January 19, 2017
Tweet

More Decks by Artheyn

Other Decks in Programming

Transcript

  1. Problematic Build a new application which reuses a lot of

    core functionalities of an existing one 2
  2. Solutions 3 • Using git submodules ‣ Hard to maintain

    with a lot of dependencies ‣ Hard to manage a proper versioning for each module ‣ Easy to link ‣ Versioning management and locking for free • Using a package manager
  3. Overview • Slicing the app: iAdvize App case study 4

    • In practice: build & use bricks • Pros & Cons • The wrong way • Our modules • Conclusion
  4. 5 1. Identify the main app domains which will form

    our bricks 2. Separate each brick from the main app 3. Reconstruct the main app by linking the bricks together Slicing the app Steps
  5. 6 Step 1 In Search of Lost Bricks User Account

    Login Logger … … … … … …
  6. 8 App Pods Workspace Podfile Step 2 Splitting the app

    into bricks App Pods Podfile Login Workspace Login
  7. 9 Step 2 Extracting the bricks App Pods Podfile Login

    Workspace Pods Workspace Podfile Login
  8. 10 Step 2 Extracting the bricks App Pods Workspace Podfile

    Login Pods Workspace Podfile Auth Pods Workspace Podfile …
  9. 12 Step 2 Module Structure Login UI Tests Login Sources

    Login Tests Login
 Integration
 App Sources Login
  10. 13 • Using an internal pod repo ‣ Useful for

    strict versioning ‣ Useless if you want to point a dependency directly to a branch • Using direct git repository link with a specific branch pod 'iAdvizeLoggerLibrary', :git => 'ssh://(…)/mobile-ios-logger-library.git', :branch => 'master' Step 3 Rebuild with CocoaPods Two different ways to manage dependencies:
  11. 14 App Pods Workspace Podfile Login Podspec Step 3 Rebuild

    with Cocoapods :branch => ‘master’
  12. 15 Sample of a Podfile in the main application def

    app_pods # COCOAPODS EXTERNAL DEPENDENCIES # HTTP requests. pod 'Alamofire', '~> 4.0' # (…) # COCOAPODS INTERNAL DEPENDENCIES # User service (user-related data storage) pod 'iAdvizeUserService', :git => 'ssh://[email protected]/iadvize/mobile-ios-user-service.git', :branch => 'master' # Account service (user profile) pod 'iAdvizeAccountService', :git => 'ssh://[email protected]/iadvize/mobile-ios-account-service.git', :branch => 'master' # Components library (reusable UI components) pod 'iAdvizeComponentsLibrary', :git => 'ssh://[email protected]/iadvize/mobile-ios-components-library.git', :branch => 'master' end Step 3 Rebuild with Cocoapods
  13. In practice 16 CocoaPods and the power of the `path`

    App Podfile Login Workspace Pods Workspace Podfile Pods pod 'iAdvizeLoginService', :path => '../mobile-ios-login-service' :path => ‘../login’ Login
  14. In practice 17 CocoaPods and the power of the `path`

    • Editing directly module files in the main app workspace like if the module was directly in your app ‣ Impossible with Carthage! • Test locally the integration of a module in the main app
  15. In practice 18 Module creation Login Podspec Podfile Module Sources

    App 1 2 3 4 Podfile :path => ‘../module’ :branch => ‘master’
  16. In practice 19 Module usage pod 'iAdvizeConversationService', :git => ‘ssh://(…)/mobile-ios-conversation-service.git’,

    :branch => 'master' 1. Add module dependency in the Podfile 2. Import, configure and use your module in your app import iAdvizeConversationService ConversationServiceManager.shouldDisplayPrincipalImageInChat = true let conversationRootViewController = ConversationServiceManager.initialViewController() as! UISplitViewController addControllerToTabBar(conversationRootViewController, at: 0)
  17. In practice 20 Application: Orchestrator of modules • Almost empty

    and deserves as a module orchestrator • Instantiates, configures and displays each module • Observes modules events (notifications) and actions (delegate) • Can forward events between modules
  18. In practice 21 Module: Reusable brick • Contains all the

    sources of a domain (including tests) • Exposes events that apps or modules can observe • Provides a way to configure it • Provides an initial view controller (if it contains some UI) • In a separate project
  19. Git workflows 22 In our applications ‣ git-flow In our

    modules ‣ “github like” workflow working with master, feature branches and tags for production versions
  20. Pros 23 • Fully separated and reusable modules ‣ Helps

    to have a proper architecture and avoid duplications • Each module has its own Xcode project so it can be developed, run and tested independently (without integrating it in a main application) ‣ Can even be shipped as a single module app for acceptance tests • Lighter Xcode project which means low build time when you work on a module • Easy to integrate with the CocoaPods local link (path) • Even if we don’t use strict versioning, we get the benefits of module version locking with the Podfile.lock • More modules -> more chance you have to work alone at a time -> less conflicts
  21. Cons 24 • Some configuration files has to be duplicated

    ‣ Continuous integration, lint, localizables, run scripts… • Multiple Podspec and Podfile to work with and maintain • Switching module dependency from remote repository to local sources and vice versa has to be done manually in the Podfile pod 'iAdvizeLoggerLibrary', :git => ‘(…)mobile-ios-logger-library.git’, :branch => 'master' pod 'iAdvizeLoggerLibrary', :path => ‘../mobile-ios-logger-library’
  22. Our modules 25 Spreading ideas User Account Authentication CommonUI Components

    Conversation Livefeed Logger Login Stats PushNotifs Tracking Utils
  23. The Wrong Way 26 (For us) • Using an Internal

    Cocoapods specs repository was not relevant ‣ Use the git repository direct link feature of CocoaPods and point to a specific branch • Trying to use strict versioning on modules can quickly turn into a nightmare ‣ No versioning is applied to our modules. The Podfile.lock prevent from accidental updates and as we own our dependencies we are full aware of break changes • Applying a complex git workflow in the modules repositories is time- consuming ‣ Using a single branch with tags for versions in production seems to be the best solution
  24. Conclusion 27 Great and straightforward mobile architecture approach even for

    small applications which helps you to think your code in terms of reusable bricks. Just taste it!