pEpForiOS/UI/EmailDisplay/EmailListViewController.swift
author Ana Rebollo <ana@pep-project.org>
Wed, 18 May 2016 17:11:45 +0200
changeset 207 77ab2e8e918d
parent 196 adbb445a7208
child 209 16d698b93533
permissions -rw-r--r--
refactor new account setup
dirk@30
     1
//
dirk@30
     2
//  EmailListViewController.swift
dirk@30
     3
//  pEpForiOS
dirk@30
     4
//
dirk@30
     5
//  Created by Dirk Zimmermann on 16/04/16.
dirk@30
     6
//  Copyright © 2016 p≡p Security S.A. All rights reserved.
dirk@30
     7
//
dirk@30
     8
dirk@30
     9
import Foundation
dirk@30
    10
import UIKit
dirk@31
    11
import CoreData
dirk@30
    12
dirk@58
    13
struct UIState {
dirk@58
    14
    let runningOpsUser = NSMutableOrderedSet()
dirk@58
    15
    let runningOpsAuto = NSMutableOrderedSet()
dirk@58
    16
dirk@58
    17
    func isSynching() -> Bool {
dirk@58
    18
        return runningOpsUser.count > 0 || runningOpsAuto.count > 0
dirk@58
    19
    }
dirk@58
    20
dirk@58
    21
    func isSynchingAuto() -> Bool {
dirk@58
    22
        return runningOpsAuto.count > 0
dirk@58
    23
    }
dirk@58
    24
dirk@58
    25
    func isSynchingUser() -> Bool {
dirk@58
    26
        return runningOpsUser.count > 0
dirk@58
    27
    }
dirk@58
    28
}
dirk@58
    29
dirk@31
    30
class EmailListViewController: UITableViewController {
dirk@155
    31
    let comp = " "
dirk@30
    32
dirk@31
    33
    var appConfig: AppConfig?
dirk@31
    34
    var fetchController: NSFetchedResultsController?
dirk@58
    35
    let state = UIState()
dirk@31
    36
dirk@31
    37
    override func viewWillAppear(animated: Bool) {
dirk@31
    38
        if appConfig == nil {
dirk@31
    39
            if let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate {
dirk@31
    40
                appConfig = appDelegate.appConfig
dirk@31
    41
            }
dirk@31
    42
        }
ana@152
    43
ana@152
    44
        let account:IAccount? = appConfig!.model.fetchLastAccount()
ana@152
    45
        if (account == nil)  {
ana@152
    46
            self.performSegueWithIdentifier("userSettings", sender: self)
ana@207
    47
        } else {
ana@207
    48
            fetchMails()
ana@152
    49
        }
ana@207
    50
        super.viewWillAppear(animated)
ana@207
    51
    }
ana@152
    52
ana@207
    53
    func fetchMails() {
ana@142
    54
        prepareFetchRequest()
dirk@55
    55
dirk@115
    56
        if let account = appConfig?.model.fetchLastAccount() {
dirk@55
    57
            let connectInfo = account.connectInfo
dirk@55
    58
dirk@67
    59
            appConfig!.grandOperator.prefetchEmails(
dirk@55
    60
                connectInfo, folder: ImapSync.defaultImapInboxName, completionBlock: {
dirk@67
    61
                    [unowned self] error in
dirk@58
    62
                    GCD.onMain({
dirk@67
    63
                        Log.info(self.comp, "Sync completed, error: \(error)")
dirk@149
    64
                        self.updateUI()
dirk@58
    65
                    })
ana@207
    66
                })
dirk@149
    67
            updateUI()
dirk@55
    68
        }
dirk@31
    69
    }
dirk@31
    70
dirk@196
    71
    @IBAction func newAccountCreatedSegue(segue: UIStoryboardSegue) {
ana@207
    72
        fetchMails()
dirk@196
    73
    }
dirk@196
    74
ana@143
    75
    func prepareFetchRequest() {
dirk@31
    76
        let predicates: [NSPredicate] = [NSPredicate.init(value: true)]
dirk@31
    77
        let fetchRequest = NSFetchRequest.init(entityName: Message.entityName())
dirk@31
    78
        fetchRequest.predicate = NSCompoundPredicate.init(
dirk@31
    79
            andPredicateWithSubpredicates: predicates)
dirk@119
    80
        fetchRequest.sortDescriptors = [NSSortDescriptor.init(key: "originationDate", ascending: false)]
dirk@31
    81
        fetchController = NSFetchedResultsController.init(
dirk@31
    82
            fetchRequest: fetchRequest,
dirk@31
    83
            managedObjectContext: appConfig!.coreDataUtil.managedObjectContext,
dirk@31
    84
            sectionNameKeyPath: nil, cacheName: nil)
dirk@31
    85
        fetchController?.delegate = self
dirk@31
    86
        do {
dirk@31
    87
            try fetchController?.performFetch()
dirk@31
    88
        } catch let err as NSError {
dirk@31
    89
            Log.error(comp, error: err)
dirk@31
    90
        }
dirk@31
    91
    }
dirk@31
    92
dirk@58
    93
    // MARK: - UI State
dirk@58
    94
dirk@58
    95
    func updateUI() {
dirk@58
    96
        if state.isSynching() {
dirk@58
    97
            UIApplication.sharedApplication().networkActivityIndicatorVisible = true
dirk@58
    98
        } else {
dirk@58
    99
            UIApplication.sharedApplication().networkActivityIndicatorVisible = false
dirk@58
   100
        }
dirk@58
   101
    }
dirk@58
   102
dirk@31
   103
    // MARK: - UITableViewDataSource
dirk@31
   104
dirk@31
   105
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
dirk@31
   106
        return (fetchController?.sections?.count)!
dirk@31
   107
    }
dirk@31
   108
dirk@31
   109
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
dirk@31
   110
        if fetchController?.sections?.count > 0 {
dirk@31
   111
            if let sections = fetchController?.sections {
dirk@31
   112
                let sectionInfo = sections[section]
dirk@31
   113
                return sectionInfo.numberOfObjects
dirk@31
   114
            }
dirk@31
   115
        }
dirk@31
   116
        return 0
dirk@31
   117
    }
dirk@31
   118
dirk@31
   119
    override func tableView(tableView: UITableView,
dirk@31
   120
                            cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
dirk@31
   121
        let cell = tableView.dequeueReusableCellWithIdentifier("EmailListViewCell", forIndexPath: indexPath) as! EmailListViewCell
dirk@31
   122
        configureCell(cell, indexPath: indexPath)
dirk@31
   123
        return cell
dirk@31
   124
    }
dirk@31
   125
dirk@31
   126
    func putString(string: String?, toLabel: UILabel) {
dirk@31
   127
        if string?.characters.count > 0 {
dirk@31
   128
            toLabel.hidden = false
dirk@31
   129
            toLabel.text = string!
dirk@31
   130
        } else {
dirk@31
   131
            toLabel.hidden = true
dirk@31
   132
        }
dirk@31
   133
    }
dirk@31
   134
dirk@31
   135
    func configureCell(cell: EmailListViewCell, indexPath: NSIndexPath) {
dirk@31
   136
        if let email = fetchController?.objectAtIndexPath(indexPath) as? Message {
dirk@31
   137
            putString(email.from?.displayString(), toLabel: cell.senderLabel)
dirk@31
   138
            putString(email.subject, toLabel: cell.subjectLabel)
dirk@31
   139
            putString(nil, toLabel: cell.summaryLabel)
dirk@32
   140
dirk@119
   141
            if let originationDate = email.originationDate {
dirk@32
   142
                let formatter = NSDateFormatter.init()
dirk@32
   143
                formatter.dateStyle = .ShortStyle
dirk@32
   144
                formatter.timeStyle = .ShortStyle
dirk@119
   145
                putString(formatter.stringFromDate(originationDate), toLabel: cell.dateLabel)
dirk@32
   146
            } else {
dirk@32
   147
                putString(nil, toLabel: cell.dateLabel)
dirk@32
   148
            }
dirk@31
   149
        }
dirk@30
   150
    }
dirk@30
   151
dirk@30
   152
}
dirk@30
   153
dirk@31
   154
extension EmailListViewController: NSFetchedResultsControllerDelegate {
dirk@31
   155
    func controllerWillChangeContent(controller: NSFetchedResultsController) {
dirk@31
   156
        tableView.beginUpdates()
dirk@30
   157
    }
dirk@30
   158
dirk@31
   159
    func controller(controller: NSFetchedResultsController,
dirk@31
   160
                    didChangeSection sectionInfo: NSFetchedResultsSectionInfo,
dirk@31
   161
                                     atIndex sectionIndex: Int,
dirk@31
   162
                                             forChangeType type: NSFetchedResultsChangeType) {
dirk@31
   163
        switch (type) {
dirk@31
   164
        case .Insert:
dirk@31
   165
            tableView.insertSections(NSIndexSet.init(index: sectionIndex),
dirk@31
   166
                                     withRowAnimation: .Fade)
dirk@31
   167
        case .Delete:
dirk@31
   168
            tableView.deleteSections(NSIndexSet.init(index: sectionIndex),
dirk@31
   169
                                     withRowAnimation: .Fade)
dirk@31
   170
        default:
dirk@31
   171
            Log.info(comp, "unhandled changeSectionType: \(type)")
dirk@31
   172
        }
dirk@30
   173
    }
dirk@30
   174
dirk@31
   175
    func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject,
dirk@31
   176
                    atIndexPath indexPath: NSIndexPath?,
dirk@31
   177
                                forChangeType type: NSFetchedResultsChangeType,
dirk@31
   178
                                              newIndexPath: NSIndexPath?) {
dirk@40
   179
        switch type {
dirk@40
   180
        case .Insert:
dirk@40
   181
            tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
dirk@40
   182
        case .Delete:
dirk@40
   183
            tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
dirk@40
   184
        case .Update:
dirk@40
   185
            if let cell = tableView.cellForRowAtIndexPath(indexPath!) {
dirk@40
   186
                self.configureCell(cell as! EmailListViewCell, indexPath: indexPath!)
dirk@40
   187
            } else {
dirk@40
   188
                Log.warn(comp, "Could not find cell for changed indexPath: \(indexPath!)")
dirk@31
   189
            }
dirk@40
   190
        case .Move:
dirk@40
   191
            if newIndexPath != indexPath {
dirk@40
   192
                tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
dirk@40
   193
                tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
dirk@40
   194
            }
dirk@31
   195
        }
dirk@31
   196
    }
dirk@31
   197
dirk@31
   198
    func controllerDidChangeContent(controller: NSFetchedResultsController) {
dirk@31
   199
        tableView.endUpdates()
dirk@31
   200
    }
dirk@30
   201
}