iOS16 Enqueued from GCDAsyncSocket - objective-c

I updated xcode14 and ran my code on an ios16 phone and it crashed. All mobile apps under ios16 are working normally。
The system prompts for the following message,
{
LogTrace();
NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), #"Must be dispatched on socketQueue");
NSAssert((readStream != NULL && writeStream != NULL), #"Read/Write stream is null");
CFStreamStatus readStatus = CFReadStreamGetStatus(readStream);
CFStreamStatus writeStatus = CFWriteStreamGetStatus(writeStream);
if ((readStatus == kCFStreamStatusNotOpen) || (writeStatus == kCFStreamStatusNotOpen))
{
LogVerbose(#"Opening read and write stream...");
BOOL r1 = CFReadStreamOpen(readStream);//Enqueued from GCDAsyncSocket (Thread 7)
BOOL r2 = CFWriteStreamOpen(writeStream);
if (!r1 || !r2)
{
LogError(#"Error in CFStreamOpen");
return NO;
}
}
return YES;
}
Error message:
Enqueued from GCDAsyncSocket (Thread 7)
which is what I did when I called the xmpp connection. I tried to find the problem, but I couldn't figure it out.

CocoaAsyncSocket library is using Background sockets which is not the apple's recommended way.
Library itself deprecated the property since iOS 10 (from 2016). And the library also recommends to use "PushKit and the XEP-0357 module" instead of this.
Set enableBackgroundingOnSocket to false to resolve this issue.
asyncSocket.enableBackgroundingOnSocket = NO;

Related

Xamarin iOS - Check if mobile data connection is available

I would like to check if mobile data is available (the app has access, it's switched on in settings, aeroplane mode isn't on and there is a valid connection).
I want to know this even when an active wifi connection is established. So I can't use any get the current connection as it won't be the current one, WiFi would be.
I have tried looking into NWPath and NWPathMonitor but got a bit confused by it all.
Thanks, if I need to add any more information just drop a comment and I will update this or reply to you.
Since you have a Tag with Xamarin, just use the API from Essentials. For the connectivity-checker see the docs.
Here is a pretty perfekt blogpost from "James Montemagno"
A sneak preview of the Post:
var current = Connectivity.NetworkAccess;
switch(current)
{
case NetworkAccess.Internet:
// Connected to internet
break;
case NetworkAccess.Local:
// Only local network access
break;
case NetworkAccess.ConstrainedInternet:
// Connected, but limited internet access such as behind a network login page
break;
case NetworkAccess.None:
// No internet available
break;
case NetworkAccess.Unknown:
// Internet access is unknown
break;
}
Edit due to the comment from #Samuel James:
Maybe this helps?
Check what type of activ connection (according docs from Mircosoft):
var profiles = Connectivity.ConnectionProfiles;
if (profiles.Contains(ConnectionProfile.Cellular))
{
// Active mobile/cellular data connection.
}
public enum ConnectionProfile
{
/// <summary>Other unknown type of connection.</summary>
Unknown,
/// <summary>The bluetooth data connection.</summary>
Bluetooth,
/// <summary>The mobile/cellular data connection.</summary>
Cellular,
/// <summary>The ethernet data connection.</summary>
Ethernet,
/// <summary>The WiFi data connection.</summary>
WiFi
}
See my answer here ,we can use CoreTelephony framework to get what the specific type of cellular is .
Try the following code
public ConnectivityTest()
{
// Register for connectivity changes, be sure to unsubscribe when finished
Connectivity.ConnectivityChanged += Connectivity_ConnectivityChanged;
}
string result;
void Connectivity_ConnectivityChanged(object sender, ConnectivityChangedEventArgs e)
{
var access = e.NetworkAccess;
var profiles = e.ConnectionProfiles;
if (Connectivity.NetworkAccess != NetworkAccess.Internet)
{
result = "NoNetworkAccess";
}
else if (profiles.Contains(ConnectionProfile.Cellular))
{
CTTelephonyNetworkInfo networkInfo = new CTTelephonyNetworkInfo();
string carrierTypeName = networkInfo.ServiceCurrentRadioAccessTechnology.Values[0];
if (carrierTypeName == null) result = "unknown";
else if (carrierTypeName == CTRadioAccessTechnology.GPRS ||
carrierTypeName == CTRadioAccessTechnology.Edge ||
carrierTypeName == CTRadioAccessTechnology.CDMA1x)
result = "2G";
else if (carrierTypeName == CTRadioAccessTechnology.WCDMA ||
carrierTypeName == CTRadioAccessTechnology.HSDPA ||
carrierTypeName == CTRadioAccessTechnology.HSUPA ||
carrierTypeName == CTRadioAccessTechnology.CDMAEVDORev0 ||
carrierTypeName == CTRadioAccessTechnology.CDMAEVDORevA ||
carrierTypeName == CTRadioAccessTechnology.CDMAEVDORevB ||
carrierTypeName == CTRadioAccessTechnology.EHRPD)
result = "3G";
else if (carrierTypeName == CTRadioAccessTechnology.LTE)
result = "4G";
else result = "5G";
}
}
Refer to
https://stackoverflow.com/a/61327753/8187800

Read 'hidden' input for CLI Dart app

What's the best way to receive 'hidden' input from a command-line Dart application? For example, in Bash, this is accomplished with:
read -s SOME_VAR
Set io.stdin.echoMode to false:
import 'dart:io' as io;
void main() {
io.stdin.echoMode = false;
String input = io.stdin.readLineSync();
// or
var input;
while(input != 32) {
input = io.stdin.readByteSync();
if(input != 10) print(input);
}
// restore echoMode
io.stdin.echoMode = true;
}
This is a slightly extended version, key differences are that it uses a finally block to ensure the mode is reset if an exception is thrown whilst the code is executing.
The code also uses a waitFor call (only available in dart cli apps) to turn this code into a synchronous call. Given this is a cli command there is no need for the complications that futures bring to the table.
The code also does the classic output of '*' as you type.
If you are doing much cli work the below code is from the dart package I'm working on called dcli. Have a look at the 'ask' method.
https://pub.dev/packages/dcli
String readHidden() {
var line = <int>[];
try {
stdin.echoMode = false;
stdin.lineMode = false;
int char;
do {
char = stdin.readByteSync();
if (char != 10) {
stdout.write('*');
// we must wait for flush as only one flush can be outstanding at a time.
waitFor<void>(stdout.flush());
line.add(char);
}
} while (char != 10);
} finally {
stdin.echoMode = true;
stdin.lineMode = true;
}
// output a newline as we have suppressed it.
print('');
return Encoding.getByName('utf-8').decode(line);
}

php-smpp Library not working and fails after two to three SMS

it is very first time i'm messing with sockets , and read many quotes that this is not for newbies.
so problem is i'm using php smpp library for sending SMS which works fine but after delivering two to three SMS delivery fails with following warning
Warning: stream_socket_sendto() [function.stream-socket-sendto]: An existing connection was forcibly closed by the remote host', and to make it work again i need to restart` apache.
Following is write function which throwing exception
public function write($buf) {
$null = null;
$write = array($this->handle_);
// keep writing until all the data has been written
while (strlen($buf) > 0) {
// wait for stream to become available for writing
$writable = #stream_select($null, $write, $null, $this->sendTimeoutSec_, $this->sendTimeoutUsec_);
if ($writable > 0) {
// write buffer to stream
$written = stream_socket_sendto($this->handle_, $buf);
if ($written === -1 || $written === false) {
throw new TTransportException('TSocket: Could not write '.$written.' bytes '.
$this->host_.':'.$this->port_);
}
// determine how much of the buffer is left to write
$buf = substr($buf, $written);
} else if ($writable === 0) {
throw new TTransportException('TSocket: timed out writing '.strlen($buf).' bytes from '.
$this->host_.':'.$this->port_);
} else {
throw new TTransportException('TSocket: Could not write '.strlen($buf).' bytes '.
$this->host_.':'.$this->port_);
}
}
}
Please anyone can put some light
It was the bug which i won't able to identify/ rectify. then i used an other library from http://www.codeforge.com/read/171085/smpp.php__html and it really saved me.

Calling a Metro based Security Token Service from an Axis2 STS Client

I want to call a Security Token Service which was created and deployed using Metro 2.2 framework from an Axis 2 STS Client. I'm trying to do the same but getting issues like the one below: -
java.lang.RuntimeException:Incorrect inclusion value: -1
I went deep into the source code and saw that in SecureConversationTokenBuilder class code is wriiten something like this:-
String inclusionValue = attribute.getAttributeValue().trim();
conversationToken.setInclusion(SP11Constants.getInclusionFromAttributeValue(inclusionValue));
then I went into the SP11Constants.getInclusionFromAttributeValue(inclusionValue) and saw the following piece of code:-
public static int getInclusionFromAttributeValue(String value ) {
if (INCLUDE_ALWAYS.equals(value)) {
return SPConstants.INCLUDE_TOEKN_ALWAYS;
} else if (INCLUDE_ALWAYS_TO_RECIPIENT.equals(value)) {
return SPConstants.INCLUDE_TOEKN_ALWAYS_TO_RECIPIENT;
} else if (INCLUDE_NEVER.equals(value)) {
return SPConstants.INCLUDE_TOKEN_NEVER;
} else if (INCLUDE_ONCE.equals(value)) {
return SPConstants.INCLUDE_TOKEN_ONCE;
} else {
return -1;
}
}
as INCLUDE_ALWAYS = "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Always" which is not equal to what is defined by metro in policy.xml like
http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Always
Therefore the above code always return -1 and in turn throws a runtime exception as below:-
public void setInclusion(int inclusion) {
if(SPConstants.INCLUDE_TOEKN_ALWAYS == inclusion ||
SPConstants.INCLUDE_TOEKN_ALWAYS_TO_RECIPIENT == inclusion ||
SPConstants.INCLUDE_TOEKN_ALWAYS_TO_INITIATOR == inclusion ||
SPConstants.INCLUDE_TOKEN_NEVER == inclusion ||
SPConstants.INCLUDE_TOKEN_ONCE == inclusion ) {
this.inclusion = inclusion;
} else {
//TODO replace this with a proper (WSSPolicyException) exception
throw new RuntimeException("Incorrect inclusion value: " + inclusion);
}
}
Just wanted to know whether it is possible to get token from Security Token Service (STS) created in Metro Framework invoked from an Axis2 based STS Client.Please advise as I'm stuck in between.
Thanks in advance.

SQLite iphone data lost when rebooting or closing the app

I have a question... I have an application using sqlite to save some data.Everything works perfectly, meaning I can add, delete, view data. The data are persistent when the application goes into background. Now, when I remove the application from memory or reboot the iPhone, the database is corrupted and all the data are messed up !
I have a class call dbAccess where all the database actions are define(add, delete, retreive rows). At the end I have a finalize action, that finalize all the statement used and then close the database.
+ (void)finalizeStatements{
NSLog(#"Finalizing the Delete Statements");
if(deleteStmt) {
NSLog(#"Delete Statement exist... finalization");
sqlite3_finalize(deleteStmt);
deleteStmt = nil;
}
NSLog(#"Finalizing the Add Statements");
if(addStmt) {
NSLog(#"Add Statement exist... finalization");
sqlite3_finalize(addStmt);
addStmt = nil;
}
NSLog(#"Finalizing the Store Statements");
if(storeStmt) {
NSLog(#"Store Statement exist... finalization");
sqlite3_finalize(storeStmt);
storeStmt = nil;
}
NSLog(#"Finalizing the Agent Statements");
if(agentStmt) {
NSLog(#"Agent Statement exist... finalization");
sqlite3_finalize(agentStmt);
agentStmt = nil;
}
NSLog(#"Closing the Database");
if(database) {
NSLog(#"The database exist... closing it");
sqlite3_close(database);
}
}
This method is called by the application delegate when applicationDidEnterBackground and applicationWillTerminate. An openDatabase method is call when applicationDidBecomeActive.
Any ideas why the database is corrupted ?
Thanks.
First off, check out fmdb or some other proven wrappers. You can also browse the code.
Not sure if there's enough info to know why it's corrupt. But, you should get return codes from ALL sqlite3_xxx calls and log at a minimum to understand what's going on or you may just be blasting past an issue.
Also, make sure to call sqlite_errmsg which will offer more clues if the return code is not success.
In my wrapper, I do this in close. It's expected that statements are finalized bu handled if not. I have a statement cache which on clear finalizes each statement.
:
- (void)close
{
if (_sqlite3)
{
NSLog(#"closing");
[self clearStatementCache];
int rc = sqlite3_close(_sqlite3);
NSLog(#"close rc=%d", rc);
if (rc == SQLITE_BUSY)
{
NSLog(#"SQLITE_BUSY: not all statements cleanly finalized");
sqlite3_stmt *stmt;
while ((stmt = sqlite3_next_stmt(_sqlite3, 0x00)) != 0)
{
NSLog(#"finalizing stmt");
sqlite3_finalize(stmt);
}
rc = sqlite3_close(_sqlite3);
}
if (rc != SQLITE_OK)
{
NSLog(#"close not OK. rc=%d", rc);
}
_sqlite3 = NULL;
}
}