Incident Identifier: 81AB2E74-1895-4DA4-9362-AE9E20B13847
Distributor ID: com.apple.AppStore
Hardware Model: iPhone16,2
Process: Uplus [16285]
Path: /private/var/containers/Bundle/Application/F737D7AC-B933-4204-926C-9149AD377F4B/Uplus.app/Uplus
Identifier: com.haier.uhome.Uplus
Version: 9.0.0 (2024091802)
AppStoreTools: 16A242b
AppVariant: 1:iPhone16,2:18
Code Type: ARM-64 (Native)
Role: Foreground
Parent Process: launchd [1]
Coalition: com.haier.uhome.Uplus [4813]
Date/Time: 2024-10-29 11:43:30.8727 +0800
Launch Time: 2024-10-29 11:43:30.8707 +0800
OS Version: iPhone OS 18.1 (22B5045g)
Release Type: Beta
Baseband Version: 2.20.02
Report Version: 104
Exception Type: EXC_BAD_ACCESS (SIGKILL)
Exception Subtype: KERN_PROTECTION_FAILURE at 0x00000001e95280e0
Exception Codes: 0x0000000000000002, 0x00000001e95280e0
VM Region Info: 0x1e95280e0 is in 0x1e9528050-0x1e956c050; bytes after start: 144 bytes before end: 278383
REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL
mapped file 1e9528000-1e9528050 [ 80] r--/rw- SM=COW Object_id=f1de19db
---> __TPRO_CONST 1e9528050-1e956c050 [ 272K] r--/rw- SM=COW /usr/lib/dyld
mapped file 1e956c050-1e9570000 [ 16K] r--/rw- SM=COW Object_id=f1de19db
Termination Reason: <0x2A> 2
Triggered by Thread: 0
Thread 0 Crashed:
0 dyld 0x00000001ac079500 0x1ac03f000 + 238848
1 dyld 0x00000001ac072bcc 0x1ac03f000 + 211916
Thread 0 crashed with ARM Thread State (64-bit):
x0: 0x2010003030100000 x1: 0x0000000fffffc0d0 x2: 0x0000000000000004 x3: 0x00000001ac047829
x4: 0x0000000000000000 x5: 0x0000000000000000 x6: 0x0000000000000000 x7: 0x0000000000000000
x8: 0x2010003030100000 x9: 0x2010003030100000 x10: 0x000000016b917dfd x11: 0x00000001ac0b4240
x12: 0x0000000000000050 x13: 0x0000000000000044 x14: 0x0000000000052010 x15: 0x0000000000000000
x16: 0x0000000000000000 x17: 0x0000000000000000 x18: 0x0000000000000000 x19: 0x0000000182bb0000
x20: 0x000000016b917b50 x21: 0x000000016b917af8 x22: 0x00000001e9528050 x23: 0x000000016b9177d8
x24: 0x0000000fffffc10c x25: 0x0000000000000000 x26: 0x0000000000000000 x27: 0x0000000000000000
x28: 0x0000000000000000 fp: 0x000000016b917870 lr: 0x84028001ac079380
sp: 0x000000016b9177d0 pc: 0x00000001ac079500 cpsr: 0x60001000
esr: 0x92000047 (Data Abort) byte write Translation fault
Binary Images:
0x1044e8000 - 0x10795bfff main_executable_path_missing arm64 /main_executable_path_missing
0x1ac03f000 - 0x1ac0c29a3 dyld arm64e /usr/lib/dyld
EOF
18.1.crash
Delve into the world of built-in app and system services available to developers. Discuss leveraging these services to enhance your app's functionality and user experience.
Post
Replies
Boosts
Views
Activity
Hi. If the app is in landscape only and when the SKStoreProductViewController is presented, the safeArea changes to what looks like a portrait mode safe area. When the SKStoreProductViewController is dismissed, the safeArea does NOT revert back to the original values.
Is there a way to force the safeArea to "reset"? I've submitted some bug tickets through Apple Feedback but I haven't received any response about it.
The below code will pop up the SKStoreProductViewController and if you have a UIView that is constrained to the safe area, then you can visibly notice that the safe area is changed and doesn't go back.
I have tested this on iPhone 14 Pro, iPhone 15, and iPhone 16 Pro and in the Simulators. The incorrect behavior happens on those and probably more.
Thanks.
#import "ViewController.h"
#import &lt;StoreKit/StoreKit.h&gt;
@interface ViewController ()
@property (nonatomic, strong) SKStoreProductViewController *productViewController;
@end
@implementation ViewController
- (IBAction)buttonTapped:(id)sender {
self.productViewController = [[SKStoreProductViewController alloc] init];
NSDictionary *parameters = @{
@"id" : @"6443575749"
};
[self.productViewController loadProductWithParameters:parameters completionBlock:^(BOOL result, NSError * _Nullable error) {
[self presentViewController:self.productViewController animated:YES completion:^{
// presented
// The panel that is constraint to the safe area visibly shows that the safe area is no longer correct.
}];
}];
}
@end
When trying the request "hotels" on MapKitJS with searchRegionPriority=default, it will return an hotel in Ramallah even if the searchRegion is very far from there. It can happen if your search region is very broad in most place (above Europe if you zoom out a lot, over Turkey and Middle East even if the bounding box is narrower), but on specific places it happens even with a small search region (like in Tripoli, Lebanon, whatever the zoom level). With searchRegionPriority=required, many hotels can be found in the same area.
Reproduce with:
https://maps-api.apple.com/v1/search?q=hotels&searchRegion=34.45512816097114,35.849070061159864,34.428418939926146,35.80795182731595&lang=en&searchRegionPriority=default
Hello,
I have a company laptop thats connected to the internet without a VPN. I need to be able to resolve my company's sub domains using a specific dns server, and have all other domains resolved by the system wide name server.
In windows, this is trivial to do. In an admin powershell I run
"Add-DnsClientNrptRule -Namespace ".foo.mycompany.com" -Nameserver "127.0.0.1"
and resolution requests for *.foo.mycompany.com is sent to a name server running on the localhost. All other dns resolution requests are handled by the system configured resolver.
MacOS does have the /etc/resolver/ solution for this, but my understanding from these forums is that this is not the recommended approach. Note - I have tried it and it works.
AFAIU, the recommended approach is to create a system Network extension using NEDNSProxyProvider, override handleNewFlow() and do what's necessary.
The issue with this solution is that it requires
handling all the dns flow
parsing of DNS datagrams to extract the host
forwarding the datagrams to the appropriate dns server
Handle responses.
Deal with flow control
Handle edge cases.
I was hoping for something much simpler than us needing to implement datagram parsing.
Could you please shed light on our options and how we could proceed ?
Hello,
I have an app in AppStore "Counter Widget". https://apps.apple.com/app/id1522170621
It allows you to add a widget to your homescreen/lockscreen to count anything.
Everything works fine except for one scenario. iOS 18+
I create 2 or more widgets for one counter. For example, medium and small widgets.
I click on the widget button to increase or decrease the value.
The button in the widget uses Button(intent: AppIntent) to update the value and calls WidgetCenter.shared.reloadAllTimelines() to update the second widget for the same counter.
For iOS 18 in this particular scenario, you don't even have to call the WidgetCenter.shared.reloadAllTimelines(). iOS already knows that there is a widget with the same INIntent settings and will update it itself.
Both widgets are updated and show the new value. Everything is correct.
Now on the homescreen I open the widget configuration for one of the widgets to change the INIntent for the widget. For example, i change the background to wallpaper. This is just a skin for the widget, and the widget is associated with the same counter value as before.
As in (2), I click the widget button to increase or decrease the value.
But now only one widget is updated. iOS ignores my call to WidgetCenter.shared.reloadAllTimelines() and does not update the second widget connected to the same counter.
As I found, iOS, when I call WidgetCenter.shared.reloadAllTimelines() from the widget itself, updates other widgets only if INIntent is absolutely equal for them.
Overriding isEqual for them did not help. That is, I cannot specify which fields from my INIntent can be ignored during such an update and consider that widgets are equal and need to be updated. Obviously iOS make this compare outside my code.
The main problem is that when the user adds a widget to the lock screen and increases and decreases the value there. After that, he opens the home screen and the widget there is not synchronized with the value from the widget on the lock screen.
How to solve this problem?
When my macOS app (currently in TestFlight and set for Mac App Store distribution) tries to terminate another app, both terminate() and forceTerminate() consistently return false. However, I can retrieve a list of all running applications so some related APIs do work.
I suspect this limitation is due to sandboxing. I have three questions:
Is there any permission or entitlement I can add in Xcode to allow my app to terminate other applications?
If no such permission exists, is there a way to guide users on how to launch my app (distributed through the Mac App Store) without sandboxing? For example, could they set it up to launch as a daemon or agent?
If unsandboxing is impossible, would I need to create a separate target specifically without sandboxing? In other words, my MacOS app would communicate with my unsandboxed daemon that would do all the terminate()-ing?
Hello,
While testing Apple Pay transaction I noticed my transactions were showing the incorrect App Name and image.
I was using two Apps which likely have similar names. BetRivers Casino and Sportsbook (app 1) and Bally Casino by BetRivers (app 2).
In the first image you see Bally Casino which is the wrong app, this is confirmed by the website links underneath. All our sites use a single app except for Ballycasino.betrivers. Our other tests did not display like this, so we would like to understand why it happened so we may assist our customers should question arise.
My other image is when our App opens Apple Pay, it shows the name "SugarHouse", I am unable to find the location of where this comes from, as we would want to edit this.
Hello fellow developers! I am interested in obtaining the following information regarding one of our Home Screen widgets:
Pull the following data about the "my_app_widget" homepage widget in total and by month for the last 12 months (Sep '23 - Sep '24):
Widget install events
Unique widget installs
Device type (iPad, iOS).
Thus far, I am using AWS Lambda and have the proper credentials within a Secrets Manager and I keep getting a 409 error from this code:
const AWS = require('aws-sdk');
const axios = require('axios');
const jose = require('jose');
const crypto = require('crypto');
const s3 = new AWS.S3();
const secretsManager = new AWS.SecretsManager();
const cloudwatchlogs = new AWS.CloudWatchLogs();
const logGroupName = '/aws/lambda/my_lambda_function';
const logStreamName = '2024/11/05/[$LATEST]XXXXXXXXXXXXXX';
const getSecret = async (secretName) => {
const secret = await secretsManager.getSecretValue({ SecretId: secretName }).promise();
return JSON.parse(secret.SecretString);
};
const logError = async (message) => {
const params = {
logGroupName,
logStreamName,
logEvents: [
{
message: JSON.stringify(message),
timestamp: Date.now()
}
]
};
try {
await cloudwatchlogs.putLogEvents(params).promise();
} catch (error) {
console.error('Failed to log to CloudWatch:', error);
}
};
const getJwtToken = async (keyId, issuerId, privateKeyPem) => {
try {
const privateKey = crypto.createPrivateKey({
key: privateKeyPem,
format: 'pem',
type: 'pkcs8'
});
const payload = {
iss: issuerId,
exp: Math.floor(Date.now() / 1000) + 20 * 60,
aud: 'appstoreconnect-v1'
};
const token = await new jose.SignJWT(payload)
.setProtectedHeader({ alg: 'ES256', kid: keyId })
.sign(privateKey);
return token;
} catch (error) {
await logError({ error: 'Error generating JWT', details: error });
throw new Error('JWT generation failed');
}
};
const fetchAndUploadReport = async (url, token, s3Key, isAnalytics = false, body = null) => {
try {
const headers = {
'Authorization': `Bearer ${token}`,
'Accept': isAnalytics ? 'application/json' : 'application/a-gzip',
'Content-Type': 'application/json'
};
const response = await axios({
method: isAnalytics ? 'post' : 'get',
url: url,
headers: headers,
data: body,
responseType: isAnalytics ? 'json' : 'stream'
});
if (response.status === 200) {
let bodyContent = isAnalytics ? JSON.stringify(response.data) : response.data;
await s3.upload({
Bucket: 'my_bucket_name',
Key: s3Key,
Body: bodyContent
}).promise();
return { statusCode: 200, body: `${s3Key} fetched and uploaded successfully` };
} else {
await logError({ error: 'API response error', status: response.status, statusText: response.statusText, url });
return { statusCode: response.status, body: response.statusText };
}
} catch (error) {
await logError({ error: 'Error fetching report', url, details: error });
return { statusCode: 500, body: JSON.stringify(`Error fetching ${s3Key}`) };
}
};
exports.handler = async (event) => {
const secretName = 'AppStoreConnectPrivateKey';
try {
const secretData = await getSecret(secretName);
const { keyId, issuerId, private_key: privateKeyPem } = secretData;
const token = await getJwtToken(keyId, issuerId, privateKeyPem);
const startDate = '2023-09-01';
const endDate = '2024-09-30';
const apiEndpoints = [
{
url: `https://api.appstoreconnect.apple.com/v1/analyticsReportRequests`, // Changed to request report
s3Key: 'my_folder/my_subfolder/unique_widget_installs.json',
isAnalytics: true,
body: {
"data": {
"type": "analyticsReportRequests",
"attributes": {
"accessType": "ONGOING",
"name": "Home Screen Widget Installs",
"category": "APP_USAGE"
},
"relationships": {
"app": {
"data": {
"type": "apps",
"id": "YYYYYYYYYYYY"
}
}
}
}
}
}
];
Returns the following error :
{
"error": "Error fetching report",
"url": "https://api.appstoreconnect.apple.com/v1/analyticsReportRequests",
"details": {
"message": "Request failed with status code 409",
"name": "AxiosError",
"stack": "AxiosError: Request failed with status code 409\n at settle (/var/task/node_modules/axios/dist/node/axios.cjs:2019:12)\n at IncomingMessage.handleStreamEnd (/var/task/node_modules/axios/dist/node/axios.cjs:3135:11)\n at IncomingMessage.emit (node:events:531:35)\n at IncomingMessage.emit (node:domain:488:12)\n at endReadableNT (node:internal/streams/readable:1696:12)\n at process.processTicksAndRejections (node:internal/process/task_queues:82:21)\n at Axios.request (/var/task/node_modules/axios/dist/node/axios.cjs:4287:41)\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async fetchAndUploadReport (/var/task/index.js:68:26)\n at async Promise.all (index 0)\n at async exports.handler (/var/task/index.js:174:25)",
"config": {
"transitional": {
"silentJSONParsing": true,
"forcedJSONParsing": true,
"clarifyTimeoutError": false
},
"adapter": [
"xhr",
"http",
"fetch"
],
"transformRequest": [
null
],
"transformResponse": [
null
],
"timeout": 0,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1,
"maxBodyLength": -1,
"env": {},
So I am not sure if the JSON body I am passing this URL endpoint are correct or if this is the correct API to be using to attempt to obtain this information. Please let me know when you have the chance and I look forward to hearing from you.
Hi everyone,
I’m experiencing a frustrating issue with my iPhone 14 Plus after updating to iOS 18. Ever since the update, the rear camera has become almost completely unusable, while the front camera still works fine. Here’s a breakdown of the problems:
Camera app shows a black screen - When I open the Camera app and switch to the rear camera, the screen is just black with no visibility of any objects or scenes.
Limited photo capability - I can only take photos using the 0.5x zoom, and even then, the results are abnormal. Every photo taken with the rear camera has a strange green light at the lower bottom, just like the one in the attached photo.
Unavailable features - All rear camera features, like video, panorama, portrait, and cinematic mode, don’t work at all. It’s like the camera is only partially functional.
“Clips” app works normally - Interestingly, the “Clips” app is still able to take videos with the rear camera, so it seems like the camera hardware itself is fine. This issue seems specific to the Camera app and any functions within it.
I waited for two updates—iOS 18.0.1 and 18.1—hoping Apple would resolve this, but unfortunately, these updates haven’t fixed the issue. I even went to the Apple Service Centre, but since my device is out of warranty, they told me that if I want it fixed, I’d have to pay MYR905 (around USD$200+) to replace the rear camera. They diagnosed it as a hardware issue, but I can’t help but feel it’s related to the iOS 18 update, as the problem started right after updating. I’ve always taken good care of my device, so this doesn’t seem to be due to any physical damage or misuse on my part.
Is anyone else experiencing something similar? Could this be a software bug in iOS 18? Any help or insights would be greatly appreciated.
Thanks!
Hi,
I want to apply in app purchases in my app. I have set it up in xcode and on appstoreconnect, it is saying ready to submit.
I dont understand what i need to do now to connect the two. I have read i need to send my app for review for them to be reviewed, but i want to test the in app purchases first on test flight and on sandbox before i send my app for review.
Please can someone clarify for me and help me?
Hello,
We’re working on a connected watch that displays notifications and handles calls using the ANCS (Apple Notification Center Service) on a Nordic Semiconductor platform. We can manage a single call by monitoring notifications with Category ID: Incoming Call and Category ID 12: Active Call, which lets us display the call status on the watch. However, we’re facing challenges with handling multiple calls, especially around holding and resuming calls.
Our key issues are:
Tracking Call on Hold: When the first call is put on hold to answer a second call, ANCS removes the first call notification. This leaves us unable to track if there’s a call on hold until it’s resumed and reappears as an Active Call. Is there any ANCS flag, category ID, or other mechanism to indicate a call is on hold?
Tracking Total Call Duration: When resuming a held call, ANCS assigns a new Active Call category ID with a new timestamp, which reflects the resumption time rather than the original call start time. This complicates tracking the total elapsed time. Is there a way to identify that this resumed call is the same as the original one to retain the initial timestamp?
Any insights or workarounds would be greatly appreciated!
Thank you.
Hello,
Since 2017 I provide a free and open source Remote Desktop for macOS, Windows and Linux that supports macOS 10.7 to macOS 15. Screen capture is done with CGDisplayCreateImage and works fine. But there is a problem on macOS 15 Sequoia I can not capture the screen in the pre-login context (I am referring to the login screen before the user access into his account). The screen capture in pre-login context works fine for all macOS versions except macOS 15 Sequoia.
In last weeks I tried to fix the issue without success:
tried CGDisplayStream
tried AVCaptureScreenInput
tried ScreenCaptureKit
tried to sign the App (and executable)
None of these work before the user login, but them works only when the user is logged in.
Additional info:
I run the App with "launch agent" when user is connected.
I run the App with "launch daemon" when user is not connected.
Any help would be greatly appreciated!
In the past, I used to ping my iPhone‘s local IP address via UDP. If local network permissions were not enabled, it would return an error. If they were enabled, it would return success, which I used to determine whether my app had local network permissions enabled. Now, with iOS 18, it seems to not work anymore. Regardless of whether local network permissions are enabled, pinging the iPhone‘s local IP address always returns success. Is there any other good method to check this permission status?
Case-ID: 9934335
Hello,
I am developing an application using VoIP Push and CallKit. I have a question: Starting with iOS 13, I understand that under the VoIP Push policy, if reportNewIncomingCall is not called continuously, the VoIP Push may be blocked. Is there a way to determine if the device has been blocked?
I am curious whether PKPushRegistry itself is unable to receive pushes or if reportNewIncomingCall returns an error when it is blocked. If push notifications are not being received, what should I do to resume receiving them?
Thank you.
I'm trying to call the Test Notification endpoint: https://developer.apple.com/documentation/appstoreserverapi/request_a_test_notification?language=objc
I'm creating a JWT bearer token using a script I run on the console with these 2 commands: npm install jsonwebtoken fs and node generate_jwt.js
Keys are taken from App Store Connect -> User and Access -> Integrations -> Keys -> In-App Purchase.
generate_jwt.js script:
const jwt = require('jsonwebtoken');
const fs = require('fs');
const keyId = 'MY_KEY_ID';
const issuerId = 'MY_ISSUER_ID';
const privateKey = `-----BEGIN PRIVATE KEY-----
MY_SECRET_KEY
-----END PRIVATE KEY-----`;
// Define JWT headers and claims
const token = jwt.sign({}, privateKey, {
algorithm: 'ES256',
expiresIn: '1h',
issuer: issuerId,
header: {
alg: 'ES256',
kid: keyId,
},
audience: 'appstoreconnect-v1'
});
console.log('JWT Token:', token);
When I run a POST https://api.storekit.itunes.apple.com/inApps/v1/notifications/test request on postman with Bearer token authentication, I get a 401 Unauthorized error.
Hello, Apple developers. I have joined the MFi certification program. My Accessory to use USB HID IAP2 communication protocol and IOS devices connected, but in the first step, the Accessory to send the following data (0 XFF, 0 x55, 0 x02, 0 x00 to 0 xee, 0 x10) for IOS devices, but the IOS devices have no response, this is probably the reason why?
I'm use iPad OS 17.5.1, when I try to use socket to connect to an ipv6 address created by PacketTunnelProvider in my iOS device, an error occurs. Here is the code to create socket server and client:
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
int dx_create_ipv6_server(const char *ipv6_address, int port) {
int server_fd;
struct sockaddr_in6 server_addr;
server_fd = socket(AF_INET6, SOCK_STREAM, 0);
if (server_fd == -1) {
perror("socket() failed");
return -1;
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin6_family = AF_INET6;
server_addr.sin6_port = htons(port);
if (inet_pton(AF_INET6, ipv6_address, &server_addr.sin6_addr) <= 0) {
perror("inet_pton() failed");
close(server_fd);
return -1;
}
if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
perror("bind() failed");
close(server_fd);
return -1;
}
if (listen(server_fd, 5) == -1) {
perror("listen() failed");
close(server_fd);
return -1;
}
printf("Server is listening on [%s]:%d\n", ipv6_address, port);
return server_fd;
}
int dx_accept_client_connection(int server_fd) {
int client_fd;
struct sockaddr_in6 client_addr;
socklen_t client_addr_len = sizeof(client_addr);
client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_addr_len);
if (client_fd == -1) {
perror("accept() failed");
return -1;
}
char client_ip[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &client_addr.sin6_addr, client_ip, sizeof(client_ip));
printf("Client connected: [%s]\n", client_ip);
return client_fd;
}
int dx_connect_to_ipv6_server(const char *ipv6_address, int port) {
int client_fd;
struct sockaddr_in6 server_addr;
client_fd = socket(AF_INET6, SOCK_STREAM, 0);
if (client_fd == -1) {
perror("socket() failed");
return -1;
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin6_family = AF_INET6;
server_addr.sin6_port = htons(port);
if (inet_pton(AF_INET6, ipv6_address, &server_addr.sin6_addr) <= 0) {
perror("inet_pton() failed");
close(client_fd);
return -1;
}
if (connect(client_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
perror("connect() failed");
close(client_fd);
return -1;
}
printf("Connected to server [%s]:%d\n", ipv6_address, port);
close(client_fd);
return 0;
}
@implementation SocketTest
+ (void)startSever:(NSString *)addr port:(int)port {
[[NSOperationQueue new] addOperationWithBlock:^{
int server_fd = dx_create_ipv6_server(addr.UTF8String, port);
if (server_fd == -1) {
return;
}
int client_fd = dx_accept_client_connection(server_fd);
if (client_fd == -1) {
close(server_fd);
return;
}
close(client_fd);
close(server_fd);
}];
}
+ (void)clientConnect:(NSString *)addr port:(int)port{
[[NSOperationQueue new] addOperationWithBlock:^{
dx_connect_to_ipv6_server(addr.UTF8String, port);
}];
}
@end
PacketTunnelProvider code:
override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) {
let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "fd84:306d:fc4e::1")
let ipv6 = NEIPv6Settings(addresses: ["fd84:306d:fc4e::1"], networkPrefixLengths: 64)
settings.ipv6Settings = ipv6
setTunnelNetworkSettings(settings) { error in
if error == nil {
self.readPackets()
}
completionHandler(error)
}
}
private func readPackets() {
// do nothing
packetFlow.readPackets { [self] packets, protocols in
self.packetFlow.writePackets(packets, withProtocols: protocols)
self.readPackets()
}
}
At main target, in viewcontroller's viewDidAppear, after starting the VPN, executed following code:
[SocketTest startSever:@"fd84:306d:fc4e::1" port:12345];
sleep(3);
[SocketTest clientConnect:@"fd84:306d:fc4e::1" port:12345];
The startSever is executed correctly, but when executing:
connect(client_fd, (struct sockaddr *)&server_addr, sizeof(server_addr))
in clientConnect, the code is blocked until it times out and returns -1.
**Even if I use GCDAsyncSocket or BlueSocket, I get the same error. The strange thing is that if I use the ipv4 address in PacketTunnelProvider, and change the above code to the ipv4 version and connect to ipv4 address, or use GCDAsyncSocket to perform the corresponding operation, it can be executed correctly.
**
I tried to search Google for problems with ios-related ipv6 addresses, but I still couldn't find a solution. Is this a bug in the ios system or is there something wrong with my code? I hope to get your help!
Stackoverflow url: iOS Socket cannot connect ipv6 address when use PacketTunnelProvider
error: Error Domain=NSCocoaErrorDomain Code=256 "The application “Google Chrome” could not be launched because a miscellaneous error occurred." UserInfo={NSURL=file:///Applications/Google%20Chrome.app/, NSLocalizedDescription=The application “Google Chrome” could not be launched because a miscellaneous error occurred., NSUnderlyingError=0x6000038376c0 {Error Domain=RBSRequestErrorDomain Code=5 "Launch failed." UserInfo={NSLocalizedFailureReason=Launch failed., NSUnderlyingError=0x6000038349f0 {Error Domain=OSLaunchdErrorDomain Code=112 "Could not find specified domain" UserInfo={NSLocalizedFailureReason=Could not find specified domain}}}}}
When I try to use socket to connect to an ipv6 address created by PacketTunnelProvider in my iOS device, an error occurs. Here is the code to create socket server and client:
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
int dx_create_ipv6_server(const char *ipv6_address, int port) {
int server_fd;
struct sockaddr_in6 server_addr;
server_fd = socket(AF_INET6, SOCK_STREAM, 0);
if (server_fd == -1) {
perror("socket() failed");
return -1;
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin6_family = AF_INET6;
server_addr.sin6_port = htons(port);
if (inet_pton(AF_INET6, ipv6_address, &server_addr.sin6_addr) <= 0) {
perror("inet_pton() failed");
close(server_fd);
return -1;
}
if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
perror("bind() failed");
close(server_fd);
return -1;
}
if (listen(server_fd, 5) == -1) {
perror("listen() failed");
close(server_fd);
return -1;
}
printf("Server is listening on [%s]:%d\n", ipv6_address, port);
return server_fd;
}
int dx_accept_client_connection(int server_fd) {
int client_fd;
struct sockaddr_in6 client_addr;
socklen_t client_addr_len = sizeof(client_addr);
client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_addr_len);
if (client_fd == -1) {
perror("accept() failed");
return -1;
}
char client_ip[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &client_addr.sin6_addr, client_ip, sizeof(client_ip));
printf("Client connected: [%s]\n", client_ip);
return client_fd;
}
int dx_connect_to_ipv6_server(const char *ipv6_address, int port) {
int client_fd;
struct sockaddr_in6 server_addr;
client_fd = socket(AF_INET6, SOCK_STREAM, 0);
if (client_fd == -1) {
perror("socket() failed");
return -1;
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin6_family = AF_INET6;
server_addr.sin6_port = htons(port);
if (inet_pton(AF_INET6, ipv6_address, &server_addr.sin6_addr) <= 0) {
perror("inet_pton() failed");
close(client_fd);
return -1;
}
if (connect(client_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
perror("connect() failed");
close(client_fd);
return -1;
}
printf("Connected to server [%s]:%d\n", ipv6_address, port);
close(client_fd);
return 0;
}
@implementation SocketTest
+ (void)startSever:(NSString *)addr port:(int)port {
[[NSOperationQueue new] addOperationWithBlock:^{
int server_fd = dx_create_ipv6_server(addr.UTF8String, port);
if (server_fd == -1) {
return;
}
int client_fd = dx_accept_client_connection(server_fd);
if (client_fd == -1) {
close(server_fd);
return;
}
close(client_fd);
close(server_fd);
}];
}
+ (void)clientConnect:(NSString *)addr port:(int)port{
[[NSOperationQueue new] addOperationWithBlock:^{
dx_connect_to_ipv6_server(addr.UTF8String, port);
}];
}
@end
PacketTunnelProvider code:
override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) {
let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "fd84:306d:fc4e::1")
let ipv6 = NEIPv6Settings(addresses: ["fd84:306d:fc4e::1"], networkPrefixLengths: 64)
settings.ipv6Settings = ipv6
setTunnelNetworkSettings(settings) { error in
if error == nil {
self.readPackets()
}
completionHandler(error)
}
}
private func readPackets() {
// do nothing
packetFlow.readPackets { [self] packets, protocols in
self.packetFlow.writePackets(packets, withProtocols: protocols)
self.readPackets()
}
}
At main target, in viewcontroller's viewDidAppear, after starting the VPN, executed following code:
[SocketTest startSever:@"fd84:306d:fc4e::1" port:12345];
sleep(3);
[SocketTest clientConnect:@"fd84:306d:fc4e::1" port:12345];
The startSever is executed correctly, but when executing:
connect(client_fd, (struct sockaddr *)&server_addr, sizeof(server_addr))
in clientConnect, the code is blocked until it times out and returns -1.
Even if I use GCDAsyncSocket or BlueSocket, I get the same error.
The strange thing is that if I use the ipv4 address in PacketTunnelProvider, and change the above code to the ipv4 version and connect to ipv4 address, or use GCDAsyncSocket to perform the corresponding operation, it can be executed correctly.
I tried to search Google for problems with ios-related ipv6 addresses, but I still couldn't find a solution. Is this a bug in the ios system or is there something wrong with my code? I hope to get your help!
Hello,
I'm using an HMSoft Bluetooth module that connects reliably to Android devices, maintaining a stable connection. However, when I try to connect it to my iPhone 12, the connection randomly disconnects after a few minutes (usually around 3 minutes). This issue occurs even when using apps like LightBlue and other BLE-based medical equipment apps, so it doesn't seem related to my app code.
Any suggestions on what I can do to prevent these unexpected disconnects? Should I change any specific settings on my iPhone or the module itself?