Language Cross Reference

Style
naming
UpperCamelCase: Types and Extensions
lowerCamelCase: identifiers and constants
lowecase_underscore: libraries, packages, directories
_leadingUnderscore: private variable or method
filenames
lowercase_with_underscores.dart
indentation
indent 2 spaces
prefer spaces to tabs
use dartfmt to correctly format
naming
lowercase_underscore: functions, variables, modules
CamelCase: classes
UPPER_CASE: constants
lowercase: packages (no underscores)
filenames
lowercase_underscored.py
indentation
use 4 consecutive spaces
prefer spaces over tabs
note: python is whitespace sensitive
naming
UpperCamelCase: Types and Protocols
lowerCamelCase: everything else
filenames
MyType.swift
MyType+MyProtocol.swift
indentation
prefer spaces to tabs
use xcode ctrl-I to automatically indent
Basics: Variables, Types, and Operators
types
int, double, bool, String, dynamic, Object
List, Set, Map

if (emp is Person) { ... }
// following could throw
(myShape as Circle).radius = 5
variables
var myAge = 35;
final myBirthYear = 1985;
cont pi = 3.14;
int myAge = 35;

// strongly typed with type inferrence
// automatic type converstion
operators
assignment: a = b
arithmetic: +, -, *, /, %
compound assignment: +=, -=, *=, /=
comparison: ==, !=, >, <, >=, <=
logical: !, &&, ||
increment/decrement
print(++a) // increment, then print
print(a++) // print, then increment
comments
// single line commeng
/* multiline
   comment */
/// doc comment
ranges
n/a
tuples
n/a
more info
types
int, float, bool, str, byte
list, set, dict, tuple

type(my_int)  # <class 'int'>
isinstance(my_int, int)
variables
myAge = 35
CONSTANT_BIRTH_YEAR = 1985

# dynamically typed
# no automatic type conversion
operators
assignment: a = b
arithmetic: +, -, *, /, %
compound assignment: +=, -=, *=, /=
comparison: ==, !=, >, <, >=, <=
logical: not, and, or
increment/decrement
n/a
comments
# inline comments
""" docstring """
ranges
range(6)         # 0 to 5
range(1, 11, 2)   # 1, 3, 5, 7, 9

array[:4]  # indexes 0 to 3
array[4:]  # indexes 4 to end
tuples
httpError = (404, "Not Found")
(code, errMsg) = httpError
code = httpError[0]

myTuple[2:5]       # access via range of indexes
for x in myTuple
if "exists" in myTuple
len(myTuple)

# tuples are immutable
types
Int, Double, Bool, String, Data, Any, AnyObject
Array, Set, Dictionary, Tuples

if item is Int { ... }
if let mySquare = rectangle as? Square { ... }
variables
var mutableAge = 35
let constantBirthYear = 1985
var myAge: Int = 35

// strongly typed, and inferred
// no automatic type converstion
operators
assignment: a = b
arithmetic: +, -, *, /, %
compound assignment: +=, -=, *=, /=
comparison: ==, !=, >, <, >=, <=
logical: !, &&, ||
increment/decrement
n/a
comments
// single line commeng
/* multiline
   comment */
/// doc comment
ranges
i in 1...5   // includes 1 and 5
i in 1..<5   // includes 1, not 5

array[..<4]  // indexes 0 to 3
array[4...]  // indexes 4 to end
tuples
let httpError = (404, "Not found")
let (code, errMsg) = httpError
let code = httpError.0
let (_, errMsg) = httpError
Nullability
value
define
// all objects can be null
String name;
safe access
let x = User?.name;
var msg = err ?? "No Errors";
var msg ??= err
forced access
n/a
value
None
define
x = None
safe access
if x is None:
# do not use == or !=
forced access
n/a
value
nil
define
// must be explicitly declared
"var optString: String?"
safe access
if let x = optString?.count { ... }
let x = optString?.count ?? 0
let x = optString?.count // x is optional
let x = optionalVar ?? otherVar
forced access
let x = optString!.count

let optString: String! = "Implicitly Unwrapped"
let x = optString   // no need for ? or !
Strings
instantiation
final aString = 'A string constant';
var mutableString = 'Change';
concatination
mutableString += ' me';
mutableString = 'Change' ' me';
interpolation
print('The value of myInt is $myInt');
multiline
var multiLineString = """
Multiline strings can "quote" 
parts of the content.
""";
raw
var raw = r'use $myVar to print objects';
grapheme clusters
import 'package:characters/characters.dart';

var laugh = 'laughing emoji: 😆';
var lastCharacter = $laugh.characters.last;
instantiation
A_STRING = "A string constant"
mutableString = "Change"
concatination
mutableString += " me"
interpolation
print("The value of my_int is {0}".format(my_int))
multiline
multilineString = '''
Multiline strings can "quote"
parts of the content.
'''
# can also use double quotes
raw
rawString = r'use /n to print a newline'
grapheme clusters
# strings are arrays, no character object
laugh = "laughing emoji: 😆"
lastCharacter = laugh[-1]
instantiation
let aString = "A string constant"
var mutableString = "Change"
concatination
mutableString += " me"
interpolation
print("The value of myInt is \(myInt)")
multiline
let multiLineString = """
Multiline strings can "quote" 
parts of the content.
"""
raw
let raw = #"use \(myVar) to print objects"#
let rawInterpolation = #"myVar: \#(myVar)"#
grapheme clusters
var laugh = "laughing emoji: 😆"
if let lastCharacter = laugh.last { ... }"
Control Flow
conditionals
if x == 5 {
  // x is 5
} else if x < 5 {
  // x less than 5
} else {
  // x greater than 5
}
ternary operator
x > 5 ? print("True") : print("False");
var xLessThanFive = x > 5 ? true : false;
loops
for (item in myArray) { ... }
myArray.forEach((item) => print(item));

for (var i = 1; i <= 10; i++) {
  continue;  // move to next iteration of loop
  break;     // end loop
}

while i < 10 { ... }

do { ... } while i < 10;
switch
var age = 35;
switch (age) {
case 40:
  print("you are over the hill");
  break;
case 18:
case 21:
  print("you can now vote or drink");
  break;
case 1...17:
case 2:
...
case 17:
  print("you are a minor");
  break;
case 0:
  // case must have at least one statement
  break;
default:
  print("you are an adult");
}
conditionals
if x == 5:
  # x is 5
elif x < 5:
  # x less than 5
else:
  # x > than 5
ternary operator
print("True") if x > 5 else print("False")
loops
for item in myList:

for i in range(1, 10):
  continue   # move to next interation of loop
  break      # end loops
  pass       # do nothing, but fills need for statement

while i < 10:
  i += 1
else:
  # do this once at end; optional
switch
n/a
conditionals
if x == 5 {
  // x is 5
} else if x < 5 {
  // x less than 5
} else {
  // x greater than 5
}
ternary operator
x > 5 ? print("True") : print("False")
let xLessThanFive = x > 5 ? true : false
loops
for item in myArray { ... }
myArray.forEach { print($0) }

for i in 1...10 {
  continue  // move to next iteration of loop
  break     // end loop
}

while i < 10 { ... }

do { ... } while i < 10
switch
var age = 35
switch age {
case 40:
  print("you are over the hill")
case 18, 21:
  print("you can now vote or drink")
case 1...17:
  print("you are a minor")
case 0:
  // case must have at least one statement
  break
default:
  print("you are an adult")
}

// Note:  switch statements end once a 
//        matching case is found
//        use keyword 'fallthrough' for 
//        C-like behavior"
Collections
array create
var mutableList = ["One", "Two"];
var emptyList = List<int>();
array access
var index = mutableList.indexOf("Two");
if (index != -1) {
  final a = mutableList[index];
}
array modify
mutableList.add("Three");
mutableList.insert(1, "Three");
mutableList += ["Three"]

mutableList[1] = "Three";

mutableList.removeAt(1);
final poppedItem = mutableArray.removeLast()
set create
var mutableSet = {1, 2, 3, 2};  / {1, 2, 3}
var emptySet = <int>{};
set modify
mutableSet.add(4);

bool wasFound = mutableSet.remove(3);

mutableSet.removeAll();
set utility
setA.union(setB);
setA.intersection(setB);
setA.difference(setB);
key-value create
var personMap = {"first": "Joe", "last": "Smith"};
var emptyMap = Map<String, String>();
key-value access
var name = personMap["first"];
key-value modify
personMap["middleInitial"] = "C";

personMap.remove("first");
key-value utility
bool wasFound = personMap.containsKey("last");
bool wasFound = personMap.containsValue("Smith");
all: properties
var numberOfElements = mutableList.length;
bool empty = myMap.isEmpty;
all: iteration
myList.forEach((item) { ... });
myMap.forEach((key, value) { ... });

var nums = [1, 2, 3];
var numStrings = nums.map((n) => n.toString());
numStrings.forEach(print);
more info
all: utility
var isTrue = myArray.contains("Cats");

var isTrue = myDict.isEmpty;
var isTrue = mySet.isNotEmpty;

// map
// numberStrings below is lazily evaluated on access
// to force full integration use map().toList()
var numbers = [1, 2, 3];
var numberStrings = numbers.map((num) => number.toString());

var cars = ['bmw', 'ford', 'tesla'];
bool isElectric(String car) => car == 'tesla';

// get all items that satisfy
var electricCars = cars.where(isElectric);
cars.any(isElectric);    // check if any items satisfy
cars.every(isElectric);  // check if all items satisfy
array create
mutable_list = ["One","Two"]
empty_list = []

new_list = mutable_list.copy()
new_list = list(mutable_list)
array access
if 1 < len(mutable_list):
  a = mutable_list[1]
array modify
mutable_list.append("Three")
mutable_list.insert(1, "Three")
mutable_list += ["Three"]

mutable_list[1] = "Three"

mutable_list.remove("Two")
mutable_list.pop(1)
del mutable_list[1]
set create
mutable_set = {1, 2, 3, 2}
empty_set = set()
set modify
mutable_set.add(4)

mutable_set.remove(5)  # will raise error if not in set
mutable_set.discard(5)  # will NOT raise error if not in set

mutable_set.clear()
set utility
set_a.union(set_b)
set_a.intersection(set_b)
set_a.difference(set_b)

set_a.issubset(set_b)
set_a.issuperset(set_b)
set_a.isdisjoint(set_b)
key-value create
person_dict = {"first": "Joe", "last": "Smith"}
empty_dict = {}

new_dict = person_dict.copy()
new_dict = dict(person_dict)
key-value access
name = person_dict["first"]

if "middle_initial" in person_dict:
key-value modify
person_dict["middle_initial"] = "C"

person_dict.pop("middle_initial")
person_dict.clear()
key-value utility
# gets value, or sets with provided value
x = person_dict.setDefault["last", "Jones"]
all: properties
count = len(my_collection)
all: iteration
for item in my_list:   # all collections

# List specific
for index, item in enumerate(person_dict):

# Dictionary specific
for key, value in person_dict:
all: utility
if "Cat" in my_pets
array create
var mutableArray = ["One", "Two"]
var emptyArray = [Int]()   // empty array
var arrayOfPi = Array(repeating: 3.14, count 10)

var newArray = mutableArray   // copy-on-write
array access
if let index = mutableArray.firstIndex(of: "Two") {
  let a = mutableArray[index]
}
array modify
mutableArray.append("Three")
mutableArray.insert("Three", at: 1)
mutableArray += ["Three"]

mutableArray[1] = "Three"

mutableArray.remove(at: 1)
let poppedItem = mutableArray.removeLast()
set create
let immutableSet: Set = [1, 2, 3, 2]  // [1, 2, 3]
var mutableSet: Set = ["One", "Two", "Three"]
var emptySet = Set<String>()
set modify
mutableSet.insert(4)

// returns item or nil
let optionalItem = mutableSet.remove(3)

mutableSet.removeAll()
set utility
setA.union(setB)
setA.intersection(setB)
setA.subtracting(setB)
setA.symmetricDifference(setB)

setA.isSubSet(of: setB)
setA.isSuperset(of: setB)
setA.isDisjoint(with: setB)
key-value create
var personDict = ["first": "Joe", "last": "Smith"]
var emptyDict = [String: String]()
key-value access
let name = personDict["first"]
key-value modify
personDict["middleInitial"] = "C"
let oldValue = personDict.updateValue("Blow", forKey: "last")

personDict["middleInitial"] = nil
let removedValue = personDict.removeValue(forKey: "first")
key-value utility
all: properties
let numberOfElements = mutableArray.count
if myDictionary.isEmpty { ... } // faster check than .count
all: iteration
for item in myArray { ... }  // all collections
mySet.forEach { print($0) }  // all collections

// Array specific
for (index, item) in myArray.enumerated() { ... }

// Dictionary specific
for (key, value) in myDictionary { ... }
for key in myDictionary.keys { ... }
for value in myDictionary.values { ... }
all: utility
let isTrue = myArray.contains("Cats")

let sortedSet = mySet.sorted() // Sets & Dicts have no order

// map, compactMap, flatMap
let numbers = [1, 2, 3]
let numberStrings = numbers.map {String($0)} // ["1", "2", "3"]

strings[1] = "Cars"
let optionalNumbers = strings.map { Int($0) }  // [1, nil, 3]
let onlyNumbers = strings.compactMap { Int($0) }  // [1, 3]

let optionalStrings: String? = ["1", nil, "3"]
let result = optionalStrings.map { Int($0) } 
// result is type [Int??]
let result = optionalString.flatMap { Int($0) } // [Int?]
Functions
overview
// positional parameter
String sayHello(String name) { ... }
// optional positional parameters
String sayHello(String name, [String greeting]) { ... }sayHello('Jane', 'Howdy');

// named parameters with default value
// Note - named params are always optional
String sayHello({bool exclaim, String name = 'World'}) { ... }
sayHello(exclaim: false);

// function as parameter
String printMath(int Function(int, int) math, int a, int b) {
  return math(a, b);
}

// primitives (int, bool, double, etc) passed by value
// objects passed by reference
closures/lambdas
var add = (int a, int b) { return a + b; }
var add = (int a, int b) => a + b;
overview
# single parameter with default
def say_hello(name = "Joe"):
say_hello("Jane")

# call with named arguments
def say_hello(name, use_exclaim)
say_hello(use_exclaim = True, name = "Jane")

# return values
def say_hello(name):
  return "Hello, " + name
greeting = say_hello("John")
closures/lambdas
add_lambda = lambda a, b : a + b
more info
overview
// single parameter with default and single return value
func sayHello(name: String = "World") -> String { ... }
print(sayHello(name: "Jane"))

// omit argument labels on call
func sayHello(_ name: String) { ... }
sayHello("Jane")

// multiple return values using tuple
func heightAndWeight(name: String) -> (Int, Int) { ... }

// inout (by reference) parameters
func swapInts(a: inout Int, b: inout Int) { ... }
swapInts(a: &intOne, b: &intTwo)

// zero or more parameters (omitting label)
for calculateSum(_ numbers: Int...) -> Int { ... }
calculateSum(1, 2, 3, 4, 5)  // 15

// single statement functions can skip return keyword
func addTwoInts(_ a: Int, _ b: Int) -> Int { a + b }
// function as parameter
func printMath(math: (Int, Int) -> Int, a: Int, b: Int) {
  print(math(a, b))
}
doMath(math: addTwoInts, a: 2, b: 3) // prints 5
closures/lambdas
let addClosure: (Int, Int) -> Int = { (a, b) in a + b }
let subtractClosure: (Int, Int) -> Int = { $0 - $1 }
more info
Enumerations
create
enum Color {
  red, green, blue
}
var myColor = Color.green;
closures/lambdas
enum Dessert {
  brownie, cookie, cake, port
}
var countOfDessertTypes = Dessert.values.length;
Dessert.values.forEach((type) { ... });
raw values
n/a
more info
associated values
n/a
create
from enum import Enum   # new in python 3.4

Art = Enum('Art', 'painting poster sculpture ascii')
new_purchase = Art.ascii
access
Art.poster         # Art.poster
Art['painting']    # Art.painting
Art.poster.name    # poster
Art.poster.value   # 2   
raw values
class State(Enum):
  utah = "UT"
  florida = "FL"
  minnisota = "MN"
  
State.utah.value   # UT
associated values
n/a
create
enum VisualArt {
  case painting, poster, sculpture, ascii
}
let newPurchase = VisualArt.poster
access
enum Dessert: CaseIterable {
  case brownie, cookie, cake, port
}
let countOfDessertTypes = Dessert.allCases.count
for type in Dessert.allCases { ... }
raw values
enum State: String {
  case utah = "UT"
  case florida = "FL"
  case minnisota = "MN"
}
print("Abbreviation for Utah is \(State.utah.rawValue)")
associated values
enum Favorite {
  case color(String)
  case number(Int)
  case none
}
let lucky = Favorite.number(7)
switch lucky {
  case .none:
    print("No favorites")
  case .number(let value):
    print("Lucky Number \(value)!")
  case .color:
    print("So pretty")
}
Structs
create
n/a
instantiate
n/a
create
# use named tuples; immutable
# updated in 3.6
from typing import NamedTuple

