I am updating a universal app for release on iOS 17+ devices using Xcode15.2 and Solar2d v3708. The last release was 7 years ago.
The app connects to the local network and used a custom UDP protocol to connect to and control specific hardware devices. The protocol involves transmitting and receiving both broadcast and unicast messages to/from IPV4 capable proprietary devices on the local network.
When I run the app in the Solar2d simulator and when I run the current version installed from the App store on my iPad, communications work well.
When I build the same code into a new development build and transfer it to my iPad, I found that attempts to send broadcast messages are failing. When I print out the error returned from the socket interface to the console, I see the message is "No Route to Host".
I requested multicast capability from Apple and when it appeared on my development portal I updated the App Id to include the multicast entitlement. I updated the development profile to include our new 6th gen IPad and the updated AppID. I downloaded and installed the development profile. That new profile is what I am selecting / using to sign the app.
I am using lua socket library to send broadcast messages
I created a very basic project with just the basic networking code example and built this for my iPad the results are the same.
local socket = require("socket")
local main, errorMain = socket.udp6()
main:setoption('broadcast', true)
local ack, mError = main:sendto("", "::FFFF:255.255.255.255", 3100)
print("My Debug Message: Main sending - " .. (ack or "nil") .. ", Error : " .. (mError or "None"))
I also tried modifying my code to use udp4 as follows and the results were the same.
local socket = require("socket")
local main, errorMain = socket.udp4()
main:setoption('broadcast', true)
local ack, mError = main:sendto("", "255.255.255.255", 3100)
print("My Debug Message: Main sending - " .. (ack or "nil") .. ", Error : " .. (mError or "None"))
console output:
My Debug Message: Main sending - nil, Error : No route to host
Any help or insight would be greatly appreciated.
Dive into the world of programming languages used for app development.
Post
Replies
Boosts
Views
Activity
I have created a Flutter application to scan Mifare DESFire cards on Android and iOS. I have tried using both flutter_nfc_kit and nfc_manager which both use CoreNFC.
On both platforms, I can get the basic information on the card. However, only on Android, I can read data from the card by using Mifare commands. On iOS I am getting a 0B response.
I have the following configuration inside my Runner.entitlements:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
<string>TAG</string>
</array>
</dict>
</plist>
I have added the following keys inside my Info.plist file:
<dict>
<key>NFCReaderUsageDescription</key>
<string>Access NFC</string>
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
<string>D2760000850100</string>
</array>
...
</dict>
However, I have noticed that I will get a different response if I add the D2760000850100 key in the Info.plist file. When I have this key added I get an error when executing a Mifare command: PlatformException(500, Communication error, Tag response error, null)
So for that reason, I decided to remove the key altogether. Now everytime, I execute a Mifare command I end up with the response of 0B. Which does not tell me anything because it is not an official response.
The Mifare command I am using is the select application command: 5A123456 where 123456 is the application ID. As mentioned before this works perfectly on Android.
The only response I can get from the Mifare DESFire card is with an ISO7816 command: 00A4040006D2760000850100. Which is the select application command according to the ISO7816 standard. However, after executing this command I need to authenticate, which requires a complex algorithm.
Is it necessary on iOS to first execute ISO7816 commands, before you can execute Mifare commands?
Hello!
In our codebase we have a NSView subclass that conforms to NSTextInputClient. This protocol is currently not marked as a main actor, but in the decade this has been in use here it has always been called on the main thread from AppKit.
With Swift 6 (or complete concurrency checking in Swift 5) this conformance causes issues since NSView is a main actor but not this protocol. I've tried a few of the usual fixes (MainActor.assumeIsolated or prefixing the protocol conformance with @preconcurrency) but they were not able to resolve all warnings.
So I dug in the AppKit headers and found that NSTextInputClient is usually implemented by the view itself, but that that is not a hard requirement (see NSTextInputContext.h the documentation for the client property or here). With that I turned my NSView subclass extension into a separate class that is not a main actor and in my NSView subclass create an instance of it and NSTextInputContext. This all seems to work fine in my initial tests, the delegate methods are called. But when the window loses and then regains key, I see a warning message in the console output.
-[TUINSCursorUIController activate:]: Foo.TextInputClient isn't subclass of NSView.
So my question is, am I doing it wrong with the custom class that implements the protocol? Or is the warning wrong?
I would also appreciate a hint on how to better resolve the concurrency issues with NSTextInputClient. Is a main actor annotation coming at some point from your end?
Thanks!
Markus
I have a Matrix structure as defined below for working with 2D numerical data in Accelerate. The underlying numerical data in this Matrix struct is stored as an Array.
struct Matrix<T> {
let rows: Int
let columns: Int
var data: [T]
init(rows: Int, columns: Int, fill: T) {
self.rows = rows
self.columns = columns
self.data = Array(repeating: fill, count: rows * columns)
}
init(rows: Int, columns: Int, source: (inout UnsafeMutableBufferPointer<T>) -> Void) {
self.rows = rows
self.columns = columns
self.data = Array(unsafeUninitializedCapacity: rows * columns) { buffer, initializedCount in
source(&buffer)
initializedCount = rows * columns
}
}
subscript(row: Int, column: Int) -> T {
get { return self.data[(row * self.columns) + column] }
set { self.data[(row * self.columns) + column] = newValue }
}
}
Multiplication is implemented by the functions shown below.
import Accelerate
infix operator .*
func .* (lhs: Matrix<Double>, rhs: Matrix<Double>) -> Matrix<Double> {
precondition(lhs.rows == rhs.rows && lhs.columns == rhs.columns, "Matrices must have same dimensions")
let result = Matrix<Double>(rows: lhs.rows, columns: rhs.columns) { buffer in
vDSP.multiply(lhs.data, rhs.data, result: &buffer)
}
return result
}
func * (lhs: Matrix<Double>, rhs: Matrix<Double>) -> Matrix<Double> {
precondition(lhs.columns == rhs.rows, "Number of columns in left matrix must equal number of rows in right matrix")
var a = lhs.data
var b = rhs.data
let m = lhs.rows // number of rows in matrices A and C
let n = rhs.columns // number of columns in matrices B and C
let k = lhs.columns // number of columns in matrix A; number of rows in matrix B
let alpha = 1.0
let beta = 0.0
// matrix multiplication where C ← αAB + βC
let c = Matrix<Double>(rows: lhs.rows, columns: rhs.columns) { buffer in
cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, m, n, k, alpha, &a, k, &b, n, beta, buffer.baseAddress, n)
}
return c
}
I can also define a Matrix structure where the underlying data is an UnsafeMutableBufferPointer. The buffer is handled by the MatrixData class.
struct Matrix<T> {
let rows: Int
let columns: Int
var data: MatrixData<T>
init(rows: Int, columns: Int, fill: T) {
self.rows = rows
self.columns = columns
self.data = MatrixData(count: rows * columns, fill: fill)
}
init(rows: Int, columns: Int) {
self.rows = rows
self.columns = columns
self.data = MatrixData(count: rows * columns)
}
subscript(row: Int, column: Int) -> T {
get { return self.data.buffer[(row * self.columns) + column] }
set { self.data.buffer[(row * self.columns) + column] = newValue }
}
}
class MatrixData<T> {
var buffer: UnsafeMutableBufferPointer<T>
var baseAddress: UnsafeMutablePointer<T> {
get { self.buffer.baseAddress! }
}
init(count: Int, fill: T) {
let start = UnsafeMutablePointer<T>.allocate(capacity: count)
self.buffer = UnsafeMutableBufferPointer(start: start, count: count)
self.buffer.initialize(repeating: fill)
}
init(count: Int) {
let start = UnsafeMutablePointer<T>.allocate(capacity: count)
self.buffer = UnsafeMutableBufferPointer(start: start, count: count)
}
deinit {
self.buffer.deinitialize()
self.buffer.deallocate()
}
}
Multiplication for this approach is implemented by the functions shown here.
import Accelerate
infix operator .*
func .* (lhs: Matrix<Double>, rhs: Matrix<Double>) -> Matrix<Double> {
precondition(lhs.rows == rhs.rows && lhs.columns == rhs.columns, "Matrices must have same dimensions")
let result = Matrix<Double>(rows: lhs.rows, columns: lhs.columns)
vDSP.multiply(lhs.data.buffer, rhs.data.buffer, result: &result.data.buffer)
return result
}
func * (lhs: Matrix<Double>, rhs: Matrix<Double>) -> Matrix<Double> {
precondition(lhs.columns == rhs.rows, "Number of columns in left matrix must equal number of rows in right matrix")
let a = lhs.data.baseAddress
let b = rhs.data.baseAddress
let m = lhs.rows // number of rows in matrices A and C
let n = rhs.columns // number of columns in matrices B and C
let k = lhs.columns // number of columns in matrix A; number of rows in matrix B
let alpha = 1.0
let beta = 0.0
// matrix multiplication where C ← αAB + βC
let c = Matrix<Double>(rows: lhs.rows, columns: rhs.columns)
cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, m, n, k, alpha, a, k, b, n, beta, c.data.baseAddress, n)
return c
}
Both of these approaches give me similar performance. The only difference that I have noticed is the matrix buffer approach allows for reference semantics. For example, the code below uses half the memory with the matrix buffer approach compared to the matrix array approach. This is because b acts as a reference to a using the matrix buffer approach; otherwise, the matrix array approach makes a full copy of a.
let n = 10_000
let a = Matrix<Double>(rows: n, columns: n, fill: 0)
var b = a
b[0, 0] = 99
b[0, 1] = 22
Other than reference semantics, are there any reasons to use one of these approaches over the other?
Is it possible to access the RoomPlan API from Objective-C? I cannot figure out how to include the RoomPlan framework into some legacy Objective-C code I have. I can include the RoomPlan.h header but it still does not recognize any of the API classes. I also could not figure out if there was a way to use RoomPlan-Swift.h to expose the API to the Objective-C code.
if we define a property in the following way:
@property (atomic) NSString *latestObject;
Can we assume that the read write to that value is thread safe?
i.e the value will be correct.
Or it is better to write our own setter/getter with Locks?
Sorry this post is duplicate
White-label messaging is like a pre-made chat app that one company creates, but other companies can make it look like it’s their own by changing its appearance and name. Basically, it’s a chat tool that businesses can buy and use with their own branding.
Hello All, some background information first. I have the following struct:
Struct Category: Identifiable, Codeable, Hashable {
var id: UUID
var name: String
var subCategory: [Category]?
}
var categories: [Category]
There is no limit how many levels deep the subcategory can be. The user is essentially creating a hierarchical data filing system.
Given that the number of subCategory levels is unlimited, I am recursing over the subcategories to find the correct level at which to insert the newCategory.
The recursive function to add category is declared as:
func recursiveAddCategory(newCategory: Category, subCategoryOf: inout [Category]?)
you will note that I am trying to pass the subCategory as a reference (using inout), so that I can add to the original
and the function is called as recursiveAddCategory(newCategory, &categories.subCategory!)
the actual append statement within the recursiveAddCategory function is:
categories.subCategory?.append(newCategory)
I am encountering no errors but also find that the newCategory is not being added to the categories array.
Any help or guidance appreciated.
Thanks
I am working thru the issues of turning on Strict Concurrency Checking. I have a SwiftData application, and I am compressing images before saving them as data. My save function is pretty simple
private func save() {
ImageCompressor.compress(image: (frontImageSelected?.asUIImage())!, maxByte: 1_048_576) { image in
guard image != nil else {
print("Error compressing image")
return
}
if let greetingCard {
greetingCard.cardName = cardName
greetingCard.cardFront = image?.pngData()
greetingCard.cardManufacturer = cardManufacturer
greetingCard.cardURL = cardURL
greetingCard.eventType = eventType
} else {
let newGreetingCard = GreetingCard(cardName: cardName, cardFront: image?.pngData(), eventType: eventType, cardManufacturer: cardManufacturer, cardURL: cardURL)
modelContext.insert(newGreetingCard)
}
}
}
I compress the selected image, I had to change my ImageCompressor.compress closure to Sendable, but now every assignment above is flagging with the above warning. I define the greetingCard as var greetingCard: GreetingCard? in my view, since I can have it passed in for edit, or generated if new.
I also get the same warning on modelContext, which is defined as @Environment(\.modelContext) private var modelContext.
It's not clear to me how to address this warning. Any pointers would be helpful.
Hi,
When using Swift Concurrency blocking tasks like file I/O, GPU work and networking can prevent forward moving progress and have the potential to exhaust the cooperative thread pool and under utilize the CPU. It's been recommended to offload these tasks from the cooperative thread pool.
Is my understanding correct that the preferred way to do this is by creating async tasks via Dispatch or OperationQueue? And combining these with Continuations if a return value from the task is required? Or should I always be using Continuations in combination with Dispatch/OperationQueue?
There are also Executors but the documentation seems a bit limited on how to use these. The new TaskExecutor is also only available on the latest beta's.
My question is basically what is the recommend way to offload a task?
Thanks!
For many years, I programmed for Windows desktops (Visual Basic and C# on Microsoft Visual Studio).
What is a good way to start progrmming for an iOS or iPadOS device. What programming apps can you recommend and what books or courses can I get (online or otherwise) to start with? Can I make code with Microsoft Visual Studio or do I need specific programming tools for writing code?
Thank you for your help.
Michel
struct Preview: View {
private static let NAME = "Test"
@Query(filter: #Predicate<Item> { $0.name == Preview.NAME})
private var items: [Item]
var body: some View {
MyView(name: Preview.NAME, items: items)
}
}
Compile error occurs: key path cannot refer to static member 'NAME'
How can a (static) constant be referred in member closure?
In my method moveSun() it successfully rotates and plays the sound the first time it is called. However, subsequent calls to the method only play the sound and do not execute the rotate action. Does anyone know what may be causing this? Here's the relevant code:
func moveSun()
{
print(sunMoving)
let rotateAction = SKAction.rotate(toAngle: 2 * CGFloat.pi, duration: 2)
let playGearSound = SKAction.playSoundFileNamed("spinningGear", waitForCompletion: true)
let rotateAndPlayGearSound = SKAction.group([rotateAction, playGearSound])
sun.run(rotateAndPlayGearSound, completion: { self.sunMoving = false; print("completed completion handler") })
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
{
for t in touches
{
self.touchDown(atPoint: t.location(in: self))
}
}
func touchDown(atPoint pos : CGPoint)
{
let touchedNodes = nodes(at: pos)
for touchedNode in touchedNodes
{
print("touchNode: \(String(describing: touchedNode.name))")
if touchedNode.name == "sun" && !sunMoving
{
sunMoving = true
moveSun()
}
}
}
I have the following var in an @Observable class:
var displayResult: String {
if let currentResult = currentResult, let decimalResult = Decimal(string: currentResult) {
let result = decimalResult.formatForDisplay()
UIAccessibility.post(notification: .announcement, argument: "Current result \(result)")
return result
} else {
return "0"
}
}
The UIAccessiblity.post gives me this warning:
Reference to static property 'announcement' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6
How can I avoid this?
I'm trying to migrate my fairly large application to Swift Concurrency. I've have a class marked as @MainActor that sub-classes a 3rd party abstract class that is not migrated to Swift Concurrency.
I get the following error:
Main actor-isolated class 'MyClass' has different actor isolation from nonisolated superclass 'OtherAbstractClass'; this is an error in the Swift 6 language mode
My class needs to be MainActor as it uses other code that is required to be on the MainActor.
I can't see how to suppress this warning, I know as a guarantee that the abstract class will always be on the main thread so I need a way of telling the compiler that when I don't own the 3rd party code.
import OtherAbstractModule
@MainActor
class MyClass: OtherAbstractClass {
....
}
How can I satisfy the compiler in this case?
Currently Swift Testing has much less features than XCTest, so the adoption will be very slow from our side. Notable features we miss are UI tests, performance tests and attachments.
I did not want to create many issues in Swift Testing GitHub project as lots of these shortcoming are most probably tracked internally (I can see lots of references to radars in GitHub issues.)
So, my question is: Is it a good idea to wait with wider adoption or should we experiment with other tools like swift Benchmarks?
import Foundation
let formatter = DateFormatter()
let displayLocalFormat = true or false
let timeZone = UTC
let dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
let currentDate = Date()
formatter.locale = displayLocalFormat ? Locale.current : Locale(identifier: "en_US_POSIX")
formatter.dateFormat = dateFormat
formatter.timeZone = timeZone
formatter.string(from: date) // This function returns date format 2024-05-23T11:16:24.706 a.m.Z
Why is "Go small with embedded Swift" still not available, despite the fact all the other WWDC24 Tuesday session videos are?
Hello,
I develop an HCE payment app.
In this app I can redirect users in Settings to set the default payment app
UIApplication.shared.open(URL(string: "App-prefs:General&path=CONTACTLESS_NFC")
But is it possible to know which app is selected or if my app is already set as default ?