Skip to content

Instantly share code, notes, and snippets.

@nolanw
Created October 30, 2016 19:21
Show Gist options
  • Save nolanw/780fe441fda242e44aa973d6a4d006bb to your computer and use it in GitHub Desktop.
Save nolanw/780fe441fda242e44aa973d6a4d006bb to your computer and use it in GitHub Desktop.
Script to download/update Crashlytics.framework and Fabric.framework without having to install Fabric.app or use CocoaPods
#!/usr/bin/env python
from __future__ import print_function
import json
from io import BytesIO
import logging
import os
import sys
try:
from urllib.request import Request, urlopen # py3
from urllib.parse import quote
except ImportError:
from urllib2 import quote, Request, urlopen # py2
from zipfile import ZipFile
log = logging.getLogger(__name__)
log.addHandler(logging.StreamHandler())
log.setLevel(logging.INFO)
def print_e(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
DEFAULT_HEADERS = {
u"User-Agent": u"Crashlytics.framework download tool", # CocoaPods search blocks urllib
}
def create_request(url):
return Request(url, headers=DEFAULT_HEADERS)
SEARCH_URL_FORMAT = u"http://search.cocoapods.org/api/v1/pods.flat.hash.json?query={}"
def pod_get_download_url(pod_name, query_extra=None):
query = u"name:{}".format(pod_name)
if query_extra is not None:
query += u" {}".format(query_extra)
url = SEARCH_URL_FORMAT.format(quote(query, safe=''))
log.debug(u"Search URL is {}".format(url))
request = create_request(url)
response = urlopen(request)
data = json.load(response)
try:
match = next(r for r in data if r[u"id"] == pod_name)
except StopIteration:
log.critical(u"Couldn't find search result for pod {}.".format(pod_name))
log.debug(u"Data was {}".format(data))
sys.exit(1)
return match[u"source"][u"http"]
def download_extract_zip_file(url, destination):
log.debug(u"Downloading {}".format(url))
request = create_request(url)
response = urlopen(url)
with ZipFile(BytesIO(response.read())) as z:
log.debug(u"Extracting to {}".format(destination))
z.extractall(destination)
PODS = [
u"Crashlytics",
u"Fabric",
]
USAGE = u"""Usage: {} destination-dir
Downloads Crashlytics and Fabric libraries to subdirectories in destination-dir.
""".format(sys.argv[0])
def main():
try:
destination_dir = sys.argv[1]
except IndexError:
print_e(USAGE)
sys.exit(1)
log.debug(u"Making destination directory if needed")
try:
os.makedirs(destination_dir)
except OSError:
pass # Lazy mkdir -p
for pod in PODS:
log.info(u"Searching CocoaPods for {}".format(pod))
query = u"name:{} twitter".format(pod)
url = pod_get_download_url(pod, "Twitter")
subdir = os.path.join(destination_dir, pod)
log.info(u"Downloading {} to {}".format(pod, subdir))
download_extract_zip_file(url, subdir)
if __name__ == "__main__":
main()
@nolanw
Copy link
Author

nolanw commented Nov 1, 2016

None of these things are particularly appealing to me:

  • CocoaPods is very invasive to an app and doesn't always compensate by offering enough value.
  • Speaking of heavyweight, Fabric.app is convenient but kinda ridiculous when you've used it before and just want to add the faux-framework for improved crash reporting.

And these don't work:

  • Carthage can't install Crashlytics.
  • Swift Package Manager if I had to bet where Crashlytics.framework becomes available it's SPM, but for now, lol.

So what's one to do if they want Crashlytics and don't want CocoaPods?

Why, look up the pod and download the .frameworks yourself of course. Hence this script.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment