From 7f22d1ff6d4fe708116542e1fcb6fb95dd768ba8 Mon Sep 17 00:00:00 2001 From: Oliver Wiese <oliver.wiese@fu-berlin.de> Date: Thu, 5 Oct 2017 15:53:55 +0200 Subject: [PATCH] add new functions in mailhandler --- enzevalos_iphone/AppDelegate.swift | 1 - .../Folder+CoreDataProperties.swift | 2 + enzevalos_iphone/ListViewController.swift | 4 +- enzevalos_iphone/MailHandler.swift | 160 ++++++++++++------ .../enzevalos_iphone.xcdatamodel/contents | 3 +- 5 files changed, 114 insertions(+), 56 deletions(-) diff --git a/enzevalos_iphone/AppDelegate.swift b/enzevalos_iphone/AppDelegate.swift index d2971e68..339fe456 100644 --- a/enzevalos_iphone/AppDelegate.swift +++ b/enzevalos_iphone/AppDelegate.swift @@ -202,7 +202,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func presentInboxViewController() { let rootViewController = (self.window?.rootViewController! as! UINavigationController) - mailHandler.allContacts(inbox: "INBOX") for vc in rootViewController.viewControllers { if let id = vc.restorationIdentifier, id == "folderViewController" { diff --git a/enzevalos_iphone/Folder+CoreDataProperties.swift b/enzevalos_iphone/Folder+CoreDataProperties.swift index ca845025..e409429a 100644 --- a/enzevalos_iphone/Folder+CoreDataProperties.swift +++ b/enzevalos_iphone/Folder+CoreDataProperties.swift @@ -19,6 +19,8 @@ extension Folder { @NSManaged public var parent: Folder? @NSManaged public var mails: NSSet? @NSManaged public var path: String + @NSManaged public var lastUpdate: Date? + @NSManaged public var delimiter: String public var flags: MCOIMAPFolderFlag{ get { diff --git a/enzevalos_iphone/ListViewController.swift b/enzevalos_iphone/ListViewController.swift index 150c8b6b..872d6a37 100644 --- a/enzevalos_iphone/ListViewController.swift +++ b/enzevalos_iphone/ListViewController.swift @@ -52,7 +52,7 @@ class ListViewController: UITableViewController { self.title = contact!.name if contact!.mails.count < 20 { loading = true - AppDelegate.getAppDelegate().mailHandler.loadMoreMails(contact!, folderPath: UserManager.backendInboxFolderPath, newMailCallback: addNewMail, completionCallback: doneLoading) + AppDelegate.getAppDelegate().mailHandler.loadMailsForRecord(contact!, folderPath: UserManager.backendInboxFolderPath, newMailCallback: addNewMail, completionCallback: doneLoading) } } } @@ -211,7 +211,7 @@ class ListViewController: UITableViewController { if y > h + reload_distance && !loading { print("loading new mail because we scrolled to the bottom") loading = true - AppDelegate.getAppDelegate().mailHandler.loadMoreMails(contact!, folderPath: UserManager.backendInboxFolderPath, newMailCallback: addNewMail, completionCallback: doneLoading) + AppDelegate.getAppDelegate().mailHandler.loadMailsForRecord(contact!, folderPath: UserManager.backendInboxFolderPath, newMailCallback: addNewMail, completionCallback: doneLoading) tableView.reloadData() } } diff --git a/enzevalos_iphone/MailHandler.swift b/enzevalos_iphone/MailHandler.swift index f9b6721a..9f023a20 100644 --- a/enzevalos_iphone/MailHandler.swift +++ b/enzevalos_iphone/MailHandler.swift @@ -133,7 +133,7 @@ class MailHandler { var delegate: MailHandlerDelegator? - fileprivate static let MAXMAILS: UInt32 = 50 + fileprivate static let MAXMAILS = 25 fileprivate let concurrentMailServer = DispatchQueue(label: "com.enzevalos.mailserverQueue", attributes: DispatchQueue.Attributes.concurrent) @@ -372,7 +372,6 @@ class MailHandler { } func startIMAPIdleIfSupported(addNewMail: @escaping (() -> ())) { - return if let supported = IMAPIdleSupported { if supported && IMAPIdleSession == nil { IMAPIdleSession = setupIMAPSession() @@ -385,7 +384,8 @@ class MailHandler { print("Something happened while idleing!") self.IMAPIdleSession = nil - self.receiveAll(newMailCallback: addNewMail, completionCallback: { _ in self.startIMAPIdleIfSupported(addNewMail: addNewMail) }) + //self.receiveAll(newMailCallback: addNewMail, completionCallback: { _ in self.startIMAPIdleIfSupported(addNewMail: addNewMail) }) + self.initInbox(inbox: "Inbox", newMailCallback: addNewMail, completionCallback: { _ in self.startIMAPIdleIfSupported(addNewMail: addNewMail) }) }) } } else { @@ -461,7 +461,7 @@ class MailHandler { self.loadMessagesFromServer(uids, folderPath: folderPath, record: nil, newMailCallback: newMailCallback, completionCallback: completionCallback) }*/ - completionCallback(true) + self.initInbox(inbox: folderPath, newMailCallback: newMailCallback, completionCallback: completionCallback) return getUIDs(for: folderPath) {allUIDs in let loadUIDs = allUIDs.suffix(Int(MailHandler.MAXMAILS)) @@ -524,7 +524,7 @@ class MailHandler { } } - private func loadMessagesFromServer(_ uids: MCOIndexSet, folderPath: String, maxLoad: UInt32 = MailHandler.MAXMAILS,record: KeyRecord?, newMailCallback: @escaping (() -> ()), completionCallback: @escaping ((_ error: Bool) -> ())) { + private func loadMessagesFromServer(_ uids: MCOIndexSet, folderPath: String, maxLoad: Int = MailHandler.MAXMAILS,record: KeyRecord?, newMailCallback: @escaping (() -> ()), completionCallback: @escaping ((_ error: Bool) -> ())) { let requestKind = MCOIMAPMessagesRequestKind(rawValue: MCOIMAPMessagesRequestKind.headers.rawValue | MCOIMAPMessagesRequestKind.flags.rawValue) let fetchOperation: MCOIMAPFetchMessagesOperation = self.IMAPSession.fetchMessagesOperation(withFolder: folderPath, requestKind: requestKind, uids: uids) @@ -536,7 +536,7 @@ class MailHandler { completionCallback(true) return } - var calledMails: UInt32 = 0 + var calledMails = 0 if let msgs = msg { let dispatchGroup = DispatchGroup() for m in msgs.reversed() { @@ -722,35 +722,6 @@ class MailHandler { } - func findMaxUID(_ folder: String, callback: @escaping ((_ maxUID: UInt64) -> ())) { - //TODO: NSP!!! - var maxUID: UInt64 = 0 - let requestKind = MCOIMAPMessagesRequestKind(rawValue: MCOIMAPMessagesRequestKind.headers.rawValue) - let uids = MCOIndexSet(range: MCORangeMake(1, UINT64_MAX)) - let dispatchGroup = DispatchGroup() - dispatchGroup.enter() - - let fetchOperation: MCOIMAPFetchMessagesOperation = self.IMAPSession.fetchMessagesOperation(withFolder: folder, requestKind: requestKind, uids: uids) - fetchOperation.start { (err, msg, vanished) -> Void in - guard err == nil else { - print("Error while fetching inbox: \(String(describing: err))") - return - } - if let msgs = msg { - for m in msgs { - let message: MCOIMAPMessage = m as! MCOIMAPMessage - let id = UInt64(message.uid) - if id > maxUID { - maxUID = id - } - } - } - dispatchGroup.leave() - } - dispatchGroup.notify(queue: DispatchQueue.main) { - callback(maxUID) - } - } func getUIDs(for folderPath: String, callback: @escaping ((_ uids: [UInt64]) -> ())) { //TODO: NSP!!! @@ -829,11 +800,6 @@ class MailHandler { } } - /*func delete(mails: [PersistentMail]) { - for mail in mails { - DataHandler.handler.deleteMail(with: mail.uid) - } - }*/ func allFolders(_ completion: @escaping (Error?, [Any]?) -> Void){ @@ -842,29 +808,119 @@ class MailHandler { } - func initInbox(inbox: String, newMailCallback: @escaping (() -> ()),completionCallback: @escaping ((Bool) -> ()) ){ - let searchExp = MCOIMAPSearchExpression.search(since: Calendar.current.date(byAdding: .month, value: -1, to: Date())) - let searchOperation = self.IMAPSession.searchExpressionOperation(withFolder: inbox, expression: searchExp) + func initFolder(folderPath: String, newMailCallback: @escaping (() -> ()),completionCallback: @escaping ((Bool) -> ())){ + let requestKind = MCOIMAPMessagesRequestKind(rawValue: MCOIMAPMessagesRequestKind.headers.rawValue) + let uids = MCOIndexSet(range: MCORangeMake(1, UINT64_MAX)) + let toFetchIDs = MCOIndexSet() - searchOperation?.start{(err, uids)-> Void in - guard err == nil else{ - print("Error while searching inbox: \(String(describing: err))") + let fetchOperation: MCOIMAPFetchMessagesOperation = self.IMAPSession.fetchMessagesOperation(withFolder: folderPath, requestKind: requestKind, uids: uids) + fetchOperation.start { (err, msg, vanished) -> Void in + guard err == nil else { + print("Error while fetching inbox: \(String(describing: err))") + completionCallback(true) return } - if let ids = uids{ - self.loadMessagesFromServer(ids, folderPath: inbox, maxLoad: 500, record: nil, newMailCallback: newMailCallback, completionCallback: completionCallback) + if let msgs = msg { + let folder = DataHandler.handler.findFolder(with: folderPath) + folder.lastUpdate = Date() + for m in msgs { + if let message = m as? MCOIMAPMessage{ + toFetchIDs.add(UInt64(message.uid)) + } + } + self.loadMessagesFromServer(toFetchIDs, folderPath: folderPath, maxLoad: 300, record: nil, newMailCallback: newMailCallback, completionCallback: completionCallback) } + else{ + completionCallback(true) + } + } + } + + /* + + We call mails of the last month (at most 500) + */ + func initInbox(inbox: String, newMailCallback: @escaping (() -> ()),completionCallback: @escaping ((Bool) -> ()) ){ + if let date = Calendar.current.date(byAdding: .month, value: -1, to: Date()){ + loadMailsSinceDate(folderpath: inbox, since: date, newMailCallback: newMailCallback, completionCallback: completionCallback) + } + else{ + initFolder(folderPath: inbox, newMailCallback: newMailCallback, completionCallback: completionCallback) } + } + func updateFolder(folderpath: String, newMailCallback: @escaping (() -> ()),completionCallback: @escaping ((Bool) -> ())){ + let folder = DataHandler.handler.findFolder(with: folderpath) + if let date = folder.lastUpdate{ + loadMailsSinceDate(folderpath: folderpath, since: date, newMailCallback: newMailCallback, completionCallback: completionCallback) + } + else{ + initFolder(folderPath: folderpath, newMailCallback: newMailCallback, completionCallback: completionCallback) + } + } + func olderMails(folderpath: String, newMailCallback: @escaping (() -> ()),completionCallback: @escaping ((Bool) -> ())){ + let folder = DataHandler.handler.findFolder(with: folderpath) + if let mails = folder.mails{ + var oldestDate:Date? + for m in mails{ + if let mail = m as? PersistentMail{ + if oldestDate == nil || mail.date < oldestDate{ + oldestDate = mail.date + } + } + } + if let date = oldestDate{ + let searchExp = MCOIMAPSearchExpression.search(before: date) + let searchOperation = self.IMAPSession.searchExpressionOperation(withFolder: folderpath, expression: searchExp) + + searchOperation?.start{(err, uids)-> Void in + guard err == nil else{ + print("Error while searching inbox: \(String(describing: err))") + completionCallback(true) + return + } + if let ids = uids{ + let folder = DataHandler.handler.findFolder(with: folderpath) + folder.lastUpdate = Date() + self.loadMessagesFromServer(ids, folderPath: folderpath, record: nil, newMailCallback: newMailCallback, completionCallback: completionCallback) + } + else{ + completionCallback(true) + } + } + } + else{ + initFolder(folderPath: folderpath, newMailCallback: newMailCallback, completionCallback: completionCallback) + } + } + else{ + initFolder(folderPath: folderpath, newMailCallback: newMailCallback, completionCallback: completionCallback) + } - private func finish(){ - print("All contacts loaded!") } - private func com(b: Bool){ - print("All contacts loaded!") + + private func loadMailsSinceDate(folderpath: String, since: Date, maxLoad: Int = MailHandler.MAXMAILS, newMailCallback: @escaping (() -> ()),completionCallback: @escaping ((Bool) -> ())){ + let searchExp = MCOIMAPSearchExpression.search(since: since) + let searchOperation = self.IMAPSession.searchExpressionOperation(withFolder: folderpath, expression: searchExp) + searchOperation?.start{(err, uids)-> Void in + guard err == nil else{ + print("Error while searching inbox: \(String(describing: err))") + completionCallback(true) + return + } + if let ids = uids{ + let folder = DataHandler.handler.findFolder(with: folderpath) + folder.lastUpdate = Date() + self.loadMessagesFromServer(ids, folderPath: folderpath, maxLoad: maxLoad, record: nil, newMailCallback: newMailCallback, completionCallback: completionCallback) + } + else{ + completionCallback(true) + } + } + } } diff --git a/enzevalos_iphone/enzevalos_iphone.xcdatamodeld/enzevalos_iphone.xcdatamodel/contents b/enzevalos_iphone/enzevalos_iphone.xcdatamodeld/enzevalos_iphone.xcdatamodel/contents index c2565491..434ff284 100644 --- a/enzevalos_iphone/enzevalos_iphone.xcdatamodeld/enzevalos_iphone.xcdatamodel/contents +++ b/enzevalos_iphone/enzevalos_iphone.xcdatamodeld/enzevalos_iphone.xcdatamodel/contents @@ -18,6 +18,7 @@ <attribute name="delimiter" optional="YES" attributeType="String" syncable="YES"/> <attribute name="flags" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/> <attribute name="lastID" optional="YES" attributeType="Decimal" defaultValueString="1" syncable="YES"/> + <attribute name="lastUpdate" optional="YES" attributeType="Date" usesScalarValueType="NO" syncable="YES"/> <attribute name="maxID" optional="YES" attributeType="Decimal" defaultValueString="1" syncable="YES"/> <attribute name="path" attributeType="String" syncable="YES"/> <relationship name="mails" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="PersistentMail" inverseName="folder" inverseEntity="PersistentMail" syncable="YES"/> @@ -82,7 +83,7 @@ <elements> <element name="Account" positionX="-288" positionY="-9" width="128" height="150"/> <element name="EnzevalosContact" positionX="-209" positionY="198" width="128" height="90"/> - <element name="Folder" positionX="-297" positionY="-18" width="128" height="150"/> + <element name="Folder" positionX="-297" positionY="-18" width="128" height="165"/> <element name="Mail_Address" positionX="-297" positionY="-18" width="128" height="150"/> <element name="PersistentKey" positionX="-315" positionY="-36" width="128" height="180"/> <element name="PersistentMail" positionX="-416" positionY="-189" width="128" height="315"/> -- GitLab