IOS-1455 sorted file fix IOS-1455
authorXavier Algarra <xavier@pep-project.org>
Tue, 12 Feb 2019 15:52:54 +0100
branchIOS-1455
changeset 761898de33f9d0ba
parent 7617 19410eed7a28
child 7626 157fa22d3915
IOS-1455 sorted file fix
pEpForiOS/Util/SortedSet.swift
pEpUtilities/pEpUtilities/pEpUtilities.xcodeproj/project.pbxproj
pEpUtilities/pEpUtilities/pEpUtilities/Foundation/SortedSet.swift
     1.1 --- a/pEpForiOS/Util/SortedSet.swift	Tue Feb 12 15:39:47 2019 +0100
     1.2 +++ b/pEpForiOS/Util/SortedSet.swift	Tue Feb 12 15:52:54 2019 +0100
     1.3 @@ -7,21 +7,20 @@
     1.4  //
     1.5  
     1.6  import UIKit
     1.7 -import pEpUtilities
     1.8  
     1.9  /// Automatically keeps containted objects sorted to the criteria of a given sort block.
    1.10  /// The implementation is completely trival and unperformant.
    1.11  /// Has to be improved if this causes performance issue in the app.
    1.12 -class SortedSet<T: Equatable>: Sequence {
    1.13 +public class SortedSet<T: Equatable>: Sequence {
    1.14      // MARK: - Public API
    1.15  
    1.16 -    typealias SortBlock = (_ first: T,_  second: T) -> ComparisonResult
    1.17 +    public typealias SortBlock = (_ first: T,_  second: T) -> ComparisonResult
    1.18  
    1.19      public var count: Int {
    1.20          return set.count
    1.21      }
    1.22      
    1.23 -    init(array: [T], sortBlock block: @escaping SortBlock) {
    1.24 +    public init(array: [T], sortBlock block: @escaping SortBlock) {
    1.25          set = NSMutableOrderedSet(array: array)
    1.26          sortBlock = block
    1.27          sort()
     2.1 --- a/pEpUtilities/pEpUtilities/pEpUtilities.xcodeproj/project.pbxproj	Tue Feb 12 15:39:47 2019 +0100
     2.2 +++ b/pEpUtilities/pEpUtilities/pEpUtilities.xcodeproj/project.pbxproj	Tue Feb 12 15:52:54 2019 +0100
     2.3 @@ -40,7 +40,6 @@
     2.4  		B7A46C58220DA6190027CCB5 /* String+Email.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7A46C57220DA6190027CCB5 /* String+Email.swift */; };
     2.5  		B7A46C5E220DBAF00027CCB5 /* OperationQueue+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7A46C5D220DBAF00027CCB5 /* OperationQueue+Extension.swift */; };
     2.6  		B7A46C62220DCEA80027CCB5 /* NSAttributedString+Parsing.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7A46C61220DCEA80027CCB5 /* NSAttributedString+Parsing.swift */; };
     2.7 -		B7DB7F4E2213098B003968DA /* SortedSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7DB7F4D2213098A003968DA /* SortedSet.swift */; };
     2.8  		B7DB7F5022130DE9003968DA /* Weak.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7DB7F4F22130DE9003968DA /* Weak.swift */; };
     2.9  		B7DB7F522213120B003968DA /* SortedSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7DB7F512213120B003968DA /* SortedSet.swift */; };
    2.10  /* End PBXBuildFile section */
    2.11 @@ -81,7 +80,6 @@
    2.12  		B7A46C57220DA6190027CCB5 /* String+Email.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Email.swift"; sourceTree = "<group>"; };
    2.13  		B7A46C5D220DBAF00027CCB5 /* OperationQueue+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "OperationQueue+Extension.swift"; sourceTree = "<group>"; };
    2.14  		B7A46C61220DCEA80027CCB5 /* NSAttributedString+Parsing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSAttributedString+Parsing.swift"; sourceTree = "<group>"; };
    2.15 -		B7DB7F4D2213098A003968DA /* SortedSet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SortedSet.swift; sourceTree = "<group>"; };
    2.16  		B7DB7F4F22130DE9003968DA /* Weak.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Weak.swift; sourceTree = "<group>"; };
    2.17  		B7DB7F512213120B003968DA /* SortedSet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SortedSet.swift; path = ../../../../pEpForiOS/Util/SortedSet.swift; sourceTree = "<group>"; };
    2.18  /* End PBXFileReference section */
    2.19 @@ -100,7 +98,6 @@
    2.20  		B70A3A5222005A7600EDCE61 /* Foundation */ = {
    2.21  			isa = PBXGroup;
    2.22  			children = (
    2.23 -				B7DB7F4D2213098A003968DA /* SortedSet.swift */,
    2.24  				B7465DCB2211BEE9008A1708 /* Tuple.swift */,
    2.25  				B7A46C51220C732E0027CCB5 /* Data+Extensions.swift */,
    2.26  				B7A46C53220C73BE0027CCB5 /* String+Extensions.swift */,
    2.27 @@ -278,7 +275,6 @@
    2.28  				B753907E2212D6B500B1FCF9 /* CGSize+Extension.swift in Sources */,
    2.29  				B75390802212DD0600B1FCF9 /* UIView+Util.swift in Sources */,
    2.30  				B7DB7F522213120B003968DA /* SortedSet.swift in Sources */,
    2.31 -				B7DB7F4E2213098B003968DA /* SortedSet.swift in Sources */,
    2.32  				B7911EC621F88AF800D7F66F /* UIImage+Extension.swift in Sources */,
    2.33  				B70A3A77220091D400EDCE61 /* Logger.swift in Sources */,
    2.34  				B7A46C56220DA5EB0027CCB5 /* Substring+Email.swift in Sources */,
     3.1 --- a/pEpUtilities/pEpUtilities/pEpUtilities/Foundation/SortedSet.swift	Tue Feb 12 15:39:47 2019 +0100
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,220 +0,0 @@
     3.4 -//
     3.5 -//  SortedSet.swift
     3.6 -//  pEp
     3.7 -//
     3.8 -//  Created by Andreas Buff on 02.10.17.
     3.9 -//  Copyright © 2017 p≡p Security S.A. All rights reserved.
    3.10 -//
    3.11 -
    3.12 -import UIKit
    3.13 -import pEpUtilities
    3.14 -
    3.15 -/// Automatically keeps containted objects sorted to the criteria of a given sort block.
    3.16 -/// The implementation is completely trival and unperformant.
    3.17 -/// Has to be improved if this causes performance issue in the app.
    3.18 -class SortedSet<T: Equatable>: Sequence {
    3.19 -    // MARK: - Public API
    3.20 -
    3.21 -    typealias SortBlock = (_ first: T,_  second: T) -> ComparisonResult
    3.22 -
    3.23 -    public var count: Int {
    3.24 -        return set.count
    3.25 -    }
    3.26 -    
    3.27 -    init(array: [T], sortBlock block: @escaping SortBlock) {
    3.28 -        set = NSMutableOrderedSet(array: array)
    3.29 -        sortBlock = block
    3.30 -        sort()
    3.31 -    }
    3.32 -    
    3.33 -    /// Inserts an object keeping the Set sorted. Returns the index it has been inserted to.
    3.34 -    ///
    3.35 -    /// - Parameter object: object to insert
    3.36 -    /// - Returns: index the object has been inserted to
    3.37 -    @discardableResult public func insert(object: T) -> Int {
    3.38 -        objc_sync_enter(self)
    3.39 -        defer { objc_sync_exit(self) }
    3.40 -
    3.41 -        let idx = indexOfObjectIfInserted(obj: object)
    3.42 -        set.insert(object, at: idx)
    3.43 -        return idx
    3.44 -    }
    3.45 -    
    3.46 -    public func remove(object: T) {
    3.47 -        objc_sync_enter(self)
    3.48 -        defer { objc_sync_exit(self) }
    3.49 -
    3.50 -        set.remove(object)
    3.51 -    }
    3.52 -    
    3.53 -    public func removeObject(at index: Int) {
    3.54 -        objc_sync_enter(self)
    3.55 -        defer { objc_sync_exit(self) }
    3.56 -
    3.57 -        guard isValidIndex(index) else {
    3.58 -            Logger.frontendLogger.errorAndCrash("Index out of range")
    3.59 -            return
    3.60 -        }
    3.61 -        set.removeObject(at: index)
    3.62 -    }
    3.63 -    
    3.64 -    public func replaceObject(at index: Int, with object: T) {
    3.65 -        objc_sync_enter(self)
    3.66 -        defer { objc_sync_exit(self) }
    3.67 -
    3.68 -        guard isValidIndex(index) else {
    3.69 -            Logger.frontendLogger.errorAndCrash("Index out of range")
    3.70 -            return
    3.71 -        }
    3.72 -        set.replaceObject(at: index, with: object)
    3.73 -    }
    3.74 -
    3.75 -    public func object(at index: Int) -> T? {
    3.76 -        objc_sync_enter(self)
    3.77 -        defer { objc_sync_exit(self) }
    3.78 -
    3.79 -        guard isValidIndex(index) else {
    3.80 -            Logger.frontendLogger.errorAndCrash("Index out of range")
    3.81 -            return nil
    3.82 -        }
    3.83 -
    3.84 -        return set.object(at: index) as? T
    3.85 -    }
    3.86 -
    3.87 -    /**
    3.88 -     - Returns: The index of `object` or nil.
    3.89 -     */
    3.90 -    public func index(of object: T) -> Int? {
    3.91 -        let idx = indexOrNotFound(of: object)
    3.92 -        if idx != NSNotFound {
    3.93 -            return idx
    3.94 -        } else {
    3.95 -            return nil
    3.96 -        }
    3.97 -    }
    3.98 -
    3.99 -    /**
   3.100 -     - Returns: The index of `object` or NSNotFound.
   3.101 -     */
   3.102 -    public func indexOrNotFound(of object: T) -> Int {
   3.103 -        objc_sync_enter(self)
   3.104 -        defer { objc_sync_exit(self) }
   3.105 -
   3.106 -        for i in 0..<set.count {
   3.107 -            guard let testee = set.object(at: i) as? T else {
   3.108 -                Logger.frontendLogger.errorAndCrash("error casting")
   3.109 -                return NSNotFound
   3.110 -            }
   3.111 -            if testee == object {
   3.112 -                return i
   3.113 -            }
   3.114 -        }
   3.115 -        return NSNotFound
   3.116 -    }
   3.117 -    
   3.118 -    public func removeAllObjects() {
   3.119 -        objc_sync_enter(self)
   3.120 -        defer { objc_sync_exit(self) }
   3.121 -        set.removeAllObjects()
   3.122 -    }
   3.123 -
   3.124 -    // MARK: - Array Support
   3.125 -
   3.126 -    public func array() -> [T] {
   3.127 -        objc_sync_enter(self)
   3.128 -        defer { objc_sync_exit(self) }
   3.129 -
   3.130 -        if let theArray = set.array as? [T] {
   3.131 -            return theArray
   3.132 -        } else {
   3.133 -            return []
   3.134 -        }
   3.135 -    }
   3.136 -
   3.137 -    public subscript(safe index: Int) -> T? {
   3.138 -        objc_sync_enter(self)
   3.139 -        defer { objc_sync_exit(self) }
   3.140 -
   3.141 -        if index >= set.count {
   3.142 -            return nil
   3.143 -        }
   3.144 -
   3.145 -        if let obj = set.object(at: index) as? T {
   3.146 -            return obj
   3.147 -        } else {
   3.148 -            return nil
   3.149 -        }
   3.150 -    }
   3.151 -
   3.152 -    // MARK: - Sequence
   3.153 -
   3.154 -    public typealias Iterator = SortedSetIterator<T>
   3.155 -
   3.156 -    public func makeIterator() -> SortedSet<T>.SortedSetIterator<T> {
   3.157 -        return SortedSetIterator.init(elements: set.array as! [T])
   3.158 -    }
   3.159 -
   3.160 -    // MARK: - Iterator
   3.161 -
   3.162 -    public struct SortedSetIterator<T>: IteratorProtocol {
   3.163 -        public typealias Element = T
   3.164 -
   3.165 -        private let elements: [T]
   3.166 -        private var index = 0
   3.167 -        private let maxIndex: Int
   3.168 -
   3.169 -        public init(elements: [T]) {
   3.170 -            self.elements = elements
   3.171 -            maxIndex = elements.count - 1
   3.172 -        }
   3.173 -
   3.174 -        public mutating func next() -> SortedSetIterator.Element? {
   3.175 -            if index > maxIndex {
   3.176 -                return nil
   3.177 -            } else {
   3.178 -                let e = elements[index]
   3.179 -                index += 1
   3.180 -                return e
   3.181 -            }
   3.182 -        }
   3.183 -    }
   3.184 -
   3.185 -    // MARK: -
   3.186 -    
   3.187 -    private var set = NSMutableOrderedSet()
   3.188 -    private var sortBlock: SortBlock
   3.189 -
   3.190 -    private func sort()  {
   3.191 -        set.sort { (first: Any, second: Any) -> ComparisonResult in
   3.192 -            guard let firstT = first as? T,
   3.193 -                let secondT = second as? T else {
   3.194 -                    Logger.frontendLogger.errorAndCrash("Error casting.")
   3.195 -                    return .orderedSame
   3.196 -            }
   3.197 -            return sortBlock(firstT, secondT)
   3.198 -        }
   3.199 -    }
   3.200 -    
   3.201 -    private func indexOfObjectIfInserted(obj: T) -> Int {
   3.202 -        for i in 0..<set.count {
   3.203 -            guard let testee = set.object(at: i) as? T else {
   3.204 -                Logger.frontendLogger.errorAndCrash("Error casing")
   3.205 -                return 0
   3.206 -            }
   3.207 -            if set.count == 0 {
   3.208 -                //set is empty
   3.209 -                return 0
   3.210 -            }
   3.211 -            if sortBlock(obj, testee) == .orderedAscending {
   3.212 -                // following object found
   3.213 -                return i
   3.214 -            }
   3.215 -        }
   3.216 -        // we would insert as the last object
   3.217 -        return Swift.max(0, set.count)
   3.218 -    }
   3.219 -
   3.220 -    private func isValidIndex(_ idx: Int) -> Bool {
   3.221 -        return idx >= 0 && idx < set.count
   3.222 -    }
   3.223 -}