Script for opening autolayout warnings in wtfautolayout

Yessen
Deem.blogs
Published in
4 min readFeb 11, 2022

--

During the run time, sometimes developer can notice messages in the XCode terminal saying:

Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x170098420 H:[UIView:0x15c62c100(2)]>",
"<NSLayoutConstraint:0x170098600 UIView:0x15c6294f0.leading == UIView:0x15c628d40.leadingMargin - 8>",
"<NSLayoutConstraint:0x170098650 H:[UIView:0x15c6294f0]-(0)-[UIView:0x15c62b750]>",
"<NSLayoutConstraint:0x1700986a0 UIView:0x15c62b750.width == UIView:0x15c6294f0.width>",
"<NSLayoutConstraint:0x1700986f0 UIView:0x15c628d40.trailingMargin == UIView:0x15c62b750.trailing - 8>",
"<NSLayoutConstraint:0x170098880 H:[UIView:0x15c6294f0]-(0)-[UIView:0x15c62c100]>",
"<NSLayoutConstraint:0x1700988d0 UIView:0x15c628d40.centerX == UIView:0x15c62c100.centerX + 1>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x170098420 H:[UIView:0x15c62c100(2)]>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

It is often annoying and quite hard to understand the issue from the message. Therefore, in order to get the details of the constraint issue, as it is written in the message, we should set “symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints” in order to debug the issue.

Symbolic breakpoint

In order to do it, go to the Breakpoint navigator in Xcode (Command-8). At the bottom of the window, click the Plus button, and choose “Symbolic Breakpoint…” from the menu.

Soon, you will notice the popup, where you should enter UIViewAlertForUnsatisfiableConstraints in the Symbol field.

If we run the code again, Xcode will stop on the new sybmolic breakpoint whenever it encounters conflicting constraints.

Debug the warning

Now, as the Xcode stopped the run time on place where there are couple of conflicting constraints, we got two parameters: $arg1 and $arg2, which are actually two constraints that are contradicting to each other.

If you type po [$arg2 description] you will notice the description of the second parameter(conflicting constraint) like this:

(lldb) po [$arg2 description]
(
"<NSLayoutConstraint:0x6000008d2620 My cool view.width == 20 (active, names: My cool view:0x7fd1fc901550 )>",
"<NSLayoutConstraint:0x6000008d3340 My cool view.width == 40 (active, names: My cool view:0x7fd1fc901550 )>"
)

Pass the message to wtfautolayout.com

Now, since usually it is hard for us to understand what exactly compiler is complaining about, we can use the beautiful service called wtfautolayout, by just passing the message from the terminal. Copy and paste the message from [$arg2 description] to wtfautolayout so you can see the UI representation of the conflicting constraints.

Automate the wtfautolayout.

Now, there is an option for Xcode to open the website with the message included automatically everytime we face autolayout warning. In order to do that, we have to add script action written in python to our symbolic breakpoint.

Here is the script, which you can copy and paste:

#!/usr/bin/env python
import sys
import subprocess
import urllib
# Opens an array of constraints in wtfautolayout.com for visualization.
#
# Usage: set a symbolic breakpoint for UIViewAlertForUnsatisfiableConstraints
# and add a Shell Command action that runs this script,
# and calls with this parameter:
# @(NSString *)[(id)$arg2 description]@
# Argument 0 is the path to the script itself, so we start
# counting arguments from 1. Any commas followed by spaces
# in the original text are interpreted as argument delimiters,
# so we need to join them back together with another comma and space.
# They also come in with backslash escapes for characters such as
# single and double quotes, so we decode those string escapes as well.
input = ", ".join(sys.argv[1:]).decode('string_escape')
# The input is an NSString, so it's wrapped in this: @"".
# We remove a double-quote from the end and an at-double-quote
# from the beginning.
stripped_input = input.rstrip('"').lstrip('@"')
# Use urllib to URL-encode special characters.
quoted_log = urllib.quote(stripped_input)
url = 'https://www.wtfautolayout.com/?constraintlog=%s' % quoted_log# Open the URL in the user's default browser.
subprocess.call(['open', url])

We must mark this script as executable by running the following Terminal command:

chmod +x /path/to/wtfautolayout.py

Next, go to your breakpoints, select the symbollic breakpoint for autolayout warnings, and press Edit Breakpoint… Then click the Add Action button, and from the popup menu select Shell Command.

In the Command field, type or choose the path to our python script code.

In the second text field, which is for passing arguments, enter

@(NSString *)[(id)$arg2 description]@

Long warning issue

As far as I understood, there is a character limit set for under 10000, when trying to send the arg2 to the script. In order to fix follow these steps:

  1. Create ~/.lldbinit file
  2. Put this following line of code inside of the lldbinit file:
setting set target.max-string-summary-length 10000

This will increase the limit for 10000 characters.

  1. Close your xcode, and open it again.

Congrats! You are all set!

Happy Coding.

Insipred by: https://www.rightpoint.com/rplabs/2019/06/wtf-auto-layout-for-ios-in-swift/

--

--