title: Dynamically Mocking iOS Dynamic Type System Text Size (UIContentSizeCategory)
body: <p>I'd like to easily test my app with different selections of system text size, including accessibility sizes. These can be set in the Settings app (Display &amp; Brightness => Text Size or General => Accessibility => Larger Text). </p>
  
  <p>The only way I can find to currently do this is to go into Settings and change the value with the UI (edit: <a href="https://stackoverflow.com/a/38316592/1148702">partial solution</a> described below). This is slow and cumbersome. I suspect there's a way to dynamically alter it using private APIs, but I can't figure out how. Since my goal is to only use this for debugging, private API use and swizzling is fine (this code won't be making its way to production).</p>
  
  <p>To try to find a private API to do this, I looked at some reverse engineering resources. I'm new to disassemblers, symbol tables, class dumps, and finding private APIs I can use, but this is what I've tried so far:</p>
  
  <ul>
  <li><p>I successfully swizzled <code>-[UIApplication preferredContentSizeCategory]</code> (other posts said this worked in the past), but this doesn't affect the result returned from <code>+[UIFont preferredFontForTextStyle:]</code>.</p></li>
  <li><p>Using the disassembler <a href="https://www.hex-rays.com/products/ida/" rel="noreferrer">IDA</a> I discovered that <code>+[UIFont preferredFontForTextStyle:]</code> is in the private framework <code>UIFoundation.framework</code>. (<code>-[UIApplication preferredContentSizeCategory]</code> is in <code>UIKit.framework</code> but the disassembly didn't look at all useful).</p></li>
  <li><p>Just as I started writing this question (it always happens that way), I discovered a <a href="https://stackoverflow.com/a/38316592/1148702">partial solution</a>. One can set a launch argument in the scheme to set the value on launch. This is useful, but not what I'm after.</p></li>
  <li><p>Through the above answer, I <a href="https://github.com/fastlane-old/snapshot/issues/446" rel="noreferrer">found</a> the value for the user's preference is apparently stored in "the <code>com.apple.UIKit.plist</code> file located in the Simulator's <code>data/Library/Preferences</code> directory". The value we're after can be set from the command line utility <code>plutil</code>. This is also an improvement! But I'd like to dynamically alter it at runtime.</p></li>
  </ul>
  
  <p>More on my results from IDA:</p>
  
  <p>I don't really know how to read disassembly, but <code>+[UIFont preferredFontForTextStyle:]</code> seems to point to a symbol called <code>___UIFontForTextStyle</code> which seems to point to some interesting-sounding symbols called <code>_getUIContentSizeCategoryUnspecified</code> and <code>_getUIContentSizeCategoryPreferenceClass</code></p>
  
  <p><a href="https://i.stack.imgur.com/mZoV3.png" rel="noreferrer"><img src="https://i.stack.imgur.com/mZoV3.png" alt="Disassembly for &lt;code&gt;___UIFontForTextStyle&lt;/code&gt;"></a></p>
  
  <p>I also found these symbols using the command-line utility <a href="https://en.wikipedia.org/wiki/Nm_(Unix)" rel="noreferrer"><code>nm</code></a> on <code>UIFoundation.framework</code>. They were marked with the lowercase letter "s" meaning, apparently, <a href="https://sourceware.org/binutils/docs/binutils/nm.html" rel="noreferrer">"The symbol is in an uninitialized data section for small objects."</a>. I have no idea what this means (all I've gathered is that they're not a class or method).</p>
  
  <p>Searching the web for the <code>_getUIContentSizeCategory...</code> symbols yields nothing, but nearby there's another symbol <code>_getUIApplicationClass</code>. I searched for that one since it sounded a bit more general, and found something similar in some <a href="https://github.com/WebKit/webkit/blob/master/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm#L66" rel="noreferrer">WebKit source</a>. Could be nothing, but maybe it's an internal Apple convention. Regardless, the example doesn't really help me solve the problem.</p>
  
  <p>Anyway thanks for reading so far. If you're still here, my question is:</p>
  
  <p>I'd like to be able to dynamically mock the value for the dynamic type size preference. These disassembly symbols might help, but maybe I'm on the wrong track. It feels like the solution is close but I just can't put all the pieces together.</p>
  
  <p>Setting this value as a launch argument is nice, but doesn't fully solve my problem. Similarly, modifying the Simulator's value in the <code>plist</code> is also nice for automation, but doesn't solve my problem.</p>
  
  <p>Is there a way to dynamically alter this value at runtime?</p>