Better way to detect WiFi enabled/disabled on iOS? - ios

After an unbelievable amount of teeth gnashing, I finally have a method that successfully detects if WiFi is enabled on iOS independent of whether it's connected or not. There are at least a couple uses for such a thing, and I don't think this violates the spirit or the letter of Apple Law(tm).
However, it's ugly and probably won't work forever. It currently works on iOS 10.2.1, as of Jan 31, 2017. I'll put my answer below and hope that someone can improve it. I've heavily researched Reachability (doesn't meet the requirements), CaptiveNetwork, HotspotHelper, SCNetworkConfiguration, Xamarin's System.Net.NetworkInterface, and more. This is it that actually works as far as I can tell.

The gist of the solution is that when there's TWO interfaces reported by getifaddrs() with the name "awdl0" then WiFi is enabled. Just one and it's disabled.
I credit pebble8888 for pointing me to https://github.com/alirp88/SMTWiFiStatus which is Objective-C, where the lack of comments make it hard to understand what's going on or what the author's intention was.
Here's my full and complete Xamarin/C# solution, which ought to be pretty readable for any other major language user:
using System;
using System.Runtime.InteropServices;
namespace Beacon.iOS
{
/// <summary>
/// code stolen from the Xamarin source code to work around goofy interactions between
/// the good-god-why-would-it-work-that-way iOS and the entirely reasonable Xamarin
/// (it doesn't report interfaces that are reported multiple times)
/// </summary>
class XamHack
{
//
// Types
//
internal struct ifaddrs
{
#pragma warning disable 0649
public IntPtr ifa_next;
public string ifa_name;
public uint ifa_flags;
public IntPtr ifa_addr;
public IntPtr ifa_netmask;
public IntPtr ifa_dstaddr;
public IntPtr ifa_data;
#pragma warning restore
}
//
// OS methods
//
[DllImport("libc")]
protected static extern int getifaddrs(out IntPtr ifap);
[DllImport("libc")]
protected static extern void freeifaddrs(IntPtr ifap);
//
// Methods
//
/// <summary>
/// Our glorious hack. I apologize to the programming gods for my sins
/// but this works (for now) and functionality trumps elegance. Even this.
/// Reverse engineered from: https://github.com/alirp88/SMTWiFiStatus
/// </summary>
public static bool IsWifiEnabled()
{
int count = 0;
IntPtr ifap;
// get the OS to put info about all the NICs into a linked list of buffers
if (getifaddrs(out ifap) != 0)
throw new SystemException("getifaddrs() failed");
try
{
// iterate throug those buffers
IntPtr next = ifap;
while (next != IntPtr.Zero)
{
// marshall the data into our struct
ifaddrs addr = (ifaddrs)Marshal.PtrToStructure(next, typeof(ifaddrs));
// count the instances of the sacred interface name
if ("awdl0" == addr.ifa_name)
count++;
// move on to the next interface
next = addr.ifa_next;
}
}
finally
{
// leaking memory is for jerks
freeifaddrs(ifap);
}
// if there's two of the sacred interface, that means WiFi is enabled. Seriously.
return (2 == count);
}
} // class
} // namespace

Related

How does Vala handle reference counting with multithreading?

As far as I understand, in multithreaded environment reference counting should be performed with locking to ensure all threads see the same snapshot of memory. But locking slows down perfomance. How does Vala solve this problem?
Reference counting is mostly handled in GObject (for GLib.Object-derived types), which in turn uses the Atomic Operations in GLib. Atomics are a tricky subject; if you want to get into details a good place to start is Herb Sutter's Atomic Weapons talk from a few years ago. I would recommend watching the videos even if you're never going to put them to use (and 99.9% of programmers should never put them to use) because it will give you a much better understanding of how computers really work.
The name "atomics" can be a bit misleading; it's not really about atomicicity, though that's part of it. The operations are atomic in the sense that the change is either made in its entirety or not at all, which is vital, but the more interesting part is that atomics act as barriers which prevent the compiler from re-ordering operations across the barrier. Herb Sutter's talk goes into a lot of detail about this which I'm not going to repeat here.
For example, think about a simple unprotected reference counter:
typedef struct {
int reference_count = 0;
} Foo;
Foo* foo_create(void) {
Foo* foo = malloc(sizeof(Foo));
foo->reference_count = 1;
}
void ref(Foo* foo) {
++(foo->reference_count);
}
void unref(Foo* foo) {
if (--(foo->reference_count) == 0) {
free(foo);
}
}
I'm going to assume you can see the problems with leaving this unprotected because I'm writing a SO post not a book.
The specific atomic operation we're interested in is compare-and-swap (CAS), which basically provides the ability to perform this operation safely:
bool cas(int* value, int* expected, int desired) {
if (*value == *expected) {
*value = desired;
return true;
} else {
return false;
}
}
Using this, we would change our refcounting implementation above to something like:
typedef struct {
int reference_count = 0;
} Foo;
Foo* foo_create(void) {
Foo* foo = malloc(sizeof(Foo));
/* No atomics needed, we haven't made the value public yet */
foo->reference_count = 1;
}
void ref(Foo* foo) {
int old_refcount;
int new_refcount;
do {
current_refcount = foo->reference_count;
new_refcount = current_refcount + 1;
} while (!cas (&(foo->reference_count), &old_refcount, new_refcount))
}
void unref(Foo* foo) {
int old_refcount;
int new_refcount;
do {
current_refcount = foo->reference_count;
new_refcount = current_refcount - 1;
} while (!cas (&(foo->reference_count), &old_refcount, new_refcount));
if (new_refcount == 0) {
free(foo);
} else if (new_recount < 0) {
// Double-free bug, code should not be reached!
}
}
But locking slows down perfomance.
So do atomics. A lot. But also a lot less than a higher-level lock would. For one thing, if you were working with a mutex what you are doing would basically be:
Acquire the lock.
Perform the operation.
Release the lock.
With atomics, we're basically begging forgiveness instead of asking permission:
Attempt to perform the operation.
Then we just look to see whether the operation was successful (i.e., if cas() returned true).
The operation is also a lot smaller and faster; with a mutext, you would probably acquire the lock then read the current value, increment / decrement it, then release the lock. With atomics, the CAS operation gets wrapped up in a single CPU instruction.
The CPU still has to deal with cache coherency by making sure that next time any other core (a bit oversimplified since even within a core there are multiple caches) asks to read the data they are presented with the new data. In other words, atomic reference counting is bad for performance, but it's a lot less bad than a mutex. Frankly, if you want reference counting instead of tracing garbage collection atomics are pretty much your least-bad option.

Vala code with static struct dont works after update to 0.44

Just did a standard job interview is to calculate the volume of water in the histogram. On Monday this code worked, and still works on this site. After updating vala, an error is now displayed.
UPD: more easy example
> Algoritm.vala:2.5-2.16: error: struct `Algotitm.first' cannot be empty
> struct first {
> ^^^^^^^^^^^^ Algoritm.vala:6.5-6.17: error: struct `Algotitm.second' cannot be empty
> struct second {
When posting a question on Stack Overflow it is always good to post an example of the code that is a minimum, complete and verifiable example.
From the link you've provided it appears you have a struct with only members marked as static:
struct First {
static int data;
static int pos;
}
void main () {
}
Marking the fields as static means they aren't instance fields and so the struct is empty of fields. That's why you are getting the error message about the struct being empty. I'm not sure Vala should even allow marking struct fields as static, but it does make sense to allow methods in structs to be static.
You need to remove the static modifiers. This will work:
struct First {
int data;
int pos;
}
void main () {
}
Update
I'm guessing you are trying to write performance optimized code and you think static helps with that. static in Vala means there is no instance data to use. If you are using a data structure like a class or struct then it only makes sense to have instances of those. If you want something to remain unchanged during the running of your program use const in a namespace.
Using a struct may give you a slight performance boost if your are using a very large number in your program. structs created in Vala are allocated on the stack instead of the heap so may be slightly faster. If you are passing structs around you may want to consider [SimpleType] attribute. That means structs will be passed by value in C as well as Vala. Without the [SimpleType] they are copied and passed by reference at the C level, which appears as copy by value in Vala.
Structs in Vala can have initializers (similar to a constructor for a class) and methods. So what I can extract from your second pastebin you could write that as:
struct First {
int data;
int pos;
public First (int[] mass) {
data= 5;
pos = mass.length;
}
public int sas () {
return data + pos;
}
}
void main () {
int[] a = {1,3,0,1,2,3,2,1};
var b = First (a);
print (#"$(b.sas ())\n");
}
That is a follow on question though and should be asked as a second question on Stack Overflow. This is a public forum that follows a format that allows other people to learn from the question and answers.

Custom List with lazy loading

I have successfully implemented like this for lazy loading in custom list
and the code I used for this is here:Custom List With Images in Blackberry
In the linked question, I position the y coordinate of heart icon and I resolved the problemm of linked Question.
if (logoThumbnailImage != null
&& logoThumbnailImage.length > index
&& logoThumbnailImage[index] != null) {
EncodedImage img = logoThumbnailImage[index];
graphics.drawImage(0, y + 10, Display.getWidth(),
Display.getHeight() - 100, img, 0, 0, 0);
graphics.drawImage(300,
y+400,
heart.getWidth(), heart.getHeight(), heart,
0, 0, 0);
Now I want to handle click event for both; that is, for list row click and on heart click
For that I saw a post written by #Nate here Custom List Field click event. But in that code the images are not loading from server and they are static Images. I want to implement #Nate's code with my code (That is lazy loading ).
If you have any Idea please suggest how can I do that. Thanks in Advance
Assuming you start with the code I posted in this answer, and use the code you show in this question to download images from a list of URLs, then you should be able to achieve lazy image loading with the following changes:
Create a listener interface that gets notified when downloads complete:
public interface DownloadListener {
// invokes if download success
public void downloadSuccess(Bitmap bitmap);
// invokes if download failed
public void errorOccured();
}
Then, the Manager subclass that represents one list row, CustomListRow, is modified to implement this interface, and update the _thumb image when the download completes:
public class CustomListRow extends Manager implements DownloadListener, FieldChangeListener {
public void downloadSuccess(final Bitmap img) {
_data.setThumb(img);
// make sure bitmap is updated on the UI / main thread
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
_thumb.setBitmap(img);
}
});
}
public void errorOccured() {
// TODO: handle error
}
Then, you'll need to add some code to create all your threads to download images in the background, and notify the DownloadListeners when the image downloads complete. You can decide where to do this. In my example, I will do this in my ListScreen class, where I instantiate the ListRander data objects and the CustomListField:
for (int i = 0; i < numberOfItem; i++) {
ListRander lr = new ListRander("Product Name " + i, icon); // icon is placeholder for thumbnail image
data.addElement(lr);
}
final CustomListField list = new CustomListField(data);
add(list);
list.setChangeListener(this);
pool = new ThreadPool(3); // 3 concurrent download threads
for (int i = 0; i < numberOfItem; i++) {
final int row = i;
// create a new runnable to download the next image, and resize it:
pool.assign(new Runnable() {
public void run() {
try {
String text=object[row].getJSONArray("UrlArray").getString(0).toString();
EncodedImage encodedImg = JPEGEncodedImage.encode(connectServerForImage(text), quality); //connectserverForImage load Images from server
EncodedImage logoThumbnail = sizeImage(encodedImg, Display.getWidth(), Display.getHeight()-100);
list.getRow(row).downloadSuccess(logoThumbnail.getBitmap());
} catch (Exception e) {
e.printStackTrace();
list.getRow(row).errorOccured();
}
}
}
});
}
You could do this in the ListScreen constructor, or whenever you have your object[] array of URLs.
You'll need to add a new method to CustomListField:
public CustomListRow getRow(int row) {
return (CustomListRow)getField(row);
}
The code above also needs a member variable added (in ListScreen) to create a thread pool:
private ThreadPool pool;
This thread pool implementation is based on this tutorial here, with very minor modifications, simply to change ArrayList (not available on BlackBerry Java) to Vector ... and removing the calls to Thread#destroy(). You'll need to copy that tutorial's ThreadPool, WorkerThread, and Done classes to your project. The above example I show creates a thread pool of 3 threads. On a single CPU smartphone, 2 or 3 threads is probably fine for your needs. Read more here if you want to get the perfect number of threads for your application.
Note: if possible, you can usually improve performance if you download images that are exactly the right size for your application, instead of burdening the network with larger images, and then resizing them inside your app. However, I realize that this depends on having some control over the images' web server, which you may not have. Just a thought for later optimization.
I am sure that I seen a good answer to this question on my travels, but can't find it now. I do recommend reviewing the BB forums here:
http://supportforums.blackberry.com/t5/Java-Development/bd-p/java_dev
as there are similar questions there.
For now, just the highlights of what you need to do:
Create an image downloading runnable to process the download - you have pretty much already done this in your previous code.
Use the Observer pattern (search the internet for this), so that the BitmapField is the Observer for the completion of your image downloading. So when the image has been downloaded, the Runnable invokes the observer, which can then update the Bitmap.
Use a Thread pool with a limited number of Threads (I would say 3), so that you do not start a whole load of image downloads at the same time. Search the internet for information on Thread Pool for help implementing this. You had not done this step in your previous example, and you can get away with running all the downloads, but I expect at some stage that this will fail.
Put these together and you have your solution. Not trivial I know. Good luck.

Dereference pointer with ARC in C function in iOS

I'm using The Amazing Audio Engine to handle playback in syncing in an iOS app.
The framework requires you to use C functions as the call back (playbackTimingReceiver) which is called on the audio thread. You then need to message the main thread again using a C function (AEAudioControllerSendAsynchronousMessageToMainThread) to which you pass a handler (pageTurnHandler).
I'm not overly experienced working with C but as I understand it I'm passing a pointer in the message which needs to be dereferenced.
Which I can achieve successfully with the line:
PlaybackManager* receiver = *((PlaybackManager**)userInfo);
But only if I turn ARC off in the project for that file using the -fno-objc-arc flag in compiled sources on the projects target.
To my question, is it possible to achieve this with ARC turned on? If so what is the correct syntax?
Relevant code segment:
#pragma mark - Audio Timing Callback
-(AEAudioControllerTimingCallback)timingReceiverCallback
{
return playbackTimingReceiver;
}
static void playbackTimingReceiver(PlaybackManager* receiver,
AEAudioController *audioController,
const AudioTimeStamp *time,
UInt32 const frames,
AEAudioTimingContext context)
{
receiver->_hostTime = getUptimeInMilliseconds(time->mHostTime);
AEAudioControllerSendAsynchronousMessageToMainThread(audioController,
pageTurnHandler,
&audioController,
sizeof(id));
}
static void pageTurnHandler(AEAudioController *audioController, void *userInfo, int userInfoLength)
{
PlaybackManager* receiver = *((PlaybackManager**)userInfo);
NSLog(#"Receiver:%#", receiver);
}
PlaybackManager * receiver = (__bridge_transfer id)*(void **)userInfo;
should do the trick. This first casts the userInfo to a pointer-to-pointer, because it contains the address of the original object pointer. Dereference that to get the original pointer, and use __bridge_transfer with a type -- id or PlaybackManager will work -- to tell ARC that the dereferenced value is actually an object that it needs to take care of.
Without running the code there appear to be two errors:
1) You are passing the contents of audioController when it looks like you meant to pass the contents of receiver - so last two args to AEAudioControllerSendAsynchronousMessageToMainThread should be &receiver & sizeof(PlaykbackManager *)
2) You need a bridge cast to get the object reference back out
Something like:
static void playbackTimingReceiver(PlaybackManager* receiver,
AEAudioController *audioController,
const AudioTimeStamp *time,
UInt32 const frames,
AEAudioTimingContext context)
{
receiver->_hostTime = getUptimeInMilliseconds(time->mHostTime);
AEAudioControllerSendAsynchronousMessageToMainThread(audioController,
pageTurnHandler,
&receiver,
sizeof(PlaybackManager*));
}
static void pageTurnHandler(AEAudioController *audioController, void *userInfo, int userInfoLength)
{
PlaybackManager* receiver = (__bridge Playback *)*((PlaybackManager**)userInfo);
NSLog(#"Receiver:%#", receiver);
}
Note: when passing object references from the ARC controlled world to the C world you often transfer ownership on the way in - so ARC doesn't release the referenced object - and transfer ownership back on the way back out - so ARC resumes ownership management. However due to the nature of AEAudioControllerSendAsynchronousMessageToMainThread, where userInfo is passed by address and copied internally - hence the size argument, it is tricker to transfer ownership. Therefore the above code does not. This means you must make sure that whatever object receiver references stays alive by having another owner.
You can just tell ARC the type of storage you would like:
PlaybackManager *audioBufferPlayer = *(__weak PlaybackManager **)userInfo;
Just be sure to do necessary nil checks before accessing any properties or calling any methods.

how to synchronize base class

i have extend a uiapplication for user interface,in which i will take a date on which i schedule a task.
and i extend another base class application for running background process which will check the date and execute desired operation.
but these both are base class so i want to synchronize them..
and don't know how to synchronize base class..
plz help mee..
First, and I know it is a fine point but programming is all about fine points, you don't synchronize on Classes, you sychronize on Objects (which are instances of Classes).
On Blackberry you can use standard Java sychronization techniques, synchronized methods:
public synchronized void mySynchronizedMethod() {
// synchronized code
}
and synchronized blocks:
public void myMethod() {
//code
syncrhonized(someObject) {
// synchronized code
}
// code
}
You can also use a specific object to synchronize with the event thread and have your code run on the event thread which allows serialized access to the UI:
public void myMethod() {
//code
syncrhonized(UiApplication.getEventLock()) {
// synchronized code
}
// code
}

Resources