I am trying to create a simple app that "blocks" other apps if a certain condition is not met. I am currently using the IOS shortcuts and have set up an automation that opens my app A whenever another app B opens.
If the condition is not met i imagine the flow to look like:
Open app A.
My app B opens instead.
I check a box in my app B.
I navigate back to app A and it works as expected.
If the condition already is met the app A would work as expected from the beginning.
What is have tried so far
My first attempt involved using an AppIntent and changing the openAppWhenRun programmatically based on the condition. I did however learn pretty quickly that changing the value of openAppWhenRun does not change if the AppIntent actually opens my app. The code for this looked like this where the value of openAppWhenRun is changed in another function.
struct BlockerIntent: AppIntent {
static let title: LocalizedStringResource = "Blocker App"
static let description: LocalizedStringResource = "Blocks an app until condition is met"
static var openAppWhenRun: Bool = false
@MainActor
func perform() async throws -> some IntentResult {
return .result()
}
}
Another attempt involved setting openAppWhenRun to false in an outer AppIntent and opening another inner AppIntent if the condition is met. If the condition in my app is met openAppWhenRun is set to true and instead of opening the inner AppIntent an Error is thrown. This functions as expected but there is an error notification showing every time I open the "blocked" app.
struct BlockerIntent: AppIntent {
static let title: LocalizedStringResource = "Blocker App"
static let description: LocalizedStringResource = "Blocks an app until condition is met"
static var openAppWhenRun: Bool = false
func perform() async throws -> some IntentResult & OpensIntent {
if (BlockerIntent.openAppWhenRun) {
throw Error.notFound
}
return .result(opensIntent: OpenBlockerApp())
}
enum Error: Swift.Error, CustomLocalizedStringResourceConvertible {
case notFound
var localizedStringResource: LocalizedStringResource {
switch self {
case .notFound: return "Ignore this message"
}
}
}
}
struct OpenBlockerApp: AppIntent {
static let title: LocalizedStringResource = "Open Blocker App"
static let description: LocalizedStringResource = "Opens Blocker App"
static var openAppWhenRun: Bool = true
@MainActor
func perform() async throws -> some IntentResult {
return .result()
}
}
My third attempt look similar to the previous one but instead I used two different inner AppIntents. The only difference between the two were that on had openAppWhenRun = false and the other had openAppWhenRun = true.
struct BlockerIntent: AppIntent {
static let title: LocalizedStringResource = "Blocker App"
static let description: LocalizedStringResource = "Blacks an app until condition is met"
static var openAppWhenRun: Bool = false
func perform() async throws -> some IntentResult & OpensIntent {
if (BlockerIntent.openAppWhenRun) {
return .result(opensIntent: DoNotOpenBlockerApp())
} else {
return .result(opensIntent: OpenBlockerApp())
}
}
}
Trying this gives me this error:
Function declares an opaque return type 'some IntentResult & OpensIntent', but the return statements in its body do not have matching underlying types
I have also tried opening the app with a URL link with little to no success often ending up in an infinity loop, I did try the ForegroundContinuableIntent but it did not function as expected since it relies on the users input.
Is there any way to do what I am trying to accomplish? I have seen other apps using a similar concept so I feel like this should be possible.
Many thanks!
Dive into the world of programming languages used for app development.
Post
Replies
Boosts
Views
Activity
I'm a newbie in working with SwiftData and I hope for your help in solving the below issue :")
It's about deleting the objects into a Model by ModelContext.delete(). It's only possible to delete the data after it has been inserted for about 30 seconds.
Just run the source code below, tap on "Add" button to add some samples, and then tap on "Delete" button right away. At this time, Delete action doesn't work. You have to wait about 30 seconds, then tap on "Delete" button, it will work - the sample data are deleted properly.
I tested this issue on Xcode 15.1 beta (15C5042i) and found that:
This issue always happens on Preview w/ iOS 17 or iOS 17.2.
This issue doesn't happen on Simulator w/ iOS 17 BUT it happens on Simulator w/ iOS 17.2
Is this an issue of iOS 17.2 ?
Full source code on GitHub
Bike.swift
import Foundation
import SwiftData
@Model class Bike {
var name: String
init(name: String) {
self.name = name
}
}
TestApp.swift
import SwiftUI
import SwiftData
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
BikeListView()
}
.modelContainer(for: Bike.self)
}
}
BikeListView.swift
import SwiftUI
import SwiftData
struct BikeListView: View {
@Environment(\.modelContext) var modelContext
@Query var bikes: [Bike]
var body: some View {
VStack {
HStack(spacing: 30) {
Button {
addSamples()
} label: {
Text("Add")
}
Button {
deleteSamples()
} label: {
Text("Delete")
}
}
List {
ForEach(bikes) { eachBike in
Text(eachBike.name)
}
}
}
}
func addSamples() {
let bikeOne = Bike(name: "One")
let bikeTwo = Bike(name: "Two")
modelContext.insert(bikeOne)
modelContext.insert(bikeTwo)
}
func deleteSamples() {
try? modelContext.delete(model: Bike.self)
}
}
#Preview {
do {
let modelConfig = ModelConfiguration(isStoredInMemoryOnly: false)
let modelContainer = try ModelContainer(for: Bike.self, configurations: modelConfig)
return BikeListView() .modelContainer(modelContainer)
} catch {
fatalError("Content View's Preview")
}
}
Thanks for reading and I'm looking forward to your help.
Hello,
I am trying to use the SwiftUI fileImporter to get the URL of a direcotry and access it for the files in it.
If I follow the document( Access the directory’s content ) and use url.startAccessingSecurityScopedResource for each file, it always returns false. but this seems to be different from the documentation. If the current behavior is correct, will the documentation be updated in the future?
Related: Access all files in UIDocumentPick… | Apple Developer Forums
I asked this question because I am concerned that if I remove the standardAccessingSecurityScopedResource to match the current situation, the standardAccessingSecurityScopedResource may become necessary due to future iOS updates.
Also, is there any way to know if the status of the AccessingSecurityScopedResource?
It would be helpful if we could callstartAcesingSecurityScopedResource only when needed.
Thanks
Here is a sample code
@main
struct SampleApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
@State private var isShowingImportFolder = false
@State private var isShowingImportFile = false
var body: some View {
VStack(spacing: 48) {
Button("Read Folder") {
isShowingImportFolder = true
}
.fileImporter(isPresented: $isShowingImportFolder, allowedContentTypes: [.folder]) { result in
switch result {
case .success(let url):
processDirectory(url)
case .failure(let error):
print("failed. error: \(error)")
}
}
Button("Read File") {
isShowingImportFile = true
}
.fileImporter(isPresented: $isShowingImportFile, allowedContentTypes: [.data]) { result in
switch result {
case .success(let url):
readFile(url)
case .failure(let error):
print("failed. error: \(error)")
}
}
}
}
private func processDirectory(_ directory: URL) {
guard directory.startAccessingSecurityScopedResource() else {
fatalError("failed. directory.startAccessingSecurityScopedResource")
}
defer { directory.stopAccessingSecurityScopedResource() }
var error: NSError?
NSFileCoordinator().coordinate(readingItemAt: directory, error: &error) { url in
let urls = try! FileManager.default.contentsOfDirectory(at: url, includingPropertiesForKeys: [.nameKey, .isDirectoryKey])
urls.lazy
.filter { !$0.hasDirectoryPath }
.forEach { readFile($0) }
}
}
private func readFile(_ url: URL) {
guard url.startAccessingSecurityScopedResource() else {
print("failed access. \(url.path)")
return
}
defer { url.stopAccessingSecurityScopedResource() }
let data = try! Data(contentsOf: url)
print("file.path: \(url.path()), size: \(data.count)")
// read file...
}
}
I am downloading flutter to build cross platform and when I am running the programme it keeps saying
[!] Xcode - develop for iOS and macOS (Xcode 15.0.1)
✗ CocoaPods not installed.
CocoaPods is used to retrieve the iOS and macOS platform side's plugin
code that responds to your plugin usage on the Dart side.
Without CocoaPods, plugins will not work on iOS or macOS.
For more info, see https://flutter.dev/platform-plugins
To install see
https://guides.cocoapods.org/using/getting-started.html#installation for
instructions.
I have tried to get it to install using sudo but still not working
In my app user accounts are handled with Firebase Auth. When creating a user how can I get the system to suggest a Unique password (that prompt that comes up on the keyboard) and also how can i get it to save these details to the keychain. My app will have a website in the future so I want the details come up when the user tries to login there.
When the user logs in i used the func below to save the details to the keychain, it says the details have been saved but it doesnt seem to come up in the passwords tab in Settings.
func saveCredentialsToKeychain(email: String, password: String) {
let query: [String: Any] = [
kSecClass as String: kSecClassInternetPassword,
kSecAttrServer as String: "myWebsite.com",
kSecAttrAccount as String: email,
kSecValueData as String: password.data(using: .utf8)!,
kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked
]
let status = SecItemAdd(query as CFDictionary, nil)
if status == errSecSuccess {
print("Credentials saved to Keychain")
} else {
print("Error saving credentials to Keychain: \(status)")
}
}
Hello,
I am working on a macOS Virtualization framework project on Xcode.
Is there a way to redirect an USB device connected to the host mac, to a virtual machine.
I know this is possible with lower layers but i would like to do it with a VZVirtualMachine object. Is it possible ?
Thanks
Hi all,
I'm trying to implement starting Live Activities with push notifications according to this article:
https://developer.apple.com/documentation/activitykit/starting-and-updating-live-activities-with-activitykit-push-notifications
I'm using Xcode 15.1 beta 3, I have run my tests on a physical device with iOS 17.2 as well as the simulator with iOS 17.2
My problem is I can't seem to be able to get the pushToStartToken needed to start the live activities. I have subscribed to the pushToStartTokenUpdates but I never get any updates.
Here is the code I used:
Task {
do {
for try await data in Activity<DailyGoalActivityAttributes>.pushToStartTokenUpdates {
let token = data.map {String(format: "%02x", $0)}.joined()
print("Activity token: \(token)")
}
} catch {
print(error)
}
}
Any help would be greatly appreciated.
Thanks,
HS
While using the application, it suddenly quits. When we attempt to reopen it, an error pop-up appears stating, 'Unable to verify app. Internet connection is required to verify trust.' We tried accessing the VPN and regularity options in settings, and clicked on 'Trust,' but it was ineffective. The only solution that works is resetting the iPad. However, after one or two days, the same issue arises again. This problem seems to occur exclusively on certain iPads. What might be causing this recurring problem?"
When building/archiving a mixed Obj-C/Swift app from an XCode Cloud Workflow, it seems that the GCC_PREPROCESSOR_DEFINITIONS (Preprocessor Macros) are not used. We use them for environment switching based on scheme and we'd like to send a test build to Testflight through XCode Cloud for internal testing.
If this is the case, is the only option to rewrite code to use Swift Active Compilation Conditions?
I have a use case to rotate a CMSampleBuffer from landscape to portrait. I have written a rough code for it. But still am facing many issues with appending of the sampleBuffer to input frame.
Here's the code:
`guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
return nil
}
// Get the dimensions of the image buffer
let width = CVPixelBufferGetWidth(imageBuffer)
let height = CVPixelBufferGetHeight(imageBuffer)
// Determine if the image needs to be rotated
let shouldRotate = width > height
// Create a CIImage from the buffer
var image = CIImage(cvImageBuffer: imageBuffer)
// Rotate the CIImage if necessary
if shouldRotate {
image = image.oriented(forExifOrientation: 6) // Rotate 90 degrees clockwise
}
let originalPixelFormatType = CVPixelBufferGetPixelFormatType(imageBuffer)
// Create a new pixel buffer
var newPixelBuffer: CVPixelBuffer?
let status = CVPixelBufferCreate(kCFAllocatorDefault, height, width,
originalPixelFormatType, nil, &newPixelBuffer)
guard status == kCVReturnSuccess, let pixelBuffer = newPixelBuffer else {
return nil
}
CVBufferPropagateAttachments(imageBuffer, newPixelBuffer!)
// Render the rotated image onto the new pixel buffer
let context = CIContext()
context.render(image, to: pixelBuffer)
CVPixelBufferUnlockBaseAddress(pixelBuffer,CVPixelBufferLockFlags(rawValue: 0))
var videoInfo: CMVideoFormatDescription?
CMVideoFormatDescriptionCreateForImageBuffer(allocator: kCFAllocatorDefault, imageBuffer: newPixelBuffer!, formatDescriptionOut: &videoInfo)
var sampleTimingInfo = CMSampleTimingInfo(duration: CMSampleBufferGetDuration(sampleBuffer), presentationTimeStamp: CMSampleBufferGetPresentationTimeStamp(sampleBuffer), decodeTimeStamp: CMSampleBufferGetDecodeTimeStamp(sampleBuffer))
var newSampleBuffer: CMSampleBuffer?
CMSampleBufferCreateForImageBuffer(allocator: kCFAllocatorDefault, imageBuffer: newPixelBuffer!, dataReady: true, makeDataReadyCallback: nil, refcon: nil, formatDescription: videoInfo!, sampleTiming: &sampleTimingInfo, sampleBufferOut: &newSampleBuffer)
let attachments: CFArray! = CMSampleBufferGetSampleAttachmentsArray(sampleBuffer, createIfNecessary: true)
let dictionary = unsafeBitCast(CFArrayGetValueAtIndex(attachments, 0),
to: CFMutableDictionary.self)
if let attachmentsArray = CMSampleBufferGetSampleAttachmentsArray(sampleBuffer, createIfNecessary: true) as? [CFDictionary] {
for attachment in attachmentsArray {
for (key, value) in attachment as! Dictionary<CFString, Any> {
if let value = value as? CFTypeRef {
CMSetAttachment(newSampleBuffer!, key: key, value: value, attachmentMode: kCMAttachmentMode_ShouldPropagate)
}
}
}
}
return newSampleBuffer!
The error that I am getting while appending the frame is:
Error occured, isVideo = false, status = 3, Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedFailureReason=An unknown error occurred (-12780), NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x282b87390 {Error Domain=NSOSStatusErrorDomain Code=-12780 "(null)"}}
I read online that this error might be due to different PixelFormatType. But how can that be because I am obtaining the PixelFormatType from the buffer itself.
If you want to see the difference between original and rotated sample buffer. https://www.diffchecker.com/V0a55kCB/
Thanks in advance!
Hi guys !
When I will build my UItests, the build fails. Well.. My project is subdivided that way: I have a workspace, within i have "n" SwiftPackage (SP), that represents my features, I have one SP per feature. At same level, I have a App project (xcproject), that represents the App, that dependes of SP's.
Some SP, has views, that can be tested but SwiftPackages cannot run UITest. So to do achieve that, I create a feature-App (as target), that depends only respective SP, to create UITests. So far everything is ok.
I implement my tests and UITest, but, when I run, they build fails, before run tests. However that SP, that I want to test, depends from another SP and while build, of UITest, the build fails because the another SP.
Someone can help me ?
I am currently refactoring the signup process for a sports media app in SwiftUI and having issues trying to have it save data associated with the new user to the backend (comprised of a mix of Firebase and a custom backend) via a signup function in an AuthService class. Whenever I enter the required info to create an account (email, username, password, etc.), I get the following errors
Error: The data couldn’t be read because it is missing.
Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "user", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "data", intValue: nil)], debugDescription: "No value associated with key CodingKeys(stringValue: \"user\", intValue: nil) (\"user\").", underlyingError: nil))
Here is all the relevant code:
SignUpView.swift
AuthService.swift
Signup.swift
For AuthService, the signup function is what's relevant as I call it in SignUpView and SignUp has the definition for AccountSignUp which is called in the other two files. What is not being read correctly in the data? What is missing and what can be done to fix it such that the info will be saved to the backend? All help will be greatly appreciated!
I have a need to list all known audio/image file types in a planned app.
What I have known so far:
images
.apng
.avi, .avif
.gif
.jpg, .jpeg, .jfif, .pjpeg, .pjp
.png
.svg
.webp
audio
.aif
.cda
.mid, .midi
.mp3
.mpa
.ogg
.wav
.wma
What are the missing ones?
I need to send confirmation mail to customer once, When Customer orders it.
I have some methods in Google but all of those methods Triggers the Mail Extension in Mail App and Opens up Mail
I don't need to trigger and show the Mail to Customers
I just want to send the Order summary to customer Mail Address
is there any way or API , SDK
I have the following code:
extension FileHandle {
func readInto(_ buffer: inout [UInt8]) -> Int {
buffer.withUnsafeMutableBytes {
Darwin.read(fileDescriptor, $0.baseAddress, $0.count)
}
}
}
It can compile, but I wonder if this is supported since it's code in an app that is going to be submitted to App Store.
The reason I don't use read(upToCount:) or readData(ofLength:) is that I am reading possibly very large files by small chunks and don't want to let Swift runtime allocate small buffers repeatedly.
I cannot get any clue on the differences between these 2 functions of Array type.
Can anyone explain by examples?
I've encountered a performance issue in Xcode related to the use of a custom rawValue in enums. When attempting to create a variable using rawValue as its name inside the enum, Xcode exhibits significant lag and performance degradation.
This only use to happen in medium to large projects.
Steps to Reproduce:
Define an enum with a custom rawValue property.
Navigate through your codebase, especially in models.
enum Example {
case test1, test2, test3
var rawValue: Int {
0
}
}
Renaming rawValue into anything else solves the issue.
It's possible that Xcode has optimizations or behaviors associated with certain conventional names, such as rawValue.
I have a struct that is identifiable, and has two String variables and a UUID. I am using @Model decorator/macro for a class I want to persist, which has a few String variables (with values assigned to them), and some arrays of my struct, which are assigned values with the init() initialiser. This class also has two functions, both of which return an integer.
I am getting many errors for the String variables and initialisation of the arrays of structs:
Referencing instance method 'setValue(forKey:to:)' on 'Array' requires that 'Record' conform to 'PersistentModel'
No exact matches in call to instance method 'setValue'
No exact matches in call to instance method 'getValue'
I tried converting the struct to class, but that did not help. I also tried writing my own encoder and decoder functions, but that did not help either.
// Created by Devansh Trivedi on 24/11/23.
//
import SwiftUI // For UUID() to make Record struct Identifiable
import SwiftData
struct Record : Identifiable {
var date: String
var value: String
var id = UUID()
}
@Model
class Card {
//https://www.donnywals.com/making-your-swiftdata-models-codable/
// enum CodingKeys: CodingKey {
// case unit, date, name
// }
// required init(from decoder: Decoder) throws {
// let container = try decoder.container(keyedBy: CodingKeys.self)
// self.unit = try container.decode(String.self, forKey: .unit)
// self.date = try container.decode(String.self, forKey: .date)
// self.name = try container.decode(String.self, forKey: .name)
// }
// func encode(to encoder: Encoder) throws {
// var container = encoder.container(keyedBy: CodingKeys.self)
// try container.encode(unit, forKey: .unit)
// try container.encode(date, forKey: .date)
// try container.encode(date, forKey: .name)
// }
var unit:String="Liters"
var date:String="Nov 23"
var name:String="Milk"
var column_1:[Record]
var column_2:[Record]
var column_3:[Record]
init() {
self.column_1 = [
Record(date: "1", value: ""),
Record(date: "2", value: ""),
Record(date: "3", value: ""),
Record(date: "4", value: ""),
Record(date: "5", value: ""),
Record(date: "6", value: ""),
Record(date: "7", value: ""),
Record(date: "8", value: ""),
Record(date: "9", value: ""),
Record(date: "10", value: "")
]
self.column_2 = [
Record(date: "11", value: ""),
Record(date: "12", value: ""),
Record(date: "13", value: ""),
Record(date: "14", value: ""),
Record(date: "15", value: ""),
Record(date: "16", value: ""),
Record(date: "17", value: ""),
Record(date: "18", value: ""),
Record(date: "19", value: ""),
Record(date: "20", value: "")
]
self.column_3 = [
Record(date: "21", value: ""),
Record(date: "22", value: ""),
Record(date: "23", value: ""),
Record(date: "24", value: ""),
Record(date: "25", value: ""),
Record(date: "26", value: ""),
Record(date: "27", value: ""),
Record(date: "28", value: ""),
Record(date: "29", value: ""),
Record(date: "30", value: ""),
Record(date: "31", value: "")
]
}
func total() -> Int {
// https://hoyelam.com/summing-up-numeric-properties-of-objects-in-an-array-in-swift/
// https://dev.to/hoyelam/summing-up-numeric-properties-of-objects-in-an-array-in-swift-4og
return column_1.lazy
.filter( { !$0.value.isEmpty } )
.map( { Int($0.value)! } )
.reduce(0, +) + column_2.lazy
.filter( { !$0.value.isEmpty } )
.map( {Int($0.value)! })
.reduce(0, +) + column_3.lazy
.filter({!$0.value.isEmpty})
.map( {Int($0.value)! })
.reduce(0, +)
}
func bill() -> Int {
return self.total()*65
}
}
I got tried of the compiler telling me that .onChange(of:) was deprecated, so I thought, find, I'll simply stub it out for the older versions. Only... I can't seem to do that? I can use @available(macOS 14, *) to build for that and later, but is there any way to do the opposite? (I'd hoped there was a #if available support, but there isn't.)
Hi! I having trouble with encoding optional field of structure to send it to my server.
Here's this struct:
struct Defect: Codable {
var type: String = ""
var count: Int? = nil
}
When server returns data like this
[["type": "SOME_TYPE_1"], ["type": "SOME_TYPE_2", "count": 2]]
app successfully decodes is, but when I'm trying to encode the same data with
func request(json: Dictionary<String, Any> = [:]) {
// some code ...
request.httpBody = try JSONSerialization.data(withJSONObject: json)
// some other code ...
}
func updateObject(defects: Array<Defect>) {
// some code ...
let json: [String: Any] = ["comment": comment, "defects": defects]
request(/*some params*/ json: json)
// some code ...
}
I got error NSException * "Invalid type in JSON write (__SwiftValue)" in this string:
request.httpBody = try JSONSerialization.data(withJSONObject: json)
Struct's fields values at this moment are:
json["defects"][0].type = "SOME_TYPE_1"
json["defects"][0].count = nil
json["defects"][1].type = "SOME_TYPE_2"
json["defects"][1].count = 2
Please give me a guidance how to solve this problem. Maybe using of encode(to:) may help me (I'm novice, and didn't try it yet).