Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Local Network Permission #282

Open
z234009184 opened this issue Feb 26, 2022 · 19 comments
Open

Local Network Permission #282

z234009184 opened this issue Feb 26, 2022 · 19 comments
Assignees
Labels
enhancement New feature or request wait more Further information is requested

Comments

@z234009184
Copy link

z234009184 commented Feb 26, 2022

Feature Description
Describe what functionality you want to see.

Thank you for your development of this library. I have a small demand. When the application is started for the first time, it mistakenly touches that it is not allowed to use the network permission. How can I know that the user does not open the network permission and let the user go to the setting page to open the network permission?

let data = CTCellularData()
        let state = data.restrictedState
        switch state {
          case .notRestricted:
          DispatchQueue.main.async {
              authorizedHandler()
          }
          default:
          DispatchQueue.main.async {
              unAuthorizedHandler()
          }
        }
@z234009184 z234009184 added the enhancement New feature or request label Feb 26, 2022
@ivanvorobei
Copy link
Member

Hi!
Which permission do you using for request?

@z234009184
Copy link
Author

image

Now SPPermission can not support Network permission
Please help

@ivanvorobei
Copy link
Member

So you want to add network permission, right?

@z234009184
Copy link
Author

I'd appreciate it if you could

@yuchenz27
Copy link

I am also very interested in the wireless data permission, I guess that is what you called the network permission right?

@z234009184
Copy link
Author

Yes,in China, when the application is started for the first time, it will apply to the system for network permission. If the user accidentally prohibits the network permission, the application will not be able to access the network until the user goes to the setting center to open the wireless network permission.

@z234009184
Copy link
Author

image

@ivanvorobei
Copy link
Member

@z234009184 fully right, no way to simple manage this permission. I can to get state of permission and request it once.
But sorry, busy with my work now.

@ivanvorobei
Copy link
Member

@z234009184 are you still need this permission?

@ivanvorobei ivanvorobei added the wait more Further information is requested label Apr 17, 2022
@z234009184
Copy link
Author

@z234009184 are you still need this permission?

Yes, I think it is necessary to add network permissions as an extension, so that you can only use the PermissionsKit

@ivanvorobei
Copy link
Member

Ok, doing it

@ivanvorobei
Copy link
Member

I did some refresh. Available one way to request permission, but no way to get status correctly. Each time need to do request permission for get state.
So apple hide API and its doesn't look like solution. Any ideas?

@ivanvorobei ivanvorobei changed the title Application fist launch need the Network permission Local Network Permission Apr 17, 2022
@yuchenz27
Copy link

yuchenz27 commented Apr 20, 2022

Hey I am coming from #280. I think the permission discussed in this issue is Wireless Data Permission not Local Network Permission.

I am looking for solutions for both of these permissions.

@ivanvorobei
Copy link
Member

@yuchenz27 I think you right, my bad. If you have code share with me, I am ready to integrate it shortly

@yuchenz27
Copy link

yuchenz27 commented Apr 20, 2022

@ivanvorobei There is no official access to these permissions. I have done some research on the Internet and found the following candidate solutions.

For Wireless Data Permission, this code works https://stackoverflow.com/questions/25623272/how-to-use-scnetworkreachability-in-swift?noredirect=1&lq=1

import SystemConfiguration

func connectedToNetwork() -> Bool {

    var zeroAddress = sockaddr_in()
    zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)
    zeroAddress.sin_family = sa_family_t(AF_INET)

    guard let defaultRouteReachability = withUnsafePointer(to: &zeroAddress, {
        $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
            SCNetworkReachabilityCreateWithAddress(nil, $0)
        }
    }) else {
        return false
    }

    var flags: SCNetworkReachabilityFlags = []
    if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) {
        return false
    }

    let isReachable = flags.contains(.reachable)
    let needsConnection = flags.contains(.connectionRequired)

    return (isReachable && !needsConnection)
}

For Local Network Permission, this code works https://stackoverflow.com/questions/63940427/ios-14-how-to-trigger-local-network-dialog-and-check-user-answer/65800221#65800221

import Foundation
import Network

@available(iOS 14.0, *)
public class LocalNetworkAuthorization: NSObject {
    private var browser: NWBrowser?
    private var netService: NetService?
    private var completion: ((Bool) -> Void)?
    
    public func requestAuthorization(completion: @escaping (Bool) -> Void) {
        self.completion = completion
        
        // Create parameters, and allow browsing over peer-to-peer link.
        let parameters = NWParameters()
        parameters.includePeerToPeer = true
        
        // Browse for a custom service type.
        let browser = NWBrowser(for: .bonjour(type: "_bonjour._tcp", domain: nil), using: parameters)
        self.browser = browser
        browser.stateUpdateHandler = { newState in
            switch newState {
            case .failed(let error):
                print(error.localizedDescription)
            case .ready, .cancelled:
                break
            case let .waiting(error):
                print("Local network permission has been denied: \(error)")
                self.reset()
                self.completion?(false)
            default:
                break
            }
        }
        
        self.netService = NetService(domain: "local.", type:"_lnp._tcp.", name: "LocalNetworkPrivacy", port: 1100)
        self.netService?.delegate = self
        
        self.browser?.start(queue: .main)
        self.netService?.publish()
    }
    
    private func reset() {
        self.browser?.cancel()
        self.browser = nil
        self.netService?.stop()
        self.netService = nil
    }
}

@available(iOS 14.0, *)
extension LocalNetworkAuthorization : NetServiceDelegate {
    public func netServiceDidPublish(_ sender: NetService) {
        self.reset()
        print("Local network permission has been granted")
        completion?(true)
    }
}

The problem for these two solutions is that they trigger the permission dialog and return the permission status through a single function, so there is no way to just check the permission status without triggering the dialog for the first time (which makes sense because we will trigger the dialog for the first time anyway).

In addition, for the second code snippet, if the user allows the permission, it will take about 0.5s to get the permission status (which is success) every time in the future sessions. On the contrary, if the user denies the permission, it will instantly return the denies status in the future sessions.

@ivanvorobei
Copy link
Member

@yuchenz27 thanks for your research! I will think how I can integrate it

@yuchenz27
Copy link

@ivanvorobei no problem, your plugin is awesome. I don't think those solutions are perfect, probably there is a better way.

@yuchenz27
Copy link

Just a reminder, the code I left for Wireless Data Permission is not actually for the permission. It just checks if there is a valid network connection. So if you grant the permission and close the cellular data on your iPhone, it will still return false.

@ivanvorobei
Copy link
Member

@yuchenz27 both permissions not true public API, so it make some logic and happen request. Its not clean solution, but best which we can propose to developers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request wait more Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants