Alexandria:α
Syene
Angle α
Distance d
d / c = α / 360°
c = 360°/α * d
Distance d = 5000 stadia
随机应变 ABCD: Always Be Coding and … : хороший
Alexandria:α
Syene
Angle α
Distance d
d / c = α / 360°
c = 360°/α * d
Distance d = 5000 stadia
Eratostheness
How long the earth’s circumstance?
Geometry sun’s position
Plato “The earth’s circumference is 400,000 stadia.”
≒ 74,000
1 stadium = 185m
True Circumference is 40,000 Km
Plato’s guess was 85% larger than the true circumference.
Archimedes: circumference of Earth is 300,000 stadia
Archimedes: Look at the geometry of a sphere and find a clever way to calculate the circumference
AVAudioRecorder
Record VC
func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool){
if flag {
performSegue(withIdentifier: "stopRecording", sender: audioRecorder.url)
} else {
print("recording was not successful")
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?){
if segue.identifier == "stopRecording"{
let laySoundsVC = segue.destination as! PlaySoundsViewController
let recordedAudioURL = sender as! url
playSoundVC.recordedAudioURL = recordedAudioURL
}
}
Stack Views: Horizontal, Vertical
-alignment, distribution, spacing
AVAudioEngine
var dollars:Int = 10
var cents:Int = 50
var amount = "$\(dollars).\(cents)"
print(amount)
dollars = 19
centsd = 99
amount = "$\(dollars).\(cents)"
print(amout)
func printMoneyString(dollars:Int, cents:Int){
print("$\(dollars).\(cents)")
}
Document Outline in Xcode
Model View Controller
view(UIView, UILabel, UIButton), controller, model
AutoLayout Basics
@IBOutlet weak var recordButton: UIButton!
@IBOutlet weak var recordingLabel: UILabel!
@IBOutlet weak var resumeButton: UIButton!
@IBOutlet weak var resumeLabel: UILabel!
@IBOutlet weak var pauseButton: UIButton!
@IBOutlet weak var pauseLabel: UILabel!
@IBOutlet weak var stopButton: UIButton!
@IBOutlet weak var stopLabel: UILabel!
@IBOutlet func recordButtonPressed(sender: UIButton){
// ...
}
ViewController and Multiple Views
Not Running, Inactive, Active, Background, Suspended
Audio in iOS
Pitch Perfect App, AVFoundation, Core Audio, Audio Hardware
import AVFoundation
class ViewController: UIViewController {
var audioRecorder: AVAudioRecorder!
@IBAction func recordAudio(_ sender: AnyObject){
recordingLabel.text = "Recording in progress"
stopRecordingButton.isEnabled = true
recordButton.isEnabled = false
let dirPath = NSSearchPathForDirectoriesInDomains(.documentDirectory,.userDomainMask, true)[0] as String
let recordingName = "recordedVoice.wav"
let pathArray = [dirPath, recordingName]
let filePath = URL(string: pathArray.joined(separator: "/"))
let session = AVAudioSession.sharedInstance()
try! session.setCategory(AVAudioSessionCategoryPlayAndRecord, with:AVAudioSessionCategoryOptions.defaultToSpeaker)
try! audioRecorder = AVAudioRecorder(url: filePath!, settings: [:])
audioRecorder.isMeteringEnabled = true
audioRecorder.prepareToRecord()
audioRecorder.record()
}
}
import UIKit
var x: Int = 42
var x = 42
let y = 100
var myString = "Hello"
// Control Flow
if x < 50 {
print("X is less than 50")
} else {
print("X is greater than or equal to 50")
}
// Classes
class ViewController: UIViewController {
// Instance Variables go here
// Class functions go here
}
// Functions
func printHello(){
print("Hello")
}
printHello()
func printHelloMessage(helloString: String){
print(helloString)
}
printHelloMessage("Oi!")
<red lines> <!-- Empty view for the list --> <RelativeLayout android:id="@+id/empty_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true"> <ImageView android:id="@+id/empty_shelter_image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:src="@drawable/ic_empty_shelter" /> <TextView android:id="@+id/empty_title_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/empty_shelter_image" android:layout_centerHorizontal="true" android:fontFamily="sans-serif-medium" android:paddingTop="16dp" android:text="@string/empty_view_title_text" android:textAppearance="?android:textAppearanceMedium" /> <TextView android:id="@+id/empty_subtitle_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/empty_title_text" android:layout_centerHorizontal="true" android:fontFamily="sans-serif" android:paddingTop="8dp" android:text="@string/empty_view_subtitle_text" android:textAppearance="?android:textAppearanceSmall" android:textColor="#A2AAB0"> </RelativeLayout>
Using a CursorLoader
Activity -> LoaderCallbacks
ArrayAdapter
Data source: ArrayList of words
Data source: Cursor of pets
public class PetCursorAdapter extends CursorAdapter {
public PetCursorAdapter(Context context, Cursor c){
super(context, c, 0);
}
public view newView(Context context, Cursor c, ViewGroup parent){
// create and return new blank list item
}
public void bindView(View view, Context context, Cursor c){
// Populate list item view with pet data
}
}
public class PetProvider extends ContentProvider {
...
@Override
public int update(Uri uri, ContentValues contentValues, String selection,
String[] selectionArgs){
final int match = sUriMatcher.match(uri);
switch (match){
case PETS:
return updatePet(uri, contentValues, selection, selectionArgs);
case PET_ID:
selection = PetEntry._ID + "=?";
selectionArgs = new String[] { String.valueOf(ContentUris.parseId(uri))};
return updatePet(uri, contentValues, selection, selectionArgs);
default:
throw new IllegalArgumentException("Update is not supported for " + uri);
}
}
}
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder){
SQLiteDatabase database = mDbHelper.getReadableDatabase();
Cursor cursor;
int match = sUriMatcher.match(uri);
switch(match){
case PETS:
//
break;
case PET_ID:
selection = PetEntry._ID + "=?";
selectionArgs = new String[] { String.valueOf(ContentUris.parseId(uri))};
cursor = database.query(PetEntry.TABLE_NAME, projection, selection, selectionArgs,
null, null, sortOrder);
break;
default:
throw new IllegalArgumentException("Cannot query unknown URI " + uri);
}
return cursor;
}
public class PetProvider extends ContentProvider {
@Override
public Uri insert(Uri uri, ContentValues contentValues){
final int match = sUriMatcher.match(uri);
switch (match){
case PETS:
return insertPet(uri, contentValues);
default:
throw new IllegalArgumentException("Insertion is not supported for " + uri);
}
}
private Uri insertPet(Uri uri, ContentValues values){
return ContentUris.withAppendedId(uri, id):
}
}
private Uri insertPet(Uri uri, ContentValues values){
String name = values.getAsString(PetEntry.COLUMN_PET_NAME);
if (name == null){
throw new IllegalArgumentException("Pet requires a name");
}
SQLiteDatabase database = mDbHelper.getWritableDatabse();
long id = database.insert(PetEntry.TABLE_NAME, null, values);
if (id == -1){
Log.e(LOG_TAG, "Failed to insert row for " + uri);
return null;
}
return ContentUris.withAppendedId(uri, id);
}
UI Code is directory interacting with database
CatalogActivity ->
EditorActivity -> Content Provider -> PetDbHelper (Pet with ID 1 has weight 7)
Manage access to a structured set of data
-good abstraction layer between data source & UI code (can add data validation, can modify how data is stored UI code is unaffeted)
-work well with other Android framework classes
UI code
Catalog Activity, Content Resolver, Pet Provider, PetDbHelper SQLiteDatabase
Contacts provider
content://com.android.contacts/contacts
Calendar provider
content://com.android.calendar/events
User Dictionary provider
content://user_dictionary/words
Scheme, Content Authority, Type of data
content authority
<provider android:name=".data.PetProvider" android:authorities="com.example.android.pets" android:exported="false" />
int match = sUriMatcher.match(uri);
if (match == CONTACTS){
// Act on the contacts table
} else if (match == CONTACTS_ID){
// Act on a single contact in contacts table
}
public class PetProvider extends ContentProvider {
private static final int PETS = 100;
private static final int PET_ID = 101;
private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
sUriMatcher.addURI(PetContract.CONTENT_AUTHORITY, PetContract.PATH_PETS,PETS);
sUriMatcher.addURI(PetContract.CONTENT_AUTHORITY,PetContract.PATH_PETS + ""/, PETS_ID);
}
...
}