Move extension out of utils
This commit is contained in:
parent
421b5aed1d
commit
429ac1c915
4 changed files with 121 additions and 93 deletions
|
|
@ -18,6 +18,8 @@
|
||||||
A2367B9B1EEFE1B300C8FE8B /* UtilsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2367B9A1EEFE1B300C8FE8B /* UtilsExtension.swift */; };
|
A2367B9B1EEFE1B300C8FE8B /* UtilsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2367B9A1EEFE1B300C8FE8B /* UtilsExtension.swift */; };
|
||||||
A2367B9C1EEFE2E500C8FE8B /* SwiftyUserDefaults.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCA049951E3357E000522E8F /* SwiftyUserDefaults.framework */; };
|
A2367B9C1EEFE2E500C8FE8B /* SwiftyUserDefaults.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCA049951E3357E000522E8F /* SwiftyUserDefaults.framework */; };
|
||||||
A2367BA01EF0387000C8FE8B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A2367B9F1EF0387000C8FE8B /* Assets.xcassets */; };
|
A2367BA01EF0387000C8FE8B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A2367B9F1EF0387000C8FE8B /* Assets.xcassets */; };
|
||||||
|
A239F51F2157B72700576CBF /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A239F51E2157B72700576CBF /* StringExtension.swift */; };
|
||||||
|
A239F5212157B75E00576CBF /* FileManagerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A239F5202157B75E00576CBF /* FileManagerExtension.swift */; };
|
||||||
A26075811EEC6F34005DB03E /* passKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A26075781EEC6F34005DB03E /* passKit.framework */; };
|
A26075811EEC6F34005DB03E /* passKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A26075781EEC6F34005DB03E /* passKit.framework */; };
|
||||||
A26075881EEC6F34005DB03E /* passKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A26075871EEC6F34005DB03E /* passKitTests.swift */; };
|
A26075881EEC6F34005DB03E /* passKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A26075871EEC6F34005DB03E /* passKitTests.swift */; };
|
||||||
A260758A1EEC6F34005DB03E /* passKit.h in Headers */ = {isa = PBXBuildFile; fileRef = A260757A1EEC6F34005DB03E /* passKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
A260758A1EEC6F34005DB03E /* passKit.h in Headers */ = {isa = PBXBuildFile; fileRef = A260757A1EEC6F34005DB03E /* passKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
|
|
@ -178,6 +180,8 @@
|
||||||
A2227D561EEE5E78002A69A9 /* libPods-passKit.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libPods-passKit.a"; path = "../../Library/Developer/Xcode/DerivedData/pass-fwlmfsjroyvbfhdyqmglrwfhvjli/Build/Products/Debug-iphonesimulator/libPods-passKit.a"; sourceTree = "<group>"; };
|
A2227D561EEE5E78002A69A9 /* libPods-passKit.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libPods-passKit.a"; path = "../../Library/Developer/Xcode/DerivedData/pass-fwlmfsjroyvbfhdyqmglrwfhvjli/Build/Products/Debug-iphonesimulator/libPods-passKit.a"; sourceTree = "<group>"; };
|
||||||
A2367B9A1EEFE1B300C8FE8B /* UtilsExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UtilsExtension.swift; sourceTree = "<group>"; };
|
A2367B9A1EEFE1B300C8FE8B /* UtilsExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UtilsExtension.swift; sourceTree = "<group>"; };
|
||||||
A2367B9F1EF0387000C8FE8B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
A2367B9F1EF0387000C8FE8B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
|
A239F51E2157B72700576CBF /* StringExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = StringExtension.swift; path = Helpers/StringExtension.swift; sourceTree = "<group>"; };
|
||||||
|
A239F5202157B75E00576CBF /* FileManagerExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = FileManagerExtension.swift; path = Helpers/FileManagerExtension.swift; sourceTree = "<group>"; };
|
||||||
A26075781EEC6F34005DB03E /* passKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = passKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
A26075781EEC6F34005DB03E /* passKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = passKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
A260757A1EEC6F34005DB03E /* passKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = passKit.h; sourceTree = "<group>"; };
|
A260757A1EEC6F34005DB03E /* passKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = passKit.h; sourceTree = "<group>"; };
|
||||||
A260757B1EEC6F34005DB03E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
A260757B1EEC6F34005DB03E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
|
|
@ -410,9 +414,11 @@
|
||||||
A2F4E2191EED80160011986E /* DefaultsKeys.swift */,
|
A2F4E2191EED80160011986E /* DefaultsKeys.swift */,
|
||||||
A2F4E21A1EED80160011986E /* Globals.swift */,
|
A2F4E21A1EED80160011986E /* Globals.swift */,
|
||||||
A2F4E21B1EED80160011986E /* NotificationNames.swift */,
|
A2F4E21B1EED80160011986E /* NotificationNames.swift */,
|
||||||
A2F4E21C1EED80160011986E /* UITextFieldExtension.swift */,
|
|
||||||
A2F4E21D1EED80160011986E /* Utils.swift */,
|
A2F4E21D1EED80160011986E /* Utils.swift */,
|
||||||
|
A2F4E21C1EED80160011986E /* UITextFieldExtension.swift */,
|
||||||
A2BEC1BA207D2EFE00F3051C /* UIViewExtension.swift */,
|
A2BEC1BA207D2EFE00F3051C /* UIViewExtension.swift */,
|
||||||
|
A239F51E2157B72700576CBF /* StringExtension.swift */,
|
||||||
|
A239F5202157B75E00576CBF /* FileManagerExtension.swift */,
|
||||||
);
|
);
|
||||||
name = Helpers;
|
name = Helpers;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
|
@ -973,6 +979,8 @@
|
||||||
A2C532BB201E5A9600DB9F53 /* PasscodeLock.swift in Sources */,
|
A2C532BB201E5A9600DB9F53 /* PasscodeLock.swift in Sources */,
|
||||||
A2F4E2151EED800F0011986E /* Password.swift in Sources */,
|
A2F4E2151EED800F0011986E /* Password.swift in Sources */,
|
||||||
A26075AD1EEC7125005DB03E /* pass.xcdatamodeld in Sources */,
|
A26075AD1EEC7125005DB03E /* pass.xcdatamodeld in Sources */,
|
||||||
|
A239F51F2157B72700576CBF /* StringExtension.swift in Sources */,
|
||||||
|
A239F5212157B75E00576CBF /* FileManagerExtension.swift in Sources */,
|
||||||
A2F4E21E1EED80160011986E /* AppError.swift in Sources */,
|
A2F4E21E1EED80160011986E /* AppError.swift in Sources */,
|
||||||
A2F4E2171EED800F0011986E /* PasswordStore.swift in Sources */,
|
A2F4E2171EED800F0011986E /* PasswordStore.swift in Sources */,
|
||||||
A2F4E2211EED80160011986E /* NotificationNames.swift in Sources */,
|
A2F4E2211EED80160011986E /* NotificationNames.swift in Sources */,
|
||||||
|
|
|
||||||
94
passKit/Helpers/FileManagerExtension.swift
Normal file
94
passKit/Helpers/FileManagerExtension.swift
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
//
|
||||||
|
// FileManagerExtension.swift
|
||||||
|
// passKit
|
||||||
|
//
|
||||||
|
// Created by Yishi Lin on 2018/9/23.
|
||||||
|
// Copyright © 2018 Bob Sun. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// https://gist.github.com/NikolaiRuhe/eeb135d20c84a7097516
|
||||||
|
public extension FileManager {
|
||||||
|
|
||||||
|
/// This method calculates the accumulated size of a directory on the volume in bytes.
|
||||||
|
///
|
||||||
|
/// As there's no simple way to get this information from the file system it has to crawl the entire hierarchy,
|
||||||
|
/// accumulating the overall sum on the way. The resulting value is roughly equivalent with the amount of bytes
|
||||||
|
/// that would become available on the volume if the directory would be deleted.
|
||||||
|
///
|
||||||
|
/// - note: There are a couple of oddities that are not taken into account (like symbolic links, meta data of
|
||||||
|
/// directories, hard links, ...).
|
||||||
|
func allocatedSizeOfDirectoryAtURL(directoryURL : URL) throws -> UInt64 {
|
||||||
|
|
||||||
|
// We'll sum up content size here:
|
||||||
|
var accumulatedSize = UInt64(0)
|
||||||
|
|
||||||
|
// prefetching some properties during traversal will speed up things a bit.
|
||||||
|
let prefetchedProperties = [
|
||||||
|
URLResourceKey.isRegularFileKey,
|
||||||
|
URLResourceKey.fileAllocatedSizeKey,
|
||||||
|
URLResourceKey.totalFileAllocatedSizeKey,
|
||||||
|
]
|
||||||
|
|
||||||
|
// The error handler simply signals errors to outside code.
|
||||||
|
var errorDidOccur: Error?
|
||||||
|
let errorHandler: (URL, Error) -> Bool = { _, error in
|
||||||
|
errorDidOccur = error
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// We have to enumerate all directory contents, including subdirectories.
|
||||||
|
let enumerator = self.enumerator(at: directoryURL,
|
||||||
|
includingPropertiesForKeys: prefetchedProperties,
|
||||||
|
options: FileManager.DirectoryEnumerationOptions(),
|
||||||
|
errorHandler: errorHandler)
|
||||||
|
precondition(enumerator != nil)
|
||||||
|
|
||||||
|
// Start the traversal:
|
||||||
|
for item in enumerator! {
|
||||||
|
let contentItemURL = item as! NSURL
|
||||||
|
|
||||||
|
// Bail out on errors from the errorHandler.
|
||||||
|
if let error = errorDidOccur { throw error }
|
||||||
|
|
||||||
|
let resourceValueForKey: (URLResourceKey) throws -> NSNumber? = { key in
|
||||||
|
var value: AnyObject?
|
||||||
|
try contentItemURL.getResourceValue(&value, forKey: key)
|
||||||
|
return value as? NSNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the type of this item, making sure we only sum up sizes of regular files.
|
||||||
|
guard let isRegularFile = try resourceValueForKey(URLResourceKey.isRegularFileKey) else {
|
||||||
|
preconditionFailure()
|
||||||
|
}
|
||||||
|
|
||||||
|
guard isRegularFile.boolValue else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// To get the file's size we first try the most comprehensive value in terms of what the file may use on disk.
|
||||||
|
// This includes metadata, compression (on file system level) and block size.
|
||||||
|
var fileSize = try resourceValueForKey(URLResourceKey.totalFileAllocatedSizeKey)
|
||||||
|
|
||||||
|
// In case the value is unavailable we use the fallback value (excluding meta data and compression)
|
||||||
|
// This value should always be available.
|
||||||
|
fileSize = try fileSize ?? resourceValueForKey(URLResourceKey.fileAllocatedSizeKey)
|
||||||
|
|
||||||
|
guard let size = fileSize else {
|
||||||
|
preconditionFailure("huh? NSURLFileAllocatedSizeKey should always return a value")
|
||||||
|
}
|
||||||
|
|
||||||
|
// We're good, add up the value.
|
||||||
|
accumulatedSize += size.uint64Value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bail out on errors from the errorHandler.
|
||||||
|
if let error = errorDidOccur { throw error }
|
||||||
|
|
||||||
|
// We finally got it.
|
||||||
|
return accumulatedSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
18
passKit/Helpers/StringExtension.swift
Normal file
18
passKit/Helpers/StringExtension.swift
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
//
|
||||||
|
// StringExtension.swift
|
||||||
|
// passKit
|
||||||
|
//
|
||||||
|
// Created by Yishi Lin on 2018/9/23.
|
||||||
|
// Copyright © 2018 Bob Sun. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public extension String {
|
||||||
|
func stringByAddingPercentEncodingForRFC3986() -> String? {
|
||||||
|
let unreserved = "-._~/?"
|
||||||
|
var allowed = CharacterSet.alphanumerics
|
||||||
|
allowed.insert(charactersIn: unreserved)
|
||||||
|
return addingPercentEncoding(withAllowedCharacters: allowed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -124,95 +124,3 @@ public class Utils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://gist.github.com/NikolaiRuhe/eeb135d20c84a7097516
|
|
||||||
public extension FileManager {
|
|
||||||
|
|
||||||
/// This method calculates the accumulated size of a directory on the volume in bytes.
|
|
||||||
///
|
|
||||||
/// As there's no simple way to get this information from the file system it has to crawl the entire hierarchy,
|
|
||||||
/// accumulating the overall sum on the way. The resulting value is roughly equivalent with the amount of bytes
|
|
||||||
/// that would become available on the volume if the directory would be deleted.
|
|
||||||
///
|
|
||||||
/// - note: There are a couple of oddities that are not taken into account (like symbolic links, meta data of
|
|
||||||
/// directories, hard links, ...).
|
|
||||||
func allocatedSizeOfDirectoryAtURL(directoryURL : URL) throws -> UInt64 {
|
|
||||||
|
|
||||||
// We'll sum up content size here:
|
|
||||||
var accumulatedSize = UInt64(0)
|
|
||||||
|
|
||||||
// prefetching some properties during traversal will speed up things a bit.
|
|
||||||
let prefetchedProperties = [
|
|
||||||
URLResourceKey.isRegularFileKey,
|
|
||||||
URLResourceKey.fileAllocatedSizeKey,
|
|
||||||
URLResourceKey.totalFileAllocatedSizeKey,
|
|
||||||
]
|
|
||||||
|
|
||||||
// The error handler simply signals errors to outside code.
|
|
||||||
var errorDidOccur: Error?
|
|
||||||
let errorHandler: (URL, Error) -> Bool = { _, error in
|
|
||||||
errorDidOccur = error
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// We have to enumerate all directory contents, including subdirectories.
|
|
||||||
let enumerator = self.enumerator(at: directoryURL,
|
|
||||||
includingPropertiesForKeys: prefetchedProperties,
|
|
||||||
options: FileManager.DirectoryEnumerationOptions(),
|
|
||||||
errorHandler: errorHandler)
|
|
||||||
precondition(enumerator != nil)
|
|
||||||
|
|
||||||
// Start the traversal:
|
|
||||||
for item in enumerator! {
|
|
||||||
let contentItemURL = item as! NSURL
|
|
||||||
|
|
||||||
// Bail out on errors from the errorHandler.
|
|
||||||
if let error = errorDidOccur { throw error }
|
|
||||||
|
|
||||||
let resourceValueForKey: (URLResourceKey) throws -> NSNumber? = { key in
|
|
||||||
var value: AnyObject?
|
|
||||||
try contentItemURL.getResourceValue(&value, forKey: key)
|
|
||||||
return value as? NSNumber
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the type of this item, making sure we only sum up sizes of regular files.
|
|
||||||
guard let isRegularFile = try resourceValueForKey(URLResourceKey.isRegularFileKey) else {
|
|
||||||
preconditionFailure()
|
|
||||||
}
|
|
||||||
|
|
||||||
guard isRegularFile.boolValue else {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// To get the file's size we first try the most comprehensive value in terms of what the file may use on disk.
|
|
||||||
// This includes metadata, compression (on file system level) and block size.
|
|
||||||
var fileSize = try resourceValueForKey(URLResourceKey.totalFileAllocatedSizeKey)
|
|
||||||
|
|
||||||
// In case the value is unavailable we use the fallback value (excluding meta data and compression)
|
|
||||||
// This value should always be available.
|
|
||||||
fileSize = try fileSize ?? resourceValueForKey(URLResourceKey.fileAllocatedSizeKey)
|
|
||||||
|
|
||||||
guard let size = fileSize else {
|
|
||||||
preconditionFailure("huh? NSURLFileAllocatedSizeKey should always return a value")
|
|
||||||
}
|
|
||||||
|
|
||||||
// We're good, add up the value.
|
|
||||||
accumulatedSize += size.uint64Value
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bail out on errors from the errorHandler.
|
|
||||||
if let error = errorDidOccur { throw error }
|
|
||||||
|
|
||||||
// We finally got it.
|
|
||||||
return accumulatedSize
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public extension String {
|
|
||||||
func stringByAddingPercentEncodingForRFC3986() -> String? {
|
|
||||||
let unreserved = "-._~/?"
|
|
||||||
var allowed = CharacterSet.alphanumerics
|
|
||||||
allowed.insert(charactersIn: unreserved)
|
|
||||||
return addingPercentEncoding(withAllowedCharacters: allowed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue