Giter Club home page Giter Club logo

vipermcflurry's Introduction

Overview

Pod version

VIPER McFlurry is a modern framework for implementing VIPER architecture in iOS application. It offers several tools and components that help either start new projects with VIPER or move from MVC.

McFlurry

Key Features

  • The framework itself pushes you to implement a proper VIPER architecture,
  • It provides an extremely nice and easy way to implement intermodule data transfer,
  • Used in default Generamba template.

Usage

This example works only for Module with UIViewController as View. However, it's possible to use this approach even with UIView and UITableViewCell acting as View.

  • Create Module input protocol for target module inherited from RamblerViperModuleInput:
@protocol SomeModuleInput <RamblerViperModuleInput>

- (void)moduleConfigurationMethod;

@end
  • Make Presenter of target module conform to this protocol.
  • Inject Presenter as moduleInput property of the view. You can skip this step if presenter is a view property with name "output".
  • Add Segue from source module ViewController to target module ViewController.
  • Inject Source ViewController into Source Router as property "transition handler".
  • In Router method call transition handler to open target module with configuration during segue.
[[self.transitionHandler openModuleUsingSegue:SegueIdentifier]
	thenChainUsingBlock:^id<RamblerViperModuleOutput>(id<SomeModuleInput> moduleInput) {
		[moduleInput moduleConfigurationMethod];
		return nil;
	}];

Working with Module output

  • Create Module output protocol for target module inherited from RamblerViperModuleOutput:
@protocol SomeModuleOutput <RamblerViperModuleOutput>

- (void)moduleConfigurationMethod;

@end
  • Make source module presenter to conform to this protocol.
  • Add to target module presenter method:
- (void)setModuleOutput:(id<RamblerViperModuleOutput>)moduleOutput;
  • Return source module presenter from configuration block in router:
[[self.transitionHandler openModuleUsingSegue:SegueIdentifier]
	thenChainUsingBlock:^id<RamblerViperModuleOutput>(id<SomeModuleInput> moduleInput) {
		[moduleInput moduleConfigurationMethod];
		return sourceRouterPresenter; // Return of module output
	}];

Working with Module Factory

Module factory can be replaced with segues for most cases. Except you need to create complex module or nontrivial module instantiation logic.

  • Use RamblerViperModuleFactory object as module fabric with Typhoon.
  • Set definition Initializer to initWithViewControllerLoader:andViewControllerIdentifier:
    • First parameter is the object which loads the view controller, e.g. UIStoryboard or TyphoonNibLoader instance,
    • Second parameter is view controller's identifier, e.g. RestorationID or NibName of ViewController.
  • Typhoon will initialize module from ViewController.
  • Inject this Factory into router.
  • Call Transition Handler's method - openModuleUsingFactory:withTransitionBlock:.
  • Second block is place where transition from one to another viewController/transitionHandler should be performed:
    [[self.transitionHandler openModuleUsingFactory:self.betaModuleFactory
                                withTransitionBlock:^(id <RamblerViperModuleTransitionHandlerProtocol> sourceModuleTransitionHandler,
                                        id <RamblerViperModuleTransitionHandlerProtocol> destinationModuleTransitionHandler) {

                                    UIViewController *sourceViewController = (id) sourceModuleTransitionHandler;
                                    UIViewController *destinationViewController = (id) destinationModuleTransitionHandler;

                                    [sourceViewController.navigationController pushViewController:destinationViewController
                                                                                         animated:YES];

                                }] thenChainUsingBlock:^id<RamblerViperModuleOutput>(id<RamblerModuleBetaInput> moduleInput) {
                                   [moduleInput configureWithExampleString:exampleString];
                                   return nil;
                               }];
  • In example above one module is pushed to navigation stack of another module.
  • Modules are linked with intermodule data transfer block.

Installation

Add to podfile

pod "ViperMcFlurry"

License

MIT

Authors

Rambler&Co team:

vipermcflurry's People

Contributors