class StudentNT(NamedTuple):
  name: str
  class: int
  school: str


# use Data Classes; mutable
# new in 3.7
from dataclasses import dataclass

@dataclass
class StudentDC:
  name: str
  class: int
  school: str = "Middletown High School"
instantiate
joe = StudentNT("Joe", 2019, "Middletown High School")

joe = StudentDC("Joe", 2019)
create
struct Student {
  var name: String
  var class: Int
  var school: String = "Middletown High School"
}
instantiate
let joe = Student(name: "Joe", class: 2019)
let graduationYear = joe.class
Classes
define
class Animal {
  String name;
  var sound = "Animal noises";
  num numberOfFleas = 0;  // num covers int and double

  bool get needsBath {    // computed property
    return numberOfFleas > 0;
  }

  // default constructor
  Animal() {
    this.name = "Unknown Animal";
  }

  // named constructor
  Animal.named(String name) {
    this.name = name;
  }
  // Animal(this.name); // syntax sugar for above

  makeSound() {
    print(sound);
  }
}
instantiate
var cat = Animal("Cat");
subclass
class Dog extends Animal {
  bool isMuddy = true;

  Dog([String name = "Dog"]) : super.named(name) {
    this.sound = "Bark";
  }

  @override
  bool get needsBath {
    return numberOfFleas > 10 && isMuddy;
  }
}
var dog = Dog();
define
class Animal:
  def __init__(self, name, sound = "Animal noises", 
               number_of_fleas = 0):
    self.name = name
    self.sound = sound
    self.number_of_fleas = number_of_fleas          
  
  # calculated property
  @property
  def needs_bath(self):
    return self.number_of_fleas > 0
  
  def make_sound(self):
    print(self.sound)
instantiate
cat = Animal("Cat")
subclass
class Dog(Animal):
  def __init__(self, name = "Dog"):
    super().__init__(name, "Bark")
    self.isMuddy = False
  
  @property
  def needs_bath(self):
    return self.number_of_fleas > 10

dog = Dog()
dog.make_soound()   # Bark
define
class Animal {
  let name: String
  var sound = "Animal noises"
  var numberOfFleas = 0
  var needsBath: Bool {     // computed property
    numberOfFleas > 0
  }

  init(name: String) {
    self.name = name
  }

  convenience init() {
    self.name = "Unknown animal"
  }

  func makeSound() {
    print(sound)
  }
}
instantiate
let cat = Animal(name: "Cat")
subclass
class Dog: Animal {
  var isMuddy = false
  
  override init(name: String = "Dog") {
    super.init(name: name)
    self.sound = "Bark"
  }

  override var needsBath: Bool {
    numberOfFleas > 10 && isMuddy
  }
}
let dog = Dog()

final class Flea: Animal { ... }  // can not subclass
Protocols & Extensions
protocols
extensions
extension NumberParsing on String {
  int parseInt() {
    return int.parse(this);
  }
}
int a = "7".parseInt()
protocols
from abc import ABC

class HealthCheckable(ABC):
  def __init__(self, height, weight):
    self.height = height
    self.weight = weight
    super().__init__()
    
  @abstractmethod
  def calculate_bmi(self):
    pass
    
class Person(HealthCheckable):
  # must implement calculate_bmi or can't be instantiated
  def calculate_bmi:
    return self.weight / self.height
extensions
n/a
protocols
protocol HealthCheckable {
  var height: Int
  var weight: Int
  func calculateBMI() -> Double
}
struct Person: HealthCheckable { ... }
extensions
// can be used with class, structures, enums, or protocols
extension Int {
  func squared() -> Int {
    return self * self
  }
}
let twoSquared = 2.squared()
Error Handling
define
class OutOfLlamasException implements Exception {
  final String msg;

  const OutOfLlamasException([this.msg]);

