Skip to content

Commit

Permalink
Example app (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
almazrafi authored May 22, 2021
1 parent aec40c7 commit 83b0656
Show file tree
Hide file tree
Showing 85 changed files with 1,944 additions and 175 deletions.
552 changes: 552 additions & 0 deletions Example/NivelirExample.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1240"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C017D13225FBAD0F008B90C0"
BuildableName = "NivelirExample.app"
BlueprintName = "NivelirExample"
ReferencedContainer = "container:NivelirExample.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C017D13225FBAD0F008B90C0"
BuildableName = "NivelirExample.app"
BlueprintName = "NivelirExample"
ReferencedContainer = "container:NivelirExample.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C017D13225FBAD0F008B90C0"
BuildableName = "NivelirExample.app"
BlueprintName = "NivelirExample"
ReferencedContainer = "container:NivelirExample.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
10 changes: 10 additions & 0 deletions Example/NivelirExample.xcworkspace/contents.xcworkspacedata

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
32 changes: 32 additions & 0 deletions Example/NivelirExample/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

private func setupNavigationBarAppearance() {
let appearance = UINavigationBar.appearance()

appearance.prefersLargeTitles = true
appearance.tintColor = Colors.important
}

func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
setupNavigationBarAppearance()

return true
}

func application(
_ application: UIApplication,
configurationForConnecting connectingSceneSession: UISceneSession,
options: UIScene.ConnectionOptions
) -> UISceneConfiguration {
UISceneConfiguration(
name: "Main",
sessionRole: connectingSceneSession.role
)
}
}
9 changes: 9 additions & 0 deletions Example/NivelirExample/Helpers/Colors.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import UIKit

enum Colors {

static let background = UIColor(named: "Background")!
static let unimportant = UIColor(named: "Unimportant")!
static let important = UIColor(named: "Important")!
static let title = UIColor(named: "Title")!
}
9 changes: 9 additions & 0 deletions Example/NivelirExample/Helpers/Images.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import UIKit

enum Images {

static let chatsTab = UIImage(named: "ChatsTab")!
static let profileTab = UIImage(named: "ProfileTab")!
static let chat = UIImage(named: "Chat")!
static let user = UIImage(named: "User")!
}
11 changes: 11 additions & 0 deletions Example/NivelirExample/Helpers/Reusable/Reusable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Foundation

protocol Reusable {
static var reuseIdentifier: String { get }
}

extension Reusable {
static var reuseIdentifier: String {
"\(Self.self)"
}
}
24 changes: 24 additions & 0 deletions Example/NivelirExample/Helpers/Reusable/UITableView+Reusable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import UIKit

extension UITableView {

func registerReusableHeaderFooterView<T: UITableViewHeaderFooterView & Reusable>(of type: T.Type) {
register(type, forHeaderFooterViewReuseIdentifier: T.reuseIdentifier)
}

func dequeueReusableHeaderFooterView<T: UITableViewHeaderFooterView & Reusable>(of type: T.Type) -> T {
dequeueReusableHeaderFooterView(withIdentifier: T.reuseIdentifier) as! T
}

func registerReusableCell<T: UITableViewCell & Reusable>(of type: T.Type) {
register(type, forCellReuseIdentifier: T.reuseIdentifier)
}

func dequeueReusableCell<T: UITableViewCell & Reusable>(of type: T.Type) -> T {
dequeueReusableCell(withIdentifier: T.reuseIdentifier) as! T
}

func dequeueReusableCell<T: UITableViewCell & Reusable>(of type: T.Type, for indexPath: IndexPath) -> T {
dequeueReusableCell(withIdentifier: T.reuseIdentifier, for: indexPath) as! T
}
}
64 changes: 64 additions & 0 deletions Example/NivelirExample/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Nivelir Example</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Main</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).MainSceneDelegate</string>
</dict>
</array>
</dict>
</dict>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>Launch</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>NSPhotoLibraryUsageDescription</key>
<string>The app requires access to your photos library to change profile images</string>
</dict>
</plist>
64 changes: 64 additions & 0 deletions Example/NivelirExample/Modules/Chat/ChatEmptyView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import UIKit

final class ChatEmptyView: UIView {

private let iconImageView = UIImageView()
private let titleLabel = UILabel()
private let subtitleLabel = UILabel()

var title: String? {
get { titleLabel.text }
set { titleLabel.text = newValue }
}
override init(frame: CGRect = .zero) {
super.init(frame: frame)

backgroundColor = Colors.background

setupIconImageView()
setupTitleLabel()
setupSubtitleLabel()
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

private func setupIconImageView() {
addSubview(iconImageView)

iconImageView.image = Images.chat
iconImageView.contentMode = .scaleAspectFit

iconImageView.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.centerY.equalToSuperview().offset(-70.0)
make.size.equalTo(140.0)
}
}

private func setupTitleLabel() {
addSubview(titleLabel)

titleLabel.textColor = Colors.title
titleLabel.font = .systemFont(ofSize: 24.0)

titleLabel.snp.makeConstraints { make in
make.top.equalTo(iconImageView.snp.bottom).offset(16.0)
make.centerX.equalToSuperview()
}
}

private func setupSubtitleLabel() {
addSubview(subtitleLabel)

subtitleLabel.text = "No messages, yet!"
subtitleLabel.textColor = Colors.unimportant
subtitleLabel.font = .systemFont(ofSize: 16.0)

subtitleLabel.snp.makeConstraints { make in
make.top.equalTo(titleLabel.snp.bottom).offset(4.0)
make.centerX.equalToSuperview()
}
}
}
20 changes: 20 additions & 0 deletions Example/NivelirExample/Modules/Chat/ChatSreen.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import UIKit
import Nivelir

struct ChatScreen: Screen {

let chatID: Int

var traits: Set<AnyHashable> {
[chatID]
}

func build(navigator: ScreenNavigator) -> UIViewController {
ChatViewController(
chatID: chatID,
screenKey: key,
screenNavigator: navigator
)
}
}

42 changes: 42 additions & 0 deletions Example/NivelirExample/Modules/Chat/ChatViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import UIKit
import Nivelir

final class ChatViewController: UIViewController, ScreenKeyedContainer {

let chatID: Int

let screenKey: ScreenKey
let screenNavigator: ScreenNavigator

init(chatID: Int, screenKey: ScreenKey, screenNavigator: ScreenNavigator) {
self.chatID = chatID

self.screenKey = screenKey
self.screenNavigator = screenNavigator

super.init(nibName: nil, bundle: nil)

hidesBottomBarWhenPushed = true
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func loadView() {
let chatEmptyView = ChatEmptyView()

chatEmptyView.title = "Chat \(chatID)"

view = chatEmptyView
}
}

extension ChatViewController: ScreenRefreshableContainer {

func refresh(completion: @escaping () -> Void) {
print("Refreshed")

completion()
}
}
Loading

0 comments on commit 83b0656

Please sign in to comment.