Is there a way to detect 3G and 2G connections speed on mobile phones and handheld devices? - mobile-website

Is there a way to detect 3G and 2G connections on mobile phones and handheld devices?
Like If I want to deliver High-end Website when user is on 3G and Highly optimized version if user is on 2G.

In Android 2.2+ there's a JS object for that.
You can write out a class for CSS use based on connection type.
But it's not available on iOS for mobile web sites as far as I know.
var connection, connectionSpeed, htmlNode, htmlClass;
connection = navigator.connection || {"type":"0"}; // fallback
switch(connection.type) {
case connection.CELL_3G: connectionSpeed = "mediumbandwidth"; break;
case connection.CELL_2G: connectionSpeed = "lowbandwidth"; break;
default: connectionSpeed = 'highbandwidth';
}
/* set the connection speed on the html element
i.e. <html class="lowbandwidth">
*/
htmlNode = document.body.parentNode;
htmlClass = htmlNode.getAttribute("class") || "";
htmlNode.setAttribute("class", htmlClass + " " + connectionSpeed);
The code is from slide 24 in this presentation:
http://davidbcalhoun.com/present/mobile-performance/

Some networks send connection type as http header.
Your best bet would be to do a speed test when user connects and try to store it on the client as cookie

Related

BLE iOS - Failed to encrypt the connection, the connection has timed out unexpectedly

I'm using #capacitor-community/bluetooth-le to connect my Ionic 6 APP to a specific BLE device.
In Android everything works fine.
In iOS, first time connects to BLE successfully but next times (after pairing) gives the following error when try to connects: "Failed to encrypt the connection, the connection has timed out unexpectedly."
I have been tried a lot of different approachs: connects after scan. Connects when is scanning. But nothing works. What is strange is in first time everything works fine (after pairing).
Any help?
Unfortunately this is kind of a known issue in iOS. What I think is happening is that because you have already paired/bonded with the device at the OS level, the connection is being re-established at the OS level when the remote BLE device is discoverable. When you are attempting to reconnect to the remote device from your app, a connection is already in place at the OS level which is why it is failing at the app level. Alternatively, maybe the stored keys from the bonding process is causing the rebonding/pairing process to clash. You can confirm the issue by doing the following:-
Go to the iOS settings, Bluetooth, then unpair the device if it exists.
Attempt to reconnect to the device from your iOS app.
Disconnect the device from your iOS app (do not unpair from the Bluetooth settings this time).
Try to connect to the remote device from your Android app (or any other device that you can use apart from the iOS device). If the connection doesn't succeed, it means that the iOS device is still connected to the remote device.
If the connection succeeds from the Android device, try to disconnect and reconnect from the iOS device. If the connection succeeds, you'll know that the issue is with the OS level connection, and if the connection doesn't succeed, you'll know that the issue is with the stored bonding/pairing keys clashing.
As for the solution, I don't think there's a simple and straight-forward one unfortunately. Below is one suggested solution which I found useful in the past (you may need to modify this for your ionic app):-
In some cases, like for HID devices, once a peripheral is bonded, iOS
will automatically connect to it whenever it sees the peripheral
advertising. This behavior occurs independently of any app, and a
peripheral can be connected to an iOS device, but not connected to the
app that originally established the bond. If a bonded peripheral
disconnects from an iOS device and then reconnects at the iOS level,
the app will need to retrieve the peripheral object
(retrieveConnectedPeripherals(with[Services/Identifiers]:) and
explicitly connect again through a CBCentralManager to establish an
app-level connection. To retrieve your device with this method, you
must specify either the Apple-assigned device identifier from the
previously-returned CBPeripheral object or at least one service it
contains.
iOS does not allow developer apps to clear a peripheral’s bonding
status from the cache. To clear a bond, the user must go to the
Bluetooth section of iOS Settings and explicitly “Forget” the
peripheral. It may be helpful to include this information in your
app’s UI if it’ll affect user experience, as most users will not know
this.
You can find more information about this in the links below:-
The ultimate guide to Apple's CoreBluetooth
CoreBluetooth iOS pairing issue
CoreBluetooth pairing/forgetting
Unable to reconnect after cancelling BLE peripheral
In my case after iPhone pairs with peripheral, never connects anymore. What is strange, in my iPhone 6s with iOS 15.5 everythings works fine.
The pugin has this code (it's possible to some is wrong?)
https://github.com/capacitor-community/bluetooth-le/blob/main/ios/Plugin/Plugin.swift
let CONNECTION_TIMEOUT: Double = 10
let DEFAULT_TIMEOUT: Double = 5
#objc func connect(_ call: CAPPluginCall) {
guard self.getDeviceManager(call) != nil else { return }
guard let device = self.getDevice(call, checkConnection: false) else { return }
let timeout = self.getTimeout(call, defaultTimeout: CONNECTION_TIMEOUT)
device.setOnConnected(timeout, {(success, message) -> Void in
if success {
// only resolve after service discovery
call.resolve()
} else {
call.reject(message)
}
})
self.deviceManager?.setOnDisconnected(device, {(_, _) -> Void in
let key = "disconnected|\(device.getId())"
self.notifyListeners(key, data: nil)
})
self.deviceManager?.connect(device, timeout, {(success, message) -> Void in
if success {
log("Connected to peripheral. Waiting for service discovery.")
} else {
call.reject(message)
}
})
}
I already tried another plugins, and the result is the same.

How to deal with purgeIdleCellConnections on 3G network?

I added thirdparty SDK to my project, and I got purgeIdleCellConnections errors when using slow 3G network .
purgeIdleCellConnections: found one to purge conn = 0x1f55b300
There is no problem on wifi network , because it don't use the cellular network for the image downloads.
I have to determine if network type is wifi or 3G :
+ (BOOL) IsEnableWIFI {
return ([[Reachability reachabilityForLocalWiFi]
currentReachabilityStatus] != NotReachable);
}
+ (BOOL) IsEnable3G {
return ([[Reachability reachabilityForInternetConnection]
currentReachabilityStatus] != NotReachable);
}
But I think this is not a good idea. How to deal with it ?
Thank you for any replies.
I have observed this debug message coming out of the iOS 6.0 SDK (when on the device connected to cellular network), correlates to active AJAX calls being terminated in my app. However it is very difficult to prove anything since this only occurs when rendering the web page in a UIWebView. I am just saying I don't think the messages are benign. I think they might indicate a bug in the Apple framework that is overly aggressive in terminating connections. It is hard to get instrumentation on the javascript running inside the UIWebView that makes the AJAX calls, so it is all highly speculative at this time.
I believe this is a debug log which came in IOS6 SDK, don't worry about this.

iOS get current wlan network name

I am looking for a way to obtain information (at least the name) of the current connected wlan network in objective-c for iOS5.
I need this because we are currently developing an application that do not work in a particular network. In this network (on our university) the port is closed that we need to connect to the server. But there is another network also available and we want to tell the user that he has to switch the network if he is connected to the aforementioned one.
I do not even know where to start. Does anyone have an idea or any hints?
Thanks and regards
From iOS >= 4.1 it's possible to obtain SSID of wireless network that device is currenctly connected to.
For this you'd use function CNCopyCurrentNetworkInfo
Details on implemenation are available on SO: iPhone get SSID without private library
It is possible to get the current wifi information from the Captive Network. In the past, apple actually disabled this for a while, but they seems to re-enabled it due to strong request. It is also possible that they decide to close this in the future.
The information we can get is BSSID, SSID, SSIDDATA. BSSID is the unique address for wifi, SSID is the current wifi name, SSIDDATA is the hex representation for the SSID.
For Swift 3.1:
func printCurrentWifiInfo() {
if let interface = CNCopySupportedInterfaces() {
for i in 0..<CFArrayGetCount(interface) {
let interfaceName: UnsafeRawPointer = CFArrayGetValueAtIndex(interface, i)
let rec = unsafeBitCast(interfaceName, to: AnyObject.self)
if let unsafeInterfaceData = CNCopyCurrentNetworkInfo("\(rec)" as CFString), let interfaceData = unsafeInterfaceData as? [String : AnyObject] {
// connected wifi
print("BSSID: \(interfaceData["BSSID"]), SSID: \(interfaceData["SSID"]), SSIDDATA: \(interfaceData["SSIDDATA"])")
} else {
// not connected wifi
}
}
}
}
For Objective-C
NSArray *interFaceNames = (__bridge_transfer id)CNCopySupportedInterfaces();
for (NSString *name in interFaceNames) {
NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)name);
NSLog[#"wifi info: bssid: %#, ssid:%#, ssidData: %#", info[#"BSSID"], info[#"SSID"], info[#"SSIDDATA"]];
}
As of iOS 12, you'll need to allow Wifi Information access in the capabilities.
From Apple:
To use this function in iOS 12 and later, enable the Access WiFi Information capability for your app in Xcode. When you enable this capability, Xcode automatically adds the Access WiFi Information entitlement to your entitlements file and App ID.

