Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/settings #33

Merged
merged 19 commits into from
May 22, 2018
Merged

feature/settings #33

merged 19 commits into from
May 22, 2018

Conversation

pablocarmu
Copy link
Contributor

Settings Screen

The way i'm coding this is:

  • I've created a parent settings screen called SettingsViewController which inherits from StaticTableViewController.

  • Instead of coding all the logic in this view controller, I've split the settings into three different categories:

    • Security: In this category should be coded:
      - frequency: the frequency wich the security methods should be prompted to the user, the options I proposed here are: allways, 1 minute, 5 minutes, 30 minutes, 1 hour .
      - Passcode: custom passcode, a new ViewController should be implemented for this, there is some open source libraries but I prefer to code this instead of using an external dependency.
      - TouchID/FaceID: if the device support any kind of biometric ID prompt the user with this option only if the passcode option is enabled.

    • Instant Uploads: In this category should be coded:
      - Photo uploads: This should allow to instant upload photos.
      - Video uploads: This should allow to instant upload videos.
      - Background uploads: Allow background uploads for the selected video or photo options. This option should be presented only if one of the video of photo uploads are selected.
      - Wifi only uploads: Like the above option, this should be presented only if one of the video of photo uploads are selected.
      - Accout to upload: This should present to the user a list of bookmarks you have in the app and select the account you want to be the one in which the instant uploads should be put.
      - Path for instant uploads: Here you can select the folder you want to be the container for the instant uploads.

    • Various Things: Here we should code:
      - Open source licenses: Is required to put the license or a link to the license for every third party libreary we use.
      - About ownCloud
      - Feedback
      - More things...

Coding each category into a separate class may look as an overhead, but this allow us to:

  • Select what settings we want to be shown: Maybe in the future, some users/customers want to ban instant uploads, so this way in a single line of code you avoid the creation and presentation of this settings.
  • Decouple the settings: Instead of one massive class with all the settings you have 3 classes (each one has a StaticTableViewSection) so you have a more decoupled settings system. This should make us able to have the code isolated and add in the future more settings/categories without make the parent settings view a massive class.

The issue to comment more settings or another way to abord this feature is linked to this pull request so if you have any requirements or any things to discuss please comment there and ping me (@pablocarmu) in the comment so we can get this pull request comment as clean as posible.

@felix-schwarz
Copy link
Contributor

@pablocarmu:

  • Decouple the settings: Instead of one massive class with all the settings you have 3 classes (each one has a StaticTableViewSection) so you have a more decoupled settings system. This should make us able to have the code isolated and add in the future more settings/categories without make the parent settings view a massive class.

Unless there's a reason not to do so, please consider making these classes subclasses of StaticTableViewSection.

@pablocarmu pablocarmu changed the title Settings Screen (Work in progress) feature/settings May 3, 2018
self.headerTitle = "Security".localized
self.identifier = SecuritySectionIdentifier

updateUI()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of breaking the creation of the rows into methods, and then checking if they exist using their identifier lateron, you could generate all rows here in the init-method and save them in instance variables.

Benefits:

  • you don't need to keep track of whether or not they were already created (=> they're all just there already, ready for use).
  • you can use the row objects directly and don't have to find and fetch them through their identifiers (=> you also don't need to generate symbols for the identifiers (like f.ex. SecurityBiometricsRowIdentifier) then, simplifying the implementation further)
  • to change the interface dynamically, you could either keep using add/remove methods on the StaticTableViewSection - or put together a new rows array and ask the tableView to reload just that section. Ideally, you could extend StaticTableViewSection with a "replaceRows" method that replaces the rows instance var with a passed in array, and triggers a section reload. I also noticed that StaticTableViewSection doesn't support "live" additions/removals and animation yet, so it may be a good idea to:
    • add animation support to add(rows:) (like add(rows:animated:) where animated defaults to false and only calls insertRows(at indexPaths: [IndexPath], with animation: UITableViewRowAnimation) if the viewController property is set)
    • add a remove(rows:animated:) method that does the same, just for removal
    • add add(row:animated:) and remove(row:animated:) convenience methods that wrap the passed row into an array and forward it to the add(rows:animated:) and remove(rows:animated:) methods.
    • in the future, an insert(rows:indexes:animated:) method could be added, too - and add(rows:animated:) be changed to become just a convenience method to call that. But if it's not needed at the moment, this can surely be saved until we need it.

@pablocarmu pablocarmu changed the base branch from master to feature/bookmarks May 10, 2018 07:56
@pablocarmu pablocarmu changed the base branch from feature/bookmarks to master May 10, 2018 07:57
Pablo Carrascal and others added 17 commits May 15, 2018 10:24
- Split the settings between Security ones, Instant Uploads ones and other settings.
- Used UserDefaults for storing settings but the pincode
- Followed @felix-schwarz recommendations and changed settings sections from NSObject to StaticTableViewSection.
- Updated StaticTableViewController and StaticTableViewSection to be able to update and reload a single section.
- Implemented insert(row, at) method to StaticTableViewSection.
- Implemented new options for the setting, now the wifi only and selected path for each video and photos.
…s that needs to retrieve them.

- Remove unused @discardableResults annotations.
- Change the settings table view style to .grouped.
- Coded UI for the last section of settings called More.
- Created ViewController with a WKWebView inside to be able to push it through the navigation controller.
- Show in a webview the help and privacy policy webpages.
- Renamed sharedBookmarkManager property on BookmarkManager.swift to shared
…s from methods to instance properties.