  @override
  String toString() => msg ?? 'Out of Llamas';
}
handle
try {
  breedMoreLlamas();
} on OutOfLlamasException {
  // A specific exception
  buyMoreLlamas();
} on Exception catch (e) {
  // Anything else that is an exception
  print('Unknown exception: $e; rethrowing');
  rethrow;   // pass on 
} finally {
  // always do this cleanup code
  cleanLlamaStalls();
}
define
class ProgrammerError(Exception):
  def __init__(self, msg = None):
    if msg is None:
      msg = "Programmer made an error"
    super(ProgrammerError, self).__init__(msg)

class NeedsCaffineError(ProgrammerError):
  def __init__(self):
    super(NeedsCaffineError, 
          self).__init__(msg="Caffine needed")
handle
try:
  new_code = write_code()
except NeedsCaffineError as e:
  get_coffee()
  
define
enum ProgrammerError: Error {
  case needsCaffine
  case notEnoughSleep
  case canNotReproduce
}
func writeCode() throws -> String { ... }
handle
let newFunction = try? writeCode()

let newCode: String?
do {
  newCode = try writeCode()
  // success
} catch ProgrammerError.needsCaffine {
  // get coffee
} catch {
  newCode = nil
}
Miscellaneous
access scope
var _private = 5;  // private to library

class Animal {
  ...
  _privateAnimalMethod() { ... }
}
more info
access scope
# convetion only, python has no access limitations
# name mangling is meant for namespaces
class WideOpen:
  def __init__(self):
    _private_variable = 5
    __mangled_name = "harder to access"
access scope
public
internal     // default, limited to defining module
fileprivate  // limited to source file
private      // limited to enclosing declaration
underscore
// used to ignore an unneeded value. ex:
let (_, errMsg) = httpError
Core Libraries (beyond the language)
filesystem
more info
network
more info
date
var now = DateTime.now();
var nowString = now.toString();
var nowISO8610 = now.toIso8601String();
more info
json
import 'dart:convert';

var jsonString = '''
{ "username": "Joe", "id": 5, "lastLoginDate": "2019-04-23" }
''';

// decode into Dart object
var user = jsonDecode(jsonString);
assert(user is Map);
print(user['id']);   // 5

// encode into JSON
var encodedJsonString = jsonEncode(user);
print(encodedJsonString);
more info
async/threading
// using async/await
Future checkVersion() async {
  var version = await lookUpVersion();
  // do something 
}

// using Futures
HttpRequest.getString(url).then((String result) {
  print(result);
}).catchError((e) {
  // Handle or ignore the error.
});
more info
filesystem
data_file = open("data.cvs")
for line in data_line:
  # process line

output_file = open("error.log", "w")
output_file.write("Programmer error again")
output_file.close()
network
import urllib.request

result = urllib.request.urlopen("").read()

# also see aiohttp library build on top of asyncio
more info
date
import datetime
now = datetime.datetime.now()
now.strftime(%x)    # MM/DD/YY
more info
json
import json

json_str = '''
{ "username": "Joe", "id": 5, "lastLoginDate": "2019-04-23" }
'''
dict_from_json = json.loads(json_str)

encoded_json = json.dumps(dict_from_json)
more info
async/threading
import asyncio

async def main():
  print('Hello ...')
  await asyncio.sleep(1)
  print('... World!')

# Python 3.7+
asyncio.run(main())
more info
filesystem
more info
network
more info
date
let now = Date()
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .none
let nowString = formatter.string(from: now)
more info
json
struct AccountInfo: Codable {
  let username: String
  let id: Int
  let lastLoginDate: String   // ISO 8601 string
}

// decode from json into swift objects
let jsonString = """
{ "username": "Joe", "id": 5, "lastLoginDate": "2019-04-23" }
"""
let jsonData = Data(jsonString.utf8)

let decoder = JSONDecoder()
let accountInfo = try? decoder.decode(AccountInfo.self, from:jsonData)

// encode from swift objects to json
let encoder = JSONEncoder()
if let accountInfoData = try? encoder.encode(accountInfo) {
  if let encodedJsonString = String(data: accountInfoData, encoding: .utf8) {
    print(encodedJsonString)
  }
}
more info
async/threading
DispatchQueue.global(qos: .userInitiated).async {
  if let url = URL(string: urlString) {
    if let data = try? Data(contentsOf: url) {
      self.parse(json: data)
      return
    }
  }
}
more info