With this article, I’m starting a series about all the goodies — useful tools — that can be found in Xcode. Some of these tidbits are tools everyone knows about while others are barely documented to undocumented. For example, how many of you know that you can view, inspect, and debug all your Auto Layout constraints live during app execution using the “Debug View Hierarchy” Xcode feature? I discussed that feature in detail in this article, “Troubleshooting Auto Layout using Xcode’s Debug View Hierarchy.” Today, we’ll discover two editors that ship with Xcode, the “Open As > Hex” and “Open As > Source Code” editors, both only available by right-clicking on files in the “Project Navigator” to reveal a contextual menu.
The Xcode hex editor
A couple of days ago, I found myself Googling the term “Xcode hex editor.” I didn’t know that Xcode had a built in hex editor! I never even noticed it and I’ve been using Xcode since 2011. Doh!
To open a file in hex, right-click on the file in the “Project Navigator” to reveal a contextual menu, and choose “Open As > Hex,” like so:
The file I selected, “CodeFile.swift,” opens in a typical hex editor — columns of bytes encoded as hex values on the left and columns showing the corresponding human-readable text on the right, as follows:
“CodeFile.swift” is a file I had just pulled from my remote Git repo. Here’s the contents of the file as pulled:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// // CodeFile.swift // LineEndings // // Created by Software Testing on 1/22/18. // Copyright © 2018 Software Testing. All rights reserved. // import Foundation import UIKit class someClass { // Some code... } |
Notice that I’ve highlighted the two consecutive hex characters, 0D 0A
, on the left, in the hex editor screenshot above. Notice that the corresponding human-readable characters are highlighted on the right. I checked the next two consecutive hex characters, 0D 0A
:
Would anyone like to speculate as to why I’m looking at the sequence 0D 0A
? I’ll give you a hint. I work in a mixed development environment. Some members of my teams develop code on Windows using Visual Studio. Other members of my team write code on OS X using Xcode. Read one of my Git tutorials, “Typical Git/GitHub workflow tutorial: configure, clone, commit, stage, push, pull, status,” specifically the section on “Git handling of line endings.”
Xcode is screwing up my file line endings (Git)
As I discussed in my aforementioned Git tutorial, Windows uses two invisible characters to mark the end of a line, a “carriage return” and a “line feed,” CR LF
(hex 0D 0A
). OS X uses one, a “line feed,” LF
(hex 0A
). When you want to go to the next line while coding, you hit the Enter
key on Windows and the return
key on Mac.
Git has settings to compensate for, and thus allow us to compare, files with different line endings. I discussed this in my Git tutorial and there’s lots of information on the web for configuring Git.
The problem I’m having is documented:
Since I upgraded to Xcode 9 every time I change even one character in the code, whole file gets its line breaks changed (I checked with xxd) and so it looks like I modified the whole file.
My Preferences->Text Editing is set to CLRF (Original line breaks) and yet it changes everything to LF. …
Reported to Apple and bugreport marked as duplicate, so they know it already. …
Git is hard enough to understand and configure properly, but having Xcode jump into the line ending quagmire is a royal pain in the ars. I don’t want to get involved in a long-winded discussion of Git here; I just want to point out the usefulness of Xcode’s hex editor — despite Xcode’s other problems.
Patch for Xcode’s screw-up
I have a manual workaround. Whenever I pull a file from my remote, and before making changes to code and saving the file, I look at the file in the hex editor. Look at the hex editor images above. Note that file “CodeFile.swift” was saved in Windows format (CRLF
). Can you guess what happened when I made some changes and I saved the file? It was saved into Mac format (LF
):
Here’s “CodeFile.swift” after I made changes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// // CodeFile.swift // LineEndings // // Created by Software Testing on 1/22/18. // Copyright © 2018 Software Testing. All rights reserved. // import Foundation import UIKit class someClass { // Some code... func showSafari() -> Void { let url = URL(string: "https://iosbrain.com") UIApplication.shared.open(url!, options: [:]) } } |
What lines of code in “CodeFile.swift” do you think Git is going to mark as changed? Since Xcode changed the line ending of every line in the file, Git is going to indicate that I changed every line in the file! @!!!#@#@!!@!!!#! (expletive). How do I know this? I do a git diff
:
That’s just crazy. Imagine if “CodeFile.swift” was a big, complex file and I made 5 changes in different parts of the file. The whole purpose of using Git for source control would be defeated. The history for the file would be reset. It would be very difficult for other developers to see the changes I made. So what to do?
I used a reliable text editor, TextWrangler, to save “CodeFile.swift” with Windows line endings (CRLF
):
Now look what happens when I do a git diff
:
Now I can commit and push “CodeFile.swift” to Git and see an accurate representation of the changes I made.
The Xcode source editor
A lot of configuration files in the software development world are stored in XML, and rightly so, as XML is a very readable format. With XML tags and indentation, looking at a .plist
or .storyboard
file in XML sometimes is a necessary “evil.”
For example, viewing a .storyboard
file as XML, you can find precise values for various settings, like constraints (i.e., a constant
), positions (i.e., rect
x
, y
, width
, and height
values), and connections (i.e., IBAction
, IBOutlet
). There’ve been a couple of occasions when I’ve had very complex layouts, encountered Auto Layout problems, and was only able to fix my layout by looking at the XML.
When using .plist
files, I sometimes find it easier to add a setting by editing the XML. Remember my article, “Oh, my — App Transport Security has blocked a cleartext HTTP (https://) resource load since it is insecure”, where I had to configure App Transport Security settings to allow loading of insecure, clear text URLs? There’s an image in that article that shows how I added the settings.
To open a .plist
or .storyboard
file in XML, right-click on the file name in the “Project Navigator” to reveal a contextual menu, like so:
Here’s a .storyboard
file being edited as XML where I’ve highlighted some of the settings I mentioned earlier:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<?xml version="1.0" encoding="UTF-8"?> <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13196" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r"> <device id="retina4_7" orientation="portrait"> <adaptation id="fullscreen"/> </device> <dependencies> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13173"/> <capability name="Safe area layout guides" minToolsVersion="9.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> <scenes> <!--View Controller--> <scene sceneID="tne-QT-ifu"> <objects> <viewController id="BYZ-38-t0r" customClass="ViewController" customModule="LineEndings" customModuleProvider="target" sceneMemberID="viewController"> <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC"> <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="WbW-vg-4cV"> <rect key="frame" x="164" y="50" width="46" height="30"/> <state key="normal" title="Button"/> <connections> <action selector="buttonPush:" destination="BYZ-38-t0r" eventType="touchUpInside" id="XGC-4l-B5n"/> </connections> </button> </subviews> <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <constraints> <constraint firstItem="WbW-vg-4cV" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" constant="30" id="bfY-kp-Wl4"/> <constraint firstItem="WbW-vg-4cV" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="gUO-oU-N3q"/> </constraints> <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/> </view> <connections> <outlet property="button" destination="WbW-vg-4cV" id="aNH-tR-5Re"/> </connections> </viewController> <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/> </objects> </scene> </scenes> </document> |
Wrapping up
Software development is so complex, and it’s only getting more complex. If you’re going to be a good developer, you need to make sure you’re making use of all the tools at your disposable. That means you may have to take some time just poking around in your IDE, trying to find tools you didn’t even know existed. One of the best things you can do is to read Apple’s Xcode documentation or some of the great third party resources out there on getting the most out of Xcode.
Be your best!