Discuss Swift.

Swift Documentation

Post

Replies

Boosts

Views

Activity

Swift Macros: Adding an enum case with an associated value produces incorrect results
Reproduced in Xcode versions 15.0.1 and 15.1 beta 3. If a Macro adds an enum case with an associated value, other cases are transformed at runtime. In the example below, the case foo is translated into the Macro-generated case bar(false). There is lots of other strange behavior, such as: Case declarations in the same file as the enum are not transformed. For example, in the code above, a function written in SimpleEnum.swift can produce SimpleEnum.foo, whereas functions in other files cannot (the declarations are transformed). Manually-defined cases with associated values are not transformed. For example, a manually-defined case foobar(Bool) can be declared and used normally everywhere. Additional enum cases without associated values get transformed to different cases. For example, if SimpleEnum has manual cases foo, foobar, and foobarfoo, and a Macro-generated bar(Bool), these transformations take place: foo -> bar(false) foobar -> bar(true) foobarfoo -> foo etc. Not all associated value types in the Macro-generated case are treated the same. String associated values seems to work properly. Int yields incrementing transformations (e.g. foo -> bar(0), foobar -> bar(1), foobarfoo -> bar(2)) Radar: FB13417290
3
3
1.2k
Nov ’23
NavigationLink and CustomStyle BackButton
Hi Guys, sorry if I am writing some nonsense, but I am just starting to create apps in Swift. I'm creating an app just for AppleWatch and I don't want to use the default backbutton that appears with navigationLink. How can I change the appearance? I'll put a diagram of my code here: NavigationStack { VStack { NavigationLink(...) { HStack { ... } } .buttonStyle(PlainButtonStyle()) .frame(height: 80) .foregroundColor(.black) .fontWeight(.bold) .tracking(-0.5) } } Everything I find on the Internet is for navigationView which I read is deprecated. I found again on google a site that recommends using .toolbar, but the button does not change. What am I doing wrong? What can I do? Thanks
0
0
161
Nov ’23
How to set the Anchors Points of a PDF in PDFKit?
I am trying to set the top anchor point of a pdf that is inside of a view with the .ignoresSafeArea() modifier. I would also like it to work on the edges when the phone is in landscape although for simplicity I will only explain what I want for the top. I want it to function like the iOS Files app pdf viewer where when tapped it hides the navigation bars but the top of the pdf stays at the same place, but when you zoom in on the pdf it can fill the whole screen. When you zoom back out the top should return to the same place as before. Here is a simple view to show how it is being used: @MainActor struct ContentView: View { @State var showBars: Bool = true @State var pdfUrl: URL? var body: some View { NavigationStack { GeometryReader { geo in ScrollView { TabView { if let url = pdfUrl { PDFViewer(pdfUrl: url) .onTapGesture { withAnimation { showBars.toggle() } } } } .tabViewStyle(.page(indexDisplayMode: .never)) .frame(width: geo.size.width, height: geo.size.height) } .scrollDisabled(true) } .ignoresSafeArea(edges: !showBars ? .all : []) } .task { pdfUrl = renderPDF() } } func renderPDF() -> URL { let renderer = ImageRenderer(content: VStack {}) let url = URL.documentsDirectory.appending(path: "samplepdf.pdf") renderer.render { size, context in guard let pdf = CGContext(url as CFURL, mediaBox: nil, nil) else { return } pdf.beginPDFPage(nil) context(pdf) pdf.endPDFPage() pdf.beginPDFPage(nil) context(pdf) pdf.endPDFPage() pdf.closePDF() } return url } } And here is what my pdfView looks like so far: struct PDFViewer: View { var pdfUrl: URL var body: some View { PDFSheetView(document: .init(url: pdfUrl)) } } class PDFViewController: UIViewController { let document: PDFDocument? var pdfView: PDFView! init(document: PDFDocument?) { self.document = document super.init(nibName: nil, bundle: nil) } override func loadView() { let view = PDFView() self.view = view self.pdfView = view view.document = document view.displayDirection = .vertical view.autoScales = true view.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true view.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true view.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true } required init?(coder: NSCoder) { document = nil super.init(coder: coder) return nil } override func viewDidLayoutSubviews() { let bounds = view.bounds if let document { if let page = document.page(at: 0) { let pageBounds = page.bounds(for: .mediaBox) if bounds.width > 0 && pageBounds.width > 0 { let scaleFactor = bounds.width / pageBounds.width let subtractionFactor = scaleFactor * 0.0125 pdfView.minScaleFactor = scaleFactor - subtractionFactor } } } } } struct PDFSheetView: UIViewControllerRepresentable { typealias UIViewControllerType = PDFViewController let document: PDFDocument? func makeUIViewController(context: Context) -> PDFViewController { let controller = PDFViewController(document: document) return controller } func updateUIViewController(_ uiViewController: PDFViewController, context: Context) { } } Is this possible to do? Like I said before, I want it to function just like the iOS Files app pdf viewer.
0
0
443
Nov ’23
Swift Regex crashes when trying to get a simple string
I'm trying to create a simple Regex Builder to parse a timestamp in hh:mm:ss or mm:ss format, a " - " separator, and then a string. I'm trying to use the new Swift RegexBuilder however it doesn't seem to work. It compiles but crashes when running when trying to get the text portion. Example code in a single playground preview file for reference: import SwiftUI import RegexBuilder struct RegexTestView: View { var string: String { let timecode = Regex { Optionally { OneOrMore(.whitespace) } // timecode section Optionally { Capture { OneOrMore(.digit) } transform: { match in Int(match) } ":" } TryCapture { OneOrMore(.digit) } transform: { match in Int(match) } ":" // seconds TryCapture { OneOrMore(.digit) Optionally { // miliseconds "." OneOrMore(.digit) } } transform: { match in TimeInterval(match) } // separator " - " Capture { // WHY CAN'T I GET THE REMAINING TEXT???? Any attempts I make to get this result in a crash. OneOrMore(.any) } transform: { match in String(match) } } let tests = [" 222:45:23.2 - foo","2:34:22 - bar"," 2:08 - baz","2:32.18","2:45:23.2 - what"] var results = "" for test in tests { guard let match = test.wholeMatch(of: timecode) else { results += "MATCH NOT FOUND" continue } results += """ •••• \(match.0) \(String(describing: match.1)) \(String(describing: match.2)) \(String(describing: match.3)) """ /* // Adding this line to the above crashes \(String(describing: match.4))\n */ } return results } var body: some View { Text(string) } } #Preview("Regex") { RegexTestView() }
1
0
634
Nov ’23
Unable to get WiFi rssi value
I want to create a function which will return the rssi value of currently connected WiFi network on my iPhone. I tried fetching the value from status bar but I guess that support is no longer provided in Swift. I have tried the following solution and other solutions with similar approach but it doesn't seem to work now. private func wifiStrength() -> Int? { let app = UIApplication.shared var rssi: Int? guard let statusBar = app.value(forKey: "statusBar") as? UIView, let foregroundView = statusBar.value(forKey: "foregroundView") as? UIView else { return rssi } for view in foregroundView.subviews { if let statusBarDataNetworkItemView = NSClassFromString("UIStatusBarDataNetworkItemView"), view .isKind(of: statusBarDataNetworkItemView) { if let val = view.value(forKey: "wifiStrengthRaw") as? Int { //print("rssi: \(val)") rssi = val break } } } return rssi }
1
0
1.1k
Nov ’23
EKEventStore().requestFullAccessToEvents() doesn't work with iOS 17
We don't need to add -- latest functions for iOS-17 as it introduces requestFullAccessToEvents. if #available(iOS 17.0, *) { eventStore.requestFullAccessToEvents(completion: { (granted: Bool, _: Error?) -> Void in completion(granted) }) } else { // Fallback on earlier versions eventStore.requestAccess(to: .event, completion: { (granted: Bool, _: Error?) -> Void in completion(granted) }) } Solution for iOS 17 Calendar request authorization is to add two keys in Info.plist file including previous key i.e. NSCalendarsUsageDescription <string>We need this permission in order to set reminders for you</string> <key>NSCalendarsWriteOnlyAccessUsageDescription</key> <string>We need this permission in order to set reminders for you</string>
0
0
431
Nov ’23
JsonElement
Hello! Kotlin has such a wonderful thing as JsonElement, which allows you to postpone the decoding of dynamic json fields until better times. Is there an analogue in Swift Decodable?
0
0
249
Nov ’23
Xcode's implementation of Localisation is so odd
Localising my app I found the entire process quite un-swift like (i.e. unsafe and unintuitive) and was not the only one, even the great Paul Hudson also thought it a strange implementation. Following a tutorial by Andrii Halabuda (https://www.youtube.com/watch?v=_PBA20ZVk1A) relying on an Enum to reduce errors, I found that the strings needed in the "Localizable.strings" strings file could not be avoided. I have not tried localisation in SwiftUI, I see that it is different, is it easier i.e. can Plists and such be avoided ? Is there any word on deeper integration that is just more like a normal method ?
2
0
656
Nov ’23
Deeper SVG integration into Xcode ?
Exporting SVG (XML) data for something like a six sided shape (hexagon) requires a piecemeal approach and very specific string needed for the XML to be rendered correctly: svgData += "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n" svgData += "<svg width=\"\(viewWidth)\" height=\"\(viewHeight)\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">\n" But there is also the addition of the obligatory prefix "M", followed by co-ordinate date, the postfixed "Z" finishing with path and colour data: <path d=\"\(svgPathData)\" fill=\"\(randomColourSVG)\" /> \n The trouble I ran into was the all important middling section that contained the x/y path data for multiple sides shapes. Could this not simply be a method to pass through from UIBezierPath or CAShapeLayer so that Xcode does this for me, much like the convenience of .cgColor used after a UIColor ? Basically, is SVG likely to get deeper integration ?
0
0
306
Nov ’23
UIBezierPath shape positioning
The following function creates a hexagon shape but as I collect the six pieces of the shape to plot into SVG co-ordinates, the x/y data is not positioning them correctly: var positionX: CGFloat = 0 var positionY: CGFloat = 0 if isFirstShape == true { // ENSURE USER SATISFACTION WITH ONE SHAPE PLACED WHERE FINGER TAPS positionX = touchLocation.x positionY = touchLocation.y } else { positionX = CGFloat.random(in: touchLocation.x - 200...touchLocation.x + 200) positionY = CGFloat.random(in: touchLocation.y - 200...touchLocation.y + 200) } let randomLength: CGFloat = CGFloat.random(in: 100...150) let randomColour: UIColor = getRandomColor(withProbabilities: colorProbabilities) let rectangle : CGRect = CGRect(x: positionX, y: positionY, width: randomLength, height: randomLength) let cornerRadius: CGFloat = 10.0 // ROUNDING CORNER VALUE var angle : CGFloat = CGFloat(0.5) // ROTATE HEXAGON 90º let sides : Int = 6 let path = UIBezierPath() var svgPathData = "M" // SVG : PATH DATA (START) let theta : CGFloat = CGFloat(2.0 * Double.pi) / CGFloat(sides) let radius : CGFloat = (rectangle.width + cornerRadius - (cos(theta) * cornerRadius)) / 2.0 let center : CGPoint = CGPoint(x: rectangle.origin.x + rectangle.width / 2.0, y: rectangle.origin.y + rectangle.width / 2.0) // DETERMINE STARTING POINT FOR DRAWING ROUNDED CORNERS let corner : CGPoint = CGPoint(x: center.x + (radius - cornerRadius) * cos(angle), y: center.y + (radius - cornerRadius) * sin(angle)) // MOVE PATH TO NEW POSITION ACCOUNTING FOR THE ROUNDED CORNER ANGLE path.move(to: CGPoint(x: corner.x + cornerRadius * cos(angle + theta), y: corner.y + cornerRadius * sin(angle + theta))) // SVG : POSITIONING DATA svgPathData += " \(corner.x) \(corner.y)" for _ in 0..<sides { angle += theta // POINT ON THE CIRCUMFERENCE OF THE CIRCLE : DETERMINED BY THE ANGLE let corner = CGPoint(x: center.x + (radius - cornerRadius) * cos(angle), y: center.y + (radius - cornerRadius) * sin(angle)) // ONE OF SIX POINTS : DETERMINED BY RADIUS AND ANGLE let tip = CGPoint(x: center.x + radius * cos(angle), y: center.y + radius * sin(angle)) let start = CGPoint(x: corner.x + cornerRadius * cos(angle - theta), y: corner.y + cornerRadius * sin(angle - theta)) let end = CGPoint(x: corner.x + cornerRadius * cos(angle + theta), y: corner.y + cornerRadius * sin(angle + theta)) path.addLine(to: start) // CONTROL POINT : INFLUENCE THE SHAPE / DIRECTION OF CURVE path.addQuadCurve(to: end, controlPoint: tip) svgPathData += " \(corner.x) \(corner.y)" // SVG : POSITIONING DATA } path.close() let bounds = path.bounds // MOVE POINTS IN RELATION TO ORIGINAL RECTANGLE DATA let transform = CGAffineTransform(translationX: -bounds.origin.x + rectangle.origin.x / 2.0, y: -bounds.origin.y + rectangle.origin.y / 2.0) path.apply(transform) // CREATE UIView WITH CAShapeLayer let hexagon = UIView(frame: rectangle) let shapeLayer = CAShapeLayer() shapeLayer.path = path.cgPath shapeLayer.fillColor = randomColour.cgColor hexagon.layer.addSublayer(shapeLayer) // SVG : COLOUR DATA let randomColourRGBA = getRGBAComponents(randomColour) let randomColourSVG = toSVGString(red : randomColourRGBA.red, green : randomColourRGBA.green, blue : randomColourRGBA.blue, alpha : randomColourRGBA.alpha) // SVG : PATH DATA (END) svgPathData += " Z" let pathElement = "<path d=\"\(svgPathData)\" fill=\"\(randomColourSVG)\" /> \n" svgPathStrings.append(pathElement) addSubview(hexagon) I tried but it just distorted the corners: let centerX = (corner.x + tip.x + start.x + end.x) / 4.0 let centerY = (corner.y + tip.y + start.y + end.y) / 4.0
0
0
316
Nov ’23
Does Apple documentation really help you learn Swift?
👋 I've been trying to learn Swift from scratch. I don't have technical developer/ computer science experience, but I have been a designer for some time. I completed reading the Swift language guide and completed the SwiftUI Concepts Tutorials. I am now about half way through the iOS App Dev Tutorial but it feels like a level beyond my current understanding. Is there any documentation that I should be looking at instead? What's the best way to learn Swift/ SwiftUI? Thanks!!
3
0
229
Nov ’23
Error setting up camera using DiscoverySession
Trying to access camera hardware using let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: AVCaptureDevice.Position.front) guard let captureDevice = deviceDiscoverySession.devices.first else { print("Failed to get the camera device") } In many devices I get the Failed to get camera device error. Devices like iPhone XS iPhone X iPhone 7 iPhone 11 iPhone 11 Pro Max iPhone 8 iPhone14,7 iPhone 12 iPhone XR iPhone SE (2nd generation) iPhone 13 iPhone 13 Pro iPhone 6s iPhone 6s Plus Is there a reason why this might happen if the hardware is functioning properly. Please help as a lot of users are facing this issue.
2
0
491
Nov ’23
Digital signature to PDF file on Swift/Objective-C
Hi there, Currently, I'm assigned to do the task that allow user can sign their digital signature on iPhone. I've researched for a week and so far, I'm lost on my way. I want to ask your all experience in working the similar task. My demand is: Allow users upload PDF document Then, allow users sign their digital signature Please give me a logic, step and how it works programmatically to research, in order to do this task. Thank you all <3
1
0
453
Nov ’23
CIImage.clampedToExtent() doesn't fill some edges
Hi, I'm trying to find an explanation to strange behaviour of .clampedToExtent() method: I'm doing pretty strait forward thing, clamp the image and then crop it with some insets, so as a result I expert same image as original with padding on every side with repeating last pixel of each edge (to apply CIPixellate filter then), here is the code: originalImage .clampedToExtent() .cropped(to: originalImage.extent.insetBy(dx: -50, dy: -50)) The result is strange: In the result image image has padding as specified, but only there sides have content there (left, right, bottom) and top side has transparent padding. Sometimes right side has transparency instead of content. So the question is why this happens and how to get all sides filled with last pixel data? I tested on two different devices with iOS 16 and 17.
2
0
956
Nov ’23