Closed Jeehut closed 5 years ago
You are absolutely abusing NetService
class. YOU CAN'T PASS SERVICE NAME IN URL!. You must set a delegate for your NetService
instance, then call .resolve(withTimeout:)
method and in netServiceDidResolveAddress(_:)
method in your delegate, you will get a dns which is usable to connect to your SMB Server.
Here is an example, which works on Playground:
import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
var services: [NetService] = []
class ServiceDelegate: NSObject, NetServiceDelegate {
func netServiceDidResolveAddress(_ sender: NetService) {
print(sender.hostName!)
let domain = sender.hostName!.trimmingCharacters(in: CharacterSet(charactersIn: "."))
let url = "smb://" + domain
// Instantiate AMSMB2 object using `url`.
}
}
let sd = ServiceDelegate()
class BrowserDelegate: NSObject, NetServiceBrowserDelegate {
func netServiceBrowser(_ browser: NetServiceBrowser, didFind service: NetService, moreComing: Bool) {
services.append(service)
print(service.name, moreComing)
service.delegate = sd
service.resolve(withTimeout: 10)
}
}
let d = BrowserDelegate()
let b = NetServiceBrowser()
b.delegate = d
b.searchForServices(ofType: "_smb._tcp", inDomain: "")
Oh, that explains why it wasn't working, thank you very much! I will try it as soon as I can and report.
There is no reason to shout tough. 😓 I'm new to the API and couldn't find good learning content on the web. So, please, be kind to me.
That was emphesizing not shouting sorry
It's working now, thank you! 🎉
Oh no, it was all working three days ago, but I just wanted to start a new feature and the same code that was working a few days ago, isn't working anymore. It's showing the same error message as already posted before:
Error Domain=NSPOSIXErrorDomain Code=12 "Cannot allocate memory" UserInfo={NSLocalizedFailureReason=Error code 12: Unknown address family :30. Only IPv4/IPv6 supported so far.}
Here's the code (it follows your example above):
let domain = service.hostName!.trimmingCharacters(in: CharacterSet(charactersIn: "."))
let url = URL(string: "smb://\(domain)")!
smbClient = AMSMB2(url: url, domain: service.domain, credential: credentials)
smbClient?.listShares { [weak self] names, _, error in
guard error == nil else {
// failure case
return
}
self?.smbShares = names
// success handling
}
You can find the full code here.
Looks like I'm running into this of libsmb2 instead of that line. As the error shows, the family of my device is 30
, which should map to IPv6 (according to this document) as supported by libsmb2. So, could it be that HAVE_SOCKADDR_IN6
is not set in AMSMB2? Doesn't it support IPv6?
Do you have any other idea why this might fail?
Okay, I found a solution for the problem: Instead of using hostname
on the NetService
object (which was something like MyServer.local
for me) I am now reading the IP address from the addresses
property by passing the resolved NetService
objec to this method:
private func ipAddress(service: NetService) -> String {
var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
guard let data = service.addresses?.first else { return "" }
data.withUnsafeBytes { (pointer: UnsafePointer<sockaddr>) -> Void in
guard getnameinfo(pointer, socklen_t(data.count), &hostname, socklen_t(hostname.count), nil, 0, NI_NUMERICHOST) == 0 else { return }
}
return String(cString: hostname)
}
In case anyone else comes across the same issue, you might want to try that, too. This still doesn't explain to me, why it was working a few days ago, but I hope it will work this way forever. :)
You can instantiate AMSMB2 not only with IPs but also with domain names. I don't know what was the problem exactly.
Okay, that's weird. Probably a router configuration issue, don't you think? I've already seen that I can't connect to VPN tunnels which are specified by IP address, it only works for domains. This time, it's the other way around though, which is even weirder. ^^
I'm using a Fritz!Box 7xxx with nearly the default settings (only some WiFi configuration changed). Nothing blocked that I know of ... that only in case somebody else comes across this, too. Nothing that's your responsibility to fix or help with here. ;)
Thanks for trying to help, anyways. Much appreciated.
I'm trying to use AMSMB2 to connect to my Synology server at home (which I'm regularly connecting to using my Mac via SMB). My app is running on an Apple TV with tvOS 12.0 and both on the simulator and on my Apple TV, I can find a service, but when calling the
listShares
method or theconnectShare
method I get the following error:The Synology's discovered
NetService
is the name of the server, something likeMyServer
, so it's not an IP address. I also tried my Synology's IP-address, but that didn't work either.You can find the code how I'm using AMSMB2 here on GitHub: https://github.com/Flinesoft/HomeCinema/blob/work/amsmb2/App/Sources/Networking/LocalNetworkConnector.swift
Any idea what might be the issue?