![]() |
Status: Tethering - noch Probleme mit MacOS und iOS
Status: Tethering
Da das Thema deutlich aufwändiger ist, als erwartet, hier mal mein aktueller Status mit ein paar Handlungsempfehlungen. In meinem Fall habe ich eine Haupt-App und eine Fernsteuerung. Die Fernsteuerung sucht und verbindet sich mit der Hauptapp und beide können jetzt der jeweils anderen Daten und somit Handlungs-/Anzeige-Anweisungen schicken. - die Windows-App kann sowohl andere Manager und Profiles im Netzwerk suchen und finden (discover) als auch gefunden werden und dann zwischen beiden Apps Daten austauschen - hier ist wichtig, dass das eigene WLAN als "Privat" und nicht als "Öffentlich" gekennzeichnet wird, teilweise muss man die App auch in der Firewall nochmals bewusst erlauben. - die Android-App kann sowohl andere Manager und Profiles im Netzwerk suchen und finden (discover) als auch gefunden werden und dann zwischen beiden Apps Daten austauschen - Permission Internet muss auf "true" gesetzt sein - die MacOS-App kann andere Manager und Profiles im Netzwerk suchen und finden (discover), diesem auch Daten schicken und Antworten empfangen, kann aber nicht gefunden werden. Ursache: DoOnReceiveData wird nie errreicht Folgende Entitlements wurden gesetzt (Entitlement.TemplateOSX.xml): <key>com.apple.security.network.client</key> <true/> <key>com.apple.security.network.server</key> <true/> - die iOS-App kann beides nicht, weder suchen und finden (discover) noch gefunden werden. Ursache: Beim BroadcastData wird die Exception "Socket-Fehler # 65Keine Route zum Host." bzw. "Socket-Fehler # 9Falsche Dateinummer." geworfen Ich frage mich jetzt: a) Welche Capabitlities müssen für den Identifier auf developer.apple.com für iOS gesetzt werden? b) Welche Capabitlities müssen für den Identifier auf developer.apple.com für MacOS gesetzt werden? c) Welche Entitlements müssen für iOS gesetzt werden (Entitlement.TemplateiOS.xml)? d) Welche Entitlements müssen für MacOS gesetzt werden (Entitlement.TemplateOSX.xml)? e) Welche Properties müssen für iOS gesetzt werden (info.plist.TemplateiOS.xml)? Muss hier z.B. com.apple.developer.networking.multicast gesetzt werden, wo man vorab auch per "Multicast Networking Entitlement Request" nachfragen muss (und dort schon eine AppStore-URL angeben muss, obwohl die App noch gar nicht mit iOS funktioniert) f) Welche Properties müssen für MacOS gesetzt werden (info.plist.TemplateOSX.xml)? Tipp 1: Formulardesigner: das Profile auf Enabled setzen und den Manager aus Disabled und dem Profile keinen Manager zuweisen. Im Programm-Code den Manager auf Enabled setzen und direkt davor dem Profile den Manager zuweisen. Sonst wird schon sehr viel initialisert (z.B. der Netzwerk-Adapter) bevor man erstmalig Zugriff im Code auf die Komponenten hat.
Delphi-Quellcode:
Tipp 2: IP-Adresse des eigenen Adapters nicht automatisch setzen lassen, sondern selbst per Indy auswählen:
CommandApp.Manager := CommandManager;
CommandManager.Enabled := True; [DELPHI] uses IdStack, IdGlobal; function getIPv4Address():String; var AAddresses: TIdStackLocalAddressList; LAddr: TIdStackLocalAddress; I: Integer; prefNetwork,IP: String; begin AAddresses:=TIdStackLocalAddressList.Create(); prefNetwork:='192.';//can be set also outside this functionality before the manager is enabled or the manager-attribute of the profile is set Result:=''; try GStack.GetLocalAddressList(AAddresses); for I := 0 to AAddresses.Count-1 do begin LAddr:=AAddresses[I]; IP:=LAddr.IPAddress; if ((IP<>'127.0.0.1') and ((Result='') or ((prefNetwork>'') and (pos(prefNetwork,IP)=1) and (pos(prefNetwork,Result)<>1)))) then begin case LAddr.IPVersion of Id_IPv4: begin mlog.info('Found IP-address*: '+IP); Result:=IP; end; Id_IPv6: begin mlog.info('Found IP-address: '+IP); end; end; end else mlog.info('Found IP-address: '+IP); end; finally AAddresses.Free; end; end; [DELPHI] Dies passiert an zwei Stellen: System.Tether.Manager.pas
Delphi-Quellcode:
System.Tether.NetworkAdapter.pas
constructor TTetheringAdapter.Create;
var ip:String; begin inherited; FRemoteManagers := TTetheringManagerInfoList.Create; ip:=getIPv4Address(); if (ip>'') then FAdapterConnectionString := ip else FAdapterConnectionString := TTetheringManagerCommunicationThread.EMPTYTOKEN; end;
Delphi-Quellcode:
Zur Sicherheit habe ich es noch hier eingebaut, da wird es aber höchstwahrscheinlich nicht gebraucht:
procedure TTetheringNetworkManagerCommunicationThread.Execute;
... if not LListening then raise ETetheringException.Create(SManagerNetworkCreation); var ip:String; ip:=TStringUtils.getIPv4Address(); if (ip>'') then LRemoteConnectionString := ip + TetheringConnectionSeparator + FTarget else LRemoteConnectionString := EMPTYTOKEN + TetheringConnectionSeparator + FTarget; System.Tether.NetworkAdapter.pas
Delphi-Quellcode:
procedure TTetheringNetworkAdapterCommon.DoDiscoverManagers(Timeout: Cardinal;
const ATargetList: TTetheringTargetHosts; const AProfileGroups, AProfileTexts: TArray<string>); ... LCommand := TTetheringManagerCommand.Create(TTetheringNetworkManagerCommunicationThread.TetheringDiscoverManagers, FAdapterConnectionString, Manager.Version, [FCommunicationThread.FTarget, LGroups, LTexts]); end else begin if (pos(TTetheringNetworkManagerCommunicationThread.EMPTYTOKEN,FAdapterConnectionString)>0) then begin var ip:String; ip:=TStringUtils.getIPv4Address(); if (ip>'') then FAdapterConnectionString:=StringReplace(FAdapterConnectionString,TTetheringNetworkManagerCommunicationThread.EMPTYTOKEN,ip,[]); end; |
AW: Status: Tethering - noch Probleme mit MacOS und iOS
Kleines Update des Status, da ich mittlerweile raus habe, dass es ab iOS 14.x und MacOS 11.x Probleme gibt. Davor als iOS 13.x und MacOS 10.x ging es problemlos.
In Teilen geht es auch mit der neuen Version, aber leider werden iOS-14.x- und Mac-11.x-Apps mit Disover nicht gefunden, weil die Methode
Delphi-Quellcode:
nie erreicht wird.
procedure TTetheringNetworkManagerCommunicationThread.DoOnReceiveData
|
AW: Status: Tethering - noch Probleme mit MacOS und iOS
Status: Tethering
- die Windows-App kann sowohl andere Manager und Profiles im Netzwerk suchen und finden (discover) als auch gefunden werden und dann zwischen beiden Apps Daten austauschen - die Android-App kann sowohl andere Manager und Profiles im Netzwerk suchen und finden (discover) als auch gefunden werden und dann zwischen beiden Apps Daten austauschen - Permission Internet muss auf "true" gesetzt sein - die iOS-App kann andere Manager und Profiles im Netzwerk suchen und finden (discover), diesem auch Daten schicken und Antworten empfangen, kann aber unter iOS 14.x nicht gefunden werden (<iOS 14 funktioniert). Ursache: DoOnReceiveData wird unter iOS 14.x nie errreicht (gleiches gilt für MacOS 11.x) - Es muss via ![]() damit iOS 14.x funktioniert; im Projekt ist das Entitlement aber nicht zu setzen, dies passiert über das Provision Profile automatisch (außer man erzeugt die Entitlement-Datei manuell);
Delphi-Quellcode:
- die MacOS-App kann andere Manager und Profiles im Netzwerk suchen und finden (discover), diesem auch Daten schicken und Antworten empfangen, kann aber unter MacOS 11.x nicht gefunden werden (<MacOS 11.x funktioniert).
<key>com.apple.developer.networking.multicast</key>
<true/> Ursache: DoOnReceiveData wird unter MacOS 11.x nie errreicht (gleiches gilt für iOS 14.x) Folgende Entitlements wurden gesetzt (Entitlement.TemplateOSX.xml oder via Projekt-Optionen):
Delphi-Quellcode:
Tipp 1: Formulardesigner: das Profile auf Enabled setzen und den Manager aus Disabled und dem Profile keinen Manager zuweisen.
<key>com.apple.security.network.client</key>
<true/> <key>com.apple.security.network.server</key> <true/> Im Programm-Code den Manager auf Enabled setzen und direkt davor dem Profile den Manager zuweisen. Sonst wird schon sehr viel initialisert (z.B. der Netzwerk-Adapter) bevor man erstmalig Zugriff im Code auf die Komponenten hat.
Delphi-Quellcode:
Tipp 2: für iOS müssen eventuell alle Exception gefangen werden, weil ansonsten das nicht erfolgreiche binden eines Sockets zum Abbruch führen kann
CommandApp.Manager := CommandManager;
CommandManager.Enabled := True; Socket-Fehler # 48Adresse wird bereits verwendet: $0000000100BCFDD0 _ZN7Idstack8TIdStack16RaiseSocketErrorEi + 316 $0000000100BD0B74 _ZN7Idstack8TIdStack20RaiseLastSocketErrorEv + 72 $0000000100BD0A18 _ZN7Idstack8TIdStack19CheckForSocketErrorEi + 44 $0000000100BCBD00 _ZN15Idstackvclposix16TIdStackVCLPosix4BindEiN6Sys tem13UnicodeStringEtN8Idglobal12TIdIPVersionE + 344 $0000000100BD99E8 _ZN14Idsockethandle15TIdSocketHandle4BindEv + 316 $0000000100BF84F8 _ZN17Idcustomtcpserver18TIdCustomTCPServer14StartL isteningEv + 188
Delphi-Quellcode:
Tipp 3: IP-Adresse des eigenen Adapters nicht automatisch setzen lassen, sondern selbst per Indy auswählen:
Application.OnException:=TgoExceptionReporter.ExceptionHandler;
TMessageManager.DefaultManager.SubscribeToMessage(TgoExceptionReportMessage, HandleExceptionReport);
Delphi-Quellcode:
Dies passiert an zwei Stellen:
uses IdStack, IdGlobal;
function getIPv4Address():String; var AAddresses: TIdStackLocalAddressList; LAddr: TIdStackLocalAddress; I: Integer; prefNetwork,IP: String; begin AAddresses:=TIdStackLocalAddressList.Create(); prefNetwork:='192.';//can be set also outside this functionality before the manager is enabled or the manager-attribute of the profile is set Result:=''; try GStack.GetLocalAddressList(AAddresses); for I := 0 to AAddresses.Count-1 do begin LAddr:=AAddresses[I]; IP:=LAddr.IPAddress; if ((IP<>'127.0.0.1') and ((Result='') or ((prefNetwork>'') and (pos(prefNetwork,IP)=1) and (pos(prefNetwork,Result)<>1)))) then begin case LAddr.IPVersion of Id_IPv4: begin mlog.info('Found IP-address*: '+IP); Result:=IP; end; Id_IPv6: begin mlog.info('Found IP-address: '+IP); end; end; end else mlog.info('Found IP-address: '+IP); end; finally AAddresses.Free; end; end; System.Tether.Manager.pas
Delphi-Quellcode:
System.Tether.NetworkAdapter.pas
constructor TTetheringAdapter.Create;
var ip:String; begin inherited; FRemoteManagers := TTetheringManagerInfoList.Create; ip:=getIPv4Address(); if (ip>'') then FAdapterConnectionString := ip else FAdapterConnectionString := TTetheringManagerCommunicationThread.EMPTYTOKEN; end;
Delphi-Quellcode:
Zur Sicherheit habe ich es noch hier eingebaut, da wird es aber höchstwahrscheinlich nicht gebraucht:
procedure TTetheringNetworkManagerCommunicationThread.Execute;
... if not LListening then raise ETetheringException.Create(SManagerNetworkCreation); var ip:String; ip:=TStringUtils.getIPv4Address(); if (ip>'') then LRemoteConnectionString := ip + TetheringConnectionSeparator + FTarget else LRemoteConnectionString := EMPTYTOKEN + TetheringConnectionSeparator + FTarget; System.Tether.NetworkAdapter.pas
Delphi-Quellcode:
procedure TTetheringNetworkAdapterCommon.DoDiscoverManagers(Timeout: Cardinal;
const ATargetList: TTetheringTargetHosts; const AProfileGroups, AProfileTexts: TArray<string>); ... LCommand := TTetheringManagerCommand.Create(TTetheringNetworkManagerCommunicationThread.TetheringDiscoverManagers, FAdapterConnectionString, Manager.Version, [FCommunicationThread.FTarget, LGroups, LTexts]); end else begin if (pos(TTetheringNetworkManagerCommunicationThread.EMPTYTOKEN,FAdapterConnectionString)>0) then begin var ip:String; ip:=TStringUtils.getIPv4Address(); if (ip>'') then FAdapterConnectionString:=StringReplace(FAdapterConnectionString,TTetheringNetworkManagerCommunicationThread.EMPTYTOKEN,ip,[]); end; |
AW: Status: Tethering - noch Probleme mit MacOS und iOS
Noch ein Tipp zum Beantragen des Multicast-Entitlement, da dies bei mir in Summe 10 Tage und 3 Rückfragen seitens Apple benötigt hat:
- sich die Mühe geben, den Applikationsflow zu beschreiben - angeben, dass die MacOS/iOS-App sich mit einer Android/Windows/iOS/MacOS-App verbinden kann und man die Embacadero Delphi Tethering Implementierung nutzt; sonst empfiehlt Apple Bonjour zu nutzen; - als technisches Verfahren IP based Broadcast UDP (Ports 2020-2040) angeben |
AW: Status: Tethering - noch Probleme mit MacOS und iOS
Falls jemand für den Issue voten möchte:
RSP-34147 Tethering: MacOS 11.x/iOS 14.x devices are not found with TTetheringManager.DiscoverManagers |
AW: Status: Tethering - noch Probleme mit MacOS und iOS
Ich habe ein Bugfix für das Thema iOS und Tethering bei aktivierten Mobilen Daten gebaut und eingestellt. Damit ergibt sich ein neuer Status für dieses Thema:
- weiterhin findet man iOS 14.x und MacOS 11.x Devices mit der Discover-Funktion nicht Alles andere funktioniert nun. |
AW: Status: Tethering - noch Probleme mit MacOS und iOS
Status: Tethering
- die Windows-App kann sowohl andere Manager und Profiles im Netzwerk suchen und finden (discover) als auch gefunden werden und dann zwischen beiden Apps Daten austauschen - die Android-App kann sowohl andere Manager und Profiles im Netzwerk suchen und finden (discover) als auch gefunden werden und dann zwischen beiden Apps Daten austauschen - Permission Internet muss auf "true" gesetzt sein - die iOS-App kann andere Manager und Profiles im Netzwerk suchen und finden (discover), diesem auch Daten schicken und Antworten empfangen, kann aber unter iOS 14.x nicht gefunden werden (<iOS 14 funktioniert). Ursache: DoOnReceiveData wird unter iOS 14.x nie errreicht (gleiches gilt für MacOS 11.x) - Es muss via ![]() damit iOS 14.x funktioniert; im Projekt ist das Entitlement aber nicht zu setzen, dies passiert über das Provision Profile automatisch (außer man erzeugt die Entitlement-Datei manuell);
Delphi-Quellcode:
- die MacOS-App kann andere Manager und Profiles im Netzwerk suchen und finden (discover), diesem auch Daten schicken und Antworten empfangen, kann aber unter MacOS 11.x nicht gefunden werden (<MacOS 11.x funktioniert).
<key>com.apple.developer.networking.multicast</key>
<true/> Ursache: DoOnReceiveData wird unter MacOS 11.x nie errreicht (gleiches gilt für iOS 14.x) Folgende Entitlements wurden gesetzt (Entitlement.TemplateOSX.xml oder via Projekt-Optionen):
Delphi-Quellcode:
Das Ticket für das iOS 14.x und MacOS 11.x-Problem ist unter
<key>com.apple.security.network.client</key>
<true/> <key>com.apple.security.network.server</key> <true/> ![]() Tipp 1: Formulardesigner: das Profile auf Enabled setzen und den Manager aus Disabled und dem Profile keinen Manager zuweisen. Im Programm-Code den Manager auf Enabled setzen und direkt davor dem Profile den Manager zuweisen. Sonst wird schon sehr viel initialisert (z.B. der Netzwerk-Adapter) bevor man erstmalig Zugriff im Code auf die Komponenten hat.
Delphi-Quellcode:
Tipp 2: für iOS müssen eventuell alle Exception gefangen werden, weil ansonsten das nicht erfolgreiche binden eines Sockets zum Abbruch führen kann
CommandApp.Manager := CommandManager;
CommandManager.Enabled := True; Socket-Fehler # 48Adresse wird bereits verwendet: $0000000100BCFDD0 _ZN7Idstack8TIdStack16RaiseSocketErrorEi + 316 $0000000100BD0B74 _ZN7Idstack8TIdStack20RaiseLastSocketErrorEv + 72 $0000000100BD0A18 _ZN7Idstack8TIdStack19CheckForSocketErrorEi + 44 $0000000100BCBD00 _ZN15Idstackvclposix16TIdStackVCLPosix4BindEiN6Sys tem13UnicodeStringEtN8Idglobal12TIdIPVersionE + 344 $0000000100BD99E8 _ZN14Idsockethandle15TIdSocketHandle4BindEv + 316 $0000000100BF84F8 _ZN17Idcustomtcpserver18TIdCustomTCPServer14StartL isteningEv + 188
Delphi-Quellcode:
Tipp 3: IP-Adresse des eigenen Adapters nicht automatisch setzen lassen, sondern selbst per Indy auswählen:
Application.OnException:=TgoExceptionReporter.ExceptionHandler;
TMessageManager.DefaultManager.SubscribeToMessage(TgoExceptionReportMessage, HandleExceptionReport);
Delphi-Quellcode:
Dies passiert an zwei Stellen:
uses IdStack, IdGlobal, System.Classes;
class var prefNetworkList:TStringList; class function getIPv4Address():String; function checkForPrefNetwork(value:String):boolean; var i:integer; begin Result:=false; for i:=0 to prefNetworkList.Count-1 do begin if (pos(prefNetworkList[i],value)=1) then begin Result:=true; exit; end; end; end; var AAddresses: TIdStackLocalAddressList; LAddr: TIdStackLocalAddress; I: Integer; IP: String; begin AAddresses:=TIdStackLocalAddressList.Create(); Result:=''; if (prefNetworkList=nil) then begin prefNetworkList:=TStringList.Create(); prefNetworkList.Add('192.168.'); end; try GStack.GetLocalAddressList(AAddresses); for I := 0 to AAddresses.Count-1 do begin LAddr:=AAddresses[I]; IP:=LAddr.IPAddress; if ((IP<>'127.0.0.1') and ((Result='') or ((prefNetworkList.Count>0) and (checkForPrefNetwork(IP)) and (not checkForPrefNetwork(result))))) then begin case LAddr.IPVersion of Id_IPv4: begin log.d('Found IP-address*: '+IP); Result:=IP; end; Id_IPv6: begin log.d('Found IP-address: '+IP); end; end; end else log.d('Found IP-address: '+IP); end; finally AAddresses.Free; end; end; System.Tether.Manager.pas
Delphi-Quellcode:
System.Tether.NetworkAdapter.pas
constructor TTetheringAdapter.Create;
var ip:String; begin inherited; FRemoteManagers := TTetheringManagerInfoList.Create; ip:=getIPv4Address(); if (ip>'') then FAdapterConnectionString := ip else FAdapterConnectionString := TTetheringManagerCommunicationThread.EMPTYTOKEN; end;
Delphi-Quellcode:
Zur Sicherheit habe ich es noch hier eingebaut, da wird es aber höchstwahrscheinlich nicht gebraucht:
procedure TTetheringNetworkManagerCommunicationThread.Execute;
... if not LListening then raise ETetheringException.Create(SManagerNetworkCreation); var ip:String; ip:=TStringUtils.getIPv4Address(); if (ip>'') then LRemoteConnectionString := ip + TetheringConnectionSeparator + FTarget else LRemoteConnectionString := EMPTYTOKEN + TetheringConnectionSeparator + FTarget; System.Tether.NetworkAdapter.pas
Delphi-Quellcode:
Tipp 4: Tethering mit iOS bei aktivierten Mobilen Daten:
procedure TTetheringNetworkAdapterCommon.DoDiscoverManagers(Timeout: Cardinal;
const ATargetList: TTetheringTargetHosts; const AProfileGroups, AProfileTexts: TArray<string>); ... LCommand := TTetheringManagerCommand.Create(TTetheringNetworkManagerCommunicationThread.TetheringDiscoverManagers, FAdapterConnectionString, Manager.Version, [FCommunicationThread.FTarget, LGroups, LTexts]); end else begin if (pos(TTetheringNetworkManagerCommunicationThread.EMPTYTOKEN,FAdapterConnectionString)>0) then begin var ip:String; ip:=TStringUtils.getIPv4Address(); if (ip>'') then FAdapterConnectionString:=StringReplace(FAdapterConnectionString,TTetheringNetworkManagerCommunicationThread.EMPTYTOKEN,ip,[]); end; Damit bei aktivierten Mobilen Daten unter iOS das Tethering funktioniert, muss die Funktion BroadcastData in System.Tether.Comm gefixt werden. Dies ist auch als Issue bei EMBT eingestellt ( ![]()
Delphi-Quellcode:
procedure TTetheringNetworkServerCommUDP.BroadcastData(const AData: TBytes; const AHost: string; InitialPort, FinalPort: Integer); var I, J: Integer; LHost: string; LData: TBytes; allWithException:boolean; toRaise:Exception; begin if TTetheringAdapter.IsLoggingItem(TTetheringAdapter.TTetheringLogItem.Comm) then TLogAdapter.Log('** UDP ** BroadcastData to "' + AHost + '": "' + TEncoding.UTF8.GetString(AData) + '"'); if AHost = '' then begin if FIPVersion = TCommIPVersion.IP_IPv4 then LHost := '255.255.255.255' else LHost := '0:0:0:0:0:0:255.255.255.255'; allWithException:=true; toRaise:=nil; for J := 0 to FUDPServer.Bindings.Count - 1 do begin try LData := TEncoding.UTF8.GetBytes(StringReplace( TEncoding.UTF8.GetString(AData), '|' + TetheringMULTIHOMED + '$', '|' + FUDPServer.Bindings.Sockets[J].IP + '$', [])); for I := InitialPort to FinalPort do FUDPServer.Bindings.Sockets[J].Broadcast(LData, I, LHost); allWithException:=false; except on E: Exception do begin if (toRaise=nil) then toRaise:=e; end; end; end; if (allWithException and (toRaise<>nil)) then raise(toRaise); end else for I := InitialPort to FinalPort do FUDPServer.SendBuffer(AHost, I, AData); end; |
AW: Status: Tethering - noch Probleme mit MacOS und iOS
Dankesehr für die Updates.
Ich komme im Moment leider nicht zum Testen. :-( Für die ganze Bürokratie muss man wohl noch zwei Leute einstellen. :-D |
AW: Status: Tethering - noch Probleme mit MacOS und iOS
Und wieder ein ganz kleines Code-Update, da die IP-Adressen-Ermittlung nur funktionierte, wenn man eine Indy-Net-Komponente schon irgendwo im Projekt eingebunden hatte:
Status: Tethering - die Windows-App kann sowohl andere Manager und Profiles im Netzwerk suchen und finden (discover) als auch gefunden werden und dann zwischen beiden Apps Daten austauschen - die Android-App kann sowohl andere Manager und Profiles im Netzwerk suchen und finden (discover) als auch gefunden werden und dann zwischen beiden Apps Daten austauschen - Permission Internet muss auf "true" gesetzt sein - die iOS-App kann andere Manager und Profiles im Netzwerk suchen und finden (discover), diesem auch Daten schicken und Antworten empfangen, kann aber unter iOS 14.x nicht gefunden werden (<iOS 14 funktioniert). Ursache: DoOnReceiveData wird unter iOS 14.x nie errreicht (gleiches gilt für MacOS 11.x) - Es muss via ![]() damit iOS 14.x funktioniert; im Projekt ist das Entitlement aber nicht zu setzen, dies passiert über das Provision Profile automatisch (außer man erzeugt die Entitlement-Datei manuell);
Delphi-Quellcode:
- die MacOS-App kann andere Manager und Profiles im Netzwerk suchen und finden (discover), diesem auch Daten schicken und Antworten empfangen, kann aber unter MacOS 11.x nicht gefunden werden (<MacOS 11.x funktioniert).
<key>com.apple.developer.networking.multicast</key>
<true/> Ursache: DoOnReceiveData wird unter MacOS 11.x nie errreicht (gleiches gilt für iOS 14.x) Folgende Entitlements wurden gesetzt (Entitlement.TemplateOSX.xml oder via Projekt-Optionen):
Delphi-Quellcode:
Das Ticket für das iOS 14.x und MacOS 11.x-Problem ist unter
<key>com.apple.security.network.client</key>
<true/> <key>com.apple.security.network.server</key> <true/> ![]() Tipp 1: Formulardesigner: das Profile auf Enabled setzen und den Manager aus Disabled und dem Profile keinen Manager zuweisen. Im Programm-Code den Manager auf Enabled setzen und direkt davor dem Profile den Manager zuweisen. Sonst wird schon sehr viel initialisert (z.B. der Netzwerk-Adapter) bevor man erstmalig Zugriff im Code auf die Komponenten hat.
Delphi-Quellcode:
Tipp 2: für iOS müssen eventuell alle Exception gefangen werden, weil ansonsten das nicht erfolgreiche binden eines Sockets zum Abbruch führen kann
CommandApp.Manager := CommandManager;
CommandManager.Enabled := True; Socket-Fehler # 48Adresse wird bereits verwendet: $0000000100BCFDD0 _ZN7Idstack8TIdStack16RaiseSocketErrorEi + 316 $0000000100BD0B74 _ZN7Idstack8TIdStack20RaiseLastSocketErrorEv + 72 $0000000100BD0A18 _ZN7Idstack8TIdStack19CheckForSocketErrorEi + 44 $0000000100BCBD00 _ZN15Idstackvclposix16TIdStackVCLPosix4BindEiN6Sys tem13UnicodeStringEtN8Idglobal12TIdIPVersionE + 344 $0000000100BD99E8 _ZN14Idsockethandle15TIdSocketHandle4BindEv + 316 $0000000100BF84F8 _ZN17Idcustomtcpserver18TIdCustomTCPServer14StartL isteningEv + 188
Delphi-Quellcode:
Tipp 3: IP-Adresse des eigenen Adapters nicht automatisch setzen lassen, sondern selbst per Indy auswählen:
Application.OnException:=TgoExceptionReporter.ExceptionHandler;
TMessageManager.DefaultManager.SubscribeToMessage(TgoExceptionReportMessage, HandleExceptionReport);
Delphi-Quellcode:
Dies passiert an zwei Stellen:uses IdStack, IdGlobal, IdSSLOpenSSL, System.Classes; class var prefNetworkList:TStringList; class function getIPv4Address():String; function checkForPrefNetwork(value:String):boolean; var i:integer; begin Result:=false; for i:=0 to prefNetworkList.Count-1 do begin if (pos(prefNetworkList[i],value)=1) then begin Result:=true; exit; end; end; end; var AAddresses: TIdStackLocalAddressList; LAddr: TIdStackLocalAddress; I: Integer; IP: String; begin AAddresses:=TIdStackLocalAddressList.Create(); Result:=''; if (prefNetworkList=nil) then begin prefNetworkList:=TStringList.Create(); prefNetworkList.Add('192.168.'); end; try if (GStack=nil) then begin var IdSSLIOHandlerSocketOpenSSL:TIdSSLIOHandlerSocketOpenSSL; IdSSLIOHandlerSocketOpenSSL:=TIdSSLIOHandlerSocketOpenSSL.create(); end; GStack.GetLocalAddressList(AAddresses); for I := 0 to AAddresses.Count-1 do begin LAddr:=AAddresses[I]; IP:=LAddr.IPAddress; if ((IP<>'127.0.0.1') and ((Result='') or ((prefNetworkList.Count>0) and (checkForPrefNetwork(IP)) and (not checkForPrefNetwork(result))))) then begin case LAddr.IPVersion of Id_IPv4: begin log.d('Found IP-address*: '+IP); Result:=IP; end; Id_IPv6: begin log.d('Found IP-address: '+IP); end; end; end else log.d('Found IP-address: '+IP); end; finally AAddresses.Free; end; end; System.Tether.Manager.pas
Delphi-Quellcode:
System.Tether.NetworkAdapter.pas
constructor TTetheringAdapter.Create;
var ip:String; begin inherited; FRemoteManagers := TTetheringManagerInfoList.Create; ip:=getIPv4Address(); if (ip>'') then FAdapterConnectionString := ip else FAdapterConnectionString := TTetheringManagerCommunicationThread.EMPTYTOKEN; end;
Delphi-Quellcode:
Zur Sicherheit habe ich es noch hier eingebaut, da wird es aber höchstwahrscheinlich nicht gebraucht:
procedure TTetheringNetworkManagerCommunicationThread.Execute;
... if not LListening then raise ETetheringException.Create(SManagerNetworkCreation); var ip:String; ip:=TStringUtils.getIPv4Address(); if (ip>'') then LRemoteConnectionString := ip + TetheringConnectionSeparator + FTarget else LRemoteConnectionString := EMPTYTOKEN + TetheringConnectionSeparator + FTarget; System.Tether.NetworkAdapter.pas
Delphi-Quellcode:
Tipp 4: Tethering mit iOS bei aktivierten Mobilen Daten:
procedure TTetheringNetworkAdapterCommon.DoDiscoverManagers(Timeout: Cardinal;
const ATargetList: TTetheringTargetHosts; const AProfileGroups, AProfileTexts: TArray<string>); ... LCommand := TTetheringManagerCommand.Create(TTetheringNetworkManagerCommunicationThread.TetheringDiscoverManagers, FAdapterConnectionString, Manager.Version, [FCommunicationThread.FTarget, LGroups, LTexts]); end else begin if (pos(TTetheringNetworkManagerCommunicationThread.EMPTYTOKEN,FAdapterConnectionString)>0) then begin var ip:String; ip:=TStringUtils.getIPv4Address(); if (ip>'') then FAdapterConnectionString:=StringReplace(FAdapterConnectionString,TTetheringNetworkManagerCommunicationThread.EMPTYTOKEN,ip,[]); end; Damit bei aktivierten Mobilen Daten unter iOS das Tethering funktioniert, muss die Funktion BroadcastData in System.Tether.Comm gefixt werden. Dies ist auch als Issue bei EMBT eingestellt ( ![]()
Delphi-Quellcode:
procedure TTetheringNetworkServerCommUDP.BroadcastData(const AData: TBytes; const AHost: string; InitialPort, FinalPort: Integer); var I, J: Integer; LHost: string; LData: TBytes; allWithException:boolean; toRaise:Exception; begin if TTetheringAdapter.IsLoggingItem(TTetheringAdapter.TTetheringLogItem.Comm) then TLogAdapter.Log('** UDP ** BroadcastData to "' + AHost + '": "' + TEncoding.UTF8.GetString(AData) + '"'); if AHost = '' then begin if FIPVersion = TCommIPVersion.IP_IPv4 then LHost := '255.255.255.255' else LHost := '0:0:0:0:0:0:255.255.255.255'; allWithException:=true; toRaise:=nil; for J := 0 to FUDPServer.Bindings.Count - 1 do begin try LData := TEncoding.UTF8.GetBytes(StringReplace( TEncoding.UTF8.GetString(AData), '|' + TetheringMULTIHOMED + '$', '|' + FUDPServer.Bindings.Sockets[J].IP + '$', [])); for I := InitialPort to FinalPort do FUDPServer.Bindings.Sockets[J].Broadcast(LData, I, LHost); allWithException:=false; except on E: Exception do begin if (toRaise=nil) then toRaise:=e; end; end; end; if (allWithException and (toRaise<>nil)) then raise(toRaise); end else for I := InitialPort to FinalPort do FUDPServer.SendBuffer(AHost, I, AData); end; |
AW: Status: Tethering - noch Probleme mit MacOS und iOS
gibt es da noch weitere Entwicklungen?
|
AW: Status: Tethering - noch Probleme mit MacOS und iOS
Leider nein, ich habe sowohl den folgenden Issue
![]() offen, wo auch Remy Lebeau (Indy) involviert ist, wo ich zumindest für das MacOS-11-Problem eine Lösung brauche, als auch den Bug ![]() bei EMBT eingestellt. Der Issue hat immerhin 5 Votes, es scheint also auch andere zu stören. |
AW: Status: Tethering - noch Probleme mit MacOS und iOS
So, mittlerweile läuft es bei mir auch mit MacOS11 und iOS14. Ich kann nur leider nicht 100% sagen warum. Das einzige Update, welches mir einfällt, ist das XCode-Update diese Woche. Vielleicht hat dies den Unterschied gemacht.
|
AW: Status: Tethering - noch Probleme mit MacOS und iOS
Danke für das Update!
Werde es mal mit der neuesten XCode Version auch probieren. |
AW: Status: Tethering - noch Probleme mit MacOS und iOS
Wichtig sind mindestens für iOS auch die von mir vorgeschlagenen Code-Anpassungen. Sonst funktioniert es nicht bei eingeschalteten Mobilen Daten.
|
AW: Status: Tethering - noch Probleme mit MacOS und iOS
Ich habe jetzt endlich das letzte Problem verstanden:
- solange ich mein MacBook per USB-C-Kabel mit meinem idPad verbunden habe, kann weder das MacBook noch das iPad discovered (also gefunden werden) - entferne ich das Kabel, funktioniert es Mal schauen, ob es dafür noch eine richtig gute Lösung gibt, aber ein Workaround ist es alle mal. |
AW: Status: Tethering - noch Probleme mit MacOS und iOS
??? Seltsam.
Naja, hast Du schonmal versucht dein iPad über Wifi anzubinden ? Das funktioniert ganz gut. |
AW: Status: Tethering - noch Probleme mit MacOS und iOS
Nein, ich dachte bisher, dass geht gar nicht. Werde ich mir dann mal ansehen.
|
AW: Status: Tethering - noch Probleme mit MacOS und iOS
Hallo Philipp,
versuche gerade Tethering über WLAN auf iOS14 zum Laufen zu bringen - hab alle Deine Schritte gefolgt: die 4 Dateien von Dir eingebunden, die Profiles mit dem Multicast-Entitlement upgedated und das "NSLocalNetworkUsageDescription" begründet. Sobald ich aber den Eintrag "<key>com.apple.developer.networking.multicast </key><true/>" in den Entitlement.Template einfüge, stürzt die iOS-App sofort ab wenn tethering activiert wird ... Irgend eine Idee? Victor |
AW: Status: Tethering - noch Probleme mit MacOS und iOS
Bei einem Absturz lässt sich ja normalerweise die Exception mit etwas Aufwand herausfinden (Aufwand, weil Delphi von Hause aus den StackTrace nur für Windows liefert)
- entweder reindebuggen oder - stückweise den Code mit Log-File-Ausgaben spicken und schauen, wo er aussteigt oder - die Exception im Log-File ausgeben (ich mache dies mit für iOS und Android mit ![]() |
AW: Status: Tethering - noch Probleme mit MacOS und iOS
Hi, ich habe es gerade mal ausprobiert, ging alles sofort anstandslos (Delphi 11), ohne irgendwo irgendwelche zusätzlichen Angaben machen zu müssen, NACHDEM ich das Verbindungskabel des IPAD zum MAC getrennt habe.
Muss ich irgendwo etwas eintragen, damit das im Appstore alles so akzeptiert wird? - Kleine Frage am Rande (habe schon länger keine IOS-Entwicklung mehr gemacht): Unter Projekt, Optionen, Anwendung, Berechtigungen wird gar kein Inhalt angezeigt. War das schon immer so? Bin gerade etwas irritiert... |
AW: Status: Tethering - noch Probleme mit MacOS und iOS
Anstandslos geht es so lange das iPad keine Telefonkarte hat. Mit Telefonkarte (also wahrscheinlich eher iPhone) ging es bei mir nicht so einfach, weil die falsche IP-Adresse gezogen wurde. Das Ticket ist auch noch offen, wenn ich mich recht entsinne, der Workaround ist aber hier dokumentiert.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:47 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz