Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// swift-tools-version: 6.0
import PackageDescription

let package = Package(
name: "ModernizationSupport",
platforms: [
.iOS("26.0"),
.macOS("26.0")
],
products: [
.library(name: "ModernizationSupport", targets: ["ModernizationSupport"])
],
targets: [
.target(name: "ModernizationSupport"),
.testTarget(name: "ModernizationSupportTests", dependencies: ["ModernizationSupport"])
]
)
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,8 @@ SDL2.0 + ffmpeg 3.1.1 + swift is different from olds


now working on tutorial4


## Modernization checks
- Run Swift package tests for modernization utilities:
- `swift test`
18 changes: 18 additions & 0 deletions Sources/ModernizationSupport/DocumentPathResolver.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Foundation

public enum DocumentPathResolver {
public static func userDocumentRoot(from absoluteDocumentPath: String) -> String? {
let components = absoluteDocumentPath.split(separator: "/").map(String.init)
guard components.count >= 3 else { return nil }
return "/" + components[0...2].joined(separator: "/") + "/Documents"
}

public static func appScopedDocumentAliasRoot(from absoluteDocumentPath: String, appName: String = "ffmpeg_tutorial") -> String? {
guard let root = userDocumentRoot(from: absoluteDocumentPath) else { return nil }
return root + "/" + appName
}

public static func needsSymlinkRefresh(currentLinkTarget: String?, expectedTarget: String) -> Bool {
return currentLinkTarget != expectedTarget
}
}
14 changes: 7 additions & 7 deletions SwiftPlayer/SwiftPlayer.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@
D848FE6B1D745F4D0058E322 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0800;
LastSwiftUpdateCheck = 1600;
LastUpgradeCheck = 0800;
ORGANIZATIONNAME = "Kwanghoon Choi";
TargetAttributes = {
Expand Down Expand Up @@ -392,7 +392,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
IPHONEOS_DEPLOYMENT_TARGET = 26.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
Expand Down Expand Up @@ -436,7 +436,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
IPHONEOS_DEPLOYMENT_TARGET = 26.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
Expand All @@ -456,7 +456,7 @@
"\"$(SRCROOT)/../SDL-iOS/include\"",
);
INFOPLIST_FILE = SwiftPlayer/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 26.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"\"$(SRCROOT)/../ffmpeg/lib\"",
Expand All @@ -466,7 +466,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "SwiftPlayer/SwiftPlayer-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
Expand All @@ -481,7 +481,7 @@
"\"$(SRCROOT)/../SDL-iOS/include\"",
);
INFOPLIST_FILE = SwiftPlayer/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 26.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"\"$(SRCROOT)/../ffmpeg/lib\"",
Expand All @@ -490,7 +490,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.ngenii.SwiftPlayer;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "SwiftPlayer/SwiftPlayer-Bridging-Header.h";
SWIFT_VERSION = 3.0;
SWIFT_VERSION = 5.0;
};
name = Release;
};
Expand Down
37 changes: 14 additions & 23 deletions SwiftPlayer/SwiftPlayer/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?


func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.


Expand Down Expand Up @@ -83,31 +83,22 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
}

