Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
Rspoon3 committed Aug 14, 2024
2 parents 4ac0327 + f5cb963 commit 729d3bc
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 44 deletions.
11 changes: 6 additions & 5 deletions Shotbot.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
94453E4C2C4AAD7900B15690 /* WidgetsBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94453E4B2C4AAD7900B15690 /* WidgetsBundle.swift */; };
94453E4E2C4AAD7900B15690 /* LatestScreenshotProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94453E4D2C4AAD7900B15690 /* LatestScreenshotProvider.swift */; };
94453E522C4AAD7A00B15690 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 94453E512C4AAD7A00B15690 /* Assets.xcassets */; };
94453E562C4AAD7A00B15690 /* WidgetsExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 94453E452C4AAD7800B15690 /* WidgetsExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
94453E562C4AAD7A00B15690 /* WidgetsExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 94453E452C4AAD7800B15690 /* WidgetsExtension.appex */; platformFilter = ios; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
9455F4DC2C4F2F3B009D0707 /* AdaptiveLabelStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9455F4DB2C4F2F3B009D0707 /* AdaptiveLabelStyle.swift */; };
946E7FC52C4C3341001E4C46 /* MultipleScreenshotsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 946E7FC12C4C3341001E4C46 /* MultipleScreenshotsView.swift */; };
946E7FC62C4C3341001E4C46 /* MultipleScreenshotsWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 946E7FC42C4C3341001E4C46 /* MultipleScreenshotsWidget.swift */; };
Expand Down Expand Up @@ -478,6 +478,7 @@
/* Begin PBXTargetDependency section */
94453E552C4AAD7A00B15690 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
platformFilter = ios;
target = 94453E442C4AAD7800B15690 /* WidgetsExtension */;
targetProxy = 94453E542C4AAD7A00B15690 /* PBXContainerItemProxy */;
};
Expand Down Expand Up @@ -586,7 +587,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 4;
CURRENT_PROJECT_VERSION = 3;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
Expand All @@ -606,7 +607,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
MARKETING_VERSION = 1.5;
MARKETING_VERSION = 1.6;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
Expand Down Expand Up @@ -650,7 +651,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 4;
CURRENT_PROJECT_VERSION = 3;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
Expand All @@ -664,7 +665,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
MARKETING_VERSION = 1.5;
MARKETING_VERSION = 1.6;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
Expand Down
12 changes: 7 additions & 5 deletions Shotbot/ShotbotApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@ import Purchases
import Persistence
import MediaManager
import AppIntents
import WidgetKit
import OSLog
import Photos
import Models

#if canImport(WidgetKit)
import WidgetKit
#endif

@main
struct ShotbotApp: App {
@UIApplicationDelegateAdaptor(AppDelegateAdaptor.self) private var appDelegate
Expand All @@ -29,10 +32,7 @@ struct ShotbotApp: App {

init() {
Purchases.logLevel = .info
Purchases.configure(
with: Configuration.Builder(withAPIKey: "appl_VOYNmwadBWEHBTYKlnZludJLwEX")
.build()
)
Purchases.configure(withAPIKey: "appl_VOYNmwadBWEHBTYKlnZludJLwEX")
}

var body: some Scene {
Expand All @@ -53,7 +53,9 @@ struct ShotbotApp: App {
case .active:
persistenceManager.numberOfActivations += 1
case .background:
#if canImport(WidgetKit)
WidgetCenter.shared.reloadAllTimelines()
#endif
default:
break
}
Expand Down
37 changes: 29 additions & 8 deletions ShotbotCore/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ let package = Package(
),
.package(
url: "https://github.com/RevenueCat/purchases-ios.git",
exact: .init("4.36.3")!
exact: .init("5.2.2")!
)
],
targets: [
Expand All @@ -45,11 +45,17 @@ let package = Package(
.target(
name: "Models",
dependencies: [
.product(name: "CollectionConcurrencyKit", package: "CollectionConcurrencyKit"),
.product(
name: "CollectionConcurrencyKit",
package: "CollectionConcurrencyKit"
),
],
resources: [.process("Resources")]
),
.testTarget(name: "ModelsTests", dependencies: ["Models"]),
.testTarget(
name: "ModelsTests",
dependencies: ["Models"]
),
.target(
name: "HomeFeature",
dependencies: [
Expand All @@ -59,10 +65,16 @@ let package = Package(
"MediaManager",
"SBFoundation",
"WidgetFeature",
.product(name: "AlertToast", package: "AlertToast")
.product(
name: "AlertToast",
package: "AlertToast"
)
]
),
.testTarget(name: "HomeFeatureTests", dependencies: ["HomeFeature"]),
.testTarget(
name: "HomeFeatureTests",
dependencies: ["HomeFeature"]
),
.target(
name: "Persistence",
dependencies: [
Expand All @@ -73,14 +85,20 @@ let package = Package(
name: "Purchases",
dependencies: [
"Persistence",
.product(name: "RevenueCat", package: "purchases-ios"),
.product(
name: "RevenueCat",
package: "purchases-ios"
),
]
),
.target(
name: "MediaManager",
dependencies: [
"Models",
.product(name: "CollectionConcurrencyKit", package: "CollectionConcurrencyKit"),
.product(
name: "CollectionConcurrencyKit",
package: "CollectionConcurrencyKit"
),
]
),
.target(
Expand All @@ -102,7 +120,10 @@ let package = Package(
.target(
name: "WidgetFeature",
dependencies: [
.product(name: "CollectionConcurrencyKit", package: "CollectionConcurrencyKit"),
.product(
name: "CollectionConcurrencyKit",
package: "CollectionConcurrencyKit"
),
]
),
]
Expand Down
24 changes: 24 additions & 0 deletions ShotbotCore/Sources/HomeFeature/HomeView/HomeViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ import SBFoundation
import Photos
import CollectionConcurrencyKit
import WidgetFeature
import Combine

@MainActor public final class HomeViewModel: ObservableObject {
private var cancellables = Set<AnyCancellable>()
private var persistenceManager: any PersistenceManaging
private let photoLibraryManager: PhotoLibraryManager
private let purchaseManager: any PurchaseManaging
Expand All @@ -28,6 +30,7 @@ import WidgetFeature
private let autoCRUDManager: any AutoCRUDManaging
private var combinedImageTask: Task<Void, Never>?
private let screenshotImporter: any ScreenshotImporting
private let notificationCenter: any NotificationCenterProtocol
private var imageQuality: ImageQuality
private let logger = Logger(category: HomeViewModel.self)
private(set) var imageResults = ImageResults()
Expand Down Expand Up @@ -92,6 +95,7 @@ import WidgetFeature
photoLibraryManager: PhotoLibraryManager = .live,
purchaseManager: any PurchaseManaging = PurchaseManager.shared,
fileManager: any FileManaging = FileManager.default,
notificationCenter: any NotificationCenterProtocol = NotificationCenter.default,
screenshotImporter: any ScreenshotImporting = ScreenshotImporter(),
reviewManager: any ReviewManaging = ReviewManager(),
imageCombiner: any ImageCombining = ImageCombiner(),
Expand All @@ -107,10 +111,23 @@ import WidgetFeature
self.autoCRUDManager = autoCRUDManager
self.imageQuality = persistenceManager.imageQuality
self.showGridView = persistenceManager.defaultHomeView == .grid
self.notificationCenter = notificationCenter

subscribeToNotificationCenterPublishers()
}


// MARK: - Private Helpers

/// Subscribes to notification center publishers such as memory warnings.
private func subscribeToNotificationCenterPublishers() {
notificationCenter.publisher(for: UIApplication.didReceiveMemoryWarningNotification)
.sink { [weak self] _ in
self?.error = SBError.lowMemoryWarning
self?.logger.warning("Memory warning hit")
}.store(in: &cancellables)
}

/// Updates `viewState` when `imageType` changes.
///
/// Will wait for `combinedImageTask` if needed.
Expand Down Expand Up @@ -369,7 +386,14 @@ import WidgetFeature
}

/// Clears all images and reverts the viewState back to individual placeholder
///
/// - Warning: `imageResults.removeAll()` causes a small memory leak.
public func clearContent() {
guard error as? SBError != SBError.lowMemoryWarning else {
logger.info("Not clearing all content due to low memory warning.")
return
}

logger.info("Clearing all content")

stopCombinedImageTask()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// NotificationCenterProtocol.swift
// ShotbotCore
//
// Created by Richard Witherspoon on 8/4/24.
//

import Foundation

public protocol NotificationCenterProtocol {
func publisher(
for name: Notification.Name
) -> NotificationCenter.Publisher
}

extension NotificationCenter: NotificationCenterProtocol {
public func publisher(for name: Notification.Name) -> Publisher {
publisher(for: name, object: nil)
}
}
12 changes: 7 additions & 5 deletions ShotbotCore/Sources/HomeFeature/ImageCombiner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,25 @@ public protocol ImageCombining {

/// An object responsible for combing images horizontally.
public struct ImageCombiner: ImageCombining {
private let logger = Logger(category: ImageCombiner.self)

// MARK: - Initializer

public init() {}

// MARK: - Public

/// Combines images Horizontally with scaling to keep consistent spacing
public func createCombinedImage(
from images: [UIImage],
imageQuality: Double
) async throws -> ShareableImage {
return try await withCheckedThrowingContinuation { continuation in
DispatchQueue.global(qos: .userInteractive).async {
self.logger.info("Starting combined image task.")
let logger = Logger(category: ImageCombiner.self)
logger.info("Starting combined image task.")

defer {
self.logger.info("Ending combined image task.")
logger.info("Ending combined image task.")
}

let imagesWidth = images.map(\.size.width).reduce(0, +)
Expand All @@ -52,7 +54,7 @@ public struct ImageCombiner: ImageCombining {
let combined = resizedImages.combineHorizontally()

guard let data = combined.pngData() else {
self.logger.error("No combined image png data")
logger.error("No combined image png data")
continuation.resume(throwing: SBError.noImageData)
return
}
Expand All @@ -61,7 +63,7 @@ public struct ImageCombiner: ImageCombining {

do {
try data.write(to: temporaryURL)
self.logger.info("Saving combined data to temporary url.")
logger.info("Saving combined data to temporary url.")

let image = ShareableImage(framedScreenshot: combined, url: temporaryURL)

Expand Down
6 changes: 5 additions & 1 deletion ShotbotCore/Sources/Models/Errors/SBError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@

import Foundation

public struct SBError: LocalizedError {
public struct SBError: LocalizedError, Equatable {
public let errorDescription: String?
public let recoverySuggestion: String?

public static let lowMemoryWarning = Self(
errorDescription: "Low Memory",
recoverySuggestion: "The device is running low on memory. Please either reduce the amount of images being framed at once or decrease the image quality."
)
public static let unsupportedImage = Self(
errorDescription: "Unsupported Image",
recoverySuggestion: "Please make sure you the image selected is a supported screenshot"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// UIGraphicsImageRendererFormat+Extension.swift
// ShotbotCore
//
// Created by Richard Witherspoon on 8/4/24.
//

import UIKit
import AVFoundation

extension UIGraphicsImageRendererFormat {
convenience init(scale: Int) {
self.init()
self.scale = 1
}

static let singleScale = UIGraphicsImageRendererFormat(scale: 1)
}
Loading

0 comments on commit 729d3bc

Please sign in to comment.