linting
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
[*.swift]
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
@@ -2,7 +2,6 @@
|
||||
/.nvim
|
||||
.DS_Store
|
||||
buildServer.json
|
||||
.swiftlint.yml
|
||||
/ImageViewer.xcodeproj/xcuserdata
|
||||
/ImageViewer.xcodeproj/project.xcworkspace/xcuserdata
|
||||
/ImageViewer/flatc
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
function_body_length: 1000
|
||||
type_body_length:
|
||||
warning: 10000
|
||||
trailing_comma:
|
||||
mandatory_comma: true
|
||||
line_length: 120
|
||||
opening_brace:
|
||||
ignore_multiline_statement_conditions: true
|
||||
identifier_name:
|
||||
min_length: 1
|
||||
allowed_symbols: ["_"]
|
||||
file_length:
|
||||
error: 10000
|
||||
warning: 3000
|
||||
cyclomatic_complexity:
|
||||
warning: 50
|
||||
error: 100
|
||||
disabled_rules:
|
||||
- todo
|
||||
+142
-107
@@ -8,7 +8,8 @@ import UIKit
|
||||
import ZIPFoundation
|
||||
|
||||
let preloadCount = 2
|
||||
/// With a whopping 2 cores, and 2 threads because no hyperthreading, it makes sense to only have a queue as an extra thread to do work with to allow the main thread for ui.
|
||||
/// With a whopping 2 cores, and 2 threads because no hyperthreading,
|
||||
/// it makes sense to only have a queue as an extra thread to do work with to allow the main thread for ui.
|
||||
let queue = DispatchQueue(label: "queue", qos: .utility)
|
||||
|
||||
enum PageTurn {
|
||||
@@ -41,7 +42,7 @@ struct Comic {
|
||||
}
|
||||
|
||||
struct GlobalState: Codable {
|
||||
var comicName: String? = nil
|
||||
var comicName: String?
|
||||
}
|
||||
|
||||
struct LocalState: Codable {
|
||||
@@ -170,7 +171,11 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
||||
}
|
||||
|
||||
func loadComics() {
|
||||
let alert = UIAlertController(title: "Failed to load comics.", message: "This is an alert.", preferredStyle: .alert)
|
||||
let alert = UIAlertController(
|
||||
title: "Failed to load comics.",
|
||||
message: "This is an alert.",
|
||||
preferredStyle: .alert
|
||||
)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
|
||||
do {
|
||||
var directories: [URL] = []
|
||||
@@ -202,16 +207,18 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
||||
|
||||
currentPath = dir
|
||||
|
||||
guard let data = try? Data(contentsOf: dir.appendingPathComponent(metadataFilename))
|
||||
let metadataPath = dir.appendingPathComponent(metadataFilename)
|
||||
guard let data = try? Data(contentsOf: metadataPath)
|
||||
else {
|
||||
alert.message = String(format: "Failed to read contents of metadata: \(dir.appendingPathComponent(metadataFilename))")
|
||||
alert.message = String(format: "Failed to read contents of metadata: \(metadataPath))")
|
||||
pendingAlert = alert
|
||||
return
|
||||
}
|
||||
var byteBuffer = ByteBuffer(data: data)
|
||||
metadata = try? getCheckedRoot(byteBuffer: &byteBuffer)
|
||||
if metadata == nil {
|
||||
alert.message = String(format: "Failed to read contents of metadata flatbuffer file: \(dir.appendingPathComponent(metadataFilename))")
|
||||
alert.message =
|
||||
String(format: "Failed to read contents of metadata flatbuffer file: \(metadataPath))")
|
||||
pendingAlert = alert
|
||||
return
|
||||
}
|
||||
@@ -307,21 +314,60 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
||||
return CGSize(width: width, height: height)
|
||||
}
|
||||
|
||||
struct Pattern {
|
||||
var pattern: NSRegularExpression
|
||||
var title: NSRegularExpression
|
||||
var volumePosition: Int
|
||||
var chapterPosition: Int
|
||||
var pagePosition: Int
|
||||
}
|
||||
|
||||
func getMetadataFromFilename(path: URL) {
|
||||
let alert = UIAlertController(
|
||||
title: "Failed to get metadata from filename.",
|
||||
message: "This is an alert.",
|
||||
preferredStyle: .alert
|
||||
)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
|
||||
|
||||
// Beautiful, is it not?
|
||||
let patterns: [(NSRegularExpression?, NSRegularExpression?, Int, Int, Int)] = [
|
||||
(try? NSRegularExpression(pattern: #"c([0-9]+(?:x[0-9]+)?) \(v([0-9]+)\) - p([0-9]+(?:-p?[0-9]+)?)"#), try? NSRegularExpression(pattern: #"^(.*) - c([0-9]+(?:x[0-9]+)?) \(v([0-9]+)\) - p([0-9]+(?:-p?[0-9]+)?)"#), 3, 1, 2),
|
||||
(try? NSRegularExpression(pattern: "v([0-9]+) p([0-9]+(?:-[0-9]+)?) - c([0-9]+(?:x[0-9]+)?)"), try? NSRegularExpression(pattern: "^(.*) - v([0-9]+) p([0-9]+(?:-[0-9]+)?) - c([0-9]+(?:x[0-9]+)?)"), 2, 3, 1),
|
||||
]
|
||||
var pattern: NSRegularExpression! = nil
|
||||
var titlePattern: NSRegularExpression! = nil
|
||||
|
||||
var pageRegexPosition: Int! = nil
|
||||
var chapterRegexPosition: Int! = nil
|
||||
var volumeRegexPosition: Int! = nil
|
||||
|
||||
var currentVolume: UInt32! = nil
|
||||
var currentChapter: (UInt32, UInt32?)!
|
||||
var nPatterns: [Pattern]?
|
||||
do {
|
||||
let fPatterns: [Pattern] = try [
|
||||
Pattern(
|
||||
pattern: NSRegularExpression(
|
||||
pattern: #"c([0-9]+(?:x[0-9]+)?) \(v([0-9]+)\) - p([0-9]+(?:-p?[0-9]+)?)"#
|
||||
),
|
||||
title: NSRegularExpression(
|
||||
pattern: #"^(.*) - c([0-9]+(?:x[0-9]+)?) \(v([0-9]+)\) - p([0-9]+(?:-p?[0-9]+)?)"#
|
||||
),
|
||||
volumePosition: 2,
|
||||
chapterPosition: 1,
|
||||
pagePosition: 3
|
||||
),
|
||||
Pattern(
|
||||
pattern: NSRegularExpression(
|
||||
pattern: "v([0-9]+) p([0-9]+(?:-[0-9]+)?) - c([0-9]+(?:x[0-9]+)?)"
|
||||
),
|
||||
title: NSRegularExpression(
|
||||
pattern: "^(.*) - v([0-9]+) p([0-9]+(?:-[0-9]+)?) - c([0-9]+(?:x[0-9]+)?)"
|
||||
),
|
||||
volumePosition: 1,
|
||||
chapterPosition: 3,
|
||||
pagePosition: 2
|
||||
),
|
||||
]
|
||||
nPatterns = fPatterns
|
||||
} catch {
|
||||
alert.message = String(format: "Regular expression is invalid")
|
||||
pendingAlert = alert
|
||||
return
|
||||
}
|
||||
guard let patterns = nPatterns else {
|
||||
alert.message = String(format: "Regular expression is invalid")
|
||||
pendingAlert = alert
|
||||
return
|
||||
}
|
||||
|
||||
if fileManager.fileExists(
|
||||
atPath: path.appendingPathComponent(metadataFilename).absoluteString
|
||||
@@ -339,8 +385,8 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
||||
|
||||
var titleValue = ""
|
||||
|
||||
let alert = UIAlertController(title: "Failed to get metadata from filename.", message: "This is an alert.", preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
|
||||
var currentVolume: UInt32!
|
||||
var currentChapter: (UInt32, UInt32?)!
|
||||
|
||||
let volumeDir = path.appendingPathComponent("volumes")
|
||||
|
||||
@@ -370,18 +416,7 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
||||
for volumeURL in volumeURLs! {
|
||||
do {
|
||||
let volumeArchive = try Archive(url: volumeURL, accessMode: .read)
|
||||
var volumeArchiveFiles: [String] = []
|
||||
for entry in volumeArchive {
|
||||
// guard let url = URL(string: entry.path) else {
|
||||
// alert.message = String(format: "failed to create URL from string: \(entry.path)")
|
||||
// pendingAlert = alert
|
||||
// return
|
||||
// }
|
||||
volumeArchiveFiles.append(entry.path)
|
||||
}
|
||||
for filename in volumeArchiveFiles.sorted() {
|
||||
filenames.append((volumeURL.lastPathComponent, filename))
|
||||
}
|
||||
volumeArchive.map { $0.path }.sorted().forEach { filenames.append((volumeURL.lastPathComponent, $0)) }
|
||||
} catch {
|
||||
alert.message = String(format: "failed to read archive: \(volumeURL)")
|
||||
pendingAlert = alert
|
||||
@@ -394,77 +429,61 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
||||
return
|
||||
}
|
||||
|
||||
var matchingPattern: Pattern?
|
||||
do {
|
||||
for (currentPattern, currentTitlePattern, currentPageRegexPosition, currentChapterRegexPosition, currentVolumeRegexPosition) in patterns {
|
||||
guard let currentPattern = currentPattern else {
|
||||
alert.message = String(format: "failed to get currentPattern")
|
||||
pendingAlert = alert
|
||||
continue
|
||||
}
|
||||
guard let currentTitlePattern = currentTitlePattern else {
|
||||
alert.message = String(format: "failed to get currentTitlePattern")
|
||||
pendingAlert = alert
|
||||
continue
|
||||
}
|
||||
for testPattern in patterns {
|
||||
let filename = filenames[0].1
|
||||
let range = NSRange(filename.startIndex..., in: filename)
|
||||
if let match = currentTitlePattern.firstMatch(in: filename, range: range) {
|
||||
if let match = testPattern.title.firstMatch(in: filename, range: range) {
|
||||
if (filename as NSString).substring(with: match.range(at: 1)) == "" {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
if let match = currentPattern.firstMatch(in: filename, range: range) {
|
||||
if (filename as NSString).substring(with: match.range(at: currentPageRegexPosition)) == "" {
|
||||
if let match = testPattern.pattern.firstMatch(in: filename, range: range) {
|
||||
if (filename as NSString).substring(with: match.range(at: testPattern.pagePosition)) == "" {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
if let match = currentPattern.firstMatch(in: filename, range: range) {
|
||||
if (filename as NSString).substring(with: match.range(at: currentChapterRegexPosition)) == "" {
|
||||
if let match = testPattern.pattern.firstMatch(in: filename, range: range) {
|
||||
if (filename as NSString).substring(with: match.range(at: testPattern.chapterPosition)) == "" {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
if let match = currentPattern.firstMatch(in: filename, range: range) {
|
||||
if (filename as NSString).substring(with: match.range(at: currentVolumeRegexPosition)) == "" {
|
||||
if let match = testPattern.pattern.firstMatch(in: filename, range: range) {
|
||||
if (filename as NSString).substring(with: match.range(at: testPattern.volumePosition)) == "" {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
pattern = currentPattern
|
||||
titlePattern = currentTitlePattern
|
||||
|
||||
pageRegexPosition = currentPageRegexPosition
|
||||
chapterRegexPosition = currentChapterRegexPosition
|
||||
volumeRegexPosition = currentVolumeRegexPosition
|
||||
matchingPattern = testPattern
|
||||
break
|
||||
}
|
||||
|
||||
if pattern == nil || titlePattern == nil || pageRegexPosition == nil || chapterRegexPosition == nil || volumeRegexPosition == nil {
|
||||
print("Could not find pattern, returning")
|
||||
guard let pattern = matchingPattern else {
|
||||
alert.message = String(format: "Could not find matching pattern, likely missing regex.")
|
||||
pendingAlert = alert
|
||||
return
|
||||
}
|
||||
|
||||
let regex = pattern!
|
||||
let titleRegex = titlePattern!
|
||||
|
||||
for (i, (volumeURL, filename)) in filenames.enumerated() {
|
||||
let range = NSRange(filename.startIndex..., in: filename)
|
||||
if i == 0 {
|
||||
if let match = titleRegex.firstMatch(in: filename, range: range) {
|
||||
if let match = pattern.title.firstMatch(in: filename, range: range) {
|
||||
titleValue = (filename as NSString).substring(with: match.range(at: 1))
|
||||
} else {
|
||||
print("Did not find match for title, regex did not handle this case.")
|
||||
return
|
||||
}
|
||||
}
|
||||
if let match = regex.firstMatch(in: filename, range: range) {
|
||||
let chapterStr = (filename as NSString).substring(with: match.range(at: chapterRegexPosition))
|
||||
if let match = pattern.pattern.firstMatch(in: filename, range: range) {
|
||||
let chapterStr = (filename as NSString).substring(with: match.range(at: pattern.chapterPosition))
|
||||
let chapterParts = chapterStr.split(separator: "x", maxSplits: 1)
|
||||
if chapterParts.count < 1 {
|
||||
alert.message = String(format: "Did not find chapter number in filename: \(filename)")
|
||||
@@ -480,13 +499,16 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
||||
nChapter0, chapterParts.count > 1 ? UInt32(chapterParts[1]) : nil
|
||||
)
|
||||
|
||||
guard let volume = UInt32((filename as NSString).substring(with: match.range(at: volumeRegexPosition))) else {
|
||||
guard let volume =
|
||||
UInt32((filename as NSString)
|
||||
.substring(with: match.range(at: pattern.volumePosition)))
|
||||
else {
|
||||
alert.message = String(format: "failed to get match for volume in filename: \(filename)")
|
||||
pendingAlert = alert
|
||||
return
|
||||
}
|
||||
|
||||
let pageStr = (filename as NSString).substring(with: match.range(at: pageRegexPosition))
|
||||
let pageStr = (filename as NSString).substring(with: match.range(at: pattern.pagePosition))
|
||||
let pageParts = pageStr.split(separator: "-", maxSplits: 1)
|
||||
guard let nPage = UInt32(pageParts[0]) else {
|
||||
alert.message = String(format: "failed to read archive: \(filename)")
|
||||
@@ -798,7 +820,8 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
||||
super.viewDidLayoutSubviews()
|
||||
guard view.bounds.size != lastLayoutSize else { return }
|
||||
lastLayoutSize = UIScreen.main.bounds.size
|
||||
if scrollingCollectionView.isHidden == true || mode != .scroll
|
||||
if scrollingCollectionView.isHidden == true
|
||||
|| mode != .scroll
|
||||
|| scrollingCollectionView.contentSize == .zero
|
||||
{
|
||||
if metadata == nil { return }
|
||||
@@ -1172,7 +1195,8 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
||||
leftView.isHidden = mode == .scroll
|
||||
rightView.isHidden = mode == .scroll
|
||||
imageView.isHidden = mode == .scroll
|
||||
// This does not optmize for the case where you switch between scrolling and non-scrolling in the same comic. However this badly supported because of the lac of state conversion.
|
||||
// This does not optmize for the case where you switch between scrolling and non-scrolling in the same comic.
|
||||
// However this is badly supported because of the lack of state conversion.
|
||||
if mode == .scroll {
|
||||
scrollingCollectionView.reloadData()
|
||||
}
|
||||
@@ -1352,7 +1376,10 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
||||
let chapterValue = metadata.volumes[progress.v].chapters[progress.c].chapter!
|
||||
let chapterString = metaValueToString(m: chapterValue)
|
||||
|
||||
let lastChapterValue = metadata.volumes[metadata.volumes.count - 1].chapters[metadata.volumes[metadata.volumes.count - 1].chapters.count - 1].chapter!
|
||||
let lastChapterValue = metadata
|
||||
.volumes[metadata.volumes.count - 1]
|
||||
.chapters[metadata.volumes[metadata.volumes.count - 1]
|
||||
.chapters.count - 1].chapter!
|
||||
let lastChapterString = metaValueToString(m: lastChapterValue)
|
||||
|
||||
let volumeValue = metadata.volumes[progress.v].volume!
|
||||
@@ -1389,12 +1416,15 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
||||
Chapter \(chapterString) of \(lastChapterString)
|
||||
Page \(pageString) of \(lastPageString)
|
||||
"""
|
||||
text += "\nImage size: \(metadata.volumes[progress.v].chapters[progress.c].images[progress.i].size!.width)x\(metadata.volumes[progress.v].chapters[progress.c].images[progress.i].size!.height)"
|
||||
let imageSize = metadata.volumes[progress.v].chapters[progress.c].images[progress.i].size!
|
||||
text += "\nImage size: \(imageSize.width)x\(imageSize.height)"
|
||||
info.text = text
|
||||
}
|
||||
|
||||
func getArchiveURL(_ volumeProgress: Int) -> URL {
|
||||
return currentPath.appendingPathComponent("volumes").appendingPathComponent(metadata.volumes[volumeProgress].archive)
|
||||
return currentPath
|
||||
.appendingPathComponent("volumes")
|
||||
.appendingPathComponent(metadata.volumes[volumeProgress].archive)
|
||||
}
|
||||
|
||||
func getImagePath(_ progress: ProgressIndices) -> String {
|
||||
@@ -1440,9 +1470,9 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
||||
}
|
||||
|
||||
func getMetadata(path: URL) -> Metadata? {
|
||||
let data = try! Data(contentsOf: path.appendingPathComponent(metadataFilename))
|
||||
guard let data = try? Data(contentsOf: path.appendingPathComponent(metadataFilename)) else { return nil }
|
||||
var byteBuffer = ByteBuffer(data: data)
|
||||
let metadata: Metadata = try! getCheckedRoot(byteBuffer: &byteBuffer)
|
||||
guard let metadata: Metadata = try? getCheckedRoot(byteBuffer: &byteBuffer) else { return nil }
|
||||
return metadata
|
||||
}
|
||||
|
||||
@@ -1471,10 +1501,8 @@ class ViewController: UIViewController, UIGestureRecognizerDelegate {
|
||||
}
|
||||
|
||||
func getPathFromComicName(name: String) -> URL? {
|
||||
for comic in comics {
|
||||
if comic.metadata.title == name {
|
||||
return comic.path
|
||||
}
|
||||
for comic in comics where comic.metadata.title == name {
|
||||
return comic.path
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1512,11 +1540,7 @@ func getDocumentsURL() -> URL? {
|
||||
}
|
||||
|
||||
extension ViewController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
|
||||
func collectionView(
|
||||
_ collectionView: UICollectionView, numberOfItemsInSection _: Int
|
||||
)
|
||||
-> Int
|
||||
{
|
||||
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection _: Int) -> Int {
|
||||
if collectionView == comicCollectionView {
|
||||
return comics.count
|
||||
} else if collectionView == scrollingCollectionView {
|
||||
@@ -1534,24 +1558,30 @@ extension ViewController: UICollectionViewDataSource, UICollectionViewDelegateFl
|
||||
return 0
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)
|
||||
-> UICollectionViewCell
|
||||
{
|
||||
func collectionView(
|
||||
_ collectionView: UICollectionView,
|
||||
cellForItemAt indexPath: IndexPath
|
||||
) -> UICollectionViewCell {
|
||||
if collectionView == comicCollectionView {
|
||||
let cell =
|
||||
guard let cell =
|
||||
collectionView.dequeueReusableCell(
|
||||
withReuseIdentifier: "ComicImageCell", for: indexPath
|
||||
)
|
||||
as! ComicImageCell
|
||||
) as? ComicImageCell
|
||||
else {
|
||||
return ComicImageCell()
|
||||
}
|
||||
cell.imageView.image = comics[indexPath.item].cover
|
||||
return cell
|
||||
} else if collectionView == scrollingCollectionView {
|
||||
let scaling = UIView.ContentMode.scaleAspectFill
|
||||
let cell =
|
||||
guard let cell =
|
||||
collectionView.dequeueReusableCell(
|
||||
withReuseIdentifier: "ScrollingImageCell", for: indexPath
|
||||
)
|
||||
as! ScrollingImageCell
|
||||
as? ScrollingImageCell
|
||||
else {
|
||||
return ScrollingImageCell()
|
||||
}
|
||||
if mode != .scroll { return cell }
|
||||
if metadata == nil {
|
||||
print("metadata is nil, should probably not be the case")
|
||||
@@ -1576,11 +1606,7 @@ extension ViewController: UICollectionViewDataSource, UICollectionViewDelegateFl
|
||||
}
|
||||
|
||||
// Xcode profiling sucks:
|
||||
return
|
||||
collectionView.dequeueReusableCell(
|
||||
withReuseIdentifier: "ScrollingImageCell", for: indexPath
|
||||
)
|
||||
as! ScrollingImageCell
|
||||
return ComicImageCell()
|
||||
}
|
||||
|
||||
func collectionView(
|
||||
@@ -1605,7 +1631,9 @@ extension ViewController: UICollectionViewDataSource, UICollectionViewDelegateFl
|
||||
let imageMetadata = metadata.volumes[newProgress.v].chapters[newProgress.c].images[newProgress.i]
|
||||
return CGSize(
|
||||
width: readerView.bounds.width,
|
||||
height: CGFloat(imageMetadata.size!.height) * readerView.bounds.width / CGFloat(imageMetadata.size!.width)
|
||||
height: CGFloat(imageMetadata.size!.height)
|
||||
* readerView.bounds.width
|
||||
/ CGFloat(imageMetadata.size!.width)
|
||||
)
|
||||
} else {
|
||||
assertionFailure()
|
||||
@@ -1696,7 +1724,8 @@ class ImageLoader {
|
||||
landscapeFitCache.totalCostLimit = 128 * 1024 * 1024
|
||||
portraitFillCache.totalCostLimit = 128 * 1024 * 1024
|
||||
landscapeFillCache.totalCostLimit = 128 * 1024 * 1024
|
||||
// The reason archives are cached and have a strict limit of four, is because Archive supposedly opens a posix file pointer and keeps it until the object is destroyed.
|
||||
// The reason archives are cached and have a strict limit of four,
|
||||
// is because Archive supposedly opens a posix file pointer and keeps it until the object is destroyed.
|
||||
archives.countLimit = 4
|
||||
}
|
||||
|
||||
@@ -1759,14 +1788,16 @@ class ImageLoader {
|
||||
|
||||
if token.isCancelled { finish(); return }
|
||||
|
||||
func extractData() -> Data {
|
||||
func extractData() -> Data? {
|
||||
var extractedData = Data()
|
||||
if self.archives.object(forKey: archiveURL.lastPathComponent as NSString) == nil {
|
||||
let archive = try! Archive(url: archiveURL, accessMode: .read)
|
||||
self.archives.setObject(archive, forKey: archiveURL.lastPathComponent as NSString)
|
||||
do {
|
||||
let archive = try Archive(url: archiveURL, accessMode: .read)
|
||||
self.archives.setObject(archive, forKey: archiveURL.lastPathComponent as NSString)
|
||||
} catch { return nil }
|
||||
}
|
||||
let archive = self.archives.object(forKey: archiveURL.lastPathComponent as NSString)!
|
||||
_ = try! archive.extract(archive[filename]!) { data in
|
||||
_ = try? archive.extract(archive[filename]!) { data in
|
||||
extractedData.append(data)
|
||||
}
|
||||
return extractedData
|
||||
@@ -1774,7 +1805,7 @@ class ImageLoader {
|
||||
|
||||
if token.isCancelled { finish(); return }
|
||||
|
||||
guard let image = cache.object(forKey: key as NSString) ?? UIImage(data: extractData()) else {
|
||||
guard let image = cache.object(forKey: key as NSString) ?? UIImage(data: extractData()!) else {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
@@ -1808,7 +1839,13 @@ class ImageLoader {
|
||||
}
|
||||
}
|
||||
|
||||
func scaleAndCacheImage(image: UIImage, orientation: Rotation, screenSize: CGSize, scaling: UIView.ContentMode, filename: String) -> UIImage {
|
||||
func scaleAndCacheImage(
|
||||
image: UIImage,
|
||||
orientation: Rotation,
|
||||
screenSize: CGSize,
|
||||
scaling: UIView.ContentMode,
|
||||
filename: String
|
||||
) -> UIImage {
|
||||
let resizeTo = if orientation == .vertical {
|
||||
CGSize(
|
||||
width: min(screenSize.width, screenSize.height),
|
||||
@@ -1860,9 +1897,7 @@ func resizeImage(_ image: UIImage, to size: CGSize) -> UIImage {
|
||||
return scaledImage!
|
||||
}
|
||||
|
||||
func aspectSize(for imageSize: CGSize, in boundingSize: CGSize, scaling: UIView.ContentMode)
|
||||
-> CGSize
|
||||
{
|
||||
func aspectSize(for imageSize: CGSize, in boundingSize: CGSize, scaling: UIView.ContentMode) -> CGSize {
|
||||
let widthRatio = boundingSize.width / imageSize.width
|
||||
let heightRatio = boundingSize.height / imageSize.height
|
||||
var scale = CGFloat()
|
||||
|
||||
Reference in New Issue
Block a user