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.
Post
Replies
Boosts
Views
Activity
Hi everyone
I'm struggling with this d*** FB SDK :-/
Basically, I've got an app that is supposed to post content to a FB Page. To achieve that, I login using the FB sdk. Then I request authorisations as follow
LoginManager().logIn(permissions: ["pages_manage_posts", "pages_read_engagement", "pages_show_list"], viewController: controller) { result in
										print("res \(result)")
										switch result {
										case .success:
												// the pageId is in data>id
												Defaults[\.facebookSwitchOn] = true
												GraphRequest.init(graphPath: "me/accounts").start { (connexion, result, error) in
														guard let result = result as? [String:Any],
																	let dataArray = result["data"] as? Array<Any>,
																	let data = dataArray.first as? [String:Any],
																	let pageId = data["id"] as? String,
																	let access = data["access_token"] as? String else { return }
														print("\(pageId)")
														Defaults[\.facebookPageId] = pageId
														Defaults[\.facebookPageAccessToken] = access
												}
												completion(true)
										case .failed(let error):
												completion(false)
												MessageManager.show(.basic(.custom(title: "Oups".local(), message: error.localizedDescription, buttonTitle: nil, configuration: MessageDisplayConfiguration.alert)), in: controller)
										default: ()
										}
								}
I save the pageId and TokenID to be able to perform a POST request as follow
GraphRequest
										.init(graphPath: "\(pageId)/photos",
//										parameters: ["source" : image, "caption" : text, "access_token" : token, "published" : false],
												parameters: ["caption" : contentDescription, "url" : "https://www.cdiscount.com/pdt2/9/2/8/1/700x700/889698377928/rw/figurine-funko-pop-deluxe-game-of-thrones-daen.jpg", "access_token" : token],
												httpMethod: .post)
										.start { (connexion, result, error) in
										completion(Result.success(true))
								}
However, I get a weird error telling that publish_actions has been deprecated.
I logged the request using Charles, and here it is
(https:// ibb.co/89wPgKx) (remove the space after the // )
Now here is the debug from the GraphAPI explorer :
curl -i -X POST \ "https://graph.facebook.com/v7.0/104226051340555/photos?caption=test%20message%20from%20Graph%20API%20for%20photo&url=https%3A%2F%2Fwww.cdiscount.com%2Fpdt2%2F9%2F2%2F8%2F1%2F700x700%2F889698377928%2Frw%2Ffigurine-funko-pop-deluxe-game-of-thrones-daen.jpg&access_token=<access token sanitized>"
Basically, it is the same request excepting the fact that parameters in the explorer are URL parameters and they are encapsulated in a json.
I can't understand why the graph explorer request succeeds while the SDK request fails.
I'm totally stuck :-/
Thanks for your help.
Hi all,
I've got a pretty simple app (basically a Hootsuite like and light).
I'd was hoping to create a widget that show the last post if it is today, or an view that encourages the user to create a new post.
To that purpose, I create a Codable model that I store in the shared UserDefaults (suiteName) and when I do so, I call the fefrshtimeline as follows :
func save() {
let encoder = JSONEncoder()
if let data = try? encoder.encode(self) {
UserDefaults.group.set(data, forKey: "lastPost")
WidgetCenter.shared.getCurrentConfigurations { (result) in
guard case .success(let widgets) = result else { return }
widgets.forEach { widget in
WidgetCenter.shared.reloadTimelines(ofKind: widget.kind)
}
}
}
}
The thing is, I put a print in the timeLine and it's never called. I also tried to change the snapShot method, nothing works so far.
Here are both methods from the Widget :
func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
print("🏵 getSnapshot")
if let model = ExtensionSharedModel.retrieve(), model.date.isToday {
print("🏵 add model \(model.displayName)")
completion(SimpleEntry(date: Date(), model: model))
} else {
print("🏵 no models to add...")
completion(SimpleEntry(date: Date()))
}
}
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
print("🏵 getTimeline")
var entries: [SimpleEntry] = []
if let model = ExtensionSharedModel.retrieve(), model.date.isToday {
print("🏵 add model \(model.displayName)")
entries = [SimpleEntry(date: Date(), model: model)]
} else {
print("🏵 no models to add...")
entries = [SimpleEntry(date: Date())]
}
let timeline = Timeline(entries: entries, policy: .atEnd)
completion(timeline)
}
The widget is static configuration widget.
I do enter in WidgetCenter.shared.reloadTimelines, but never in the protocol methods.
Thanks for your help :-)
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
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.
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
						guard let cell: VehicleCell = collectionView.automaticallyDequeueReusableCell(forIndexPath: indexPath) else { return nil }
						cell.configure(model)
						cell.vehicleDelegate = self?.vehicleDelegate
						return cell
				}
		func configure(_ vehicle: Vehicle) {
				self.vehicle = vehicle
				print("🚖 \(vehicle.model) - \(vehicle.isCurrentVehicle ? "👍" : "👹")")
		}
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
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.
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	ATACharacteristics<CBCharacteristic: 0x280006100, UUID = 6E400002-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0xC, value = (null), notifying = NO>
📲 write	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>
📲		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	ATACharacteristics<CBCharacteristic: 0x282c88300, UUID = 6E400002-B5A3-F393-E0A9-E50E24DCCA9E, properties = 0xC, value = (null), notifying = NO>
📲 write	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>
📲		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.
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
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.
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
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.
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
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!
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!