func createSymbolickLinkForDocuments() {
if let attributes = try? FileManager.default.attributesOfItem(atPath: self.documentPathForUserWithAppName), let type: FileAttributeType = attributes[.type] as? FileAttributeType {
if type == .typeSymbolicLink && (self.docPath as String) == self.linkOfDocumentPathForUserWithAppName {
return
}
let destinationPath = self.docPath as String

if let attributes = try? FileManager.default.attributesOfItem(atPath: self.documentPathForUserWithAppName),
let type = attributes[.type] as? FileAttributeType,
type == .typeSymbolicLink,
destinationPath == self.linkOfDocumentPathForUserWithAppName {
return
}

do {
let attributes = try? FileManager.default.attributesOfItem(atPath: self.documentPathForUserWithAppName)
if let attributes = attributes {

let type: FileAttributeType = attributes[.type] as! FileAttributeType
if type == .typeSymbolicLink {
try FileManager.default.removeItem(atPath: self.documentPathForUserWithAppName)
try FileManager.default.createSymbolicLink(atPath: self.documentPathForUserWithAppName, withDestinationPath: self.docPath as String)
}
else {
try FileManager.default.removeItem(atPath: self.documentPathForUserWithAppName)
try FileManager.default.createSymbolicLink(atPath: self.documentPathForUserWithAppName, withDestinationPath: self.docPath as String)
}
} else {
try FileManager.default.createSymbolicLink(atPath: self.documentPathForUserWithAppName, withDestinationPath: self.docPath as String)
if FileManager.default.fileExists(atPath: self.documentPathForUserWithAppName) {
try FileManager.default.removeItem(atPath: self.documentPathForUserWithAppName)
}

} catch let err as NSError {
assertionFailure(err.localizedDescription)
try FileManager.default.createSymbolicLink(atPath: self.documentPathForUserWithAppName, withDestinationPath: destinationPath)
} catch {
assertionFailure(error.localizedDescription)
}
}
}

46 changes: 25 additions & 21 deletions SwiftPlayer/SwiftPlayer/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let prevIO = UIApplication.shared.statusBarOrientation
if UIInterfaceOrientationIsPortrait(prevIO) {
if UIDevice.current.orientation.isPortrait || UIDevice.current.orientation == .unknown {
UIDevice.current.setValue(UIDeviceOrientation.landscapeLeft.rawValue, forKey: "orientation")
}
}
Expand All @@ -37,25 +36,30 @@ class ViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

weak var weakSelf = self
if let path = self.path, 0 < path.lengthOfBytes(using: .utf8) {
self.player = Player(path: path)

self.player?.start(start: {
DispatchQueue.main.async {
guard weakSelf?.setupSDL(player: weakSelf!.player!) ?? false else {
weakSelf?.player?.cancel()
return
}

weakSelf?.displayLink = CADisplayLink(target: self, selector: #selector(ViewController.update(link:)))
weakSelf?.displayLink?.add(to: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
}
}, stop: {
var event = SDL_Event(quit: SDL_QuitEvent(type: SDL_QUIT.rawValue, timestamp: 0))
SDL_PushEvent(&event)
})
guard let path = self.path, 0 < path.lengthOfBytes(using: .utf8) else {
return
}

self.player = Player(path: path)

self.player?.start(start: { [weak self] in
DispatchQueue.main.async {
guard let self else {
return
}

guard let player = self.player, self.setupSDL(player: player) else {
self.player?.cancel()
return
}

self.displayLink = CADisplayLink(target: self, selector: #selector(ViewController.update(link:)))
self.displayLink?.add(to: .current, forMode: .default)
}
}, stop: {
var event = SDL_Event(quit: SDL_QuitEvent(type: SDL_QUIT.rawValue, timestamp: 0))
SDL_PushEvent(&event)
})
}

override func viewDidDisappear(_ animated: Bool) {
Expand All @@ -69,7 +73,7 @@ class ViewController: UIViewController {
}

var start: Double = 0
func update(link: CADisplayLink) {
@objc func update(link: CADisplayLink) {
if 0 == start {
start = link.timestamp
}
Expand Down
29 changes: 29 additions & 0 deletions Tests/ModernizationSupportTests/DocumentPathResolverTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import XCTest
@testable import ModernizationSupport

final class DocumentPathResolverTests: XCTestCase {
func testUserDocumentRootFromSimulatorPath() {
let path = "/Users/test/Library/Developer/CoreSimulator/Devices/abc/data/Containers/Data/Application/xyz/Documents"
XCTAssertEqual(
DocumentPathResolver.userDocumentRoot(from: path),
"/Users/test/Library/Documents"
)
}

func testUserDocumentRootWithInvalidPathReturnsNil() {
XCTAssertNil(DocumentPathResolver.userDocumentRoot(from: "/tmp"))
}

func testAppScopedDocumentAliasRootUsesDefaultAppName() {
let path = "/Users/test/Library/Developer/CoreSimulator/Devices/abc/data"
XCTAssertEqual(
DocumentPathResolver.appScopedDocumentAliasRoot(from: path),
"/Users/test/Library/Documents/ffmpeg_tutorial"
)
}

func testNeedsSymlinkRefreshWhenTargetsDiffer() {
XCTAssertTrue(DocumentPathResolver.needsSymlinkRefresh(currentLinkTarget: "/old", expectedTarget: "/new"))
XCTAssertFalse(DocumentPathResolver.needsSymlinkRefresh(currentLinkTarget: "/same", expectedTarget: "/same"))
}
}
18 changes: 9 additions & 9 deletions tutorial/tutorial.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@
A96D16E81D5860C5009F7AC2 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0800;
LastSwiftUpdateCheck = 1600;
LastUpgradeCheck = 0800;
ORGANIZATIONNAME = gretech;
TargetAttributes = {
Expand Down Expand Up @@ -603,7 +603,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
IPHONEOS_DEPLOYMENT_TARGET = 26.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
Expand Down Expand Up @@ -644,7 +644,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
IPHONEOS_DEPLOYMENT_TARGET = 26.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
Expand Down Expand Up @@ -680,7 +680,7 @@
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "tutorial/tutorial-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
Expand Down Expand Up @@ -712,7 +712,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "tutorial/tutorial-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 3.0;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
Expand All @@ -736,12 +736,12 @@
/usr/local/Cellar/sdl2/2.0.4/lib,
/usr/local/Cellar/ffmpeg/3.1.3/lib,
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
MACOSX_DEPLOYMENT_TARGET = 26.0;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_OBJC_BRIDGING_HEADER = "tutorial6/tutorial6-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
Expand All @@ -764,11 +764,11 @@
/usr/local/Cellar/sdl2/2.0.4/lib,
/usr/local/Cellar/ffmpeg/3.1.3/lib,
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
MACOSX_DEPLOYMENT_TARGET = 26.0;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_OBJC_BRIDGING_HEADER = "tutorial6/tutorial6-Bridging-Header.h";
SWIFT_VERSION = 3.0;
SWIFT_VERSION = 5.0;
};
name = Release;
};
Expand Down
36 changes: 14 additions & 22 deletions tutorial/tutorial/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
// Override point for customization after application launch.

av_register_all()
Expand Down Expand Up @@ -87,30 +87,22 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
}

func createSymbolickLinkForDocuments() {
if let attributes = try? FileManager.default.attributesOfItem(atPath: self.documentPathForUserWithAppName), let type: FileAttributeType = attributes[.type] as? FileAttributeType {
if type == .typeSymbolicLink && (self.docPath as String) == self.linkOfDocumentPathForUserWithAppName {
return
}
let destinationPath = self.docPath as String

if let attributes = try? FileManager.default.attributesOfItem(atPath: self.documentPathForUserWithAppName),
let type = attributes[.type] as? FileAttributeType,
type == .typeSymbolicLink,
destinationPath == self.linkOfDocumentPathForUserWithAppName {
return
}

do {
let attributes = try? FileManager.default.attributesOfItem(atPath: self.documentPathForUserWithAppName)
if let attributes = attributes {

let type: FileAttributeType = attributes[.type] as! FileAttributeType
if type == .typeSymbolicLink {
try FileManager.default.removeItem(atPath: self.documentPathForUserWithAppName)
try FileManager.default.createSymbolicLink(atPath: self.documentPathForUserWithAppName, withDestinationPath: self.docPath as String)
}
else {
try FileManager.default.removeItem(atPath: self.documentPathForUserWithAppName)
try FileManager.default.createSymbolicLink(atPath: self.documentPathForUserWithAppName, withDestinationPath: self.docPath as String)
}
} else {
try FileManager.default.createSymbolicLink(atPath: self.documentPathForUserWithAppName, withDestinationPath: self.docPath as String)
if FileManager.default.fileExists(atPath: self.documentPathForUserWithAppName) {
try FileManager.default.removeItem(atPath: self.documentPathForUserWithAppName)
}

} catch let err as NSError {
assertionFailure(err.localizedDescription)
try FileManager.default.createSymbolicLink(atPath: self.documentPathForUserWithAppName, withDestinationPath: destinationPath)
} catch {
assertionFailure(error.localizedDescription)
}
}

Expand Down