How to test low bandwidth conditions on the iPhone
Asked Answered
S

8

7

I have an application that does a lot of binary data loading. I've encountered scenarios where an unstable 3G connection may intermittently cut out during the loading of some of this binary data, causing issues.

Is there any way, using the simulator or otherwise, to test for low-bandwidth/unstable connection scenarios?

I seem to recall Adobe Flash having bandwidth simulators in their test suite.

Suffering answered 29/7, 2010 at 18:2 Comment(1)
Is testing in NYC an option? (kidding.)Callihan
K
7

You can accomplish this by creating a wireless network on your Mac using Internet Sharing, degrading that interface using firewall rules, and connecting your iPhone to that network. This will actually work to debug any device that connects to a wireless network.

Using this technique, you can simulate extremely meager, lossy, or latent networks.

I use this technique instead of Apple's official Network Link Conditioner for a couple reasons:

  • Throttling can be applied only to specific connected devices, rather than affecting your development machine's network connection.
  • It can be scripted to simulate rapidly changing or "bursty" networks.
  • Unlike the Network Link Conditioner built into iOS, you can change the settings while your application remains in the foreground.

This uses ipfw's dummeynet feature. ipfw is technically deprecated in modern versions of OS X, but it still works fine. Unfortunately, pf (the replacement) doesn't yet support arbitrary packet delays. I'll update this answer if something changes.

Creating an awful Wi-Fi network

  1. Plug into Ethernet if you aren't already.
  2. Enable Internet Sharing in the Sharing pane of System Preferences. Choose to "Share your connection from: Ethernet" and check "Wi-Fi".
  3. Get your phone connected to the network you just created and make sure you can browse the web.
  4. Tell Mac OS's built-in firewall (ipfw) to ensure packets that have latency applied (pass through the "dummynet" in ipfw parlance) are still routed through the normal rules. This allows Internet Sharing to continue working:

    phil@Nebula ~$ sudo sysctl -w net.inet.ip.fw.one_pass=0
    net.inet.ip.fw.one_pass: 0 -> 0
    
  5. Configure the low-quality pipe through which your iPhone's traffic will pass (14Kb/s throughput with 1% packet loss):

    phil@Nebula ~$ sudo ipfw pipe 1 config bw 14KB/s
    phil@Nebula ~$ sudo ipfw pipe 1 config plr 0.01
    

The next step varies depending on whether you're on Mountain Lion or below, or Mavericks.

For Mountain Lion (10.8) or below:

Route packets into the pipe, but only for traffic over your AirPort interface:

phil@Nebula ~$ sudo ipfw add 10 pipe 1 ip from any to any via en1
00010 pipe 1 ip from any to any via en1

Important: If you're using an Air or new MacBook Pro without a physical ethernet port, your AirPort interface will likely be called en0. Replace en1 with en0 above if that's the case.

For Mavericks (10.9):

Check the output of ifconfig and look for the bridge interface created by Internet Sharing:

bridge0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    options=63<RXCSUM,TXCSUM,TSO4,TSO6>
    ether xx:xx:xx:xx:xx:xx
    Configuration:
            id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
            maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200
            root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0
            ipfilter disabled flags 0x2
    member: en4 flags=3<LEARNING,DISCOVER>
            ifmaxaddr 0 port 6 priority 0 path cost 0
    nd6 options=1<PERFORMNUD>
    media: <unknown type>
    status: inactive
bridge100: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    options=3<RXCSUM,TXCSUM>
    ether xx:xx:xx:xx:xx:xx
    inet 192.168.2.1 netmask 0xffffff00 broadcast 192.168.2.255
    Configuration:
            id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
            maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200
            root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0
            ipfilter disabled flags 0x2
    member: en1 flags=3<LEARNING,DISCOVER>
            ifmaxaddr 0 port 5 priority 0 path cost 0
    media: autoselect
    status: active

You want the bridge interface that has an IP address; in most cases, it will be bridge100.

Route packets into the pipe, but only for traffic over the bridge interface:

phil@Nebula ~$ sudo ipfw add 10 pipe 1 ip from any to any via bridge100
00010 pipe 1 ip from any to any via bridge100

Change bridge100 if it has a different name on your system.

Simulating a changing network

