Posts

Post marked as solved
4 Replies
1.9k Views
I have an app in Swift that does a lot of numerical processing on ordered pairs and vectors, so I'm looking into some ways to improve performance including adopting SIMD from the Accelerate framework for some calculations, but I'm not seeing performance improve. There are some related posts on the forums that seem inconclusive and also a bit more complex. I pared my testing down to a couple of brief XCTests with self.measure blocks on repeated add and multiply operations of two double values. The tests set random initial values to ensure there's no compiler optimization of loop calculations based on constants. There's also no big collection of fixture data, so there's no chance allocations or vector index dereference or similar issues could be involved. The regular multiple-instruction code runs an order of magnitude faster than the SIMD code! I don't understand why this is - would the SIMD code be faster in C++, could it be some Swift conversion? Or is there some aspect of my SIMD code that is incurring some known penalty? Curious if anyone out there is using SIMD in Swift in production and if you see anything in my test code that explains the difference. func testPerformance_double() { var xL = Double.random(in: 0.0...1.0) var yL = Double.random(in: 0.0...1.0) let xR = Double.random(in: 0.0...1.0) let yR = Double.random(in: 0.0...1.0) let increment = Double.random(in: 0.0...0.1) &#9;&#9;Swift.print("xL: \(xL), xR: \(xR), increment: \(increment)") var result: Double = 0.0 self.measure { for _ in 0..<100000 { result = xL + xR result = yL + yR result = xL * xR result = yL * yR xL += increment yL += increment } } Swift.print("last result: \(result)") // read from result } func testPerformance_simd() { var vL = simd_double2(Double.random(in: 0.0...1.0), Double.random(in: 0.0...1.0)) let vR = simd_double2(Double.random(in: 0.0...1.0), Double.random(in: 0.0...1.0)) let increment = Double.random(in: 0.0...0.1) let vIncrement = simd_double2(increment, increment) var result = simd_double2(0.0, 0.0) Swift.print("vL.x: \(vL.x), vL.y: \(vL.y), increment: \(increment)") self.measure { for _ in 0..<100000 { result = vL + vR result = vL * vR vL = vL + vIncrement } } Swift.print("last result: \(String(describing: result))") } The measurements show the block with SIMD operations taking an order of magnitude more time than the multiple operations! ...testPerformance&#92;&#95;double measured [Time, seconds] average: 0.049, relative standard deviation: 3.059%, values: [0.049262, 0.049617, 0.048499, 0.047859, 0.048270, 0.048564, 0.047529, 0.052578, 0.047267, 0.047432], performanceMetricID:com.apple.XCTPerformanceMetric&#92;&#95;WallClockTime, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.100, maxStandardDeviation: 0.100 ...testPerformance&#92;&#95;simd measured [Time, seconds] average: 0.579, relative standard deviation: 5.932%, values: [0.626196, 0.605790, 0.635180, 0.611197, 0.553179, 0.548163, 0.552648, 0.549264, 0.552745, 0.551465], performanceMetricID:com.apple.XCTPerformanceMetric&#92;&#95;WallClockTime, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.100, maxStandardDeviation: 0.100
Posted
by ccorbell.
Last updated
.
Post not yet marked as solved
2 Replies
705 Views
This is mainly a Mac app issue, though it's perhaps related to a similar issue with iOS app receipt validation on App Store review testing. I'm stuck in app store rejections because they are seeing a 'damaged app' error trying to launch my app on some of their test environments. I cannot reproduce in numerous attempts. Has anyone else been stuck this way (esp. recently) and if so what did you do to resolve? My app runs perfectly if I compile without app store code and notarize it myself, on a variety of systems. It's universal (M1 and intel), tested on all the above, both admin and standard accounts, so that makes me think the issue is only in the StoreKit / receipt-validation code. The app does local receipt validation in a very standard way, requesting the receipt if it's absent. I've tested this with the exact app submitted (and rejected) to app store review, exported from the Xcode organizer, and in my testing the app successfully refreshes or validates the receipt. At worst (e.g. if offline) it prompts to log in with the apple ID. I'm using a sandbox App Store account to test. I've never seen a 'damaged app' error happen even when I manually delete the receipt. The worst I've seen is a notarization error if I copy the app to a different machine (since app store archived build is not notarized, docs state that App Store will notarize it). Since there's no Mac TestFlight I can't download the actual binary that App Store review is testing which presumably has modifications (at least, notarization). And their error reports are very vague, just a screenshot of the error and generic testing advice. I can't be the only one who has been in this situation, and although I've used a DTS support ticket I don't know how soon they'll get back to me. Any helpful knowledge is appreciated!
Posted
by ccorbell.
Last updated
.
Post marked as solved
1 Replies
604 Views
I have an NSDocument-based Mac app built for 10.14+, written in Swift. Just updated my (intel) OS to Big Sur to test, and while the app builds and generally functions fine the document window toolbar is totally messed up when I run the app. In particular: only one toolbar item (Save) shows up on the toolbar in icon+text mode, the rest are all shoved into the menu, regardless of window size same is true if I switch to Icon only mode when I right-click on the menu bar to customize it in the app, everything is haywire - tons of blank space between titles and icons, some icons as you scroll down are huge, default set looks like it only contains one button If I turn off icons and show only text toolbar items, they all show up properly on the toolbar. In Xcode (12.2), the toolbar in the document .xib looks totally fine - all buttons and icons in the right place, default set looks great, etc. There's nothing very custom about my toolbar - it's just using standard toolbar buttons with icons set from image assets, and a few separators between items. Default is visible, regular size, Icon+Text. All works perfectly under 10.14 and 10.15. Anyone else seen this bizarre toolbar behavior under Big Sur? This is my app's last release-blocking issue!
Posted
by ccorbell.
Last updated
.
Post not yet marked as solved
0 Replies
595 Views
I'm releasing a Mac app through the app store. It's a one-time purchase app; no in-app purchases, no subscriptions. I'm doing local validation of the receipt on application launch. The Receipt Validation Programming Guide - https://developer.apple.com/library/archive/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateLocally.html#//apple_ref/doc/uid/TP40010573-CH1-SW3 says "When an application is installed from the App Store, it contains an application receipt..." I've done validation in in an iOS app before which has in-app purchases, so there, in addition to checking the receipt on launch, I would send an SKReceiptRefreshRequest to get additional in-app purchase data etc. - and retry the refresh request periodically if needed. Is it correct that there's no need for me to send a refresh request for this simpler case, with no subscription or in-app purchase? I.e. I can always just rely on the receipt in the bundle? Or should one still make some refresh-receipt attempts before assuming an invalid receipt in this basic case?
Posted
by ccorbell.
Last updated
.
Post marked as solved
1 Replies
638 Views
I'm using GKNoise with a gradient map to generate color noise, getting a CGImage via SKTexture, on Mac OS. The GKNoise gradientColors: init parameter takes a map of NSNumber to NSColor instances. I'm setting two to the min and max values (-1.0, 1.0), with a GKPerlinNoiseSource. It works as expected if the two colors are opaque. If one or both colors has an alpha component less than 1.0, I expect the output to have transparency. However, it looks to me like the alpha is completely ignored in GKNoise's gradient color input (treated as if it's always 1.0). Is there anything I overlooked to make GKNoise/SKTexture support alpha components of gradient input colors, corresponding to transparency in the output CGImage? Or is this 'as designed' or a known bug? Below is test code that reproduces it - in the view, both CGImages draw identically; I expect the one drawn with the red alpha=0.5 to be darker in the red parts when the background is black, lighter when it's white, etc. import GameplayKit class GKNoiseGradientIssue {       var noiseSource: GKNoiseSource       var color0_opaque = NSColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)   var color0_halfAlpha = NSColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 0.5)       var color1_opaque = NSColor(red: 0.0, green: 0.0, blue: 1.0, alpha: 1.0)       var opaqueNoise: GKNoise   var halfAlphaNoise: GKNoise        var opaqueNoiseMap: GKNoiseMap   var halfAlphaNoiseMap: GKNoiseMap       var opaqueImage: CGImage   var halfAlphaImage: CGImage       init() {     let source = GKPerlinNoiseSource(frequency: 0.15,                          octaveCount: 7,                          persistence: 1.25,                          lacunarity: 0.5,                          seed: 12345)     self.noiseSource = source           let opaqueGradient: [NSNumber: NSColor] = [-1.0: color0_opaque, 1.0: color1_opaque]     self.opaqueNoise = GKNoise(source, gradientColors: opaqueGradient)           let halfAlphaGradient: [NSNumber: NSColor] = [-1.0: color0_halfAlpha, 1.0: color1_opaque]     self.halfAlphaNoise = GKNoise(source, gradientColors: halfAlphaGradient)           self.opaqueNoiseMap = GKNoiseMap(self.opaqueNoise,                      size: [200.0, 200.0],                      origin: [0.0, 0.0],                      sampleCount: [200, 200],                      seamless: false)           self.halfAlphaNoiseMap = GKNoiseMap(self.halfAlphaNoise,                         size: [200.0, 200.0],                         origin: [0.0, 0.0],                         sampleCount: [200, 200],                         seamless: false)           let opaqueTexture = SKTexture(noiseMap: self.opaqueNoiseMap)     self.opaqueImage = opaqueTexture.cgImage()           let halfAlphaTexture = SKTexture(noiseMap: self.halfAlphaNoiseMap)     self.halfAlphaImage = halfAlphaTexture.cgImage()         } } class GradientIssueView: NSView {   var issue: GKNoiseGradientIssue?       override func awakeFromNib() {     self.issue = GKNoiseGradientIssue()   }       override func draw(_ dirtyRect: NSRect) {     NSColor.black.setFill()     self.bounds.fill()           if let cgc = NSGraphicsContext.current?.cgContext {       cgc.draw(self.issue!.opaqueImage,             in: CGRect(origin: CGPoint(x: 10.0, y: 10.0),                  size: CGSize(width: 200.0, height: 200.0)))               cgc.draw(self.issue!.halfAlphaImage,        in: CGRect(origin: CGPoint(x: 10.0, y: 220.0),              size: CGSize(width: 200.0, height: 200.0)))     }   } }
Posted
by ccorbell.
Last updated
.
Post not yet marked as solved
1 Replies
1.9k Views
I can't tell if I am misunderstanding the expected behavior of WKNavigationDelegate or if something is misconfigured or broken. My goal is to load the initial web content in my WKWebView, but then intercept link-clicks within that content and (at least sometimes) open those in Safari, as described in these forum posts: WKWebView - Open external link websites in Safari https://developer.apple.com/forums/thread/125641 Open WKWebView Links in Safari https://developer.apple.com/forums/thread/68427?answerId=199512022#199512022 Here's my simplified delegate method code. Because it gets called on the initial request load, it checks against a copy of the original URL and if it matches calls decisionHandler(.allow). (I'd hoped to be able to use .navigationType instead of checking the URL, but it comes in as .other on first load, which seems too vague to always allow). If it's any other URL, I call decisionHandler(.cancel) and attempt to open with UIApplication open(). func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { &#9;&#9;Swift.print(#function) &#9;&#9;if let navActionURL = navigationAction.request.url { &#9;&#9;&#9;&#9;if navActionURL == self.originalURL { &#9;&#9;&#9;&#9;&#9;&#9;decisionHandler(.allow) &#9;&#9;&#9;&#9;} else { &#9;&#9;&#9;&#9;&#9;&#9;decisionHandler(.cancel) &#9;&#9;&#9;&#9;&#9;&#9;UIApplication.shared.open(navActionURL, options: [:], completionHandler: nil) &#9;&#9;&#9;&#9;} &#9;&#9;} &#9;&#9; &#9;&#9; } This doesn't work however because the delegate method is only called once, on the WKWebiew's initial load() - on that call the URLs match and .allow is returned. The delegate method is not called at all for the click on the link. (FWIW the link is a relative href in the source HTML; it is to a different page not just a hashtag on the same page). Can anyone clarify how this is supposed to work? It makes no sense to me to have the delegate control the initial load() - if I didn't want to show the content in the WebView, I wouldn't load the URLRequest. It makes sense for me to have the delegate callback invoked for subsequent navigation, but that isn't happening.
Posted
by ccorbell.
Last updated
.
Post not yet marked as solved
9 Replies
2k Views
There are similar questions in the forums but none of the solutions there are working, I'm not seeing new solutions offered in those threads. I was on Xcode 11.5 and my iPhones updated to 13.6.1, at which point they stopped working for debugging - error alert "(Device-name) not available. Please reconnect the device" from Xcode on run attempt, and "The current device configuration is unsupported" error in the Devices tab of Devices and Simulators. I've updated Xcode to 11.7 and have tried every combination you can imagine of: cleaning the project deleting derived data disconnecting/reconnecting device (I'm connected by USB cable) restarting Xcode, the phone, and my Mac running an iOS 13.6 simulator build (saw a stackoverflow post that said doing this before running on the device seemed to help) None of this has solved the problem so I'm totally blocked now. Does anyone know if this is a known issue & can you recommend a fix? Also one more point: some other threads talk about making changes in Settings/Developer on the phone but I'm actually no longer seeing Developer in Settings at all. Thanks for help!
Posted
by ccorbell.
Last updated
.
Post marked as solved
1 Replies
436 Views
I'm currently working with an app that was initially created for local development only using a free account, and the company account holder is now setting up the app store record. Because I don't usually create apps with free accounts I was unaware that XCode will actually (without any notification) reserve the bundle ID for an app created this way. This is referenced in a few forum issues, e.g. https://developer.apple.com/forums/thread/80294 We encountered this and can't create the bundle ID in the paid account because of it, which is a bummer, but easy to work around by changing the bundle ID. My question: there isn't anything similar done with app name, is there? All my experience + docs I've read says app name must be explicitly reserved with a paid account, but since I was surprised by this auto-registration of bundle ID I want to confirm. Xcode does not automatically reserve app names ever, correct? If we're getting an "in use" error creating the app and it isn't published, it can't be our free account project that has reserved it, it must be another paid app developer? Thanks, Christopher
Posted
by ccorbell.
Last updated
.
Post not yet marked as solved
0 Replies
529 Views
I'm working on implementing printing for my graphics app. This is an NSDocument-based app written in Swift.I'm setting printInfo fields as follows, on the .printInfo member of the document class, and passing that instance into NSPrintOperation:self.printInfo.topMargin = 0.0 self.printInfo.rightMargin = 0.0 self.printInfo.leftMargin = 0.0 self.printInfo.bottomMargin = 0.0 self.printInfo.isHorizontallyCentered = true self.printInfo.isVerticallyCentered = true self.printInfo.orientation = .landscape let newPrintOp = NSPrintOperation(view: self.printView!, printInfo: self.printInfo) newPrintOp.showsPrintPanel = true return newPrintOpNow, I know that the *actual* printer page bounds I get from the system will depend on what printer is selected in Page Setup. This buggy behavior I'm seeing occurs when I select the "Any" default system printer. It sends back (and enforces) the following imageablePageBounds:(18.0, 18.0, 734.0, 576.0)This is a page with 1/4" margins on top, left, and bottom, and 40pt margin on the right! (792-734-18 = 40). So not only is it not centered as requested, it doesn't even permit a centered image with 1/2" margin to be printed without clipping.I think this is a bug. The "Any" printer should give a reasonable 1/4" minimum margin - particularly for printing to PDF.Note this error does not happen if I select my actual printer in page setup, which provides both normal and borderless options. The normal option then gives me back a reasonable, centered imageablePageBounds (with a consistent small margin), while the borderless option gives me the expected (0.0, 0.0, 792.0, 612.0) for borderless letter/leandscape.Is this 40-pt right margin a known bug in the system default "Any" printer page setup?Also FWIW I've posted this issue on stackoverflow with some screenshots of the print panel showing the issue:https://stackoverflow.com/questions/59691305/cocoa-printing-with-swift-any-printer-setup-has-irregular-margins-page-sizeThanks for any tips or workarounds, or replies if you've seen this as well.Christopher
Posted
by ccorbell.
Last updated
.