Posts

Post marked as solved
4 Replies
2.8k Views
I'm in the midst of moving all of my images into asset catalogs, adding size classes, and applying tags.I have two kudos's to share for any Apple engineers who might be reading: it's been really useful to work with multiple selected assets, thank you for allowing multiple selection; and, it's been really useful to drag a set of images into an asset catalog and have them associated with each other based on file name (e.g., .png, @2x.png, @2x~iPad.png).I started with single monolithic asset catalog, but then I realized that I will need multiple asset catalogs in order to separate out some images between Xcode targets (different apps), but not before I already started adding and configuring a ton of assets that now need to be separated out. So, I have two workflow questions:Is it possible to break out a set of assets, that are already in an asset catalog folder and configured with size classes and tags, into their own asset catalog file? If so, how? I tried dragging them out but that doesn't work.Is it possible to "name" image files appropriately for size classes, so that when I drag a set of images, they are associated with each other by size class? If so, what is the naming convention? I know this works for ~iPad, but I'm transitioning away from specifying iPad to specifying size regular.Thanks in advance for any tips on these.
Posted Last updated
.
Post not yet marked as solved
2 Replies
206 Views
Back in the Swift 4 days, I implemented a RandomNumberGenerator for the purpose of testing, which is to say, it always returns the same sequence of UInt64's, so that I can validate code that accepts a RandomNumberGenerator. However, as of "circa" Swift 5, this test is reliably failing, because even though it returns a different number in the next function, it fails to return any element except the first one from arrays (sequences, etc.). Sample code is here: class MockRandomNumberGenerator: RandomNumberGenerator {     var current: UInt64 = 0     func next() -> UInt64 {         defer { current += 1 }         return current     } } var mockRandomNumberGenerator = MockRandomNumberGenerator() let testArray = 0..<10 for _ in 0..<testArray.count {     print("testArray.randomElement   : \(testArray.randomElement(using: &mockRandomNumberGenerator)!)")     print("testArray[Int.random(...)]: \(testArray[Int.random(in: 0..<testArray.count, using: &mockRandomNumberGenerator)])") } The output of this is always 0, for every iteration. I expected the sequence to be returned in order, from 0 to 9. So, it fails in the same way for both array randomElement() and range random(in:). Prior to Swift 5, this same implementation returned the sequence in order. What do I need to do in the random number generator implementation to get it to work with arrays (and ranges) correctly?
Posted Last updated
.
Post not yet marked as solved
2 Replies
827 Views
Hi,I have a confounding localization problem for the menu bar and preferences in an iPad-on-macOS (Catalyst) app.Here is all I did to find the problem. I checked the Mac checkbox for an existing, shipping app that contains 10 localizations, and I added the default menu bar to its Main.storyboard file. The Main.storyboard file is not localized, as I replace all app-specific strings at runtime by calling NSLocalizedString directly. I also have a Settings bundle localized to the same 10 languages.The first problem I observed was, the menu bar items that refer to the app name (such as About, Quit, etc.), appear in ALL-CAPS (e.g., NSMENUITEMTITLEABOUT, etc.):The menu bar menu title for the app is correct, but it appears to not substitute the app name in any menu items that require it. The rest of the application (main window contents) localizes as expected.If I select a different region and language to run, all of the CamelCase menu items (Preferences, Services, etc.) appear localized, but the all-caps items are still not localized.I tried changing the storyboard file to have localization (Base, and all of the app's supported locales), but it had no effect. I also observed that if I add my own menu items using the same string keys found in my Localization.strings files, and ensure that the storyboard is using those localization files, my app-specific menu items are also not being localized. Only the system menu items without the app name are being localized.Lastly, I observed that the Preferences window's strings are also entirely in ALL-CAPS. If I copy each of the localizable strings from the Settings' Root.strings files into the respective Localizable.strings files, the Preferences window strings still don't get localized.If anyone familiar with the subtleties of localization and Catalyst can offer suggestions for me to diagnose or fix these problems, let me know what to try next.Regards, Brian
Posted Last updated
.
Post marked as solved
5 Replies
10k Views
I am having a bizarre problem relating to having an application and a framework (it's what we need to do for Watch or Today, or etc, right?), and a Swift view class I moved from the application to the framework. Because, Watch or Today, or etc..What's bizarre is, I literally moved the class from the app to the framework, I didn't modify the source code outside of adding a handful of "public" in front of the class name and related methods so that compilation would chill out. It was compiling and rendering cleanly for the application in the simulator, which has a main storyboard and a separate storyboard using the new storyboard reference feature. All targets except the legacy target (the application I am replacing) are iOS 9. I should mention that the class happens to have the same class name of a class in a legacy target that is Objective-C based, but neither the new target nor the framework are Objective-C based, both are pure Swift (yay, me!), and there is no relation to the legacy target.OK. So the problem. The main.storyboard happily soaks up the moved class, and renders it OK after the move. But when the storyboard reference loads a view controller containing the exact same class name, with the same Module name (the framework), it first logs "Unknown class &lt;yadda-yadda-deleted&gt; in Interface Builder file." and then promptly crashes (SEGV) attempting to accessing anything in the missing class.This is a fairly infuriating prolem. I don't know how to move forward. I saw on stackoverflow that there was a similar problem in Xcode 6 where if the Module name wasn't set, it might crash in a way like this. Only, both in the Main storyboard and the stoaryboard reference, the Module name is set. What gives?I'm not particularly inclined to figure out how to report this in standalone code to bugreporter, I'm much more keen to get advice, if anyone else has run into a similar problem and successfully worked around it.
Posted Last updated
.
Post not yet marked as solved
1 Replies
2.3k Views
I have XCUITest automation whose main purpose, beside testing, is to make clean, localized screenshots for use in the App Store. The storyboard view controllers contain UITextViews that do not dismiss on typing/tapping the return key. For the sake of argument, assume I am targeting iPad only--I have a solution for iPhone, because that needed another way to dismiss the keyboard anyway. I am having difficulty finding an XCUITest keyboard-dismissing solution that works across all devices, independently of Simulator settings and the test's locale settings.Nominally, the following appears to work for Englishif XCUIApplication().keyboards.buttons["Hide keyboard"].exists { XCUIApplication().keyboards.buttons["Hide keyboard"].tap() } if XCUIApplication().keyboards.buttons["Dismiss"].exists { XCUIApplication().keyboards.buttons["Dismiss"].tap() }However, if I specify another language, such as French, and region, such as France, in the Scheme, for either or both of the Run and Test targets, it fails, because (presumably) the keyboard accessibility labels are localized. Except for the "exists" tests above, the taps are essentially the same as what might recorded if I use the record feature in Xcode. There are two alternative button taps, depending in part on the toggle software keyboard setting.Is there a best practice for dismissing the keyboard, that is more straightforward and locale-agnostic?
Posted Last updated
.
Post marked as solved
2 Replies
1.3k Views
I have a UnitCurrency dimension and Money measurement type in RolePlayingCore, here on GitHub:https://github.com/mrlegowatch/RolePlayingCoreIt is failing to build or test in the latest Xcode 10.2 beta with Swift 5, and I'm getting lost in the documentation and error messages.To get you up to speed where I am at, I'll create a simplified use case, and walk you from Swift 4.2, to my Swift 5 conundrum.Let's say we are using Xcode 10.1 and Swift 4.2. Say we have two currencies, gp and cp, where one has a coefficient of 1 and the other 0.01:public class UnitCurrency : Dimension { static let gp = UnitCurrency(symbol: "gp", converter: UnitConverterLinear(coefficient: 1.0)) static let cp = UnitCurrency(symbol: "cp", converter: UnitConverterLinear(coefficient: 0.01)) }Let's implement a unit test point for confirming which one is the base unit, like this: XCTAssertEqual(UnitCurrency.baseUnit(), UnitCurrency.gp, "base unit should be gp")It will fail, as expected:XCTAssertEqual failed: throwing "*** You must override baseUnit in your class TestDimension.UnitCurrency to define its base unit." - base unit should be goldPiecesThe class is currently missing an implementation for the class func baseUnit(). The documentation for Foundation Dimension on https://developer.apple.com/documentation/foundation/dimensiondescribes a class func baseUnit() requirement, but suggests declaring a public static let in the section on "Creating a Custom NSDimension Subclass", like this: public static let baseUnit = gpThat doesn't work, as the test will still fail, so it appears that one must implement the class func after all, like this: public override class func baseUnit() -&gt; UnitCurrency { return gp }With that, the unit test point will pass.Let's further define a Money measurement for this unit:public typealias Money = Measurement&lt;UnitCurrency&gt;And, a unit test point with some assertions about how to combine money: let goldPieces = Money(value: 25, unit: .gp) let copperPieces = Money(value: 14, unit: .cp) let totalPieces = goldPieces - copperPieces XCTAssertEqual(totalPieces.value, 24.86, accuracy: 0.0001, "adding coins in gp") let totalPiecesInCopper = totalPieces.converted(to: .cp) XCTAssertEqual(totalPiecesInCopper.value, 2486, accuracy: 0.01, "adding coins in cp")The build and test succeeds. Next, we close the project, open it in Xcode 10.2 beta, and change the Swift version to 5 (note: using Convert &gt; To Current Swift Syntax does not produce any code changes), and now it complains about the declaration for class func baseUnit():Cannot override a Self return type with a non-Self return typeIf I change the return type to "Self", then instead I get this error message on the next line returning gp:Cannot convert return expression of type 'UnitCurrency' to return type 'Self'It has a fix-it suggestion to add "as! Self", which then results in a handful of warnings and errors, including a fix-it suggestion to remove "as! Self":Error: 'Self' is only available in a protocol or as the result of a method in a class; did you mean 'UnitCurrency'? Fix-it: Replace Self with UnitCurrency (which gets me back to the original error) Error: Cannot convert return expression of type 'UnitCurrency' to return type 'Self' Fix-it: Insert as! Self (so 'gp as! Self as! Self') Warning: Forced cast of 'UnitCurrency' to same type has no effect Fix-It: Replace 'as! Self' with '' (which gets me back to the previous error).Trying to use the static let also gets me back to the original problem in Swift 4.2.I'm kind of stuck now, seeking advice on what to try next.
Posted Last updated
.
Post not yet marked as solved
7 Replies
4.9k Views
I have a large-ish Xcode project that builds a framework, extension and application. The framework has logic tests, and embeds xcasset resources used by both the extension and the application. Some of the logic tests validate that all of the required xcassets can be found, so that when the application calls the framework to obtain them, they're in a known good state, and should never fail to load them. In particular, the framework wraps calls to UIImage(named: in:) with the bundle parameter set to the framework.Under Xcode 9.4, the logic tests run, verify that all of the required xcassets are present, and succeed. Under Xcode 10 beta 1, none of the xcassets can be found. I've used Clean Build Folder several times under both Xcode 9.4 and 10. Xcode 9.4 always succeeds, Xcode 10 spectacularly fails. If I build the application, it is able to launch, and run when built with Xcode 9.4, but with Xcode 10, the application also fails to find any framework xcassets, in the same way as the logic tests fail under Xcode 10. No code changes have been applied to any source code or the project settings yet (the exact same project assets and source code are being used in both cases).In the verbose build output, the only differences between the builds are:Xcode 10 is using full paths to xcasssets when invoking CompileAssetCatalogXcode 9.4 is exporting PATH before invoking actoolThe respective actool is being invoked (Xcode or Xcode-beta in the path)--filter-for-device-os-version is 12 for Xcode 10, and 11.4 for Xcode 9.4The resulting Assets.car file is 26.4 MB in size for Xcode 10, and 32.2 MB for Xcode 9.4.Does anyone have any ideas what might be going on, what I might check for, next? I'm not sure if this is an asset catalog compilation bug, but I would rule out an XCTest related build bug, since the application has the same problem as the logic tests.
Posted Last updated
.