You can change the values 14KB/s and 0.01 in step 5 above to simulate different types of networks. You can also specify config delay 1000 to introduce a 1000ms delay. See the manpage for more options.

You can continue to reconfigure the pipe after adding the rule for it. For instance, to simulate nearing the edge of cellular coverage, issue this command while your app is running and connected (95% packet loss):

    phil@Nebula ~$ sudo ipfw pipe 1 config plr 0.95

There is no need to run sudo ipfw add 10 … again after reconfiguring the pipe. You can script these changes to simulate an extremely dynamic network environment.

Cleaning up

You can issue sudo ipfw delete 10 to put everything back to normal, or just reboot.

Kylynn answered 13/9, 2012 at 2:49 Comment(3)
isn't ipfw deprecated ? developer.apple.com/library/mac/#documentation/Darwin/Reference/…Mikey
@MarcelFalliere Yes, but it's still available as of Mountain Lion. Perhaps you'd like to contribute an answer that does the same thing with pf?Kylynn
I'm on montainLion. The thing is I read the man page instead of blindly using your command lines. You helped me a lot, puttin me in the right direction. I made a script out of it, with params, and that clean every pipe afterwards. I have to share this !Mikey
F
5

Here is a great script I've used on OS X to throttle connection speed, or just turn it off, for any domain you want. I wish I could remember where I got it from to give credit.

Save the code to a file on your machine and name it "throttling". Then to run, just enter the below in terminal, and select from one of these speeds: [full|fast|medium|slow|wwdc|off].

"./throttling medium"

If you have the script set up to throttle localhost:3000 and stackoverflow.com, then loading up a page from either of those domains in your browser (or iphone simulator or whatever) will respond slower and load files slower. It's been really great for testing iphone connectivity bugs.

http://gist.github.com/499177

Furfuran answered 29/7, 2010 at 20:46 Comment(0)
H
2

You could test a number of things if you turn 3G off and connect to wifi.

  1. Log into your router and rate limit the mac address of your iphone. (to test slow connections)

  2. Kill the power to the wifi when in the middle of downloading data

  3. Reboot the wifi router when downloading so the phone has connection, loses it, and gets it again. ( to test different scenarios )

Happy Coding!

Hurds answered 29/7, 2010 at 20:7 Comment(2)
You can't turn 3G off on CDMA iPhones.Coraliecoraline
If you notice the date stamp on this answer, "answered Jul 29 '10 at 20:07" it was way before the CDMA iPhone.Hurds
C
1

I read of someone testing with their iPhone connected by USB cable and the phone wrapped in aluminum foil to get the cellular signal reduced. You can turn off WiFi and 3G and just have Edge and then attenuate it with foil. Sounds crude but...

You could also use an iPhone 4 and hold in your hand to short the two antennas together ;-)

Cahoon answered 29/7, 2010 at 18:27 Comment(0)
W
1

Chrome 38 includes network emulation in the device emulation settings. You can select from Offline, GPRS, EDGE, 3G, DSL and WiFi. Also emulates increased latency.

It's not as accurate as testing on a real device but it's much quicker to set up.

Whiffet answered 13/10, 2014 at 13:31 Comment(0)
C
0

Well, low bandwidth is simple: turn off Wifi, turn off 3G. Cutting connection is also simple: turn on wifi, get connected, power off your wifi access point.

Caerleon answered 29/7, 2010 at 18:6 Comment(1)
You can't turn 3G off on CDMA iPhones. This option may be going away entirely; I wouldn't put it past Apple and their mania for removing useful options.Coraliecoraline
F
0

I guess you could connect to a Mac (if you had one) setup as a WiFi base station (ad-hoc network). Then on the Mac set up a "dummynet" bandwidth limit and/or high packet loss filter.

That's what I do to simulate the slower higher-latency DSL lines I am making software to setup for Macs.

Formosa answered 29/7, 2010 at 18:7 Comment(0)
G
0

On the iPhone you can't. One way would be to share your computer WIFI connection to your iPhone but to slow it down using a special application.

This blog post describes some approaches for that:

http://blog.aptivate.org/2010/01/23/make-sure-your-apps-work-in-the-field/

Gwennie answered 29/7, 2010 at 18:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.