Posts

Post not yet marked as solved
1 Replies
831 Views
Hi,I've got annotations on a MKMapView and I added a custom view inside the detailCalloutAccessoryView. This custom view performs a request and should present various amount of data depending on the request's reply. Basically, I can show 1 or 2 rows of data.Sometimes, when I touch an annotation and the result is only one row, the callout is not resized. However, if I dimiss the annotation and select it once again, it is rendered correctly.What is the "right" way to make it work? Using a intrinsicContentSize, or calling layoutIfNeeded (already tried, did not work)Thanks for your help.
Posted
by radada.
Last updated
.
Post not yet marked as solved
6 Replies
561 Views
Hi I'm trying to use the new PhaseAnimator from iOS 17 and I noticed a bug. For some reason, the animation is not deallocated when the view is removed from hierarchy, leading to a crash app. Example enum OuterBreathState: CaseIterable { case exhale, inhale var scale: CGFloat { switch self { case .inhale: return 2 case .exhale: return 1 } } var color: Color { switch self { case .inhale: return .white case .exhale: return .blue } } } struct PhaseView: View { var body: some View { PhaseAnimator(OuterBreathState.allCases) { state in Circle() .background(.clear) .frame(width: 150, height: 150) .padding(.vertical) .scaleEffect(state.scale) .background(in: Circle()) .foregroundStyle(state.color) } animation: {state in switch state { case .inhale: return .easeInOut(duration: 1.5) case .exhale: return .easeInOut(duration: 3.5) } } } } struct ContentView: View { var body: some View { NavigationStack { NavigationLink("push") { PhaseView() } } } } Pushing the view works just fine, but after popping, the app becomes unresponsive 😓 It's the content update that fails actually. If I make no updates to the Circle, everything works fine. I also tried with the phaseAnimator trailing function, I get the same behaviour. Interesting fact : if I use a trigger (and even a timer that flips that trigger to mimic the infinite loop), it does not crash the app. Here is the code enum OuterBreathState: CaseIterable { case exhale, inhale var scale: CGFloat { switch self { case .inhale: return 2 case .exhale: return 1 } } var color: Color { switch self { case .inhale: return .white case .exhale: return .blue } } } struct PhaseView: View { @State var animate = false let timer = Timer.publish(every: 5, tolerance: .zero, on: .main, in: .default).autoconnect() var body: some View { PhaseAnimator(OuterBreathState.allCases, trigger: animate) { state in Circle() .background(.clear) .frame(width: 150, height: 150) .padding(.vertical) .scaleEffect(state.scale) .background(in: Circle()) .foregroundStyle(state.color) } animation: {state in switch state { case .inhale: return .easeInOut(duration: 1.5) case .exhale: return .easeInOut(duration: 3.5) } } .onReceive(timer, perform: { _ in animate.toggle() }) .onTapGesture { animate.toggle() } } } struct ContentView: View { var body: some View { NavigationStack { NavigationLink("push") { PhaseView() } } } } #Preview { ContentView() } Any idea why it crashes and how I can make it work ? Thanks!
Posted
by radada.
Last updated
.
Post not yet marked as solved
1 Replies
779 Views
Hi ;-) I develop a framwork along with a testApp that both belongs to the same workspace. I added a file to my framework, it is in the Copy Ressources part of the Build Phases, I double checked the name, no issues here. I want to load this file using pretty straightforward code using [NSBundle bundleForClass: [self class]] as follows   NSBundle *bundle = [NSBundle bundleForClass: [self class]];   NSString *jsonPath = [bundle pathForResource:@"deviceSafeAreas" ofType:nil]; It always returns nil. The strange part is that if I print the bundlePath iVar, I get the same path for both [NSBundle mainBundle] and [NSBundle bundleForClass: [self class]]. I even tried to "force" the [self class] into [MyClass class], but I get the same result. If I inspect the derivedData, the file is present at the root of the framework This folder is inside ~/Library/Developer/Xcode/DerivedData/XXXXXX/Build/Products/Debug-iphonesimulator My guess is that since I do not really embeed the framework, but use it from the workspace, xcode messes things up and is not able to properly get the framework's bundle, mbut I may be wrong. Any help would be appreciated. thanks.
Posted
by radada.
Last updated
.
Post marked as solved
6 Replies
961 Views
Hi everyone, For various optimization purposes, I want to get the device's max display size without the safe areas for both portrait and lanscape. I can use the UIWindow's safeAreaInsets, but that only gives me the current safe areas, not the one for opposite layout (assuming there is only portrait and landscape). I had a look at UITraitCollections (I really thought I could achieve it with it), but it seems like a dead end. Anyone can help me with that ? Thanks!
Posted
by radada.
Last updated
.
Post not yet marked as solved
2 Replies
1.3k Views
Hi all :-) Very specific question today : I work for a company that produces an objC framework to many many clients and we want to know if we can update our framework to swift. To do so, we want to know if the framework is incorporated to pure objC projects or swift ones (depending on the version) I tried to search, but I can't find any clue on how to check this. If I incorporate a Swift file to our framework, objC only clients will see their compilation fail. I looked for .swiftinterface file w/o any luck too. Is there any way (even indirect with some preproc conditions and scripts) that can allow me to retrieve if our framework is used with a Swift project (or not) and if yes, which version of swift is used by our clients. Thanks for your help!
Posted
by radada.
Last updated
.
Post not yet marked as solved
1 Replies
1k Views
Hi all ;-) I'm using SPM to create various libraries. So far, I only had to localize strings, so I added a Resources folder, some .lproj data and a defaultLocalization in my Package.swift file. Now I'd like to localize some images in the XCAsset catalog, but when I click on "localize" on my image, the only localization that is proposed is the defaultLocalization from my Package.swift file (if I change "en" to "fr", I now get a "French" localize option, but English has gone). How can I make Xcode aware of the supported localization inside my package ? Thanks.
Posted
by radada.
Last updated
.
Post not yet marked as solved
4 Replies
2.0k Views
Hi all, I'm using AVAudioEngine to play multiple nodes at various times (like GarageBand for example). So far I managed to play the various files at the right time using this code : DispatchQueue.global(qos: .background).async {             AudioManager.instance.audioEngine.attach(AudioManager.instance.mixer)             AudioManager.instance.audioEngine.connect(AudioManager.instance.mixer, to: AudioManager.instance.audioEngine.outputNode, format: nil)           // !important - start the engine *before* setting up the player nodes           try! AudioManager.instance.audioEngine.start()                      for audioFile in data {             // Create and attach the audioPlayer node for this file             let audioPlayer = AVAudioPlayerNode()             AudioManager.instance.audioEngine.attach(audioPlayer)             AudioManager.instance.nodes.append(audioPlayer)             // Notice the output is the mixer in this case             AudioManager.instance.audioEngine.connect(audioPlayer, to: AudioManager.instance.mixer, format: nil)             let fileUrl = audioFile.audio.fileUrl             if let file : AVAudioFile = try? AVAudioFile.init(forReading: fileUrl) {                 let time = audioFile.start > 0 ? AudioManager.instance.secondsToAVAudioTime(hostTime: mach_absolute_time(), time: Double(audioFile.start / CGFloat.secondsToPoints)) : nil                 audioPlayer.scheduleFile(file, at: time, completionHandler: nil)                 audioPlayer.play(at: time)             }           }         } Basically my data object contains struct that have a reference to an audio fileURL and the startPosition at which it should begin. That works great. now I would like to export all these tracks mixed into a single file and save it to the Document's directory of the user. How can I achieve this? Thanks for your help.
Posted
by radada.
Last updated
.
Post not yet marked as solved
0 Replies
395 Views
Hi all ;-) I'm working on a library that crashes if the user stresses the iPhone with many language changes. Weird because this lib has no UI (and no localisable content) but heavily relies on the Keychain and disk writing. I was wondering if some Apple engineer can give me some information about what happens in iOS when a language change is triggered, so that I can find a clue of what's going on. Thanks
Posted
by radada.
Last updated
.
Post marked as solved
2 Replies
1.2k Views
Hi everyone ;-) I use SPM for quite a while now, but it's been a week now since I started having refresh and checking out issues. It's either "the SSL certificate is not valid" or an unknown error occured". Sometimes, after trying and trying, the SPM update or version check succeeds, but it's a real pain the a**. Before, I did not have so many issues. Is there something wrong with GitHub or Xcode theses days ? For the record, I'm working on 2 projects that have common packages, and it seems that Xcode does not handle that very well, especially when I drag n drop a package onto my project to use it as a local package. Thanks for your help
Posted
by radada.
Last updated
.
Post marked as solved
5 Replies
2.7k Views
Hi everyone ;-) Weird behavior here. I develop an app that works fine under iOS 14.x (any subversion). It's a classic storyboard/swift app. It is supposed to be compatible with iOS 13.x devices but when I launch it, I get a crash right away, no crash log, no report, and not in a method or class that I developed :-/ It seems that I tries to load a SwiftUI object (State object) and doesn't find it, which is pretty logical. Th thing is : I don't use SwiftUI in my code (besides maybe the SceneDelegate ? ) Here is the only data I can gather dyld: Symbol not found: _$s7SwiftUI11StateObjectVMn Referenced from: /Users/gg/Library/Developer/CoreSimulator/Devices/9EADF5C5-D5E6-46F8-8A99-98801D5F67FD/data/Containers/Bundle/Application/C9272BF0-688C-4DA4-8799-B9E335155905/taxi.Chauffeur.app/taxi.Chauffeur Expected in: /System/Library/Frameworks/SwiftUI.framework/SwiftUI in /Users/gg/Library/Developer/CoreSimulator/Devices/9EADF5C5-D5E6-46F8-8A99-98801D5F67FD/data/Containers/Bundle/Application/C9272BF0-688C-4DA4-8799-B9E335155905/taxi.Chauffeur.app/taxi.Chauffeur dyld: launch, loading dependent libraries DYLD_SHARED_CACHE_DIR=/Users/gg/Library/Developer/CoreSimulator/Caches/dyld/20D91/com.apple.CoreSimulator.SimRuntime.iOS-13-7.17H22 DYLD_ROOT_PATH=/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.7.simruntime/Contents/Resources/RuntimeRoot DYLD_LIBRARY_PATH=/Users/gg/Library/Developer/Xcode/DerivedData/taxi.Chauffeur-ceaclbvdpopdwqdodbmzcecwohzz/Build/Products/Debug-iphonesimulator:/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.7.simruntime/Contents/Resources/RuntimeRoot/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.7.simruntime/Contents/Resources/RuntimeRoot/usr/lib/libBacktraceRecording.dylib:/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.7.simruntime/Contents/Resources/RuntimeRoot/usr/lib/libMainThreadChecker.dylib:/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.7.simruntime/Contents/Resources/RuntimeRoot/Developer/Library/PrivateFrameworks/DTDDISupport.framewor Any help would be most appreciated. Thanks.
Posted
by radada.
Last updated
.
Post not yet marked as solved
6 Replies
4.3k Views
Hi, pretty dumb question, but how can we debug a widget, especially a TimelineProvider ? I added breakpoints, print statements, it seems that I never refresh my Widget :-/ When a user adds some content in my app, I save the data to a shared UserDefauls as follows func save() {         let encoder = JSONEncoder()         if let data = try? encoder.encode(self) {             UserDefaults.group.set(data, forKey: "lastPost")             UserDefaults.group.synchronize()             WidgetCenter.shared.getCurrentConfigurations { (result) in                 guard case .success(let widgets) = result else { return }                 widgets.forEach { widget in                     WidgetCenter.shared.reloadTimelines(ofKind: widget.kind)                 }             }         }     } Here is my TimeLineProvider struct Provider: TimelineProvider {     @AppStorage("lastPost", store: UserDefaults(suiteName: "group.com.kaiman.apps")) var currentModelData: Data?     var currentModel: ExtensionSharedModel? {         guard let data = currentModelData else { return nil }         return ExtensionSharedModel.retrieve(from: data)     }        func placeholder(in context: Context) -> WidgetModelEntry {         print("🏵 placeholder")         return WidgetModelEntry(date: Date())     }     func getSnapshot(in context: Context, completion: @escaping (WidgetModelEntry) -> ()) {         print("🏵 getSnapshot")         let currentDate = Date()         if let model = currentModel, model.date.isToday {             print("🏵 add model \(model.displayName)")             completion(WidgetModelEntry(date: currentDate, model: model))         } else {             print("🏵 no models to add...")             completion(WidgetModelEntry(date: currentDate))         }     }     func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {         print("🏵 getTimeline")         var entries: [WidgetModelEntry] = []         // Generate a timeline consisting of five entries an hour apart, starting from the current date.         let currentDate = Date()         if let model = currentModel, model.date.isToday {             print("🏵 add model \(model.displayName)")             entries = [WidgetModelEntry(date: currentDate, model: model),                        WidgetModelEntry(date: currentDate.dateAtEndOf(.day), model: model)]         } else {             print("🏵 no models to add...")             entries = [WidgetModelEntry(date: currentDate.dateAtEndOf(.day))]         }         let timeline = Timeline(entries: entries, policy: .atEnd)         completion(timeline)     } } I can't see what am I doing wrong :-/ I do enter in the WidgetCenter.shared.reloadTimelines(ofKind: widget.kind) , the data is saved to the shared UD. Thanks for your help
Posted
by radada.
Last updated
.
Post not yet marked as solved
0 Replies
499 Views
Hi guys, It's been a long since I used a pretty neat code that slightly animates some shadows to give life to my apps. func addShadowMotion() {         let horizontalEffect = UIInterpolatingMotionEffect(             keyPath: "layer.shadowOffset.width",             type: .tiltAlongHorizontalAxis)         horizontalEffect.minimumRelativeValue = 16         horizontalEffect.maximumRelativeValue = -16                  let verticalEffect = UIInterpolatingMotionEffect(             keyPath: "layer.shadowOffset.height",             type: .tiltAlongVerticalAxis)         verticalEffect.minimumRelativeValue = 16         verticalEffect.maximumRelativeValue = -16                  let effectGroup = UIMotionEffectGroup()         effectGroup.motionEffects = [ horizontalEffect,                                       verticalEffect ]                  addMotionEffect(effectGroup)     } As stipulated, it worked fine until the last iOS update. Now, the shadow move half the screen as you can see :-/ Any ideas ? Thanks. Image link: (remove the extra space) https ://ibb.co/prMz6Tg
Posted
by radada.
Last updated
.
Post not yet marked as solved
0 Replies
513 Views
Hi everyone ;-) I'm currently developing an app that is synced to a BT device. This BT device has 2 states (let's say ON and OFF though it is still powered on, like a bulb). When I connect to the peripheral, I get 2 characteristics : a write and a read characteristic. In order to retrieve the current state, I have to send a write frame that basically ask the peripheral to give me its current state. As a response, I get a frame that contains the current peripheral state. If I connect to the peripheral, ask the state (ON for instance), I receive ON. I turn the peripheral OFF, I receive OFF. Now I kill my app and launch it again. The app will reconnect to the peripheral, ask the current state. The response is OFF. So far so good.... I can keep on changing the peripheral state, I always retrieve the last state of the peripheral when I relaunch the app. Now for the weird part : I do exactly the same operations, but before launching my app, I switch again the peripheral state (in the above example, it would now be ON). I launch the app, send a write frame to the peripheral, and the response is ... OFF. One could argue that it is a peripheral issue, but fellow colleagues on Android do not have this bug, so I guess it's on my side. Just for the record, here are my BT implementation, which is pretty straightforward. extension BluetoothManager: CBPeripheralDelegate {         func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {         log("didDiscoverCharacteristicsFor \(service)")         if let characteristics = service.characteristics {             for characteristic in characteristics {                 if let chara = ATACharacteristics.from(characteristic) {                     switch chara {                     case .write:                         log("write  ATACharacteristics\(characteristic)")                         peripheral.setNotifyValue(true, for: characteristic)                         self.characteristics.append(chara)                         readStateFromBox(characteristic)                                              case .read:                         log("read  ATACharacteristics\(characteristic)")                         self.characteristics.append(chara)                                              case .nus: ()                     }                 }             }         }     }       func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {         log("didUpdateValueFor \(characteristic)")         if let data = characteristic.value,            let validator = try? ATAFrameDecoder().decode(data) as? LuminousStatusFrameValidator {             log("   data \(data as NSData)")             updateState(from: validator)         }     }     func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {         log("didWriteValueFor \(characteristic)")         if let data = characteristic.value,            let validator = try? ATAFrameDecoder().decode(data) as? LuminousStatusFrameValidator  {             log("   data \(data as NSData)")             updateState(from: validator)         }     } } Here are although the logs for both scenarios. When receiving the didWrite frame, if I get a "00" after "02a00461" it means ON, if I get a "fe", it means OFF First the good one : 📲 centralManagerDidUpdateState poweredOn 📲 didDiscoverServices <CBPeripheral: 0x281508000, identifier = A274CD79-938C-CAEF-2CE7-D20CB5B6961F, name = ATA-000008, state = connected> 📲 didDiscoverCharacteristicsFor <CBService: 0x2831a5280, isPrimary = YES, UUID = 6E400001-B5A3-F393-E0A9-E50E24DCCA9E> 📲 read&#9;ATACharacteristics<CBCharacteristic: 0x280006100, UUID = 6E400002-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0xC, value = (null), notifying = NO> 📲 write&#9;ATACharacteristics<CBCharacteristic: 0x2800044e0, UUID = 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0x10, value = {length = 13, bytes = 0x02a00461fe0000000000122903}, notifying = NO> 📲 readStateFromBox {length = 9, bytes = 0x02a50000000001a603} for <CBCharacteristic: 0x2800044e0, UUID = 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0x10, value = {length = 13, bytes = 0x02a00461fe0000000000122903}, notifying = NO> 📲 didUpdateNotificationStateFor <CBCharacteristic: 0x2800044e0, UUID = 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0x10, value = {length = 13, bytes = 0x02a00461fe0000000000122903}, notifying = YES> 📲 didWriteValueFor <CBCharacteristic: 0x2800044e0, UUID = 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0x10, value = {length = 13, bytes = 0x02a00461fe0000000000122903}, notifying = YES> 📲&#9;&#9;data {length = 13, bytes = 0x02a00461fe0000000000122903} 📲 updateState occupied 📲 acknowledge {length = 9, bytes = 0x0206a000000003a703} for Optional(<CBCharacteristic: 0x2800044e0, UUID = 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0x10, value = {length = 13, bytes = 0x02a00461fe0000000000122903}, notifying = YES>) and then the bug 📲 centralManagerDidUpdateState poweredOn 📲 didDiscoverServices <CBPeripheral: 0x2839885a0, identifier = A274CD79-938C-CAEF-2CE7-D20CB5B6961F, name = ATA-000008, state = connected> 📲 didDiscoverCharacteristicsFor <CBService: 0x281dd5100, isPrimary = YES, UUID = 6E400001-B5A3-F393-E0A9-E50E24DCCA9E> 📲 read&#9;ATACharacteristics<CBCharacteristic: 0x282c88300, UUID = 6E400002-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0xC, value = (null), notifying = NO> 📲 write&#9;ATACharacteristics<CBCharacteristic: 0x282c881e0, UUID = 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0x10, value = {length = 13, bytes = 0x02a0046100000000000013d603}, notifying = NO> 📲 readStateFromBox {length = 9, bytes = 0x02a50000000001a603} for <CBCharacteristic: 0x282c881e0, UUID = 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0x10, value = {length = 13, bytes = 0x02a0046100000000000013d603}, notifying = NO> 📲 didUpdateNotificationStateFor <CBCharacteristic: 0x282c881e0, UUID = 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0x10, value = {length = 13, bytes = 0x02a0046100000000000013d603}, notifying = YES> 📲 didWriteValueFor <CBCharacteristic: 0x282c881e0, UUID = 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0x10, value = {length = 13, bytes = 0x02a0046100000000000013d603}, notifying = YES> 📲&#9;&#9;data {length = 13, bytes = 0x02a0046100000000000013d603} 📲 updateState free 📲 acknowledge {length = 9, bytes = 0x0206a000000003a703} for Optional(<CBCharacteristic: 0x282c881e0, UUID = 6E400003-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0x10, value = {length = 13, bytes = 0x02a0046100000000000013d603}, notifying = YES>) Is there some kind of cache on BT exchanges ? I don't know why it reacts like that. Thanks for your help.
Posted
by radada.
Last updated
.
Post marked as solved
2 Replies
544 Views
Hi everyone, I can't find any of the last builds I uploaded on AppStoreConnect. There isn't any "activity" view anymore and they don't appear anywhere (uploaded just with a warning that worked until now, no errors). I received the email from Apple too. If I try to upload again using transporter, I get an "build already exists" error, so my builds are definitively on appstoreconnect. Anyone experiencing this bug? Thanks.
Posted
by radada.
Last updated
.
Post not yet marked as solved
0 Replies
478 Views
Hi all, I encountered a weird behavior today : I've got a collectionView, a struct file (with the proper Hashable protocol implemented). Everything works fine ... the first time. When my model changes, I trigger a reload using the same code as the first time : datasource.apply(snap, animatingDifferences: animatingDifferences, completion: completion) I do enter in the datasource'z completion block. The cell is dequeued, I do enter in the configure method (where I change some stuff). My model is properly updated too. let dataSource = DataSource(collectionView: collectionView) { [weak self] (collection, indexPath, model) -> UICollectionViewCell? in &#9;&#9;&#9;&#9;&#9;&#9;guard let cell: VehicleCell = collectionView.automaticallyDequeueReusableCell(forIndexPath: indexPath) else { return nil } &#9;&#9;&#9;&#9;&#9;&#9;cell.configure(model) &#9;&#9;&#9;&#9;&#9;&#9;cell.vehicleDelegate = self?.vehicleDelegate &#9;&#9;&#9;&#9;&#9;&#9;return cell &#9;&#9;&#9;&#9;} &#9;&#9;func configure(_ vehicle: Vehicle) { &#9;&#9;&#9;&#9;self.vehicle = vehicle &#9;&#9;&#9;&#9;print("🚖 \(vehicle.model) - \(vehicle.isCurrentVehicle ? "👍" : "👹")") &#9;&#9;} If I log the model in the configure method, I do have the good values ... but the cells are never updated 🚖 Coupé Série 1 - 👹 🚖 207SW - 👍 🚖 207SW - 👍 🚖 Coupé Série 1 - 👹 🚖 Coupé Série 1 - 👍 🚖 207SW - 👹 🚖 Coupé Série 1 - 👹 🚖 207SW - 👍 How can a cell can be updated and configured and not update visually ? Thanks
Posted
by radada.
Last updated
.