alaija avatar andreyzarembo avatar brain89 avatar dani-gavrilov avatar delebedev avatar etolstoy avatar isevendays avatar juyka avatar metalheadsanya avatar readmecritic avatar rock88 avatar serkrapiv avatar valentinpopkov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vipermcflurry's Issues

Swift: openModuleUsingSegue holds old VC in memory

screen shot 2016-07-18 at 09 15 41

Привет, на скриншоте видно что у нас в памяти находятся два SecondViewController(3,10,2...) другими словами, кто то держит старые реферы в памяти. Вот реализация Роутера:

screen shot 2016-07-18 at 09 24 58

При подходе с фабриками все ок.

Без moduleOutput ситуация таже.

Думаю на свизлинг. Может у вас будут идеи. Спасибо

Ошибка в Podfile примера

Здравствуйте, не удаётся запустить пример из мастера.

В Podfile дважды объявлен таргет "ViperMcFlurry_Tests" и нет таргета "ViperMcFlurry_Example".

Carthage integration

Version 1.5.1 does not build with latest Carthage.

CompileC ~/Library/Developer/Xcode/DerivedData/ViperMcFlurry-fixoxtjhfnbvqbcmndjrdxijtiic/Build/Intermediates/ViperMcFlurry.build/Release-iphoneos/ViperMcFlurry.build/Objects-normal/arm64/RamblerViperModuleFactory.o /Users/alexanderzalutskiy/Work/Gazelkin/Carthage/Checkouts/ViperMcFlurry/Code/IntermoduleDataTransfer/RamblerViperModuleFactory.m normal arm64 objective-c com.apple.compilers.llvm.clang.1_0.compiler
CompileC ~/Library/Developer/Xcode/DerivedData/ViperMcFlurry-fixoxtjhfnbvqbcmndjrdxijtiic/Build/Intermediates/ViperMcFlurry.build/Release-iphoneos/ViperMcFlurry.build/Objects-normal/armv7/RamblerViperOpenModulePromise.o /Users/alexanderzalutskiy/Work/Gazelkin/Carthage/Checkouts/ViperMcFlurry/Code/IntermoduleDataTransfer/RamblerViperOpenModulePromise.m normal armv7 objective-c com.apple.compilers.llvm.clang.1_0.compiler
CompileC ~/Library/Developer/Xcode/DerivedData/ViperMcFlurry-fixoxtjhfnbvqbcmndjrdxijtiic/Build/Intermediates/ViperMcFlurry.build/Release-iphoneos/ViperMcFlurry.build/Objects-normal/armv7/RamblerViperModuleFactory.o /Users/alexanderzalutskiy/Work/Gazelkin/Carthage/Checkouts/ViperMcFlurry/Code/IntermoduleDataTransfer/RamblerViperModuleFactory.m normal armv7 objective-c com.apple.compilers.llvm.clang.1_0.compiler
CompileC ~/Library/Developer/Xcode/DerivedData/ViperMcFlurry-fixoxtjhfnbvqbcmndjrdxijtiic/Build/Intermediates/ViperMcFlurry.build/Release-iphoneos/ViperMcFlurry.build/Objects-normal/arm64/RamblerViperOpenModulePromise.o /Users/alexanderzalutskiy/Work/Gazelkin/Carthage/Checkouts/ViperMcFlurry/Code/IntermoduleDataTransfer/RamblerViperOpenModulePromise.m normal arm64 objective-c com.apple.compilers.llvm.clang.1_0.compiler
CompileC ~/Library/Developer/Xcode/DerivedData/ViperMcFlurry-fixoxtjhfnbvqbcmndjrdxijtiic/Build/Intermediates/ViperMcFlurry.build/Release-iphoneos/ViperMcFlurry.build/Objects-normal/arm64/UIViewController+RamblerViperModuleTransitionHandlerProtocol.o /Users/alexanderzalutskiy/Work/Gazelkin/Carthage/Checkouts/ViperMcFlurry/Code/IntermoduleDataTransfer/UIViewController+RamblerViperModuleTransitionHandlerProtocol.m normal arm64 objective-c com.apple.compilers.llvm.clang.1_0.compiler
CompileC ~/Library/Developer/Xcode/DerivedData/ViperMcFlurry-fixoxtjhfnbvqbcmndjrdxijtiic/Build/Intermediates/ViperMcFlurry.build/Release-iphoneos/ViperMcFlurry.build/Objects-normal/armv7/UIViewController+RamblerViperModuleTransitionHandlerProtocol.o /Users/alexanderzalutskiy/Work/Gazelkin/Carthage/Checkouts/ViperMcFlurry/Code/IntermoduleDataTransfer/UIViewController+RamblerViperModuleTransitionHandlerProtocol.m normal armv7 objective-c com.apple.compilers.llvm.clang.1_0.compiler

Close multiple modules question

Hi guys, can you provide example how to close multiple modules at a time? Or using "unwind" segues will work like a charm?

Incorrect checking if destinationViewController has moduleInput method

Look UIViewController+RamblerViperModuleTransitionHandlerProtocol.m at lines 112-115, there you can see the following:

id<RamblerViperModuleTransitionHandlerProtocol> targetModuleTransitionHandler = destinationViewController;
if ([targetModuleTransitionHandler respondsToSelector:@selector(moduleInput)]) {
    moduleInput = [targetModuleTransitionHandler moduleInput];
}

and lines 28-34:

- (id)moduleInput {
    id result = objc_getAssociatedObject(self, @selector(moduleInput));
    if (result == nil && [self respondsToSelector:@selector(output)]) {
        result = [(id<TranditionalViperViewWithOutput>)self output];
    }
    return result;
}

This checking is incorrect, because if you implement method in category of some object (for example UIViewController), like you do at lines 28-34, all objects of this class (all UIViewControllers) will respond to this method even if you won't import this category.

Also look UIViewController+RamblerViperModuleTransitionHandlerProtocol.h at line 11, there you can see the following:

@interface UIViewController (RamblerViperModuleTransitionHandlerProtocol)<RamblerViperModuleTransitionHandlerProtocol>

This mean that all objects of this class (all UIViewControllers) will conform to this protocol, so even if you will try to change old checking with something like this:

if ([destinationViewController conformsToProtocol:@protocol(RamblerViperModuleTransitionHandlerProtocol)]) {
    moduleInput = [destinationViewController moduleInput];
}

every UIViewController will pass this check.

Because of this, when i try to combine VIPER module with old MVC like this:

[[self.transitionHandler openModuleUsingSegue:@"..."] thenChainUsingBlock:^id<RamblerViperModuleOutput>(id<RamblerViperModuleInput> moduleInput) {
    return nil;
}];

i got nil in moduleInput, instead of expected segue.destinationViewController.

Model output example

Здраствуйте дорогие.
Мне очень интересно узнать как законфигурить model output. В вашем примере в README непонятно кто target module, а кто source module, и зачем в протоколе RamblerViperModuleInput находится optional public func setModuleOutput(moduleOutput: RamblerViperModuleOutput!).
Допустим у нас есть модуль First который открывает модуль Second по openModuleUsingSegue. Кто из них должен имплементить RamblerViperModuleOutput?

Implementation for macOS target?

Hey, guys!

How about an implementation of a framework for macOS target? I'll suggest that it's easy to implement this feature. Also, I can try this and make PR.

ViperMCFlurry for Swift.

Здравствуйте ребят, возникла проблема с работой VMCF, происходит ошибка при которой я не соответствую типу RamblerViperModuleLinkBlock. В своем проекте я использую Generamba и не использую Typhoon, так как не считаю это необходимым (Возможно, я не прав так что поправьте). Следуя документации к библиотеке, у меня должен быть подобный блок кода:

[[self.transitionHandler openModuleUsingSegue:SegueIdentifier]
    thenChainUsingBlock:^id<RamblerViperModuleOutput>(id<SomeModuleInput> moduleInput) {
        [moduleInput moduleConfigurationMethod];
        return nil;
    }];

А вот мой код, с ошибкой:

pastedgraphic-1

Наверное, потому что требуется вернуть non-optional значение и поэтому я не соответствую RamblerViperModuleLinkBlock. Если есть возможность, можете объяснить что я не так делаю? И где присвоить значение в transitionHandler, и что именно нужно туда присвоить? Так как я новичок, то любая помощь будет полезна. Заранее спасибо!

Method - (void)closeCurrentModule in UIViewController (RamblerViperModuleTransitionHandlerProtocol) is not working properly

The implementation of this method gets stuck in the following case - we have a modal UINavigationController with a stack of UIViewControllers. Currently it will close the modal controller, no matter where you called this method. The problem is in this sequence:

- (void)closeCurrentModule {
    if (self.presentingViewController) {
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    else if ([self.parentViewController isKindOfClass:[UINavigationController class]]) {
...

Ошибки при сборке McFlurry

Содержимое Podfile:

platform :ios, '8.0'

source 'https://github.com/cocoapods/Specs.git'

inhibit_all_warnings!
use_frameworks!

target 'news' do
    pod "Typhoon"
    pod "RamblerTyphoonUtils"
    pod "ViperMcFlurry"
end

Через Generamba rviper_controller генерится код, который использует ViperMcFlurry
Например в NewsModuleAssembly.m у меня:
#import <ViperMcFlurry/ViperMcFlurry.h>

Который не видит такой либы. Устанавливаю через CocoaPods

При попытке запустить проект с сгенереным кодом и с установленными Pods
есть 2 ошибки связанные с McFlurry ошибки:

/Users/Evsenev/news/Pods/ViperMcFlurry/Code/IntermoduleDataTransfer.h
/Users/Evsenev/news/Pods/ViperMcFlurry/Code/IntermoduleDataTransfer.h:11:9: 'RamblerViperModuleFactoryProtocol.h' file not found

/Users/Evsenev/news/news/modules/NewsModule/Router/NewsModuleRouter.m
/Users/Evsenev/news/news/modules/NewsModule/Router/NewsModuleRouter.m:11:9: Could not build module 'ViperMcFlurry'

iOS 14 Crash

Hello,

I am having a new error when I try to run my app with iOS 14 and XCode 12 beta 6. What might cause this and how can I solve it?

/Users/test/Documents/TestApp/TestApp/Test App/Classes/Modules/Poses/Router/YMTestRouter.m:20:86: Incompatible block pointer types sending 'id (^)(__strong id)' to parameter of type 'RamblerViperModuleLinkBlock' (aka 'id (^)(__strong id)')

[[self.transitionHandler openModuleUsingSegue:@"openDetail"] thenChainUsingBlock:^id <RamblerViperModuleOutput>(id <YMTestModuleInput> moduleInput) {
    [moduleInput configureCurrentModuleWithPlainTestObject:object];
    return nil;
}];

BTW, Your example app also crashes with the same error.

1.3.0 не компилируется со Swift

В версии 1.2.0 IntermoduleDataTransfer.h был такой:

#import "IntermoduleDataTransfer/RamblerViperModuleFactoryProtocol.h"
#import "IntermoduleDataTransfer/RamblerViperModuleInput.h"
#import "IntermoduleDataTransfer/RamblerViperModuleOutput.h"
#import "IntermoduleDataTransfer/RamblerViperModuleTransitionHandlerProtocol.h"
#import "IntermoduleDataTransfer/RamblerViperOpenModulePromise.h"
#import "IntermoduleDataTransfer/UIViewController+RamblerViperModuleTransitionHandlerProtocol.h"
#import "IntermoduleDataTransfer/RamblerViperModuleFactory.h"

В 1.3.0 убрали папки и теперь не компилируется:
screen

Установка через CocoaPods 1.0.1
XCode 7.3.1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.