Post

Replies

Boosts

Views

Activity

Trying to print NSAttributedString via many UITextViews causes crash
My Mac app uses many NSTextViews just fine for printing a long string, but trying to do the same on iOS with many UITextViews and associated UIViewPrintFormatters just causes a crash.*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]' *** First throw call stack: ( 0 CoreFoundation 0x00007fff23c7127e __exceptionPreprocess + 350 1 libobjc.A.dylib 0x00007fff513fbb20 objc_exception_throw + 48 2 CoreFoundation 0x00007fff23d03ab1 _CFThrowFormattedException + 194 3 CoreFoundation 0x00007fff23b83bf9 -[__NSArrayM objectAtIndex:] + 169 4 UIKitCore 0x00007fff48029503 -[UITextViewPrintFormatter rectForPageAtIndex:] + 86 5 UIKitCore 0x00007fff4806bc79 __57-[UIPrintPageRenderer drawPrintFormatter:forPageAtIndex:]_block_invoke + 41 6 UIKitCore 0x00007fff4806bcf9 __57-[UIPrintPageRenderer drawPrintFormatter:forPageAtIndex:]_block_invoke.43 + 29 7 libdispatch.dylib 0x000000010e4f6d48 _dispatch_client_callout + 8 8 libdispatch.dylib 0x000000010e505b24 _dispatch_async_and_wait_invoke + 175 9 libdispatch.dylib 0x000000010e4f6d48 _dispatch_client_callout + 8 10 libdispatch.dylib 0x000000010e504de6 _dispatch_main_queue_callback_4CF + 1500 11 CoreFoundation 0x00007fff23bd4049 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9 12 CoreFoundation 0x00007fff23bceca9 __CFRunLoopRun + 2329 13 CoreFoundation 0x00007fff23bce066 CFRunLoopRunSpecific + 438 14 GraphicsServices 0x00007fff384c0bb0 GSEventRunModal + 65 15 UIKitCore 0x00007fff48092d4d UIApplicationMain + 1621 16 myApp 0x000000010e1ca61b main + 75 17 libdyld.dylib 0x00007fff5227ec25 start + 1 18 ??? 0x0000000000000001 0x0 + 1 )Here's the code:class ViewController: UIViewController { override func viewDidAppear(_ animated: Bool) { let printController = UIPrintInteractionController.shared let printPageRenderer = PrintPageRenderer() printController.printPageRenderer = printPageRenderer printController.present(animated: true) } } class PrintPageRenderer: UIPrintPageRenderer { let layoutManager = NSLayoutManager() let textStorage = NSTextStorage(string: "fhdjksalhfj dskla fjf") var textViews = [UITextView]() override func prepare(forDrawingPages range: NSRange) { DispatchQueue.main.sync { for (i, textView) in textViews.enumerated() { let printFormatter = textView.viewPrintFormatter() addPrintFormatter(printFormatter, startingAtPageAt: i) } } } override var numberOfPages: Int { textStorage.addLayoutManager(layoutManager) let size = CGFloat(50) for _ in 0..<2 { let textContainer = NSTextContainer(size: CGSize(width: size, height: size)) layoutManager.addTextContainer(textContainer) let textView = UITextView(frame: CGRect(x: 0, y: 0, width: size, height: size), textContainer: textContainer) textViews.append(textView) } return textViews.count } }My goal is printing a document from an attributed string and showing a custom header and footer on each page.
9
0
1.9k
Jan ’20
FileManager.trashItem(at:resultingItemURL:) never returns if called inside NSFileCoordinator.coordinate(writingItemAt:options:error:byAccessor:)
In the following code, the string "after" is never printed:class ViewController: UIViewController, UIDocumentPickerDelegate { override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) let documentPicker = UIDocumentPickerViewController(documentTypes: [kUTTypeText as String], in: .open) documentPicker.delegate = self present(documentPicker, animated: true) } func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { let url = urls[0] guard url.startAccessingSecurityScopedResource() else { return } defer { url.stopAccessingSecurityScopedResource() } DispatchQueue.global(qos: .background).async { var fcError, _error: NSError? NSFileCoordinator(filePresenter: nil).coordinate(writingItemAt: url, options: [.forMoving], error: &fcError, byAccessor: { url in print("before") do { try FileManager.default.trashItem(at: url, resultingItemURL: nil) // try FileManager.default.moveItem(at: url, to: url.deletingLastPathComponent().appendingPathComponent("bla")) } catch { _error = error as NSError } print("after") }) print(fcError ?? _error) } } }Other file operations (such as moving a file, see commented out line) work as expected. Commenting out the part with the NSFileCoordinator seems to solve the problem.
4
0
1.3k
Jan ’20
UITextView automatically scrolls upwards when dragging selection handles and textContainerInset is about half the textview height
Anyone else noticed this issue? Is there a workaround? The issue can be reproduced on an iPad Pro 11" with this code:class ViewController: UIViewController { @IBOutlet weak var textView: TextView! override func viewDidLoad() { super.viewDidLoad() let h = CGFloat(560) textView.textContainerInset = UIEdgeInsets(top: h, left: 0, bottom: 0, right: 0) } }
2
0
473
Mar ’20
Resolve bookmark created in iOS app in Share Extension
I create a URL bookmark with `URL.bookmarkData(options: [], includingResourceValuesForKeys: [.localizedNameKey])` and resolve it with `NSURL(resolvingBookmarkData: bookmarkData, options: [], relativeTo: nil, bookmarkDataIsStale: nil) as URL`. This works fine within my main app, but when sharing the bookmarkData via an App Group with my Share Extension, it gives the error "The file couldn't be opened because you don't have permission to view it.". Is there any way I can do this?
4
0
1.1k
Jun ’20
Getting inode number from URL
I couldn't find any other way of getting the inode number without using FileManager.attributesOfItem(atPath: url.path)[.systemFileNumber]. I'm already using FileManager.enumerator(at:includingPropertiesForKeys:errorHandler:) for enumerating large directories and using that other FileManager method only for accessing the inode number doubles the scan time. I looked for a URLResourceKey but there doesn't seem to be any. I would be really grateful for any kind of help.
26
0
4.7k
Aug ’20
Resolve bookmark created in iOS app in Share Extension
I create a URL bookmark with URL.bookmarkData(options: [], includingResourceValuesForKeys: [.localizedNameKey]) and resolve it with NSURL(resolvingBookmarkData: bookmarkData, options: [], relativeTo: nil, bookmarkDataIsStale: nil) as URL. This works fine within my main app, but when sharing the bookmarkData via an App Group with my Share Extension, it gives the error "The file couldn't be opened because you don't have permission to view it.". Is there any way I can do this?
0
0
271
Aug ’20
Swift string interpolation produces string that takes very long to insert in a dictionary
Under some conditions, string interpolation produces a string that is way slower to use as a dictionary key than a string produced with String(format:). Take the following code: var map = [String: String]() let start = Date() for _ in 0..<100000 {     var s = "asdf"     s = (s as NSString).appendingPathComponent("")     s = transform(s)     s = (s as NSString).substring(from: 1)     map[s] = s } print(-start.timeIntervalSinceNow) func transform(_ s: String) -> String {     return "\(s)/\(s)" //    return String(format: "%@/%@", s, s) } On my Mac I get the time interval 0.69 seconds printed out in the console (when using the string interpolation), but when commenting out line 13 and uncommenting line 14 (so that we use String(format:)) I get a 0.33 seconds time interval, less than half the time. Curiously, whenever uncommenting line 5 or line 7, string interpolation is faster. This took me quite a lot of time to figure out, since I would expect both methods to produce the same kind of string, but string interpolation to be always faster. Does anybody know why?
7
0
1.2k
Aug ’20
getattrlistbulk lists files with underscore prefix on exFAT
It seems that on exFAT macOS creates a file with an underscore prefix for each file to hold some metadata (I guess). When enumerating a directory with FileManager, these files are not listed, but they are when using getattrlistbulk. Is there a way to mimick the FileManager behaviour? Unfortunately I have to resort to getattrlistbulk because FileManager doesn't allow me to efficiently get a file's inode number.
5
0
587
Aug ’20
EXC_BAD_ACCESS (code=2) when NSTextField in NSOutlineView has a connected IBOutlet action
I'm transitioning one of my projects from using .xib files to a single .storyboard file, and this one issue is driving me crazy. It seems to happen only in the project version with the storyboard. Every time I launch the app, the EXC_BAD_ACCESS error happens where the AppDelegate is declared. I could isolate the problem which can now be reproduced every second or third time when launching the following sample project: https://www.icloud.com/iclouddrive/0Vx_ZOrGuD7U0S9u_8dJz-_0A#problem It seems that when removing the connection from the text field in the outline view to its action textFieldAction in ViewController, the crash doesn't happen anymore. How is this possible?
4
0
678
Sep ’20
Views inside split view resize in real time only when window has full size content view
I noticed that when a window has full size content view, the views inside a scroll view are resized smoothly when adding a new split view item (i.e. in real time while the animation is running), but when the window has not full size content view, only the split view divider animates to its new position, while right from the beginning of the animation the views are instantly drawn as if the animation had already finished. Is there a setting that allows me to turn these smooth animations on even if I don't use a full size content view? Here is a sample project and steps to reproduce the issue: https://www.icloud.com/iclouddrive/0zKg8hqwLpV682-6LuxeykZLw#problem2 Run the project. Press Cmd-L to add a view to the right of the split view. The text view will resize smoothly. Now deactivate the full size content view for the window in the storyboard and relaunch the project. Press Cmd-L. The text view will resize instantly at the start of the animation, and only the split view separator moves smoothly to its final position.
0
0
304
Sep ’20
Text view resizes weirdly in split view when window has full size content view
In my project I have a split view that contains a text view and a collapsible sidebar to its right. When the sidebar is animated in and out quickly repeatedly (i.e. before the previous animation finishes), the space occupied by the text inside the text view shrinks and leaves the remaining space in the text view blank. This doesn't happen if I disable the full size content view or the sidebar is added without the animation. Here are a sample project and the steps to reproduce the issue: https://www.icloud.com/iclouddrive/0zKg8hqwLpV682-6LuxeykZLw#problem2 Run the project. Press Cmd-L to add a view to the right of the split view. Repeat this step about 10 times: press Cmd-L twice as fast as possible, so that the second press happens before the collapse animation finishes. About after each second of these 10 steps the text view occupies less space horizontally which is left blank.
3
0
417
Sep ’20
Scroll event is called only for every second swipe when wantsScrollEventsForSwipeTracking(on:) is enabled
In my project I have text view filling up the whole window and with a swipe left or right I want to slide a sidebar in or out. I implemented wantsScrollEventsForSwipeTracking(on:) and scrollWheel(with:) in the main ViewController, but I am observing some weird behaviour: when I swipe once scrollWheel(with:) is called repeatedly until the swipe momentum has finished, but if I swipe again, either while there is still momentum or even if it has already finished, that method is not called (regardless whether I swipe left or right). Swiping a third time works again. This is a real problem because this would always require two swipes after the first one. Here are a sample project and the steps to reproduce the issue: https://www.icloud.com/iclouddrive/0ISqzjoxbpvvF3_Wv1ji8sR_w#problem3 Run the attached project. Inside the text view, swipe left. The console will print some scroll event details. When the scroll momentum has finished (nothing is printed anymore in the console), swipe left again. Now nothing will be printed out in the console. If you repeat once more, it will work again. Now you can repeat step 3 with a swipe to the right instead of left, the same thing will happen. You can also try without waiting until the scroll momentum has finished. If you swipe again while the console is still printing the momentum events (left or right doesn't matter), the momentum will be immediately stopped, but the new swipe is also not forwarded.
0
0
278
Sep ’20