I am building an app about photos and
I want to create a photo sharing feature like Apple's Photos App.
Please see Steps to Reproduce and attached project.
The current share method has the following issues
The file name of the shared photo changes to “FullSizeRender”.
The creation and update dates of shared photos will change to the date they were edited or shared.
I want to ensure that the following conditions are definitely met
Share the latest edited version.
The creation date should be when the original photo was first created.
How can I improve the code?
STEPS TO REPRODUCE
class PHAssetShareManager {
static func shareAssets(_ assets: [PHAsset], from viewController: UIViewController, sourceView: UIView) {
let manager = PHAssetResourceManager.default()
var filesToShare: [URL] = []
let group = DispatchGroup()
for asset in assets {
group.enter()
getAssetFile(asset, resourceManager: manager) { fileURL in
if let fileURL = fileURL {
filesToShare.append(fileURL)
}
group.leave()
}
}
group.notify(queue: .main) {
self.presentShareSheet(filesToShare, from: viewController, sourceView: sourceView)
}
}
private static func getAssetFile(_ asset: PHAsset, resourceManager: PHAssetResourceManager, completion: @escaping (URL?) -> Void) {
print("getAssetFile")
let resources: [PHAssetResource]
switch asset.mediaType {
case .image:
if asset.mediaSubtypes.contains(.photoLive) {
// let editedResources = PHAssetResource.assetResources(for: asset).filter { $0.type == .fullSizePairedVideo }
// let originalResources = PHAssetResource.assetResources(for: asset).filter { $0.type == .pairedVideo }
let editedResources = PHAssetResource.assetResources(for: asset).filter { $0.type == .fullSizePhoto }
let originalResources = PHAssetResource.assetResources(for: asset).filter { $0.type == .photo }
resources = editedResources.isEmpty ? originalResources : editedResources
} else {
let editedResources = PHAssetResource.assetResources(for: asset).filter { $0.type == .fullSizePhoto }
let originalResources = PHAssetResource.assetResources(for: asset).filter { $0.type == .photo }
resources = editedResources.isEmpty ? originalResources : editedResources
}
case .video:
let editedResources = PHAssetResource.assetResources(for: asset).filter { $0.type == .fullSizeVideo }
let originalResources = PHAssetResource.assetResources(for: asset).filter { $0.type == .video }
resources = editedResources.isEmpty ? originalResources : editedResources
default:
print("Unsupported media type")
completion(nil)
return
}
guard let resource = resources.first else {
print("No resource found")
completion(nil)
return
}
let fileName = resource.originalFilename
let tempDirectoryURL = FileManager.default.temporaryDirectory
let localURL = tempDirectoryURL.appendingPathComponent(fileName)
// Delete existing files and reset cache
if FileManager.default.fileExists(atPath: localURL.path) {
do {
try FileManager.default.removeItem(at: localURL)
} catch {
print("Error removing existing file: \(error)")
}
}
let options = PHAssetResourceRequestOptions()
options.isNetworkAccessAllowed = true
resourceManager.writeData(for: resource, toFile: localURL, options: options) { (error) in
if let error = error {
print("Error writing asset data: \(error)")
completion(nil)
} else {
completion(localURL)
}
}
}
private static func presentShareSheet(_ items: [Any], from viewController: UIViewController, sourceView: UIView) {
print("presentShareSheet")
let activityViewController = UIActivityViewController(activityItems: items, applicationActivities: nil)
if UIDevice.current.userInterfaceIdiom == .pad {
activityViewController.popoverPresentationController?.sourceView = sourceView
activityViewController.popoverPresentationController?.sourceRect = sourceView.bounds
}
viewController.present(activityViewController, animated: true, completion: nil)
}
}```
UIKit
RSS for tagConstruct and manage graphical, event-driven user interfaces for iOS or tvOS apps using UIKit.
Post
Replies
Boosts
Views
Activity
Input issues occur in the textField while using a bilingual keyboard (Korean and English).
System settings:
Keyboard: Bilingual (Korean & English)
Project environment:
Xcode >= 15.4 & iOS >= 18.0
Base localization: Korean
// UITextField settings:
textField.keyboardType = .decimalPad // or .phonePad
self.textField.addTarget(self, action: #selector(self.textFieldEditingChanged), for: .editingChanged)
@objc
func textFieldEditingChanged() {
self.textField.text = "\(self.textField.text!)-"
}
/*
Input: 123456
Expected: 1-2-3-4-5-6-
Result: 11111123456-
*/
The issue occurs when modifying the text of the textField in the editingChanged event.
In the above code, a hyphen is appended to the input with each character.
When typing 123456, the expected result is:
Input: 1 → Result: 1-
Input: 2 → Result: 1-2-
…
Input: 6 → Result: 1-2-3-4-5-6-
However, the actual result is 11111123456-.
Another example:
@objc
func textFieldEditingChanged() {
print("before", self.textField.text!)
self.textField.text = self.textField.text?.replacingOccurrences(of: "0", with: "1")
print("after", self.textField.text!)
}
When inputting 0 1 0 sequentially, the output is:
before 0 after 1
before 01 after 11
before 010 after 111
The value of "after" matches expectations,
but the "before" value reverts to 0 on the next input, even though it appears as 1 on the UI.
When the bilingual keyboard option is turned off or the base localization is set to something other than Korea, the issue does not occur.
Could you provide information on whether this issue will be resolved in the next iOS version, or if there is a workaround?
Hi,
We are going to create a tvOS App with portrait display(HDMI screen will rotate 90 degree).
It seems there is no rotate setting in tvOS18, neither Xcode provide relative support.
As our investigation, we might need to rotate each UIKit component 90 degree by code to archive it.
Is there any better suggestion?
Thanks.
I am trying to change UITabBar background color runtime as theme changed. It is already working in iOS 17 as I am updating UITabBar.appearance().barTintColor and tintColor
But for iOS first i need to change because I don't want that new elevated tabbar so I create custom tabbar controller as described in
https://stackoverflow.com/questions/78631030/how-to-disable-the-new-uitabbarcontroller-view-style-in-ipados-18
Accepted Answer by awulf.
And by doing this, My tabbar looks same like Old and it is working in iPhone and ipad for iOS 16, iOS 17 and iOS 18 too.
But the issue is that I am unable to change my tabbar background color.
I have also checked this forum: https://forums.developer.apple.com/forums/thread/761056
But not able to change
I have set below 3 properties but no effect
let appearance = UITabBar.appearance()
appearance.backgroundColor =
appearance.barTintColor =
appearance.tintColor =
I have created CustomTabBarController in storyboard and all working fine
Also the appearance changed only once per application lifecycle.
It will change color by restarting the app then it will pick last selected theme and the colors are changed.
but not able to change colors runtime
I have also did below code for reloading purpose
tabBar.setNeedsLayout()
tabBar.setNeedsDisplay()
But nothing work
I notice that the UIControlEventEditingChanged action will be called twice under Chinese or Japanese when click confirm button of the UITextfield's keyboard. While for other languages such as English it only be called once. Could anyone can explain the detail for it?
In iOS18, WKWebView's default cookie SameSite value is Lax. Prior to iOS18, the default value is None.
Is this intentional, or a bug? This change is not documented anywhere.
I made a sample XCode project (ViewController code below) to show this change. It loads www.apple.com into a WKWebView and prints cookies. That site has several cookies, but it only explicitly sets SameSite to None for one cookie, s_vi. Every other cookie relies on default WKWebView behavior. When looking at cookies, either in the console or in Safari's Web Inspector, the SameSite value differs. If older than iOS18, every cookie has SameSite of None. If iOS18, all cookies except s_vi have SameSIte of Lax.
I also tried manually setting the following cookies:
testCookie-none with SameSite set to None
testCookie-lax with SameSite set to Lax
testCookie-strict with SameSite set to Strict
testCookie- with SameSite set to an empty string
When looking at these cookies, testCookie-none and testCookie- have their SameSite of None if older than iOS18, but are both Lax in iOS18. So, it seems we cannot manually set the SameSIte to None either.
I realize updating the server to return the SameSite value would resolve this. However, in my app where I'm struggling with this issue, that server is Salesforce. Only they can update their response headers. Since this change isn't documented by Apple, I am assuming it is a bug and not intentional. Are there any workarounds? Any input by Apple on a fix?
Below is the ViewController code, and images of the cookies in Safari's Web Inspector.
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
var webView: WKWebView!
override func loadView() {
// Create WKWebView
let config = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: config)
// Allow inspection in Safari debugger
webView.isInspectable = true
// Track the request to load our website
webView.navigationDelegate = self
// Manually add four cookies:
// testCookie-none with SameSite set to None
// testCookie-lax with SameSite set to Lax
// testCookie-strict with SameSite set to Strict
// testCookie- with SameSite set to an empty string
addTestCookies()
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
// Load a website
let urlString = "https://www.apple.com"
self.webView.load(URLRequest(url: URL(string:urlString)!))
}
// Once the website loads, print the cookies.
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
WKWebsiteDataStore.default().httpCookieStore.getAllCookies { cookies in
for cookie in cookies {
print(cookie)
}
}
}
/*
Manually add the following cookies for domain .apple.com
testCookie-none with SameSite set to None
testCookie-lax with SameSite set to Lax
testCookie-strict with SameSite set to Strict
testCookie- with SameSite set to an empty string
In older iOS versions, both testCookie-none and testCookie- will have their SameSite as none.
In iOS18, no cookie will have SameSite as None.
*/
func addTestCookies()
{
let httpCookieStore = WKWebsiteDataStore.default().httpCookieStore
for sameSitePolicy in ["none", "lax", "strict", ""] {
httpCookieStore.setCookie(HTTPCookie(properties: [
HTTPCookiePropertyKey.path: "/",
HTTPCookiePropertyKey.name: "testCookie-"+sameSitePolicy,
HTTPCookiePropertyKey.value: "1",
HTTPCookiePropertyKey.domain: ".apple.com",
HTTPCookiePropertyKey.secure: true,
HTTPCookiePropertyKey.sameSitePolicy: sameSitePolicy
])!)
}
}
}
Previously this code would trigger fine on pressesBegan in iOS 17 and earlier versions, but no longer works in iOS 18. How can I start capturing pressesBegan in iOS 18? It seems like UIResponder is just not capturing the keyboard anymore?
struct ContentView: View {
var body: some View {
KeyBoardView()
}
}
//To Use in SwiftUI
struct KeyBoardView: UIViewRepresentable{
func makeUIView(context: Context) -> KeyEventView {
KeyEventView()
}
func updateUIView(_ uiView: KeyEventView, context: Context) {
}
class KeyEventView: UIView {
init() {
super.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?)
{
print("test")
}
}
}
Hi all,
Firebase statistics show that some crashes seem to occur suddenly. Can you give me some suggestions?
Users also meet the following requirements:
iOS18 and above
RTL language
From the stack frame, the crash occurred in the transition animation project, but I did not reproduce this stack frame
A very small number of users can experience it twice
The crashed page is relatively complex, and it is a mixture of auto-layout and frame
I retrieved some other articles, but they don’t seem to be the same problem
https://developer.apple.com/forums/thread/693118
https://stackoverflow.com/questions/56027014/collectionview-crashing-in-nsisengine-after-a-few-scrolls
Thank you for reading, looking forward to your reply ;)
CoreAutoLayout: _engineVar_rawRemove
We're trying to implement a backup/restore data feature in our business productivity iPad app using UIDocumentPickerViewController and AppleArchive, but discovered AppleArchive crashes instead of failing gracefully when decrypting a corrupt archive.
As described in forum post 765101, UIDocumentPickerViewController can handoff a corrupt copy of an archive to UIDocumentPickerDelegate under specific circumstances.
We've duplicated this behavior with iPadOS 16.6.1 and 17.7 when building our app with Xcode 15.4 targeting minimum deployment of iPadOS 16. We haven't tested this with the bleeding edge iPadOS 18.
Our app is primarily Objective-C, but it utilizes the Swift-based AppleArchive 'EncryptingAndDecryptingDirectories' sample code associated with WWDC21 session:
10233: Bring Encrypted Archives and Performance Improvements to Your App with Accelerate.
The WWDC21 'EncryptingAndDecryptingDirectories' Swift sample project crashes in a similar manner when a corrupt archive file created by UIDocumentPickerViewController is dropped into the sample app's window for decryption (see attached crash log).
Does anyone know if there's a workaround for the 'EncryptingAndDecryptingDirectories' sample project to prevent AppleArchive from crashing when decrypting a corrupt archive?
crash log.txt
We're trying to implement a backup/restore data feature in our business productivity iPad app using UIDocumentPickerViewController and AppleArchive, but discovered odd behavior of [UIDocumentPickerViewController initForOpeningContentTypes: asCopy:YES] when reading large archive files from a USB drive.
We've duplicated this behavior with iPadOS 16.6.1 and 17.7 when building our app with Xcode 15.4 targeting minimum deployment of iPadOS 16. We haven't tested this with bleeding edge iPadOS 18.
Here's our Objective-C code which presents the picker:
NSArray* contentTypeArray = @[UTTypeAppleArchive];
UIDocumentPickerViewController* docPickerVC = [[UIDocumentPickerViewController alloc] initForOpeningContentTypes:contentTypeArray asCopy:YES];
docPickerVC.delegate = self;
docPickerVC.allowsMultipleSelection = NO;
docPickerVC.shouldShowFileExtensions = YES;
docPickerVC.modalPresentationStyle = UIModalPresentationPopover;
docPickerVC.popoverPresentationController.sourceView = self.view;
[self presentViewController:docPickerVC animated:YES completion:nil];
The UIDocumentPickerViewController remains visible until the selected external archive file has been copied from the USB drive to the app's local tmp sandbox. This may take several seconds due to the slow access speed of the USB drive. During this time the UIDocumentPickerViewController does NOT disable its tableview rows displaying files found on the USB drive. Even the most patient user will tap the desired filename a second (or third or fourth) time since the user's initial tap appears to have been ignored by UIDocumentPickerViewController, which lacks sufficient UI feedback showing it's busy copying the selected file.
When the user taps the file a second time, UIDocumentPickerViewController apparently begins to copy the archive file once again. The end result is a truncated copy of the selected file based on the time between taps. For instance, a 788 MB source archive may be copied as a 56 MB file. Here, the UIDocumentPickerDelegate receives a 56 MB file instead of the original 788 MB of data.
Not surprisingly, AppleArchive fails to decrypt the local copy of the archive because it's missing data. Instead of failing gracefully, AppleArchive crashes in AAArchiveStreamClose() (see forums post 765102 for details).
Does anyone know if there's a workaround for this strange behavior of UIDocumentPickerViewController?
Can anyone help me to resolve this issue?
I have two collectionviews in a tableview and each time you try to scroll the collecctionview after clicking a cell, it crashes with the following error:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Expected dequeued view to be returned to the collection view in preparation for display. When the collection view's data source is asked to provide a view for a given index path, ensure that a single view is dequeued and returned to the collection view. Avoid dequeuing views without a request from the collection view. For retrieving an existing view in the collection view, use -[UICollectionView cellForItemAtIndexPath:] or -[UICollectionView supplementaryViewForElementKind:atIndexPath:]
I am using Storyboard to present a UIImagePickerController on a view controller (a simple initial view without any navigation or tab bar). Due to a requirement, we need to exclude the arm64 architecture. However, when I try to present the screen, it gets stuck. I am unable to select an image, and the screen becomes inaccessible. It's happening only on simulator.
Does anyone have any solution.
I just finished updating my app to support the new screen sizes for the iPhone 16 series devices (iPhone16 Pro and iPhone 16 Pro Max). In testing the changes, I've come across what I hope is simply a bug in the Xcode 16 simulators. I don't have any actual devices (yet) that I can use to test.
In landscape mode, my app presents a "tab" on the right side of the screen that can be tapped to bring out another view. Activating the tab is based on capturing the screen coordinates from a "tap".
In Xcode 16, using the iPhone16 simulators on IOS 18, the area of the tab does not recognize that a tap has occurred. After hours of banging my head against my laptop, it dawned on me that the area of the screen that hosts the "tab" is in exactly the same location as "unavailable area" that represents the camera on the simulator. I have arrived at the assumption that the issue is that the simulator is treating the same space at the bottom of the device as it treats that reserved area at the top of the screen.
Has anyone else experienced this?
Is this a bug in the simulator or is this expected behavior on the iPhone 16 series devices?
I have issue with unwanted changing offset in collection view to top or to near top.
It is happening in collection view with vertical scroll when estimatedItemSize is not set to zero (main factor). If estimatedItemSize is zero it is always fine.
It is SDK that provides items that should be loaded in few cells, items have dynamic height which is received from server and can be updated several times.
Scenario when it happens (when was noticed) is 2 sections, in section 0 item is at index 4 of 14, section 1 is with only one cell with dynamic height item.
If specific item is at index 0 in section 0 or have 1 cell per section (tried 15 sections and set items in sections 5 and 15) all is good regardless of estimatedItemSize.
When new height is received if I call invalidateLayout or reloadItemAtIndexPaths it will “jump”. That same height is set in sizeForItemAtIndexPath.
In some combinations it happens and in some not and that is the most annoying part.
I tried setting estimated height to received height and it didn’t help (other cell may be smaller or larger). Also if I put items in one section at indexes 4 and 14 it “jumps”.
I managed to make it work by setting at specific moment estimatedItemSize to zero then put back to one that SDK user set and didn’t see any issues but I was wondering if there is any other solution for this and did anyone had issue like this. It would be nice to have solution to keep one estimatedItemSize if it is not the default one (zero).
iPadOS18 Tab Bar has been moved to top of screen. Everything looks ok when translucent=true. But there is an unwanted white space at bottom of screen when setting translucent=false.
Is it iPadOS bug?
See white area at bottom of attached screenshot.
As you can see, when I swipe to see the context actions in the collectionview, the searchbar flicks. Same story when, in a popover, i change the PreferredContentSize.
Hi there,
I'm trying to migrate my app to using the UIDocumentViewController so I can use the new launch experience. My app exports a custom file type and uses UIDocument + UIDocumentBrowserViewController.
I tried creating a UIDocumentViewController and making it the root view of my app but it doesn't recognise my custom document type.
class Document_VC: UIDocumentViewController {
var storyCardsDocument: PlotCardDocument? {
self.document as? PlotCardDocument
}
override func viewDidLoad() {
super.viewDidLoad()
configureViewForCurrentDocument()
}
override func documentDidOpen() {
configureViewForCurrentDocument()
}
func configureViewForCurrentDocument() {
guard let document = storyCardsDocument,
!document.documentState.contains(.closed)
&& isViewLoaded else { return }
print("Document opened: \(document.fileURL)")
}
}
The app opens but when I navigate to a document made in a previous version of the app it is greyed out. I also don't see a 'New' button in the launcher view.
To try and see what I was doing wrong, I tested the markdown app sample code. When I make the UIDocumentViewController the root and try to open or create a new markdown document I get the following error:
no document class found. Define the correct UIDocument subclass with the key UIDocumentClass in the info.plist's CFBundleDocumentTypes dictionary.
I am making an IOS application using XCode Storyboard.
I have a UICollectionViewController in the following structure
UIViewController -> UIView -> UITabBarController -> UICollectionViewController
The app loads without crashing, and UICollectionViewController.viewDidLoad() and .numberOfSections() execute correctly.
But anything that I put in
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)
does not seem to execute. Once the app loads, no cells load. And any print statement in the function doesn't execute either.
All elements have their corresponding class correctly assigned in the Storyboard Identity Inspector, and the cells have the correct reusable identifier.
How can I make it work correctly?
My Collection View Controller:
class ValidCardsCollectionViewController: UICollectionViewController {
let dataSource: [String] = ["hearts", "clubs", "diamonds", "spades"]
override func viewDidLoad() {
super.viewDidLoad()
print(dataSource)
}
override func numberOfSections(in collectionView: UICollectionView) -> Int {
print("Loading \(dataSource.count) cells")
return dataSource.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
var cell = UICollectionViewCell()
if let cardCell = collectionView.dequeueReusableCell(withReuseIdentifier: "CardCell", for: indexPath) as? CardCollectionViewCell{
cardCell.configure(with: dataSource[indexPath.row])
cell = cardCell
}
print("loading cell")
return cell
}
My UICollectionViewCell:
class CardCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var lblStr: UILabel!
func configure(with str:String){
lblStr.text = str
}
}
Storyboard layout:
Simulator:
HI
i have found libsystem_kernel.dylib crash. i can't reproduce this error even this is not unrecognisable. here is stack trace
Crashed: com.apple.main-thread
0 libsystem_kernel.dylib 0xaac mach_msg_trap + 8
1 libsystem_kernel.dylib 0x107c mach_msg + 72
2 CoreFoundation 0x6c88 + 368
3 CoreFoundation 0xaf90 + 1160
4 CoreFoundation 0x1e174 CFRunLoopRunSpecific + 572
5 GraphicsServices 0x1988 GSEventRunModal + 160
6 UIKitCore 0x4e5a88 + 1080
7 UIKitCore 0x27ef78 UIApplicationMain + 336
8 libTweaks.dylib 0x2a6b4 _apdecr_UIApplicationMain(int, char**, NSString*, NSString*) + 108
9 libswiftUIKit.dylib 0x27ee4 $s5UIKit17UIApplicationMainys5Int32VAD_SpySpys4Int8VGGSgSSSgAJtF + 100
10 REDDI 0x214d6c main + 4368469356 (AppDelegate.swift:4368469356)
11 ??? 0x1028a84d0 (Missing)
Hello!
I discovered a bug on Catalyst about a three years ago but it still seems to be not fixed. My bug report number is FB9705748.
The Internet is silent on this so I'm even not sure, perhaps it's only me.
So to the problem. When you display UICollectionViewController or UIViewController that contains UICollectionView, interact with the collection view then dismiss the view controller, the displayed view controller isn't released if dismissal is done through navigation bar item.
The problem occurs only when the run target is My Mac (Mac Catalyst). Everything is fine when you run on iOS or via My Mac (Designed for iPad).
The sample project is uploaded to GitHub. It has a video that shows this strange behavior, see the log for 'deinit' messages.
I did have some workaround to fix this but it stops to work, presumable on the new macOS. Also, chances are that it's not only UICollectionView which initiates the glitch, it's just that I only encounter it with collection views.