1680800213
Getting started with Modular
Please send feature requests and bugs at the issue tracker.
This README was created based on templates made available by Stagehand under a BSD-style license.
This project follows the all-contributors specification. Contributions of any kind are welcome!
Run this command:
With Flutter:
$ flutter pub add flutter_modular
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
flutter_modular: ^5.0.3
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:flutter_modular/flutter_modular.dart';
import 'package:flutter/material.dart';
import 'package:flutter_modular/flutter_modular.dart';
import 'app/app_module.dart';
import 'app/app_widget.dart';
void main() {
runApp(ModularApp(module: AppModule(), child: AppWidget()));
}
Download Details:
Author: flutterando.com.br
Source Code: https://github.com/Flutterando/modular
1679593320
Modular, contributor-friendly and blazing-fast implementation of the Ethereum protocol
The project is still work in progress, see the disclaimer below.
Reth (short for Rust Ethereum, pronunciation) is a new Ethereum full node implementation that is focused on being user-friendly, highly modular, as well as being fast and efficient. Reth is an Execution Layer (EL) and is compatible with all Ethereum Consensus Layer (CL) implementations that support the Engine API. It is originally built and driven forward by Paradigm, and is licensed under the Apache and MIT licenses.
As a full Ethereum node, Reth allows users to connect to the Ethereum network and interact with the Ethereum blockchain. This includes sending and receiving transactions/logs/traces, as well as accessing and interacting with smart contracts. Building a successful Ethereum node requires creating a high-quality implementation that is both secure and efficient, as well as being easy to use on consumer hardware. It also requires building a strong community of contributors who can help support and improve the software.
More concretely, our goals are:
The project is not ready for use. We hope to have full sync implemented sometime in Q1 2023, followed by optimizations. In the meantime, we're working on making sure every crate of the repository is well documented, abstracted and tested.
See the Reth Book for instructions on how to run Reth.
Rust minimum required version to build this project is 1.65.0 published 02.11.2022
Prerequisites:
libclang
libclang-dev
To fully test Reth, you will need to have Geth installed, but it is possible to run a subset of tests without Geth.
First, clone the repository:
git clone https://github.com/paradigmxyz/reth
cd reth
Next, run the tests:
# Without Geth
cargo test --all
# With Geth
cargo test --all --features geth-tests
We recommend using cargo nextest
to speed up testing. With nextest installed, simply substitute cargo test
with cargo nextest run
.
If you want to contribute, or follow along with contributor discussion, you can use our main telegram to chat with us about the development of Reth!
See our contributor docs for more information on the project.
A good starting point is Project Layout which gives an overview of the repository's structure, and descriptions for each package.
Our contributor guidelines can be found in CONTRIBUTING.md
.
If you have any questions, first see if the answer to your question can be found in the book.
If the answer is not there:
See SECURITY.md
.
Reth is a new implementation of the Ethereum protocol. In the process of developing the node we investigated the design decisions other nodes have made to understand what is done well, what is not, and where we can improve the status quo.
None of this would have been possible without them, so big shoutout to the teams below:
This project is work in progress and subject to frequent changes as we are still working on wiring up each individual node component into a full syncing pipeline.
It has not been audited for security purposes and should not be used in production yet.
We will be updating the documentation with the completion status of each component, as well as include more contributing guidelines (design docs, architecture diagrams, repository layouts) and "good first issues". See the "Contributing and Getting Help" section above for more.
We appreciate your patience until we get there. Until then, we are happy to answer all questions in the Telegram link above.
Author: Paradigmxyz
Source Code: https://github.com/paradigmxyz/reth
License: Apache-2.0, MIT licenses found
1677565860
An interface-oriented router for managing modules and injecting dependencies with protocol.
The view router can perform all navigation types in UIKit / AppKit through one method.
The service router can discover and prepare corresponding module with its protocol.
Add this to your Podfile.
For Objective-C project:
pod 'ZIKRouter', '>= 1.1.1'
# or only use ServiceRouter
pod 'ZIKRouter/ServiceRouter' , '>=1.1.1'
For Swift project:
pod 'ZRouter', '>= 1.1.1'
# or only use ServiceRouter
pod 'ZRouter/ServiceRouter' , '>=1.1.1'
Add this to your Cartfile:
github "Zuikyo/ZIKRouter" >= 1.1.1
Build frameworks:
carthage update
Build DEBUG version to enable route checking:
carthage update --configuration Debug
Remember to use release version in production environment.
For Objective-C project, use ZIKRouter.framework
. For Swift project, use ZRouter.framework
.
This is the demo view controller and protocol:
///Editor view's interface
protocol EditorViewInput: class {
weak var delegate: EditorDelegate? { get set }
func constructForCreatingNewNote()
}
///Editor view controller
class NoteEditorViewController: UIViewController, EditorViewInput {
...
}
Objective-C Sample
///editor view's interface
@protocol EditorViewInput <ZIKViewRoutable>
@property (nonatomic, weak) id<EditorDelegate> delegate;
- (void)constructForCreatingNewNote;
@end
///Editor view controller
@interface NoteEditorViewController: UIViewController <EditorViewInput>
@end
@implementation NoteEditorViewController
@end
There're 2 steps to create route for your module.
To make your class become modular, you need to create router for your module. You don't need to modify the module's code. That will reduce the cost for refactoring existing modules.
Create router subclass for your module:
import ZIKRouter.Internal
import ZRouter
class NoteEditorViewRouter: ZIKViewRouter<NoteEditorViewController, ViewRouteConfig> {
override class func registerRoutableDestination() {
// Register class with this router. A router can register multi views, and a view can be registered with multi routers
registerView(NoteEditorViewController.self)
// Register protocol. Then we can fetch this router with the protocol
register(RoutableView<EditorViewInput>())
}
// Return the destination module
override func destination(with configuration: ViewRouteConfig) -> NoteEditorViewController? {
// In configuration, you can get parameters from the caller for creating the instance
let destination: NoteEditorViewController? = ... /// instantiate your view controller
return destination
}
override func prepareDestination(_ destination: NoteEditorViewController, configuration: ViewRouteConfig) {
// Inject dependencies to destination
}
}
Objective-C Sample
//NoteEditorViewRouter.h
@import ZIKRouter;
@interface NoteEditorViewRouter : ZIKViewRouter
@end
//NoteEditorViewRouter.m
@import ZIKRouter.Internal;
@implementation NoteEditorViewRouter
+ (void)registerRoutableDestination {
// Register class with this router. A router can register multi views, and a view can be registered with multi routers
[self registerView:[NoteEditorViewController class]];
// Register protocol. Then we can fetch this router with the protocol
[self registerViewProtocol:ZIKRoutable(EditorViewInput)];
}
// Return the destination module
- (NoteEditorViewController *)destinationWithConfiguration:(ZIKViewRouteConfiguration *)configuration {
// In configuration, you can get parameters from the caller for creating the instance
NoteEditorViewController *destination = ... // instantiate your view controller
return destination;
}
- (void)prepareDestination:(NoteEditorViewController *)destination configuration:(ZIKViewRouteConfiguration *)configuration {
// Inject dependencies to destination
}
@end
Each router can control their own routing, such as using different custom transition. And the router can be very easy to add additional features.
Read the documentation for more details and more methods to override.
If your module is very simple and don't need a router subclass, you can just register the class in a simpler way:
ZIKAnyViewRouter.register(RoutableView<EditorViewInput>(), forMakingView: NoteEditorViewController.self)
Objective-C Sample
[ZIKViewRouter registerViewProtocol:ZIKRoutable(EditorViewInput) forMakingView:[NoteEditorViewController class]];
or with custom creating block:
ZIKAnyViewRouter.register(RoutableView<EditorViewInput>(),
forMakingView: NoteEditorViewController.self) { (config, router) -> EditorViewInput? in
let destination: NoteEditorViewController? = ... // instantiate your view controller
return destination;
}
Objective-C Sample
[ZIKViewRouter
registerViewProtocol:ZIKRoutable(EditorViewInput)
forMakingView:[NoteEditorViewController class]
making:^id _Nullable(ZIKViewRouteConfiguration *config, ZIKViewRouter *router) {
NoteEditorViewController *destination = ... // instantiate your view controller
return destination;
}];
or with custom factory function:
function makeEditorViewController(config: ViewRouteConfig) -> EditorViewInput? {
let destination: NoteEditorViewController? = ... // instantiate your view controller
return destination;
}
ZIKAnyViewRouter.register(RoutableView<EditorViewInput>(),
forMakingView: NoteEditorViewController.self, making: makeEditorViewController)
Objective-C Sample
id<EditorViewInput> makeEditorViewController(ZIKViewRouteConfiguration *config) {
NoteEditorViewController *destination = ... // instantiate your view controller
return destination;
}
[ZIKViewRouter
registerViewProtocol:ZIKRoutable(EditorViewInput)
forMakingView:[NoteEditorViewController class]
factory:makeEditorViewController];
The declaration is for checking routes at compile time, and supporting storyboard.
// Declare NoteEditorViewController is routable
// This means there is a router for NoteEditorViewController
extension NoteEditorViewController: ZIKRoutableView {
}
// Declare EditorViewInput is routable
// This means you can use EditorViewInput to fetch router
extension RoutableView where Protocol == EditorViewInput {
init() { self.init(declaredProtocol: Protocol.self) }
}
Objective-C Sample
// Declare NoteEditorViewController is routable
// This means there is a router for NoteEditorViewController
DeclareRoutableView(NoteEditorViewController, NoteEditorViewRouter)
// If the protocol inherits from ZIKViewRoutable, it's routable
// This means you can use EditorViewInput to fetch router
@protocol EditorViewInput <ZIKViewRoutable>
@property (nonatomic, weak) id<EditorDelegate> delegate;
- (void)constructForCreatingNewNote;
@end
If you use an undeclared protocol for routing, there will be compile time error. So it's much safer and easier to manage protocols and to know which protocols are routable.
Unroutable error in Swift:
Unroutable error in Objective-C:
Now you can get and show NoteEditorViewController
with router.
Transition to editor view directly:
class TestViewController: UIViewController {
// Transition to editor view directly
func showEditorDirectly() {
Router.perform(to: RoutableView<EditorViewInput>(), path: .push(from: self))
}
}
Objective-C Sample
@implementation TestViewController
- (void)showEditorDirectly {
// Transition to editor view directly
[ZIKRouterToView(EditorViewInput) performPath:ZIKViewRoutePath.pushFrom(self)];
}
@end
You can change transition type with ViewRoutePath
:
enum ViewRoutePath {
case push(from: UIViewController)
case presentModally(from: UIViewController)
case presentAsPopover(from: UIViewController, configure: ZIKViewRoutePopoverConfigure)
case performSegue(from: UIViewController, identifier: String, sender: Any?)
case show(from: UIViewController)
case showDetail(from: UIViewController)
case addAsChildViewController(from: UIViewController, addingChildViewHandler: (UIViewController, @escaping () -> Void) -> Void)
case addAsSubview(from: UIView)
case custom(from: ZIKViewRouteSource?)
case makeDestination
case extensible(path: ZIKViewRoutePath)
}
Encapsulating view transition can hide the UIKit detail, then you can perform route outside the view layer (presenter, view model, interactor, service) and be cross-platform.
Prepare it before transition to editor view:
class TestViewController: UIViewController {
// Transition to editor view, and prepare the destination with EditorViewInput
func showEditor() {
Router.perform(
to: RoutableView<EditorViewInput>(),
path: .push(from: self),
configuring: { (config, _) in
// Route config
// Prepare the destination before transition
config.prepareDestination = { [weak self] destination in
//destination is inferred as EditorViewInput
destination.delegate = self
destination.constructForCreatingNewNote()
}
config.successHandler = { destination in
// Transition succeed
}
config.errorHandler = { (action, error) in
// Transition failed
}
})
}
}
Objective-C Sample
@implementation TestViewController
- (void)showEditor {
// Transition to editor view, and prepare the destination with EditorViewInput
[ZIKRouterToView(EditorViewInput)
performPath:ZIKViewRoutePath.pushFrom(self)
configuring:^(ZIKViewRouteConfig *config) {
// Route config
// Prepare the destination before transition
config.prepareDestination = ^(id<EditorViewInput> destination) {
destination.delegate = self;
[destination constructForCreatingNewNote];
};
config.successHandler = ^(id<EditorViewInput> destination) {
// Transition is completed
};
config.errorHandler = ^(ZIKRouteAction routeAction, NSError * error) {
// Transition failed
};
}];
}
@end
For more detail, read Perform Route.
If you don't want to show a view, but only need to get instance of the module, you can use makeDestination
:
// destination is inferred as EditorViewInput
let destination = Router.makeDestination(to: RoutableView<EditorViewInput>())
Objective-C Sample
id<EditorViewInput> destination = [ZIKRouterToView(EditorViewInput) makeDestination];
Some parameters can't be delivered though destination's protocol:
the destination class uses custom initializers to create instance, router needs to get required parameter from the caller
the module contains multi components, and you need to pass parameters to those components. Those parameters do not belong to the destination, so they should not exist in destination's protocol
You can use module config protocol and a custom configuration to transfer parameters.
Instead of EditorViewInput
, we use another routable protocol EditorViewModuleInput
as config protocol for routing:
// In general, a module config protocol only contains `makeDestinationWith`, for declaring parameters and destination type. You can also add other properties or methods
protocol EditorViewModuleInput: class {
// Factory method for transferring parameters and making destination
var makeDestinationWith: (_ note: Note) -> EditorViewInput? { get }
}
Objective-C Sample
// In general, a module config protocol only contains `makeDestinationWith`, for declaring parameters and destination type. You can also add other properties or methods
@protocol EditorViewModuleInput <ZIKViewModuleRoutable>
// Factory method for transferring parameters and making destination
@property (nonatomic, copy, readonly) id<EditorViewInput> _Nullable(^makeDestinationWith)(Note *note);
@end
This configuration works like a factory for the destination with EditorViewModuleInput
protocol. It declares parameters for creating the destination.
Now the user can use the module with its module config protocol and transfer parameters:
var note = ...
Router.makeDestination(to: RoutableViewModule<EditorViewModuleInput>()) { (config) in
// Transfer parameters and get EditorViewInput
let destination = config.makeDestinationWith(note)
}
Objective-C Sample
Note *note = ...
[ZIKRouterToViewModule(EditorViewModuleInput)
performPath:ZIKViewRoutePath.showFrom(self)
configuring:^(ZIKViewRouteConfiguration<EditorViewModuleInput> *config) {
// Transfer parameters and get EditorViewInput
id<EditorViewInput> destination = config.makeDestinationWith(note);
}];
For more detail, read Transfer Parameters with Custom Configuration.
If you get a destination from other place, you can perform on the destination with its router.
For example, an UIViewController supports 3D touch, and implments UIViewControllerPreviewingDelegate
:
class SourceViewController: UIViewController, UIViewControllerPreviewingDelegate {
func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
// Return the destination UIViewController to let system preview it
let destination = Router.makeDestination(to: RoutableView<EditorViewInput>())
return destination
}
func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
guard let destination = viewControllerToCommit as? EditorViewInput else {
return
}
// Show the destination
Router.to(RoutableView<EditorViewInput>())?.perform(onDestination: destination, path: .presentModally(from: self))
}
Objective-C Sample
@implementation SourceViewController
- (nullable UIViewController *)previewingContext:(id <UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location {
//Return the destination UIViewController to let system preview it
UIViewController<EditorViewInput> *destination = [ZIKRouterToView(EditorViewInput) makeDestination];
return destination;
}
- (void)previewingContext:(id <UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit {
// Show the destination
UIViewController<EditorViewInput> *destination;
if ([viewControllerToCommit conformsToProtocol:@protocol(EditorViewInput)]) {
destination = viewControllerToCommit;
} else {
return;
}
[ZIKRouterToView(EditorViewInput) performOnDestination:destination path:ZIKViewRoutePath.presentModallyFrom(self)];
}
@end
If you don't want to show the destination, but just want to prepare an existing destination, you can prepare the destination with its router.
If the router injects dependencies inside it, this can properly setting the destination instance.
var destination: DestinationViewInput = ...
Router.to(RoutableView<EditorViewInput>())?.prepare(destination: destination, configuring: { (config, _) in
config.prepareDestination = { destination in
// Prepare
}
})
Objective-C Sample
UIViewController<EditorViewInput> *destination = ...
[ZIKRouterToView(EditorViewInput) prepareDestination:destination configuring:^(ZIKViewRouteConfiguration *config) {
config.prepareDestination = ^(id<EditorViewInput> destination) {
// Prepare
};
}];
You can remove the view by removeRoute
, without using pop / dismiss / removeFromParentViewController / removeFromSuperview:
class TestViewController: UIViewController {
var router: DestinationViewRouter<EditorViewInput>?
func showEditor() {
// Hold the router
router = Router.perform(to: RoutableView<EditorViewInput>(), path: .push(from: self))
}
// Router will pop the editor view controller
func removeEditorDirectly() {
guard let router = router, router.canRemove else {
return
}
router.removeRoute()
router = nil
}
func removeEditorWithResult() {
guard let router = router, router.canRemove else {
return
}
router.removeRoute(successHandler: {
print("remove success")
}, errorHandler: { (action, error) in
print("remove failed, error: \(error)")
})
router = nil
}
func removeEditorAndPrepare() {
guard let router = router, router.canRemove else {
return
}
router.removeRoute(configuring: { (config) in
config.animated = true
config.prepareDestination = { destination in
// Use destination before remove it
}
})
router = nil
}
}
Objective-C Sample
@interface TestViewController()
@property (nonatomic, strong) ZIKDestinationViewRouter(id<EditorViewInput>) *router;
@end
@implementation TestViewController
- (void)showEditorDirectly {
// Hold the router
self.router = [ZIKRouterToView(EditorViewInput) performPath:ZIKViewRoutePath.pushFrom(self)];
}
// Router will pop the editor view controller
- (void)removeEditorDirectly {
if (![self.router canRemove]) {
return;
}
[self.router removeRoute];
self.router = nil;
}
- (void)removeEditorWithResult {
if (![self.router canRemove]) {
return;
}
[self.router removeRouteWithSuccessHandler:^{
NSLog(@"pop success");
} errorHandler:^(ZIKRouteAction routeAction, NSError *error) {
NSLog(@"pop failed,error: %@",error);
}];
self.router = nil;
}
- (void)removeEditorAndPrepare {
if (![self.router canRemove]) {
return;
}
[self.router removeRouteWithConfiguring:^(ZIKViewRemoveConfiguration *config) {
config.animated = YES;
config.prepareDestination = ^(UIViewController<EditorViewInput> *destination) {
// Use destination before remove it
};
}];
self.router = nil;
}
@end
For more detail, read Remove Route.
You can use another protocol to get router, as long as the protocol provides the same interface of the real protocol. Even the protocol is little different from the real protocol, you can adapt two protocols with category, extension and proxy.
Required protocol used by the user:
/// Required protocol to use editor module
protocol RequiredEditorViewInput: class {
weak var delegate: EditorDelegate? { get set }
func constructForCreatingNewNote()
}
Objective-C Sample
/// Required protocol to use editor module
@protocol RequiredEditorViewInput <ZIKViewRoutable>
@property (nonatomic, weak) id<EditorDelegate> delegate;
- (void)constructForCreatingNewNote;
@end
In the host app context, connect required protocol and provided protocol:
/// In the host app, add required protocol to editor router
class EditorViewAdapter: ZIKViewRouteAdapter {
override class func registerRoutableDestination() {
// If you can get the router, you can just register RequiredEditorViewInput to it
NoteEditorViewRouter.register(RoutableView<RequiredEditorViewInput>())
// If you don't know the router, you can use adapter
register(adapter: RoutableView<RequiredEditorViewInput>(), forAdaptee: RoutableView<EditorViewInput>())
}
}
/// Make NoteEditorViewController conform to RequiredEditorViewInput
extension NoteEditorViewController: RequiredEditorViewInput {
}
Objective-C Sample
/// In the host app, add required protocol to editor router
//EditorViewAdapter.h
@interface EditorViewAdapter : ZIKViewRouteAdapter
@end
//EditorViewAdapter.m
@implementation EditorViewAdapter
+ (void)registerRoutableDestination {
// If you can get the router, you can just register RequiredEditorViewInput to it
[NoteEditorViewRouter registerViewProtocol:ZIKRoutable(RequiredEditorViewInput)];
// If you don't know the router, you can use adapter
[self registerDestinationAdapter:ZIKRoutable(RequiredEditorViewInput) forAdaptee:ZIKRoutable(EditorViewInput)];
}
@end
/// Make NoteEditorViewController conform to RequiredEditorViewInput
@interface NoteEditorViewController (Adapter) <RequiredEditorViewInput>
@end
@implementation NoteEditorViewController (Adapter)
@end
After adapting, RequiredEditorViewInput
and EditorViewInput
can get the same router.
UseRequiredEditorViewInput
to get module:
class TestViewController: UIViewController {
func showEditorDirectly() {
Router.perform(to: RoutableView<RequiredEditorViewInput>(), path: .push(from: self))
}
}
Objective-C Sample
@implementation TestViewController
- (void)showEditorDirectly {
[ZIKRouterToView(RequiredEditorViewInput) performPath:ZIKViewRoutePath.pushFrom(self)];
}
@end
Use required protocol
and provided protocol
to perfectly decouple modules, adapt interface and declare dependencies of the module. And you don't have to use a public header to manage those protocols.
Separating required protocol
and provided protocol
makes your code truly modular. The caller declares its required protocol
, and the provided module can easily be replaced by another module with the same required protocol
.
Read the ZIKLoginModule
module in demo. The login module depends on an alert module, and the alert module is different in ZIKRouterDemo
and ZIKRouterDemo-macOS
. You can change the provided module without changing anything in the login module.
For more detail, read Module Adapter.
ZIKRouter also provides a default URLRouter. It's easy to communicate with modules via url.
URLRouter is not contained by default. If you want to use it, add submodule pod 'ZIKRouter/URLRouter'
to your Podfile
, and call [ZIKRouter enableDefaultURLRouteRule]
to enable URLRouter.
You can register router with a url:
class NoteEditorViewRouter: ZIKViewRouter<NoteEditorViewController, ViewRouteConfig> {
override class func registerRoutableDestination() {
registerView(NoteEditorViewController.self)
register(RoutableView<EditorViewInput>())
// Register url
registerURLPattern("app://editor/:title")
}
}
Objective-C Sample
@implementation NoteEditorViewRouter
+ (void)registerRoutableDestination {
[self registerView:[NoteEditorViewController class]];
[self registerViewProtocol:ZIKRoutable(EditorViewInput)];
// Register url
[self registerURLPattern:@"app://editor/:title"];
}
@end
Then you can get the router with it's url:
ZIKAnyViewRouter.performURL("app://editor/test_note", path: .push(from: self))
Objective-C Sample
[ZIKAnyViewRouter performURL:@"app://editor/test_note" path:ZIKViewRoutePath.pushFrom(self)];
And handle URL Scheme:
public func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
let urlString = url.absoluteString
if let _ = ZIKAnyViewRouter.performURL(urlString, fromSource: self.rootViewController) {
return true
} else if let _ = ZIKAnyServiceRouter.performURL(urlString) {
return true
} else {
return false
}
}
Objective-C Sample
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if ([ZIKAnyViewRouter performURL:urlString fromSource:self.rootViewController]) {
return YES;
} else if ([ZIKAnyServiceRouter performURL:urlString]) {
return YES;
} else {
return NO;
}
}
If your project has different requirements for URL router, you can write your URL router by yourself. You can create custom ZIKRouter as parent class, add more powerful features in it. See ZIKRouter+URLRouter.h
.
There're other features, you can get details in the documentation:
Instead of view, you can also get any service modules:
/// time service's interface
protocol TimeServiceInput {
func currentTimeString() -> String
}
class TestViewController: UIViewController {
@IBOutlet weak var timeLabel: UILabel!
func callTimeService() {
// Get the service for TimeServiceInput
let timeService = Router.makeDestination(
to: RoutableService<TimeServiceInput>(),
preparation: { destination in
// prepare the service if needed
})
//Use the service
timeLabel.text = timeService.currentTimeString()
}
}
Objective-C Sample
/// time service's interface
@protocol TimeServiceInput <ZIKServiceRoutable>
- (NSString *)currentTimeString;
@end
@interface TestViewController ()
@property (weak, nonatomic) IBOutlet UILabel *timeLabel;
@end
@implementation TestViewController
- (void)callTimeService {
// Get the service for TimeServiceInput
id<TimeServiceInput> timeService = [ZIKRouterToService(TimeServiceInput) makeDestination];
self.timeLabel.text = [timeService currentTimeString];
}
ZIKRouter is designed for VIPER architecture at first. But you can also use it in MVC or anywhere.
The demo (ZIKRouterDemo) in this repository shows how to use ZIKRouter to perform each route type. Open Router.xcworkspace
to run it.
If you want to see how it works in a VIPER architecture app, go to ZIKViper.
You can use Xcode file template to create router and protocol code quickly:
The template ZIKRouter.xctemplate
is in Templates.
Copy ZIKRouter.xctemplate
to ~/Library/Developer/Xcode/Templates/ZIKRouter.xctemplate
, then you can use it in Xcode -> File -> New -> File -> Templates
.
一个用于模块间解耦和通信,基于接口进行模块管理和依赖注入的组件化路由工具。用多种方式最大程度地发挥编译检查的功能。
通过 protocol 寻找对应的模块,并用 protocol 进行依赖注入和模块通信。
Service Router 可以管理任意自定义模块。View Router 进一步封装了界面跳转。
Author: Zuikyo
Source Code: https://github.com/Zuikyo/ZIKRouter
License: MIT license
1676454660
A powerful and intuitive WYSIWYG interface that allows anyone to create Machine Learning models!
The concept of AI-Blocs is to have a simple scene with draggable objects that have scripts attached to them. The model can be run directly on the editor or be exported to a standalone script that runs on Tensorflow.
Variables are parsed from python scripts and can be edited from the AI-Blocs properties panel.
The project requires python (https://www.python.org/) and tensorflow (https://www.tensorflow.org/) to run projects. You can still create and edit projects without these dependencies.
To run AI-Blocs, download the project archive and launch AI-Blocs.exe.
To run your model simply press the "Play" button and let the magic happen!
All releases can be found here: https://github.com/MrNothing/AI-Blocks/releases/
First type: npm install
To run the project from the sources: npm run test
To build the project from the sources: npm run pack
Documentation and video tutorials can be found on the website: https://mrnothing.github.io/AI-Blocks/index.html
Author: MrNothing
Source Code: https://github.com/MrNothing/AI-Blocks
License: View license
1675496649
Todo App But Minimal, Open-source, and Free
Tedu is currently released on Google Play, and you can download it by clicking on the button below:
I believe that everyone can contribute to this project, even without the knowledge in computer science and programming. So please, if you have free time, consider contributing to this project in these areas:
At my current job at Cafe Bazaar, we were trying to migrate our Android project to a modular structure so we could scale our Android chapter in the long-term. This project's architecture is the result of my research and development on the idea of having a modular Android project, and I tried to solve all the challenges that one could face when migrating to a modular structure.
📱📲 Navigation
Handling navigation in a modular structure could be challenging, especially if you are using the Jetpack's Navigation Component. What I've come up with is a structure in which every feature module has its navigation graph, and their graph file resides in the platform module, in this case, the :platform:mobile
module. Navigation inside a module is done using the Actions, and nothing differs here from a monolith project, but to navigate between modules(inter-module navigation), I've used deep-links with the help of Navigation Component's deep-linking feature. Now, this has two issues, first is that the SafeArgs plugin can't help us to have type safety when we are using deep-links and the second is that, we can't pass Parcelable/Serializable data between destinations. For the first issue, I haven't done anything because I didn't have the time to implement a Gradle plugin like SafeArgs for deep links, but for the second issue, I've implemented an extension function for the NavController called interModuleNavigate
which receives two parameters:
And it's used like this:
findNavController().interModuleNavigate(
getString(R.string.deeplink_userprofile).toUri(),
userEntity
)
We store deep-link values in a string resource file so that we could use them in the navigation graph file for defining a deep-link destination and also use them at the runtime to navigate to that destination. Now that you've understood how the front-end of this implementation is used, let's talk about its back-end and how things look behind the curtain. Since we normally can't pass Parcelable/Serializable data using deep-links, I've decided to write the data on the disk and then read it afterward. Every deep-link that is used for inter-module navigation and requires to pass a marshallable data, needs to have a query called extraData
. We set this query's value at the runtime, and it's a timestamp, fetched from System.currentTimeMillis
. We use this timestamp to name the file that we are going to write on the disk, so in the destination, we would know what file to read from to access the marshalled data. Since we are passing the timestamp as part of the deep-link's URI, we don't have to worry about losing it in configuration changes or process death, because every query is saved inside Fragment's argument bundle and we know that Fragment will take care of its argument bundle automatically and stores it when onSaveInstanceState
happens. All of this is happening inside the :library:navigation
module if you want to take a look.
💉 Dependency Injection
I've used dagger-android for dependency injection purposes. One important thing to note here is that dagger-android isn't usable in a modular structure as-is, and I've extended it to be able to use it in a modular structure. You can find the extension source code in :library:androiddagger
and :library:dependencyinjection
modules.
In the above image, you can see the scope hierarchy that I've used. Yellow ones are Singleton, and the green one is bounded to a Fragment lifecycle, in this case, the AddTodoFragment. One weird scope in the above image is @AndroidCoreScope
, which is the root scope and dependency-wise, it only contains the Application and Application's Context dependencies; therefore, it's one level higher than @LibraryScope
s, so that library components could access the Application class and its Context. These scopes(except @AddTodoScope
), are implemented in the :library:dependencyinjection
module and whoever needs to use them requires to depend on this Gradle module. In dagger-android world, there is an annotation called @ContributesAndroidInjector
which is used by dagger-android's annotation processor to generate sub-components and then they all will be collected in a class called DispatchingAndroidInjector
; Now, we have a limitation here, since dagger-android technically supports just one DispatchingAndroidInjector
and since we have several feature modules, each of them will have their own DispatchingAndroidInjector
, so we need to merge them somehow. To solve this issue, I've implemented a base class for the Application class, called DaggerAndroidApplication
which has a function called installFeature
, and receives a feature component and stores that component in a HashMap, so then we could use the HashMap to fetch a DispatchingAndroidInjector
that we need and inject it to our Fragment/Activity. If you take a look in the Tedu
class, which is the Application class, you'll see these lines, that is used to install a feature:
override fun onCreate() {
super.onCreate()
installFeature(TodoListComponentBuilder)
installFeature(AddTodoComponentBuilder)
installFeature(SettingsComponentBuilder)
installFeature(BackupComponentBuilder)
}
In the code above, you can see that we are passing Builder objects, which is a new concept in my dagger-android implementation. If we want to achieve a better build speed because of our modular structure, we need to let each module build its component on its own and to do this, we need to have Singleton instance of that component so that all the dependant components could use a single instance. Component Builder is the place where we build the component and in its underlying layer, it will save the built component in a singleton manner. Now to inject a component in our Fragment/Activity, there is an extension function called inject
which accepts a generic that is used to determine what DispatchingAndroidInjector
you want to use:
override fun onAttach(context: Context) {
super.onAttach(context)
inject<AddTodoComponent>()
}
Author: PHELAT
Source Code: https://github.com/PHELAT/Tedu
License: GPL-3.0 license
1673859970
Para is a scalable, multitenant backend server/framework for object persistence and retrieval. It helps you build and prototype applications faster by taking care of backend operations. It can be a part of your JVM-based application or it can be deployed as standalone, multitenant API server with multiple applications and clients connecting to it.
The name "pára" means "steam" in Bulgarian. And just like steam is used to power stuff, you can use Para to power your mobile or web application backend.
DAO
natively)+----------------------------------------------------------+
| ____ ___ _ ____ ___ _ |
| / __ \/ __` / ___/ __` / |
| / /_/ / /_/ / / / /_/ / |
| / .___/\__,_/_/ \__,_/ +-------------+
| /_/ | Persistence |
+-------------------+ +-----------------+ +-------------+
| REST API | | Search |---| Cache |
+---------+---------+--+--------+--------+---+------+------+
| | |
+---------+---------+ +--------+--------+ +------+------+
| Signed Requests | | Search Index | | Data Store |
| and JWT Tokens | | (Any) | | (Any) |
+----+---------^----+ +-----------------+ +-------------+
| |
+----v---------+-------------------------------------------+
| Clients: JavaScript, PHP, Java, C#, Android, iOS, et al. |
+----------------------------------------------------------+
application.conf
file in the same directory as the JAR package.java -jar -Dconfig.file=./application.conf para-*.jar
npm install -g para-cli
# run setup and set endpoint to either 'http://localhost:8080' or 'https://paraio.com'
# the keys for the root app are inside application.conf
$ para-cli setup
$ para-cli new-app "myapp" --name "My App"
Tagged Docker images for Para are located at erudikaltd/para
on Docker Hub. It's highly recommended that you pull only release images like :1.45.1
or :latest_stable
because the :latest
tag can be broken or unstable. First, create an application.conf
file and a data
folder and start the Para container:
$ touch application.conf && mkdir data
$ docker run -ti -p 8080:8080 --rm -v $(pwd)/data:/para/data \
-v $(pwd)/application.conf:/para/application.conf \
-e JAVA_OPTS="-Dconfig.file=/para/application.conf" erudikaltd/para:latest_stable
Environment variables
JAVA_OPTS
- Java system properties, e.g. -Dpara.port=8000
BOOT_SLEEP
- Startup delay, in seconds
Plugins
To use plugins, create a new Dockerfile-plugins
which does a multi-stage build like so:
# change X.Y.Z to the version you want to use
FROM erudikaltd/para:v1.XY.Z-base AS base
FROM erudikaltd/para-search-lucene:1.XY.Z AS search
FROM erudikaltd/para-dao-mongodb:1.XY.Z AS dao
FROM base AS final
COPY --from=search /para/lib/*.jar /para/lib
COPY --from=dao /para/lib/*.jar /para/lib
Then simply run $ docker build -f Dockerfile-plugins -t para-mongo .
Para can be compiled with JDK 8+:
To compile it you'll need Maven. Once you have it, just clone and build:
$ git clone https://github.com/erudika/para.git && cd para
$ mvn install -DskipTests=true
To generate the executable "fat-jar" run $ mvn package
and it will be in ./para-jar/target/para-x.y.z-SNAPSHOT.jar
. Two JAR files will be generated in total - the fat one is a bit bigger in size.
To build the base package without plugins (excludes para-dao-sql
and para-search-lucene
), run:
$ cd para-jar && mvn -Pbase package
To run a local instance of Para for development, use:
$ mvn -Dconfig.file=./application.conf spring-boot:run
You can run Para as a standalone server by downloading the executable JAR and then:
$ java -jar para-X.Y.Z.jar
The you can browse your objects through the Para Web Console console.paraio.org. Simply change the API endpoint to be your local server and connect your access keys. The admin interface is client-side only and your secret key is never sent over the the network. Instead, a JWT access token is generated locally and sent to the server on each request.
Alternatively, you can build a WAR file and deploy it to your favorite servlet container:
$ cd para-war && mvn package
You can also integrate Para with your project by adding it as a dependency. Para is hosted on Maven Central. Here's the Maven snippet to include in your pom.xml
:
<dependency>
<groupId>com.erudika</groupId>
<artifactId>para-server</artifactId>
<version>{see_green_version_badge_above}</version>
</dependency>
For building lightweight client-only applications connecting to Para, include only the client module:
<dependency>
<groupId>com.erudika</groupId>
<artifactId>para-client</artifactId>
<version>{see_green_version_badge_above}</version>
</dependency>
$ npm install -g para-cli
Use these client libraries to quickly integrate Para into your project:
Use these DAO
implementations to connect to different databases:
AWSDynamoDAO
(included in para-server
)H2DAO
is the default DAO
and it's part of the SQL plugin (packaged with the JAR file)The Search
interface is implemented by:
The Cache
interface is implemented by:
para-server
)The Queue
interface is implemented by:
AWSQueue
classLocalQueue
for single-host deployments and local development2.0
- migration to Quarkus, Java 13+ only, native imagepara
tagpara
tag on Stack Overflowgit checkout -b my-new-feature
)git commit -am 'Added a new feature'
)git push origin my-new-feature
)Please try to respect the code style of this project. To check your code, run it through the style checker:
mvn validate
For more information see CONTRIBUTING.md
We offer hosting and premium support at paraio.com where you can try Para online with a free developer account. Browse and manage your users and objects, do backups and edit permissions with a few clicks in the web console. By upgrading to a premium account you will be able to scale you projects up and down in seconds and manage multiple apps.
See how Para compares to other open source backend frameworks.
This project is fully funded and supported by Erudika - an independent, bootstrapped company.
Author: Erudika
Source Code: https://github.com/Erudika/para
License: Apache-2.0 license
1667449080
Nebular is a customizable Angular 10 UI Library with a focus on beautiful design and ability to adapt it to your brand easily. It comes with 4 stunning visual themes, a powerful theming engine with runtime theme switching and support of custom css properties mode. Nebular is based on Eva Design System specifications.
You can install Nebular with Angular CLI:
ng add @nebular/theme
Configuration will be done automatically.
If you want to have more control over setup process you can use manual setup guide.
Nebular supports most recent browsers. Browser support list can be found here.
Try low-code internal tool builder for free
Made with :heart: by Akveo team. Follow us on Twitter to get the latest news first! We're always happy to receive your feedback!
Documentation | Stackblitz Template | UI Bakery - Angular UI Builder | Angular templates
Author: Akveo
Source Code: https://github.com/akveo/nebular
License: MIT license
1665646020
Modular arithmetic for Julia.
This module supports modular values and arithmetic. The moduli are integers (at least 2) and the values are either integers or Gaussian integers.
An element of $\mathbb{Z}_N$ is entered as Mod{N}(a)
and is of type Mod{N}
. An element of $\mathbb{Z}_N[i]$ is entered a Mod{N}(a+b*im)
and is of type GaussMod{N}
. Both types are fully interoperable with each other and with (ordinary) integers and Gaussian integers.
julia> a = Mod{17}(9); b = Mod{17}(10);
julia> a+b
Mod{17}(2)
julia> 2a
Mod{17}(1)
julia> a = Mod{17}(9-2im)
Mod{17}(9 + 15im)
julia> 2a
Mod{17}(1 + 13im)
julia> a'
Mod{17}(9 + 2im)
julia> typeof(a)
GaussMod{17}
julia> typeof(b)
Mod{17}
julia> supertype(ans)
AbstractMod
Mod
numbersIntegers modulo N
(where N>1
) are values in the set {0,1,2,...,N-1}
. All arithmetic takes place modulo N
. To create a mod-N
number we use Mod{N}(a)
. For example:
julia> Mod{10}(3)
Mod{10}(3)
julia> Mod{10}(23)
Mod{10}(3)
julia> Mod{10}(-3)
Mod{10}(7)
The usual arithmetic operations may be used. Furthermore, oridinary integers can be combined with Mod
values. However, values of different moduli cannot be used together in an arithmetic expression.
julia> a = Mod{10}(5)
Mod{10}(5)
julia> b = Mod{10}(6)
Mod{10}(6)
julia> a+b
Mod{10}(1)
julia> a-b
Mod{10}(9)
julia> a*b
Mod{10}(0)
julia> 2b
Mod{10}(2)
Division is permitted, but if the denominator is not invertible, an error is thrown.
julia> a = Mod{10}(5)
Mod{10}(5)
julia> b = Mod{10}(3)
Mod{10}(3)
julia> a/b
Mod{10}(5)
julia> b/a
ERROR: Mod{10}(5) is not invertible
Exponentiation by an integer is permitted.
julia> a = Mod{17}(2)
Mod{17}(2)
julia> a^16
Mod{17}(1)
julia> a^(-3)
Mod{17}(15)
Invertibility can be checked with is_invertible
.
julia> a = Mod{10}(3)
Mod{10}(3)
julia> is_invertible(a)
true
julia> inv(a)
Mod{10}(7)
julia> a = Mod{10}(4)
Mod{10}(4)
julia> is_invertible(a)
false
julia> inv(a)
ERROR: Mod{10}(4) is not invertible
Modular number with different moduli cannot be combined using the usual operations.
julia> a = Mod{10}(1)
Mod{10}(1)
julia> b = Mod{9}(1)
Mod{9}(1)
julia> a+b
ERROR: can not promote types Mod{10,Int64} and Mod{9,Int64}
GaussMod
numbersWe can also work modulo N
with Gaussian integers (numbers of the form a+b*im
where a
and b
are integers).
julia> a = Mod{10}(2-3im)
Mod{10}(2 + 7im)
julia> b = Mod{10}(5+6im)
Mod{10}(5 + 6im)
julia> a+b
Mod{10}(7 + 3im)
julia> a*b
Mod{10}(8 + 7im)
In addition to the usual arithmetic operations, the following features apply to GaussMod
values.
real
and imag
(or reim
) to extract the real and imaginary parts: ```julia julia> a = Mod{10}(2-3im) Mod{10}(2 + 7im)julia> real(a) Mod{10}(2)
julia> imag(a) Mod{10}(7)
julia> reim(a) (Mod{10}(2), Mod{10}(7))
#### Complex conjugate
Use `a'` (or `conj(a)`) to get the complex conjugate value:
```julia
julia> a = Mod{10}(2-3im)
Mod{10}(2 + 7im)
julia> a'
Mod{10}(2 + 3im)
julia> a*a'
Mod{10}(3 + 0im)
julia> a+a'
Mod{10}(4 + 0im)
Given a Mod
number, the modulus is recovered using the modulus
function and the numerical value with value
:
julia> a = Mod{23}(100)
Mod{23}(8)
julia> modulus(a)
23
julia> value(a)
8
Integer operations on 64-bit numbers can give results requiring more than 64 bits. Fortunately, when working with modular numbers the results of the operations are bounded by the modulus.
julia> N = 10^18 # this is a 60-bit number
1000000000000000000
julia> a = 10^15
1000000000000000
julia> a*a # We see that a*a overflows
5076944270305263616
julia> Mod{N}(a*a) # this gives an incorrect answer
Mod{1000000000000000000}(76944270305263616)
julia> Mod{N}(a) * Mod{N}(a) # but this is correct!
Mod{1000000000000000000}(0)
The standard Julia functions zero
, zeros
, one
, and ones
may be used with Mod
types:
julia> zero(Mod{9})
Mod{9}(0)
julia> one(GaussMod{7})
Mod{7}(1 + 0im)
julia> zeros(Mod{9},2,2)
2×2 Array{Mod{9},2}:
Mod{9}(0) Mod{9}(0)
Mod{9}(0) Mod{9}(0)
julia> ones(GaussMod{5},4)
4-element Array{GaussMod{5},1}:
Mod{5}(1 + 0im)
Mod{5}(1 + 0im)
Mod{5}(1 + 0im)
Mod{5}(1 + 0im)
The Mod{m}
type can be used as an iterator (in for
statements and list comprehension):
julia> for a in Mod{5}
println(a)
end
Mod{5}(0)
Mod{5}(1)
Mod{5}(2)
Mod{5}(3)
Mod{5}(4)
julia> collect(Mod{6})
6-element Vector{Mod{6, T} where T}:
Mod{6}(0)
Mod{6}(1)
Mod{6}(2)
Mod{6}(3)
Mod{6}(4)
Mod{6}(5)
julia> [k*k for k ∈ Mod{7}]
7-element Vector{Mod{7, Int64}}:
Mod{7}(0)
Mod{7}(1)
Mod{7}(4)
Mod{7}(2)
Mod{7}(2)
Mod{7}(4)
Mod{7}(1)
julia> prod(k for k in Mod{5} if k!=0) == -1 # Wilson's theorem
true
One can also use GaussMod
as an iterator:
julia> for z in GaussMod{3}
println(z)
end
Mod{3}(0 + 0im)
Mod{3}(0 + 1im)
Mod{3}(0 + 2im)
Mod{3}(1 + 0im)
Mod{3}(1 + 1im)
Mod{3}(1 + 2im)
Mod{3}(2 + 0im)
Mod{3}(2 + 1im)
Mod{3}(2 + 2im)
The rand
function can be used to produce random Mod
values:
julia> rand(Mod{17})
Mod{17}(13)
julia> rand(GaussMod{17})
Mod{17}(3 + 6im)
With extra arguments, rand
produces random vectors or matrices populated with modular numbers:
julia> rand(GaussMod{10},4)
4-element Array{GaussMod{10},1}:
Mod{10}(6 + 0im)
Mod{10}(3 + 2im)
Mod{10}(9 + 9im)
Mod{10}(2 + 5im)
julia> rand(Mod{10},2,5)
2×5 Array{Mod{10},2}:
Mod{10}(3) Mod{10}(1) Mod{10}(1) Mod{10}(3) Mod{10}(0)
Mod{10}(1) Mod{10}(1) Mod{10}(8) Mod{10}(4) Mod{10}(0)
The Chinese Remainder Theorem gives a solution to the following problem. Given integers a, b, m, n
with gcd(m,n)==1
find an integer x
such that mod(x,m)==mod(a,m)
and mod(x,n)==mod(b,n)
. We provide the CRT
function to solve this problem as illustrated here with a=3
, m=10
, b=5
, and n=17
:
julia> s = Mod{10}(3); t = Mod{17}(5);
julia> CRT(s,t)
73
We find that mod(73,10)
equals 3
and mod(73,17)
equals 5
as required. The answer is reported as 73
because any value of x
congruent to 73 modulo 170 is a solution.
The CRT
function can be applied to any number of arguments so long as their moduli are pairwise relatively prime.
The result of Mod{N}(a//b)
is exactly Mod{N}(numerator(a)) / Mod{n}(denominator(b))
. This may equal Mod{N}(a)/Mod{N}(b)
if a
and b
are relatively prime to each other and to N
.
When a Mod
and a Rational
are operated with each other, the Rational
is first converted to a Mod
, and then the operation proceeds.
Bad things happen if the denominator and the modulus are not relatively prime.
Mod
sThe Mod
and GaussMod
types work well with my SimplePolynomials and LinearAlgebraX modules.
julia> using LinearAlgebraX
julia> A = rand(GaussMod{13},3,3)
3×3 Array{GaussMod{13},2}:
Mod{13}(11 + 0im) Mod{13}(0 + 10im) Mod{13}(1 + 9im)
Mod{13}(8 + 4im) Mod{13}(11 + 10im) Mod{13}(1 + 8im)
Mod{13}(11 + 6im) Mod{13}(10 + 6im) Mod{13}(7 + 3im)
julia> detx(A)
Mod{13}(2 + 11im)
julia> invx(A)
3×3 Array{GaussMod{13},2}:
Mod{13}(4 + 6im) Mod{13}(3 + 3im) Mod{13}(5 + 1im)
Mod{13}(5 + 0im) Mod{13}(9 + 12im) Mod{13}(3 + 10im)
Mod{13}(11 + 6im) Mod{13}(5 + 1im) Mod{13}(10 + 12im)
julia> ans * A
3×3 Array{GaussMod{13},2}:
Mod{13}(1 + 0im) Mod{13}(0 + 0im) Mod{13}(0 + 0im)
Mod{13}(0 + 0im) Mod{13}(1 + 0im) Mod{13}(0 + 0im)
Mod{13}(0 + 0im) Mod{13}(0 + 0im) Mod{13}(1 + 0im)
julia> char_poly(A)
Mod{13}(11 + 2im) + Mod{13}(2 + 1im)*x + Mod{13}(10 + 0im)*x^2 + Mod{13}(1 + 0im)*x^3
Author: Scheinerman
Source Code: https://github.com/scheinerman/Mods.jl
License: MIT license
1619190000
We just had a webinar with Abby Carey from Google, where we discussed deploying Flask applications on GCP, using all the differerent services that it gives you.
In the webinar, Abby covered:
Using Cloud Code (A PyCharm plugin) that can be used to create new projects with a Flask or a Django template
Building your flask Cloud Run application locally, and then deploying it to GCP
Automatic rebuilds and redeploys on changes made to the codebase using Cloud Code
Managing Secrets using Cloud Code
Confugiruing and working with Cloud SQL Databases
Using Google Pub/Sub to as a means of communication between different services, which include but are not limited to Cloud Run and Google Storage.
The code to the first application can be found on GitHub.
#blueprint #web-development #modular #flask #application
1596091320
Almost every iOS app other than very small hobby projects have a tracker architecture to measure and track analytic events. Sometimes its enough to implement either third party solution or in-house tracking solution, sometimes you should support both of these. Besides just implementing them, for the sake of the project, you want to keep tracking mechanism tidy too.
Since Trendyol iOS app is one of the most popular iOS apps in Turkey at the e-commerce category, we use both varieties of third party solutions and an in-house solution too for event tracking. Actually we had a tracking mechanism which has been performing well until the last quarter, however we have noticed that it won’t scale enough and comes with some problems as app grows. First take a look at the previous tracking solution we want to change, to see what are the problems here.
Let’s start with Tracking Service;
typealias TrackingParams = [String: Any]?
enum TrackingService {
case awesomeTracking(params: TrackingParams)
case firebase(name: String, params: TrackingParams)
case adjust(event: ADJEvent?)
case facebook(facebookEvents: FacebookEvents)
}
TrackingService is a basic enum that contains tracking options. As you can see, it consists of some of the popular third party solutions and one in-house solution named AwesomeTracking.
#ios #events #tracker #swift #modular
1594391400
The basic idea behind Modularity is that: The best approach to your complex challenge isn’t performing one giant task, but a system of separate and mostly-independent sub-tasks working together towards one big goal. This concept has a biological basis. There are functionally specialized regions in the brain that are domain specific for different cognitive processes. Within a part of the brain, called the thalamus, lies the lateral geniculate nucleus (LGN), which is divided into layers that separately process color and contrast: both major components of vision. Modular Neural Networks use this idea to solve complex AI problems. Several independent neural networks are trained simultaneously for a specific sub-task and their results are combined at the end to perform a single task. The benefits of modular neural networks include:
As we all know, an AI does not inherently have language, so this is our job to train our model to do reasoning over a given text. By reasoning, we mean tasks like arithmetic, sorting, comparisons, and counting.
Figure 1: Visual Question Answering is the task of answering questions about an image to show that the system understands the image.
Figure 2: Reading comprehension is the task of answering questions about a passage of text to show that the system understands the passage.
Suppose we want to create a Question Answering System,Figure 1 and 2 illustrate how the QA model works!
Consider the question “What does the sign say next to the traffic light?” in Figure 1. Multiple reasoning steps are needed to answer such a question: find all “signs” in the image, find the “traffic light”, select the sign “next to the traffic light”, and then find “what it says”. Or the question in figure 2: first we need to find all the truancy rates in the given text, pick the highest one, and then find “Which area it is tied for”. We would like to develop models that are capable of understanding the compositional semantics of such complex questions in order to provide the correct answer.
#modular #neural-networks #qa #lstm