I want to send a notification FROM my iPhone to another iPhone [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
before I start I realize this issue has been raised before in this forum because I found the thread. However, the question was not answered.
I am building a system using iPhones as the worker machines. I phrase it like this because I want to place an emphasis on the phone not being some product of apple but as a piece of equipment which is either capable or not of performing a given task.
I have jailbroken both phones I am using and will use them exclusively to achieve a solution to the problem the system sets out to solve. My system will be used by me and me alone and so the issue of how Apple intended these devices to be used, the user experience etc is irrelevant to me.
Ok, having said all that I'll briefly outline the system. Two iPhones, one with its guts in an electronics project box nailed above my front door, camera facing visitors. Other iPhone, intact and in my pocket. I have hooked pins 1 & 11 to the door bell button and alert the phone to its being pressed by monitoring the audio route change. I need an app on my pocket phone that will be woken by a notification sent by the door phone. The door phone will also send an image once I have accepted the notification on my pocket phone. There is no internet here at all, I do however have a wifi router to which both phones are connected.
So that's the system, I have searched high and low to find code that can help me to get the door phone to generate a push notification and send it to my pocket phone, all I have found so far is this https://github.com/stefanhafeneger/PushMeBaby which is what I need only it's written for mac not iPhone and I'm new to Objective C so porting is really hard.
Please could someone give me a hand to accomplish what I am trying to do, I know Apple didn't intend for me to use its product like I am but then neither do a lot of manufacturers but hobbyists still manage to use them in ever more inventive and innovative ways irrespective. I am currently using a PC and a webcam to see who's at the door and it uses a lot of electric, the new system is far better if only I can get it to work so please, please if you have the ability/knowledge to help me then post a reply and I will be eternally grateful. Thanks you, Richard.
Pair the phones with Bluetooth using GameKit.
Here's an SO question about how to bluetooth pair two iPhones: How to use bluetooth to connect two iPhone?
The easiest way is using the highly opaque GameKit. Here's an Apple example app that achieves this: http://developer.apple.com/library/ios/#samplecode/GKTank/Introduction/Intro.html
And from that example that snippet that sends packets (in TankViewController.m):
- (void)sendNetworkPacket:(GKSession *)session packetID:(int)packetID withData:(void *)data ofLength:(int)length reliable:(BOOL)howtosend {
// the packet we'll send is resued
static unsigned char networkPacket[kMaxTankPacketSize];
const unsigned int packetHeaderSize = 2 * sizeof(int); // we have two "ints" for our header
if(length < (kMaxTankPacketSize - packetHeaderSize)) { // our networkPacket buffer size minus the size of the header info
int *pIntData = (int *)&networkPacket[0];
// header info
pIntData[0] = gamePacketNumber++;
pIntData[1] = packetID;
// copy data in after the header
memcpy( &networkPacket[packetHeaderSize], data, length );
NSData *packet = [NSData dataWithBytes: networkPacket length: (length+8)];
if(howtosend == YES) {
[session sendData:packet toPeers:[NSArray arrayWithObject:gamePeerId] withDataMode:GKSendDataReliable error:nil];
} else {
[session sendData:packet toPeers:[NSArray arrayWithObject:gamePeerId] withDataMode:GKSendDataUnreliable error:nil];
}
}
}
I can't think of an easy way to send a message directly from one phone to the other. (although I'm not used to jailbroken stuff, so who knows...). In any case, here's what I would do:
Set up a simple web server to interface between the two devices. You say you don't have internet, so just running Apache or whatever on a local computer on the network should do the trick. Whenever you want to send a message, the sending phone posts something to the server. Unfortunately, if you can't/don't want to use Apple's push notification service, I think the receiving phone is going to have to constantly monitor the server to see if there are any new messages. :(

Can you pass WiFi settings from an iOS device to an ExternalAccessory object?

I've heard that iOS 5 introduced a feature in which the iOS device can share its wifi configuration with a docked accessory via the ExternalAccessory framework. The trouble is that I can't find any specific details on implementing this type of scheme in the SDK docs.
From my research, I've begun to suspect it's achieved via the 'iPhone Configuration Utility' but this still seems like a bit of a messy method to implement on a device.
Anyone got any ideas?
Once the wifi setup data is available, it should be easy enough to package it up and send it out via the ExternalAccessory framework to the device, where I'll build in protocol support accordingly.
Thanks
Yes! you certainly can. However, to use HomeKit (the library you need) you first need to be a certified MFi (Made For iDevice-iPhone-iPod-iPad) developer. This gives you the ability to allow a user to view all available wifi networks and choose to link the device.
One example of this is Withings with their Aura sleep aid. See screenshot from on boarding experience:
Then the user can then choose to share their home wifi information securely with the new device.
The user-visible UI looks like this:
http://www.theregister.co.uk/2012/07/12/pure_contour_200i_air_airplay_wireless_music_system/
https://withings.zendesk.com/hc/en-us/articles/201488707-Wi-Fi-Setup-of-the-Wireless-Scale-WS-30
A bit late but configureAccessory is the method (part of ExternalAccessory) introduced in iOS 8.0 that you can use to configure a wifi accessory:
https://developer.apple.com/documentation/externalaccessory/eawifiunconfiguredaccessorybrowser/1613907-configureaccessory
It's part of the EAWiFiUnconfiguredAccessoryBrowser class:
https://developer.apple.com/documentation/externalaccessory/eawifiunconfiguredaccessorybrowser
And showBluetoothAccessoryPicker is the one for Bluetooth products:
https://developer.apple.com/documentation/externalaccessory/eaaccessorymanager/1613913-showbluetoothaccessorypicker
which is part of the EAAccessoryManager class:
https://developer.apple.com/documentation/externalaccessory/eaaccessorymanager
I doubt Apple would ever allow for an average developer to access private data such as wifi connections settings. Maybe trusted third party accessory provider yes, but you probably no.
Wifi settings are private and contain passwords. An average (non-power) user uses more or less the same/similar password for everything including their Wifi network. If an app can easily read that it could be badly exploited.
The same way you cannot get the Apple id let alone the password.
Have you seen this: iPhone get SSID without private library
Is prompting the App user for a secured network password out of the question?
You can at least get the SSID of an unsecured network and pass it to your accessory with a getter something like:
#import <SystemConfiguration/CaptiveNetwork.h>
#implementation DeviceWifiSSID
//https://stackoverflow.com/a/5198968/614688
+(NSString *)deviceSSID
{
NSArray *ifs = (__bridge id)CNCopySupportedInterfaces();
id info = nil;
for (NSString *ifnam in ifs) {
info = (__bridge id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
if ([info objectForKey:#"SSID"] != nil)
{
return [info objectForKey:#"SSID"];
}
}
return nil;
}
#end