Post

Replies

Boosts

Views

Activity

How to track network requests?
Hello! I am part of a research team who need advice on how to track and intercept network requests from a device. More specifically, we are interested in collecting the websites the research participants have tried to access. We want something like what YouGov does with their Pulse App. Also, is it possible to implement this without having to rely on an external server that acts as a intermediary? How do we achieve this? We'd appreciate a detailed response with helpful links to how to implement it. Thank you very much for your time.
5
0
684
Mar ’24
Sharing bundle ID for a flutter project
Hello. We are working on a flutter project using the same unique iOS app bundle id in all of our team's local repo. Only one of us is enrolled in an individual Apple Developer Program. The app runs properly for at least 3 of us while others are getting the error that the bundle ID is not available. Given that it the 3 of us did not require a unique bundle ID in each of our local copies, do you know how to resolve this issue? Also, it would be helpful if you could share how to handle the issue of requiring a unique bundle ID for flutter projects if our team is not enrolled in the Apple Developer Enterprise program.
1
0
589
Mar ’24
DNS Proxy extension not launching
Hello! I created a simple DNS filter application for iOS but the extension is not launching. I am getting this log message in the console. Failed to start extension edu.stanford.stilakid.testDnsFilter.DNSFiltering: Error Domain=NSCocoaErrorDomain Code=4097 "connection to service named edu.stanford.stilakid.testDnsFilter.DNSFiltering.apple-extension-service" UserInfo={NSDebugDescription=connection to service named edu.stanford.stilakid.testDnsFilter.DNSFiltering.apple-extension-service} For another project with the same code for dns filtering but different bundleID, I also got the following log message. Failed to start extension edu.stanford.sml.rdahlke.controlShift.DNSProxy: Error Domain=PlugInKit Code=4 "RBSLaunchRequest error trying to launch plugin edu.stanford.sml.rdahlke.controlShift.DNSProxy(D26CD63C-4656-4A30-99A0-7C867265DD75): Error Domain=RBSRequestErrorDomain Code=5 "Launch failed." UserInfo={NSLocalizedFailureReason=Launch failed., NSUnderlyingError=0xc62b8c0d0 {Error Domain=NSPOSIXErrorDomain Code=111 "Unknown error: 111" UserInfo={NSLocalizedDescription=Launchd job spawn failed}}}" UserInfo={NSLocalizedDescription=RBSLaunchRequest error trying to launch plugin edu.stanford.sml.rdahlke.controlShift.DNSProxy(D26CD63C-4656-4A30-99A0-7C867265DD75): Error Domain=RBSRequestErrorDomain Code=5 "Launch failed." UserInfo={NSLocalizedFailureReason=Launch failed., NSUnderlyingError=0xc62b8c0d0 {Error Domain=NSPOSIXErrorDomain Code=111 "Unknown error: 111" UserInfo={NSLocalizedDescription=Launchd job spawn failed}}}} Also, the log messages I have defined inside the constructor of the dns proxy extension is nowhere to be found in the logs, so I am pretty sure the extension is failing to launch. The debugger attached to the main target app shows no errors as well, so it is able to load and update dnsProtocol. Here is the code: // DNSProxyProvider.swift // DNSFiltering // // Created by Juben Rana on 2/20/24. // import NetworkExtension import os.log class DNSProxyProvider: NEDNSProxyProvider { // MARK: - Logger static let logger = Logger(subsystem: "edu.stanford.sml.rdahlke.controlShift", category: "dns-filter") override init() { Self.logger.log(level: .debug, "TestDns: dns proxy provider will init") self.logger = Self.logger super.init() } let logger: Logger override func startProxy(options:[String: Any]? = nil, completionHandler: @escaping (Error?) -> Void) { // Add code here to start the DNS proxy. logger.log(level: .debug, "TestDns: proxy will start") completionHandler(nil) } override func stopProxy(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { // Add code here to stop the DNS proxy. logger.log(level: .debug, "TestDns: proxy will stop") completionHandler() } override func sleep(completionHandler: @escaping () -> Void) { // Add code here to get ready to sleep. completionHandler() } override func wake() { // Add code here to wake up. } override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool { // Add code here to handle the incoming flow. logger.log(level: .debug, "TestDns: proxy is handling flow") return false } } // ContentView.swift // testDnsFilter // // Created by Juben Rana on 2/20/24. // import SwiftUI struct ContentView: View { var body: some View { VStack { // LoginScreen() // .onOpenURL { url in // GIDSignIn.sharedInstance.handle(url) // } Spacer() #if os(macOS) Text("I'm running on macOS") #else Text("I'm running on iOS") #endif Spacer() Button("Activate") { #if os(macOS) ContentFilterMac.shared.activate() #elseif os(iOS) ContentFilter.shared.enable() #endif } Spacer() Button("Deactivate") { #if os(macOS) ContentFilterMac.shared.deactivate() #elseif os(iOS) ContentFilter.shared.disable() #endif } Spacer() Spacer() } .padding() } } #Preview { ContentView() } // // ContentFilter.swift // controlShift // // Created by Juben Rana on 9/28/23. // // This is only for macOS import Foundation import NetworkExtension import os.log // MARK: - Content Filter class ContentFilter { // MARK: - Set Up static let shared = ContentFilter() private init() { Self.logger.log(level: .debug, "content filter will init") self.logger = Self.logger } // MARK: - Logger static let logger = Logger(subsystem: "edu.stanford.stilakid.testDnsFilter", category: "content-filter") let logger: Logger // MARK: - DNS Filter private let manager = NEDNSProxyManager.shared() func enable() { loadAndUpdatePreferences { self.manager.localizedDescription = "DNSProxySample" let dnsProtocol = NEDNSProxyProviderProtocol() dnsProtocol.providerBundleIdentifier = "edu.stanford.stilakid.testDnsFilter.DNSFiltering" self.manager.providerProtocol = dnsProtocol self.manager.isEnabled = true } } func disable() { loadAndUpdatePreferences { self.manager.isEnabled = false } } private func loadAndUpdatePreferences(_ completion: @escaping () -> Void) { manager.loadFromPreferences { error in guard error == nil else { debugPrint("DNSProxySample.App: load error") return } completion() self.manager.saveToPreferences { (error) in guard error == nil else { debugPrint("DNSProxySample.App: save error") return } debugPrint("DNSProxySample.App: saved") } } } }
5
0
716
Feb ’24
Entitlement not being recognized by Xcode?
Hello! I have never distributed an apple app before. Right now, I am trying to distribute a macOS app. I created a provisioning profile of type "Developer ID Application" and it has the following capabilities enabled. Now, when I download the profile and use it for my app, xcode gives me the following error: Lmk what I need to do since I am super unfamiliar with this process.
1
0
564
Feb ’24
Supervise device without erasing data?
Hello! I made an iOS app for a research study that blocks network connections with certain websites. I need to block around 2000 web domains. To achieve this, I had two options: Use Screentime API Use Network Extension Screentime API has a limitation that limits the number of websites it can block to 50 (https://developer.apple.com/documentation/managedsettings/webcontentsettings/blockedbyfilter-swift.property). The Network Extension on the other hand requires my device to be in supervised mode, which as I understand it, involves erasing the data on the phone and resetting it. Hence, I am here to ask if there is a way to do this without erasing user data when setting the device into supervised mode. Also, I am open to hearing any other alternatives I could pursue. Thanks!!
2
0
744
Feb ’24
'main' attribute cannot be used in a module that contains top-level code
Hi! I'm having this issue that wasn't present before in this project. In my app's entry file, which is named 'controlShiftApp.swift' and NOT 'main.swift' (which has been documented to cause the same error), the @main attribute gives the following error: 'main' attribute cannot be used in a module that contains top-level code I have no other files named main.swift in this target. I only have main.swift in the targets for system extensions. I also haven't used @main anywhere else in this project. Here is a screenshot to show you what I mean. I'd really appreciate inputs on this matter. I need to get this fixed so that I can continue my development ASAP. Also, I'm new to Swift so many things are not as trivial to me, and I would like it if you could give me clear steps on how to resolve this. Thanks!
2
0
1.6k
Sep ’23
Make basic content filter work on Mac Catalyst
Hello! New to swift development. I've created a very basic iOS app that uses the network extension to block web domains. Now, I am trying to make it work on a macOS using Mac Catalyst. However, when I build the project, I get this error: 2023-09-08 23:31:32.540010+0600 controlShift[69583:2468143] [Metadata] unable to get a dev_t for store 1795162192. 2023-09-08 23:31:33.986014+0600 controlShift[69583:2467453] [] -[NEFilterManager saveToPreferencesWithCompletionHandler:]_block_invoke_3: failed to save the new configuration: (null) The app launches and the UI works correctly. However, it fails to save the preference as stated in the error, so it does not block anything. Here is the relevant part of the code in the root file: var body: some Scene { WindowGroup { ContentView() .environment(\.managedObjectContext, persistenceController.container.viewContext) .onAppear { NEFilterManager.shared().loadFromPreferences { error in if let loadError = error { print("Failed to load the filter configuration: \(loadError)") return } } DispatchQueue.main.asyncAfter(deadline: .now()+1.5) { if NEFilterManager.shared().providerConfiguration == nil { let newConfiguration = NEFilterProviderConfiguration() newConfiguration.username = "UserName" newConfiguration.organization = "myApp " newConfiguration.filterBrowsers = true newConfiguration.filterSockets = true newConfiguration.serverAddress = "http://192.168.100.48:3000" NEFilterManager.shared().providerConfiguration = newConfiguration } NEFilterManager.shared().isEnabled = true NEFilterManager.shared().saveToPreferences { error in if let saveError = error { print("Failed to save the filter configuration: \(saveError)") } } } } } I'm at a loss for what is wrong. Lmk if you need additional details. Thanks! btw, I am very new to swift and iOS/macOS development in general so if there's a better way to write or structure the logic inside the "onAppear" method (of which I'm sure there is), lmk as well. ^_^
5
0
873
Sep ’23
Filter content without MDM profile?
Hello! I'm new to iOS development and am developing an app that blocks certain websites. At the moment, I'm thinking of using the Network Extension capability to do the job. From what I have read, in the production version of the app, you'd need to make use of MDM profiles since NE filtering only works on supervised devices. So, I'm here to ask the community if there are better options than using this method. As far as screen time api is concerned, I believe it requires the user to specify which websites they want blocked by themselves using the activity picker so that doesn't quite work for me since i want to allow the app to block groups of websites by itself based on the user's preference. Thanks!
4
1
1.1k
Aug ’23
Managed Settings shield website using a list of urls
Hello! Rookie Swift developer here! I am trying to make an app that uses the Screen Time API to block a list of websites. Specifically, I want it to take a list of web domains in String format and restrict them instead of using the FamilyActivityPicker. So far, I have been unsuccessful. When using the FamilyActivityPicker, I have been able to restrict websites by modifying the shield instance variable of the ManagedSettingsStore. let store = ManagedSettingsStore() // Got selection from familyActivityPicker. store.shield.webDomains = selection.webDomainTokens "store.shield.webDomains" is of type "Set<Token>" and as far as I know, you can create a WebDomain struct with a String url but not Token. I was only able to get a token using the FamilyActivityPicker. Hence, I was wondering if it was even possible to do this and if so, how you'd go about it. Thanks!
1
1
821
Aug ’23