objcio / app-architecture Goto Github PK
View Code? Open in Web Editor NEWSample Code of the App Architecture Book
Home Page: https://www.objc.io/books/app-architecture
Sample Code of the App Architecture Book
Home Page: https://www.objc.io/books/app-architecture
I'm not familiar with swift ,but OC,so .... is there a oc version?
Hey guys, first of all apologies if this is not the correct way to contact you.
Second and the most important is to thank you for your great content (book and videos are so good).
Third, It seems as that the code is not updated, at least not for Recordings-MVVM-C app, or not synced with the videos (video 05). You made a lot of refactoring which I really want to explore but can't find the updated code. Is it possible to push it? even on a separate branch is ok.
Thanks!
In "One-App-Eight-Architectures" project you have created a model directly in a view controller. I understand that for simplification you have chosen this path. But for example in MVVM the view should not know about model. I think that this can be confusing for some people. I know - it's simple example app. But from the whole point of view - this is a book about app architectures so why to violate their basic principles and dependencies and bend them over when you try to teach them?
tableView.reloadData
in folder.didSet
conflicts with tableView.deleteRows
or tableView.insertRows
, so the app will crash on creating or deleting folders.
Two solutions:
tableView.deleteRows
and tableView.insertRows
, or call tableView.reloadData()
imperatively instead of auto call in folder.didSet
.tableView.reloadData()
in folder.didSet
. For example, add a updatingInteractive
instance variable, set to true
on start of deleteItem(item:)
and insert(item:)
methods, set to false
on end.Project: Recordings-controller-owned-networking*
These keys in FolderViewController
are reversed and cause some changes to call reloadData instead of the correct insert animation. This incorrect code is in the book as well.
let oldValue = userInfo[Item.newValueKey]
let newValue = userInfo[Item.oldValueKey]
let oldValue = userInfo[Item.newValueKey]
let newValue = userInfo[Item.oldValueKey]
In the MVC+VS version of the Recordings application, one of the features that can be implemented with ease thanks to the architecture is the Time Travel Debugging.
I noticed that when traveling through the history of the View States, in case a view is presented on top of the actual View Hierarchy you lose access to the slide until you dismiss the actual view, which adds another view state to the history, in this case the culprit is the recording screen. Is that behaviour expected? If not, or even if it is, how would be a good way to not lose access to the slider when the history contains a screen that is presented on top of the actual view context?
The problem seems to be on line 20 of FolderViewController:
viewModel.folderContents.bind(to: tableView.rx.items(dataSource: dataSource)).disposed(by: disposeBag)
I'm getting the following:
2019-05-23 12:20:09.318611-0300 Recordings[15921:6162304] Warning: Unable to create restoration in progress marker file
Assertion failed: This is a feature to warn you that there is already a delegate (or data source) set somewhere previously. The action you are trying to perform will clear that delegate (data source) and that means that some of your features that depend on that delegate (data source) being set will likely stop working.
If you are ok with this, try to set delegate (data source) to `nil` in front of this operation.
This is the source object value: <UITableView: 0x7fa7e805c200; frame = (0 0; 375 812); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x60800005bdb0>; layer = <CALayer: 0x60000023a040>; contentOffset: {0, 0}; contentSize: {0, 0}; adjustedContentInset: {0, 0, 0, 0}>
This is the original delegate (data source) value: <Recordings.FolderViewController: 0x7fa7e7d1a890>
Hint: Maybe delegate was already set in xib or storyboard and now it's being overwritten in code.
: file /Users/jeff/Developer/app-architecture/Recordings-MVVM-C/Pods/RxCocoa/RxCocoa/Common/DelegateProxyType.swift, line 222
2019-05-23 12:20:15.881476-0300 Recordings[15921:6162304] Assertion failed: This is a feature to warn you that there is already a delegate (or data source) set somewhere previously. The action you are trying to perform will clear that delegate (data source) and that means that some of your features that depend on that delegate (data source) being set will likely stop working.
This seems to happen in both Xcode 9.4.1 and 10.2 using RxSwift 4.0.0 and RxDataSources 3.0.2. Setting the tableView's delegate and dataSource to nil
after super.viewDidLoad()
fixes the issue for me.
I'm trying to understand why MultiViewController
was extended for the MVC version. The function mvcDidLoad()
and the action mvcButtonPressed()
are typically just included in the ViewController class. I looked through the accompanying book and some of the videos and didn't see any mention of extending the ViewController under the MVC pattern. I also didn't see that with the Recordings application. Is there some benefit, structural or clarity to this?
i download the project and when i run the One-App-Eight-Architectures ,it is runs some errors,my Xcode is 10.2
I was getting an xcodebuild error when running carthage update --platform iOS
for the MVVM-C project as it couldn't build RxDataSources
. I got it to work by updating the cartfile to this:
github "ReactiveX/RxSwift" ~> 4.0.0
github "RxSwiftCommunity/RxDataSources" ~> 3.0
I don't want to create a PR because I'm not sure if this was just an issue for me.
Fix:
In FolderViewController
folder
property is a struct, so in methods deleteItem(item:)
and insert(item:)
changing the folder property will trigger didSet
block with tableView.reloadData()
.
Therefore, tableView.deleteRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
and self.tableView.insertRows(at: [IndexPath(row: self.folder.contents.endIndex-1, section: 0)], with: .automatic)
are redundand and provoke a crash.
Deleting these lines should fix it
So that I can complete it by myself. Thx
This can be worked around with some funny casting:
let newValue = change.newValue ?? (nil as Any? as! Value)
onChange(newValue)
Then we can also observe optionals correctly.
Thanks to the awesome help of Jordan Rose of the Swift team for providing the workaround!
Would it be possible to put the example projects under an open source license like the MIT license?
Hello,
I bought the book. I clicked the download link, pressed the .epub
and it opened in Books. 👍
I bought the videos. I clicked the download link, pressed the .m4v
and it opened in Quicktime Player. 👍
I cloned this repository. I clicked on the Xcode project and got build errors. And then it started a chain nightmare of updating Carthage, fixing brew
, fixing macOS permissions, reading about how Carthage maybe only builds for latest Swift version (4.2) while RxSwift.framework
is built for 4.0.2 through git issues etc. etc.
Can the dependencies be uploaded, or can there be a step-by-step guide where I can 100% make sure that the project builds? I feel like the code is part of the "product" and it's sad that everyone who clones it has to potentially go through hours of re-configuration. Some of this maybe will be unavoidable (ex. getting an older version of Xcode), but at least that's the only step I would have to take.
(P.S. The particular project that I mentioned is MVVM-C)
In MVC (model owned networking), after the View Controller initiates a network call, the UI only changes when the store gets updated on completion of the call. How would one update the UI to reflect network errors in this case, because the store wont update when there's no data fetched?
Should it just be propagated via the callback of the network call? (In the example in the book, there's a callback that is used only for stopping the refreshControl - should errors be made available here?)
refreshControl?.beginRefreshing()
task = folder.loadContents { [weak self] in
// Make error available here?
self?.refreshControl?.endRefreshing()
}
The callback of AVAudioSession.requestRecordPermission
may not be called on main thread, so the timer in start
method may doesn't start, due to absence of runloop.
The solution:
AVAudioSession.sharedInstance().requestRecordPermission() { allowed in
DispatchQueue.main.async {
if allowed {
self.start(url)
} else {
self.update(nil)
}
}
}
Loving the book so far! Noticed one issue in the MVC sample code.
override func viewDidAppear(_ animated: Bool) {
super.viewWillAppear(animated)
Is it a bad thing if the Coordinator becomes huge? If it is what are good solutions?
Thanks!
FolderViewController.swift 中
if let changeReason = userInfo[Item.changeReasonKey] as? String {
let oldValue = userInfo[Item.newValueKey]
let newValue = userInfo[Item.oldValueKey]
应改为:
if let changeReason = userInfo[Item.changeReasonKey] as? String {
let oldValue = userInfo[Item.newValueKey]
let newValue = userInfo[Item.oldValueKey]
I'm following the steps in the README to install RxSwift via Carthage, but running into complier issues. Specifically, No such module 'RxDataSources'
.
The only error I get when running carthage update --platform iOS
is a build failure from xcodebuild
, but I'm guessing is the same issue.
Seems like everything is installed correctly.
*** Fetching RxSwift
*** Checking out RxDataSources at "3.0.2"
*** Checking out RxSwift at "4.0.0"
*** xcodebuild output can be found in /var/folders/vn/djlphdns25qcvv_53qqwcs9c000bsw/T/carthage-xcodebuild.CSrNEV.log
*** Skipped downloading RxSwift.framework binary due to the error:
"API rate limit exceeded for 216.52.20.6. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)"
*** Skipped downloading RxDataSources.framework binary due to the error:
"API rate limit exceeded for 216.52.20.6. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)"
*** Building scheme "RxBlocking-iOS" in Rx.xcworkspace
*** Building scheme "RxCocoa-iOS" in Rx.xcworkspace
Any ideas? Anyone else run into this? I'd love to be able to build so I can play around and better grok reactive programming.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.