- Changed SecurityAskfrequency, now it's Int based enum.
- Change the row creation in the MoreSettingsSection to instance properties.
- Added new remove method to StaticTableViewSection for removing only one row.
- Fixed som typo errors.
- Updated the method calls to insert/remove cells in a "live" way.
- Minor bug fixes.
- Remove old unused code.
- Changed the way the frequency options are prompted from an AlertView to a separate View Controller.
- Updated project.
Copy link
Contributor

@felix-schwarz felix-schwarz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this looks really good! 👍

Just one more thing:
If you have a block of code that inserts or removes more than one row, please wrap it in a self.tableView.performBatchUpdates() (=> for an example, check BookmarkViewController.composeSectionsAndRows, which covers both animated and non-animated versions).

} else {
isPhotoWifiOnlyUploadsEnabled = false
remove(rows: [photosWifiOnlyRow!, photosSelectedPathRow!], animated: true)
userDefaults.removeObject(forKey: UploadsPhotoSelectedPathKey)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this to the willSet/didSet closures for isPhotoUploadEnabled, too, to keep UI code and defaults manipulation separate.

@@ -22,7 +22,7 @@ import ownCloudSDK
class BookmarkManager: NSObject {
public var bookmarks : NSMutableArray

static var sharedBookmarkManager : BookmarkManager = {
static var shared : BookmarkManager = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, so much nicer 😃

"Security" = "Security";
"Passcode Lock" = "Passcode Lock";
"FaceID" = "FaceID";
"TouchID" = "TouchID";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change this to "Face ID" and "Touch ID" (adding a space) to match Apple's naming scheme.

@@ -25,113 +25,113 @@ class GlobalSettingsViewController: StaticTableViewController {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can remove this file now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe worth to keep this file in the repo as some kind of "recipes". It really helped me some times to understand how the StaticTableView... structure works. As we are open source maybe itcould be valuable for contributors.

override init(userDefaults: UserDefaults) {
super.init(userDefaults: userDefaults)
self.headerTitle = "More".localized
self.footerTitle = "owncloud 2018 iOS beta"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can get the version number from NSBundle.main.object(forInfoDictionaryKey: ) using kCFBundleVersionKey (build number) and "CFBundleShortVersionString" (version number, i.e. "1.0") as keys and display it here.


self.navigationItem.title = "Settings".localized

let standardUserDefaults = UserDefaults.standard
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC we'll need to grab a different UserDefaults instance via UserDefaults(suiteName: appGroupIdentifier) here. However, since it'll be needed in more places, I'd really like to add that to OCAppIdentity, so SettingsViewController can grab it from there in the future.

For now, please use

// TODO: Use OCAppIdentity-provided user defaults in the future
let userDefaults = UserDefaults(suitename: OCAppIdentity.sharedAppIdentity().appGroupIdentifier)


} else {
isVideoWifiOnlyUploadsEnabled = false
userDefaults.removeObject(forKey: UploadsVideoSelectedPathKey)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this to the willSet/didSet closures for isVideoUploadEnabled, too, to keep UI code and defaults manipulation separate.

@@ -182,4 +182,12 @@ class StaticTableViewSection: NSObject {

return nil
}

private func selectAnimation(_ animated: Bool) -> UITableViewRowAnimation {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem to be used anywhere. Please remove it.

if canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) {
switch self.biometryType {
case .faceID : return "Face ID"
case .touchID: return "Touch ID"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add ".localized" to make use of localizations in Localizable.strings.


extension LAContext {

func supportedBiometricsAuthenticationNAme() -> String? {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tiny typo here: "NAme" vs "Name" at the end of the method.

- Some minor typo.
- Implemented the build number and version number in the footer of the setting header.
- Implemented the build number and version number as subject in the feedback email.
- Removed section identifier constants.
- Fixed a bug in the frequency selector.
- Changed the user defaults from .standard to one provided by de SDK.
- Removed unused code.
return ""
}

var appBuildNumber: String {
Copy link
Contributor

@felix-schwarz felix-schwarz May 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great idea to make these "properties". 👍

@@ -164,6 +161,8 @@ class SecuritySettingsSection: SettingsSection {

var rowsToRemove: [StaticTableViewRow] = []
frequencyRow?.cell?.detailTextLabel?.text = SecurityAskFrequency.always.toString()
frequency = .always
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to move this to isPasscodeSecurityEnabled/willSet.

@michaelstingl
Copy link
Contributor

michaelstingl commented May 18, 2018

Suggested changes:

  • Show Git hash (on bottom with version?)
  • Hide/explain unfinished settings
  • Open links in SFSafariViewController
  • Make links to Help/Privacy brandable/MDM
  • Make entries like "Recommend to a friend" brandable/MDM

@jesmrec
Copy link
Contributor

jesmrec commented May 18, 2018

A couple of minor details regarding the settings view

  • In Send feedback option, the subject of the mail has a lack of one )
  • In the bottom of the view you wrote Owncloud instead of ownCloud . The content of such label has to be brandable as well.

- Fix ownCloud typo.
- Replaced the WKWebkit with SFSafariViewController.
- Implemented user confirmation when open external url through SFSafariViewController.
- Show the git commit next to the app's version and build number.
@jesmrec
Copy link
Contributor

jesmrec commented May 22, 2018

Approved

@jesmrec jesmrec merged commit 1dc1da6 into master May 22, 2018
@felix-schwarz felix-schwarz deleted the feature/settings branch June 20, 2018 07:52
@jesmrec jesmrec added this to the 0.1.0 milestone Jul 2, 2018
@jesmrec jesmrec mentioned this pull request Aug 1, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants