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
Dive into the world of programming languages used for app development.
Post
Replies
Boosts
Views
Activity
What is the purpose of the new .memoryTarget option in CIContextOption added in iOS 17? And it is interesting that this option is added only in swift interface.
https://developer.apple.com/documentation/coreimage/cicontextoption/4172811-memorytarget
I want to convert byte size strings like "1234kb", "100mb" or "5gb" to their actual number representation. Is there any builtin functions for this purpose?
I am aware Swift deliberately hides details (the actual index number) for safety, by introducing this verbose construct.
But I just got curious - is it possible to convert Index back to its underlying number?
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
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.
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()
}
If I am using MKMapView in my App do I need to pay any cost for using map.
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
}
Cannot record for duration, regardless of the value of 'dur' it always records for about 7 seconds.
self.recorder!.prepareToRecord()
let time = self.recorder!.deviceCurrentTime + 0.01
let dur: TimeInterval = 1.0
self.recorder!.record(atTime: time, forDuration: dur)
Any help appreciated, thanks. Paul
In C++, I can write 123457890ull to imply it's an unsigned long long integer. Does Swift provide similar language construct?
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>
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?
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 ?
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 ?
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
👋 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!!
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.
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
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.