How can I get fake contacts in iOS Simulator? Is there a shell script I can use or an editor for my contacts?
Edit: I use React Native so I can't just throw some Swift project in there - is there a command line tool or way to connect the iOS Simulator to my Contacts application on my Mac?
You can download this generated VCF file, and then drag/drop it to your Simulator to import (1000) fake contacts. I created this test data using the mock data generation website Mockaroo.
This was created using a small Node.js script that takes a CSV and converts it into one single VCF file - which you can then drag and drop to the iOS Simulator. This is the simplest way to import contacts, no code required or installation of apps needed off GitHub (as the other answers imply). This CSV parser assumes you have three columns at the top of the file (First Name, Last Name, and Phone Number. If you want to add more columns/variables for importing, simply modify your CSV and the parser below based off the vCard spec.
Save the below script as "mock.js" and run it with node mock (here's a GitHub gist of it). This assumes the script below, along with your CSV file (e.g. "MOCK_DATA.csv") is in the same directory. The output of running this script will be a file named "vcards.vcf".
const fs = require('fs');
const csv = fs.readFileSync('./MOCK_DATA.csv', 'utf8');
const records = csv.split('\n').slice(1);
const VCARDS = [];
records.forEach(function(record, i) {
const data = record.split(',');
const VCARD = [
'BEGIN:VCARD',
'VERSION:4.0',
`N:${data[1]};${data[0]};;;`,
`FN:${data[0]} ${data[1]}`,
`TEL;type=HOME:${data[2]}`,
'END:VCARD'
].join('\n');
VCARDS.push(VCARD);
});
fs.writeFileSync(`./vcards.vcf`, VCARDS.join('\n'));
if you're looking for a programmatic way to do this sort of thing, simctl is a nice tool -
/usr/bin/xcrun simctl addmedia booted ~/path/to/contact.vcf
NSHipster has a great writeup: https://nshipster.com/simctl/
One key thing I overlooked is that a simulator must be "booted" before you can interact with it programmatically.
I'm mostly doing this to be able to take screenshots with fastlane, and I run this bash script at the start of that lane.
It 1. lists all of the ios 13.4 devices 2. greps the UUIDs and 3. loops through each simulator to boot it, add a vcf, and shut it down
It takes a few minutes to run, but for me beats opening all of the simulators and dragging a vcf. I also clear the simulator data, as there's no de-duping here.
#!/bin/bash
xcrun simctl list devices 'iOS 13.4' \
| grep -E -o -i "([0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12})" \
| while read line ; do
xcrun simctl boot $line
/usr/bin/xcrun simctl addmedia booted PathTo.vcf
xcrun simctl shutdown $line
done
Bit cleaner version of niftylettuce's answer, with Faker data, images, and extra data for evenly numbered contacts:
https://github.com/corysimmons/vcf-generator
I just found this while looking to do the same. Here is what I ended up doing:
for i in {0..100}
do
echo "BEGIN:VCARD\n
VERSION:4.0\n
PRODID:-//BBros.us llc//bvCard.com//EN\n
N:User"$i";TEst;;;\n
FN:TEst User"$i"\n
EMAIL:test.user"$i"#domain.com\n
ORG:Great Business\n
END:VCARD" > "File$(printf "%03d" "$i").vcf"
done
In Terminal I changed to a test folder, and ran this script in there. It created the VCard files, and I then dragged them to a running simulator window and dropped them on the simulator. This caused the simulator to open Contacts and import them.
I hope this helps.
* UPDATE *
So once I updated Xcode I can now only import a single contact at once, which is not ideal. This lead me to another solution:
https://github.com/cristianbica/CBSimulatorSeed-Swift
This is a quick app you can build & run in simulator to seed many contacts for you.
Related
I'm writing a test that is supposed to test uploading a video file, using XCUITest in XCode 12. The test is supposed to be self-contained so I'm not certain how to exactly do this.
Typically I want the flow to work like this:
App builds
File is copied from the code folder (I've moved the video to be in the code) into the simulator
Tests run
However step 2 is giving me a ton of problems. I'm trying using this in a build phase:
xcrun simctl addmedia booted ~/code/resources/Video.mov
Bur it's currently giving a completely unspecified error. I'm not sure if this is because I'm trying to do it before the simulator is "booted" or if something else is going on. Does anyone have a solution?
I figured it out. The correct way to do this was to just use a . instead of ~ and then realize that:
. puts you at the project level (.xcproj)
I am working with an iOS app which uses both objective-c and swift code. Currently app IPA size became large. Some resources are included but may not be used in Release IPA. I want to find out which resource should be removed and which resource are making my app size increased unnecessarily. I wonder if there is any such tool or xcode profiler to analyze.
So far the best tool I found is https://github.com/tinymind/LSUnusedResources
LSUnusedResources
A Mac App to find unused images and resources in an XCode project. It is heavily influenced by jeffhodnett‘s Unused, but Unused is very slow, and the results are not entirely correct. So It made some performance optimization, the search speed is more faster than Unused.
Export unused resource list
Use this tool and export unused/unreferenced resource list into unused.txt
Remove references from Xcode .pbxproj file
Use the below python script to delete references from project.pbxproj file:
file = open("unused.txt","r")
data = [line.rstrip('\n') for line in open("project.pbxproj", 'r')]
newFile = open("project2.pbxproj","w")
def removeLine(imageName):
temp = data
for line_s in temp:
if line_s.find(imageName) != -1:
data.remove(line_s)
else:
continue
for line in file:
if (len(line) > 5):
tokens = line.split("/")
len_a = len(tokens)
imageName = tokens[len_a-1]
removeLine(imageName.rstrip('\n'))
for line in data:
newFile.write(line)
newFile.write('\n')
And an alternative script, in bash:
#!/bin/bash
UNUSED_ASSETS_FILENAME="unused-images.txt"
XCODEPROJ_PATH="zilly.xcodeproj/project.pbxproj"
while read LINE; do
FILENAME="$(basename "$LINE")"
if [[ $FILENAME =~ (png|jpeg|jpg|gif)$ ]]; then
echo "Removing '$FILENAME' references from $XCODEPROJ_PATH"
sed -i '' "/$FILENAME/d" $XCODEPROJ_PATH
fi
done < $UNUSED_ASSETS_FILENAME
First of all, are you using the latest Xcode version? Xcode 8.3 produces binaries 2-3 times larger than Xcode 8.2, and Apple fixed this bug in 8.3.1.
Also, you can check out On Demand Resources, which will let you upload your heavy assets to App Store, but not bundled within the app - and when the user will download your app, iOS will automatically download necessary assets for properly running the app.
You can change the .ipa file to have the .zip extension and unpack it. You later on can use simple inspection (Disk Inventory X for instance) of the unarchived .zip file and
see what's going on there.
Also, it is probable that you're looking at a App Store Submission .ipa, which will contain necessary dSYM files and other miscellaneous data.
You can check what App Store .ipa sizes for different devices the app will have by following steps in this answer.
And last but not least, check out this Q&A by Apple on reducing the size of your app.
Recommend an effective tool to analysis App Size:
WBBlades
Advantages:
Directly measure the size of .a or .framework after linking, no need to compile again and again.
Clearly show the differences between two versions,helping you to control the increasing size.
Effectively detect unused Code (ObjC & Swift)
Widely used in apps of Wuba inc.
Is there any programmatic way to control the xcode > simulate location command? I have external location test scripts I'd like to run, and ideally the test suite could cause xcode to change the location of the connected phone at will.
Is this possible, and if so how?
Not sure if it's exactly what you're after, but you can have different unit test bundles use different locations (or GPX files) by setting it up in the scheme.
You could then have unit tests in each bundle which test what you need regarding that specific location.
xctool can also just run the unit tests in a specific target using the -only option:
path/to/xctool.sh \
-workspace YourWorkspace.xcworkspace \
-scheme YourScheme \
test -only SomeTestTarget
There is a GitHub project called Pokemon-Go-Controller that does exactly what you want.
Overview of the solution:
Create a gpx file
Create a blank project referencing (not copying) that gpx file and run it on your device
Run auto clicker which will constantly click update location in Xcode
Update gpx file using some script and the device location will be automatically updated
Instead of the auto clicker you can use this Apple Script:
#Will continue update the location to the location name below from Xcode:
property locationName : "pokemonLocation" #name of your gpx filex
###########################
tell application "System Events"
tell process "Xcode"
repeat while true
click menu item locationName of menu 1 of menu item "Simulate Location" of menu 1 of menu bar item "Debug" of menu bar 1
delay 0.2
end repeat
end tell
end tell
Yes, it is possible.
1. Set up the GPX files as described in #InsertWittyName 's answer, or as described in this blog post.
2. Use Instruments to run your app in the Simulator using the different GPX files.
I would write out the entire process, but someone more eloquent than myself already has.
As an avid S/O user, I would be bereft to leave what is basically a single-link answer. So here is some extra, bonus information.
You should definitely look into security testing your location aware features. I will be at Black Hat this year, so if you're there, let's talk about it!
If you don't like the previously linked/sort of explained answer, you could use XCTest with code to simulate different locations (like this).
It looks like there are also Apple Script solutions, like this one.
I hope I have at the very least provided enough information to qualify as more than just a lazy link-only answer. Enjoy, and good luck!
idevicelocation is a command line tool to mock geolocation in ios devices.
Usage:
$ idevicelocation [OPTIONS] LATITUDE LONGITUDE
Set the location passing two arguments, latitude and longitude:
$ idevicelocation 48.856614 2.3522219000000177
Passing negative values :
$ idevicelocation 77.432332 -- -7.008373564
Stopping Location Simulation:
$ idevicelocation --stop
Options:
-d enable connection debug messages.<br/>
-u specify device UDID.<br/>
-h help.<br/>
-s stop location simulation on device.
It uses libimobiledevice library to communicate with the process com.apple.dt.simulatelocation which is also used by Xcode internally for the same purpose.
Build instructions are there in the README file. Make sure to mount the correct developer image before going random places. Thanks to Angulo for writing this awesome utility.
This tool is not currently being shipped with libimobiledevice package although there's a Pull Request pending since long.
How can I customize the default Carrier name to something else, e.g. AT&T?
There is a way to change the carrier name without using any objective c code or image editor app: https://github.com/toursprung/iOS-Screenshot-Automator/blob/master/changeCarrierName
This solution works great with all versions of iOS (including iOS 6 and 7)
The key point is
sudo plutil -convert xml1 SpringBoard.strings
We don't necessarily have to convert it back to binary code since Mac OS accepts both formats.
After you converted your file to XML, you can easily edit the file with vim or any other editor of your choice.
UPDATE:
I uploaded a detailed description on how to update the carrier name: https://github.com/toursprung/iOS-Screenshot-Automator/blob/master/changeCarrierName
Copy and paste into terminal, replacing DERP with your carrier string:
find -E /Applications/Xcode.app -iregex '.*/en(glish)?.lproj/SpringBoard.strings' -exec sudo /usr/libexec/PlistBuddy -c 'Set :SIMULATOR_CARRIER_STRING DERP' {} \;
Finds relevant files and modifies them in place. No copying files, converting binary to xml, or editing strings in other applications.
You can use this hack, just compile the XCDFakeCarrier.m file in your project and change the FakeCarrier constant to what you want.
There is a perfect app for this called Status Magic that I was beta testing. Just trying to find a link for it...
You import a screenshot and it removes all the carrier specific text from it and replaces it with a standard status bar and you can edit the time, carrier info, etc...
Means you don't have to use Photoshop or anything.
Will be back with a link...
LINK
https://itunes.apple.com/uk/app/status-magic/id547920381?mt=12
EDIT Just found out that the app is still in review fro the Mac App Store. Should be out soon. It really is perfect for what you are wanting to do though. And really easy to use.
I don't know if that's possible with iOS Simulator (If it's even possible you have to dig deep :) ). The best way is to take the screenshot (Command+S), and change the image in Adobe Photoshop, or some image processing program like that.
I am able to run instrument using command line for a single device / simulator, but I need to run it on two devices. Manually I can achieve this by opening two new window of Instruments and make two copy of the js and import it. But I need to achieve this using Command Line. Can anybody help me in achieving this or does anybody have the guidelines for the same?
I struggled with this as well here is a part of my solution.
What i did is:
Create trace files in instruments with you script .js file pre selected and save it to disk.
Reads the UDID of all connected devices.
Loop trough all connected devices and replace the UDID in your trace file with the currenct UDID.
In the same loop open instruments.
for line in $(system_profiler SPUSBDataType | sed -n -e '/iPad/,/Serial/p' -e '/iPhone/,/Serial/p' | grep "Serial Number:" | awk -F ": " '{print $2}'); do
UDID=${line}
file$x $(replace 345w67ww89ww0w98w762wewq33e2 with ${UDID})
open -a Instruments /PATH/TO/TRACE/file$x
done
This solution will open multiple windows of Instruments.
You can go trough them with appleScript to click the record button.
Another way to achieve it is to open two separate instance of Instrument and execute it