Drag and Drop Contacts not working with macOS 13 Ventura - swiftui

The bounty expires in 13 hours. Answers to this question are eligible for a +50 reputation bounty.
iphaaw is looking for an answer from a reputable source.
The following code has been working fine in Monterey, but since upgrading to Ventura no longer allows a contact to be drag and dropped into my app.
let contactsUTTypes = [UTType.vCard, UTType.contact]
func performDrop(info: DropInfo) -> Bool
{
print (info)
let items = info.itemProviders(for: contactsUTTypes)
print (items)
for item in items
{
item.loadDataRepresentation(forTypeIdentifier: UTType.vCard.identifier, completionHandler: { (data, error) in
if let data = data,
let contact = try? CNContactVCardSerialization.contacts(with: data).first
{
print("Contact: \(contact.givenName)")
}
})
}
return true
}
It has been working fine up until I installed Ventura. Now when I drop a contact
let items = info.itemProviders(for: contactsUTTypes)
returns 0
Has anything changed in Ventura?

Related

lottie animation causing app crash on device

I am using Lottie to display animations in application and I tried to use this animation
AnimationURL
LottieView -
struct LottieView: UIViewRepresentable {
var animationName: String
func makeUIView(context: UIViewRepresentableContext<LottieView>) -> UIView {
let view = UIView()
return view
}
func updateUIView(_ uiView: UIViewType, context: Context) {
let animationView = AnimationView()
let animation = Animation.named(animationName)
animationView.animation = animation
animationView.contentMode = .scaleAspectFit
animationView.backgroundBehavior = .pauseAndRestore
animationView.loopMode = .loop
animationView.translatesAutoresizingMaskIntoConstraints = false
uiView.addSubview(animationView)
NSLayoutConstraint.activate([
animationView.heightAnchor.constraint(equalTo: uiView.heightAnchor),
animationView.widthAnchor.constraint(equalTo: uiView.widthAnchor)
])
animationView.play()
}
}
But when I want to display animation, application crashes in AnimatorNode file from Lottie library in this function (Thread 1: EXC_BAD_ACCESS (code=2, address=0x16ce6bff0)):
func updateContents(_ frame: CGFloat, forceLocalUpdate: Bool) -> Bool {
guard isEnabled else {
return parentNode?.updateContents(frame, forceLocalUpdate: forceLocalUpdate) ?? false
}
}
When I opened View Hierarchy after app crash, I received this log -
Failed to unarchive request data with error: Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set. around line 1, column 0." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set. around line 1, column 0., NSJSONSerializationErrorIndex=0}
On simulator, animation is running normally, but when I build application on device, application is crashing on this animation. Is there any way to fix this and use this animation?
We ran into the same issue.
It doesn't depend on SwiftUI / UIKit thing.
On Simulator it works ok because your simulator has more memory than iPhone does. So maybe your animation.json is too hard for current version of Lottie-ios lib. Maybe its good idea to report them, that they should update implementation of lib on iOS side.
Thank you!

Show downloaded mp4 inside a view like VStack and play it AVPlayer, SwiftUI

I'm working on the offline downloads section for a video streaming app. Currently, I'm able to download videos and also can see the file path for the downloads as follows:
Button(action: {
let fileManager = FileManager.default
do {
let resourceKeys : [URLResourceKey] = [.creationDateKey, .isDirectoryKey]
let documentsURL = try fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
let enumerator = FileManager.default.enumerator(at: documentsURL,
includingPropertiesForKeys: resourceKeys,
options: [.skipsHiddenFiles], errorHandler: { (url, error) -> Bool in
print("directoryEnumerator error at \(url): ", error)
return true
})!
for case let fileURL as URL in enumerator {
let resourceValues = try fileURL.resourceValues(forKeys: Set(resourceKeys))
// print(fileURL.path, resourceValues.creationDate!, resourceValues.isDirectory!)
print(fileURL.path)
self.array.append(fileURL.path)
}
} catch {
print(error)
}
}){
Text("Check downloads")
}
//response when button is clicked
/private/var/mobile/Containers/Data/Application/AD90B554-3465-43DD-BAE2-04BC83F850A3/Documents/Bz75srG5nctDCnAWIspM.mp4
/private/var/mobile/Containers/Data/Application/AD90B554-3465-43DD-BAE2-04BC83F850A3/Documents/GWYgrgDVYaowxeGcOjzp.mp4
Since I've renamed the mp4 files using movie ID's (eg: GWYgrgDVYaowxeGcOjzp.mp4) my goal is to use this name to show which videos were downloaded and allow users to play the video. I'm able to do the name processing later on, but how am I able to get the downloaded mp4 files into a view like a VStack? I was thinking of looping through and adding the files into an array but wanted to check if there's a different way. Also, would be great if you could show me how to play a video using the path as the url. I've tried applying suggested methods but ended up with a "NSURLConnection finished with error - code -1002" error. Thank you!

SwiftUI change output format of `Text` using as `.timer`

Is there a way to change the output format of a Text using init(_ date: Date, style: Text.DateStyle)?
Using a .timer, the output is like: 0:42, but I want something like 00:00:42.
Background
I want to create a widget (iOS 14) where a timer is running, and as I think it's not a good idea to trigger a widget update every second, and this may even also not work reliably, at least that's not how widget are indented to be used.
So I thought about using this predefined timer functionality of Text.
I'm quite new to SwiftUI and don't really know about all the capabilities yet. So maybe I could create a similar custom Text-View by myself? Any ideas on how to achieve this?
Or asked differently: Is there a way to create such self-updating components by oneself, that also work in an iOS 14 widget? (Seems like using Timer.publish to update the View does not work in an iOS 14 widget)
No solution => Workaround
As of today, there doesn't seem to be a proper solution for this. But as the interest in a "solution" or workaround for this seems to be there, I'll just post what I ended up with, for now.
Code
Basically I just manually update the Text once a second, and calculate the difference from the reference date to "now".
struct SomeView: View {
let referenceDate = Date() // <- Put your start date here
#State var duration: Int = 0
let timer = Timer.publish(every: 1, on: .current, in: .common).autoconnect()
var body: some View {
Text(self.duration.formatted(allowedUnits: [.hour, .minute, .second]) ?? "")
.onReceive(self.timer) { _ in
self.duration = referenceDate.durationToNow ?? 0
}
}
}
extension Date {
var durationToNow: Int? {
return Calendar.current
.dateComponents([.second], from: self, to: Date())
.second
}
}
extension Int {
func formatted(allowedUnits: NSCalendar.Unit = [.hour, .minute]) -> String? {
let formatter = DateComponentsFormatter()
formatter.allowedUnits = allowedUnits
formatter.zeroFormattingBehavior = .pad
return formatter.string(from: DateComponents(second: self))
}
}
WidgetKit limitations
This unfortunately does not work for WidgetKit, as the timer does not run or at least the UI does not refresh. So I ended up, only displaying minutes in the widget (which is kinda ok for my purpose) and just set an update in the "timeline" for each minute.

How to disable a button if textfields are empty in xcode 8 , swift 3

I just made my first app, when I run app and click button if textfields are empty ,it stops and I get an error
How do I disable button if textfields are empty so my app doesn't crash ?
I saw previous posts but nothing worked for me , it's for xcode8 swift 3
Will really appreciate any help , thank you
Btw it works fine if I fill all the textfields and then click buttons .
Zainee
First bind delegate of textfield to view controller.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let value = NSString(string: textField.text!).replacingCharacters(in: range, with: string)
if value.characters.count > 0 {
self.btnSubmit.isEnabled = true
} else {
self.btnSubmit.isEnabled = false
}
return true
}

Mapbox Map for first time users with no connectivity

I need help with displaying a default mapView to first-time users with no network connectivity. Then as soon as the network is available, load the mapView using the styleURL.
The latter part is taken care of, however, I'm still struggling with displaying the mapView for the first-time users using the local styles I downloaded from Mapbox:
let localURL = Bundle.main.url(forResource: "style", withExtension: "json")
if Reachability.isConnectedToNetwork() == true {
mapView = MGLMapView(frame: view.bounds, styleURL: styleURL)
...
} else {
mapView = MGLMapView(frame: view.bounds, styleURL: localURL)
...
}
Am I missing something?