100 Days of Swift & Hacking with iOS UIKit 版關鍵字重點整理
--
Paul Hudson 大大在網路上撰寫許多適合初學者學習的 iOS App 開發教材,彼得潘平時也常跟 Paul 學習。
想學習 iOS UIKit App 開發,Paul 的 100 Days of Swift & Hacking with iOS UIKit 版十分值得一讀。100 Days of Swift 包含了 30 個不同主題的 project。
Hacking with iOS 則包含 39 個 project,前 30 個是 100 Days of Swift 的 project,然後再加碼 9 個額外的 project。
有興趣的朋友可參考以上連結仔細研讀 Paul 的文章和影片,如果已有一定基礎,也可從 GitHub 下載專案的程式快速研究。
- Paul 大大官方版的範例程式
HackingWithSwift 下分成 UIKit & SwiftUI 兩個版本,UIKit 版在資料夾 Classic 下。
- Khumar 的範例程式
Pual 網頁上的教學有更新,不過官方 GitHub 的程式有些仍是舊的版本,新版可參考 Khumar 的連結。
最近彼得潘也花了點時間研究這 39 個專案,以下一一列出它們的關鍵字重點整理 & App 畫面,歡迎有興趣的朋友參考。
ps:
- 彼得潘在整理關鍵字時,主要將它列在第一次出現的 project。比方 IBOutlet 初次出現在 project 1,因此將它列在 project 1,之後的 project 即使有用到 IBOutlet 也不會列出。
- 39 個專案裡有 10 個跟遊戲相關的主題,跟 SpriteKit 技術有關。以下特別將這 10 個 project 的名稱加上(Game),對遊戲開發沒興趣的朋友可先跳過。
- 39 個專案裡有許多技術是工作一兩年的 iOS 工程師也不一定會接觸的,想轉職新手 iOS App 工程師的朋友可先目標研究以下專案:
1~10,12~13,15~16,18~19,21,24,27~28,31~32,38。
Project 1: Storm Viewer
關鍵技術:
Xcode,project,UIKit,Interface Builder,storyboard,swift,UIViewController,title,viewDidLoad,viewWillAppear,viewWillDisappear,FileManager,Bundle.main,resourcePath,contentsOfDirectory,UITableViewController,data source,UITableView,UITableViewCell,delegate,UITableViewDataSource,UITableViewDelegate,tableView(_:numberOfRowsInSection:),tableView(_:cellForRowAt:),cell reuse id,dequeueReusableCell(withIdentifier:for:),IndexPath,row,textLabel,tableView(_:didSelectRowAt:),IBOutlet,UIImageView,aspect fit,UIImage,UINavigationController,navigationController,navigationBar,hidesBarsOnTap,pushViewController,storyboard id,instantiateViewController(withIdentifier:),prefersLargeTitles,navigationItem,largeTitleDisplayMode,Auto Layout,constraint
Project 2: Guess the Flag
關鍵技術:
asset catalogs,UIButton,append,setImage(_:for:),UIControlState,normal,UIView,CALayer,layer,borderWidth,borderColor,UIColor,CGColor,IBAction,tag,shuffle,random,UIAlertController,alert,UIAlertAction,addAction,present(_:animated:completion:),uppercased,2x,3x
Project 3: Social Media
關鍵技術:
UIBarButtonItem,rightBarButtonItem,#selector,@objc,UIActivityViewController,share,jpegData(compressionQuality:),popoverPresentationController?.barButtonItem,Info,Privacy — Photo Library Additions Usage Description
ps: 網頁的教學有更新,官方範例裡的 shareTapped 請更新成以下版本,並在 App 的 Info 頁面加入 Privacy — Photo Library Additions Usage Description。
@objc func shareTapped() {
guard let image = imageView.image?.jpegData(compressionQuality: 0.8) else {
print("No image found")
return
}let vc = UIActivityViewController(activityItems: [image], applicationActivities: [])
vc.popoverPresentationController?.barButtonItem = navigationItem.rightBarButtonItem
present(vc, animated: true)
}
Project 4: Easy Browser
關鍵技術:
WebKit,WKWebView,WKNavigationDelegate,loadView,URL,URLRequest,load,allowsBackForwardNavigationGestures,actionSheet,UIProgressView,sizeToFit,flexibleSpace,UIToolbar,toolbarItems,isToolbarHidden,KVO,key value observing,addObserver(_:forKeyPath:options:context:),#keyPath(WKWebView.estimatedProgress),webView(_:didFinish:),webView(_:decidePolicyFor:decisionHandler:),observeValue(forKeyPath:of:change:context:),contains
Project 5: Word Scramble
關鍵技術:
capture list,strong,weak,unowned,strong reference cycle,retain cycle,path(forResource:ofType:),String(contentsOfFile:),components(separatedBy:),randomElement,reloadData,addTextField,textFields,range(of:),firstIndex(of:),UITextChecker,rangeOfMisspelledWord,insertRows,lowercased,NSRange,NSNotFound,utf16
ps: 網頁的教學有更新,官方範例裡的 isPossible & isReal 請更新成以下版本。
func isPossible(word: String) -> Bool {
guard var tempWord = title?.lowercased() else { return false } for letter in word {
if let position = tempWord.firstIndex(of: letter) {
tempWord.remove(at: position)
} else {
return false
}
} return true
}func isReal(word: String) -> Bool {
let checker = UITextChecker()
let range = NSRange(location: 0, length: word.utf16.count)
let misspelledRange = checker.rangeOfMisspelledWord(in: word, range: range, startingAt: 0, wrap: false, language: "en") return misspelledRange.location == NSNotFound
}
Project 6: Auto Layout
關鍵技術:
addSubview,aspect ratio,NSLayoutConstraint,translatesAutoresizingMaskIntoConstraints,visual format language,constraints(withVisualFormat:options:metrics:views:),addConstraints,NSLayoutAnchor,constraint(equalTo:constant:),isActive,prefersStatusBarHidden
Project 7: Whitehouse Petitions
關鍵技術:
UITabBarController,Data,Data(contentsOf:),network,JSON,Codable,JSONDecoder,decode(_:from:),loadHTMLString(_:baseURL:),AppDelegate,application(_:didFinishLaunchingWithOptions:),UIWindow,window,rootViewController,UIStoryboard,UIStoryboard(name:bundle:),UITabBarItem,UITabBarItem(tabBarSystemItem:tag:),SceneDelegate,scene(_:willConnectTo:options:)
ps:
- ViewController 裡記得改成以下網址
if navigationController?.tabBarItem.tag == 0 {
urlString = "https://www.hackingwithswift.com/samples/petitions-1.json"
} else {
urlString = "https://www.hackingwithswift.com/samples/petitions-2.json"
}
- 新版 Xcode 專案多了 SceneDelegate.swift,請在 SceneDelegate 的 scene(_:willConnectTo:options:) 加入以下程式。
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let _ = (scene as? UIWindowScene) else { return }
if let tabBarController = window?.rootViewController as? UITabBarController {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "NavController")
vc.tabBarItem = UITabBarItem(tabBarSystemItem: .topRated, tag: 1)
tabBarController.viewControllers?.append(vc)
}
}
Project 8: 7 Swifty Words
關鍵技術:
iPad,layoutMarginsGuide,activate,addTarget(_:action:for:),touchUpInside,subviews,isHidden,enumerated,tuple,replacingOccurrences(of:with:),trimmingCharacters(in:),whitespacesAndNewlines,setTitle(_:for:),joined,UIFont,isUserInteractionEnabled,placeholder,setContentHuggingPriority(_:for:),UILayoutPriority,vertical,horizontal,CGRect,frame,didSet,property observer,removeAll
ps: 網頁的教學有更新,改成從程式製作畫面,新版的程式可參考 Khumar 的 GitHub。
Project 9: Grand Central Dispatch
關鍵技術:
GCD,grand central dispatch,async,DispatchQueue,main,global,qos,performSelector(inBackground:),performSelector(onMainThread:with:waitUntilDone:)
ps: ViewController 裡記得改成以下網址
if navigationController?.tabBarItem.tag == 0 {
urlString = "https://www.hackingwithswift.com/samples/petitions-1.json"
} else {
urlString = "https://www.hackingwithswift.com/samples/petitions-2.json"
}
Project 10: Names to Faces
關鍵技術:
UICollectionViewController,UICollectionView,UICollectionViewCell,UICollectionViewDataSource,UICollectionViewDelegate,custom cell,cell size,section inset,collectionView(_:didSelectItemAt:),collectionView(_:cellForItemAt:),UIImagePickerControllerDelegate,init,documentDirectory,appendingPathComponent,cornerRadius,UIImagePickerController,allowsEditing,imagePickerController(_:didFinishPickingMediaWithInfo:),originalImage,UUID,write(to:),dismiss,fatalError,NSObject
Project 11: Pachinko(Game)
關鍵技術:
game,SpriteKit,Set,first,SKView,scene,SKScene,anchor point,scaleMode,presentScene,didMove(to:),zPosition,blendMode,replace,SKSpriteNode,rectangleOf,circleOfRadius,edgeLoopFrom,CGPoint,addChild,position,touchesBegan(_:with:),UITouch,location(in:),nodes(at:),CGSize,name,SKAction,rotate,pi,radians,repeatForever,run,isDynamic,SKPhysicsBody,SKPhysicsContactDelegate,physicsWorld,contactDelegate,contactTestBitMask,collisionBitMask,restitution,SKNode,removeFromParent,didBegin(_:),SKPhysicsContact,bodyA,bodyB,node,SKLabelNode,horizontalAlignmentMode,SKEmitterNode,sks,SpriteKit Particle File
Project 12: UserDefaults
關鍵技術:
save,NSKeyedArchiver,archivedData(withRootObject:requiringSecureCoding:),UserDefaults,standard,set(_:forKey:),object(forKey:),data(forKey:),NSKeyedUnarchiver,unarchiveTopLevelObjectWithData,NSCoding,init(coder:),encode(with:),decodeObject(forKey:),encode(_:forKey:),JSONDecoder,JSONEncoder,encode,Codable
Project 13: Instafilter
關鍵技術:
UISlider,editedImage,CoreImage,CIFilter,CIContext,outputImage,UIImageWriteToSavedPhotosAlbum,CIImage,createCGImage(_:from:),CGImage,inputKeys,func image(_ image: UIImage, didFinishSavingWithError error: NSError?, contextInfo: UnsafeRawPointer),localizedDescription
Project 14: Whack-a-Penguin(Game)
關鍵技術:
SKCropNode,maskNode,moveBy(x:y:duration:),SKTexture,asyncAfter(deadline:qos:flags:execute:),now,wait(forDuration:),sequence,run(block:),parent,playSoundFileNamed(_:waitForCompletion:),scale
ps: GameViewController 裡的 scaleMode 請改成 fill。
scene.scaleMode = .fill
Project 15: Animation
關鍵技術:
Core Animation,center,animate(withDuration:animations:completion:),spring animation,animate(withDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:) ,transform,CGAffineTransform,identity,translation,scale,rotationAngle,alpha,clear
Project 16: Capital Cities
關鍵技術:
map,MapKit,MKMapView,CLLocationCoordinate2D,latitude,longitude,annotation,MKAnnotation,addAnnotation,MKMapViewDelegate,mapView(_:viewFor:),MKAnnotationView,dequeueReusableAnnotationView(withIdentifier:),MKMarkerAnnotationView,canShowCallout,rightCalloutAccessoryView,detailDisclosure,mapView(_:annotationView:calloutAccessoryControlTapped:)
ps:
請將程式裡的 MKPinAnnotationView 改成 MKMarkerAnnotationView
Project 17: Space Race(Game)
關鍵技術:
SKEmitterNode,advanceSimulationTime,gravity,CGVector,Timer,scheduledTimer(timeInterval:target:selector:userInfo:repeats:),invalidate,velocity,angularVelocity,linearDamping,angularDamping,update(_:),touchesMoved(_:with:),CADisplayLink
ps: GameViewController 裡的 scaleMode 請改成 fill。
scene.scaleMode = .fill
Project 18: Debugging
關鍵技術:
debug,print,assert,breakpoint,debug view hierarchy
Project 19: JavaScript Injection
關鍵技術:
Application Extension,Safari extension,JavaScript,JavaScript Injection,NSExtensionItem,extensionContext,inputItems,attachments,NSItemProvider,loadItem(forTypeIdentifier:options:completionHandler:),NSDictionary,NSExtension,NSExtensionAttributes,NSExtensionJavaScriptPreprocessingResultsKey,completeRequest(returningItems:),UITextView,NotificationCenter,default,addObserver(_:selector:name:object:),UIResponder,keyboardWillHideNotification,keyboardWillChangeFrameNotification,keyboardFrameEndUserInfoKey,convert(_:from:),cgRectValue,contentInset,UIEdgeInsets,safeAreaInsets,scrollIndicatorInsets,selectedRange,scrollRangeToVisible,NSExtensionJavaScriptFinalizeArgumentKey,completeRequest(returningItems:),Notification.Name,post(name:object:userInfo:)
ps: adjustForKeyboard 裡的 script.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardViewEndFrame.height, right: 0)
請改成以下寫法。
script.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardViewEndFrame.height - view.safeAreaInsets.bottom, right: 0)
App 操作:
打開 Safari App,從選單點選 Extension,輸入 JavaScript 程式 alert(document.title),點選 Done 關閉頁面時會跳出 alert。
Project 20: Fireworks Night(Game)
關鍵技術:
UIBezierPath,move(to:),addLine(to:),follow(_:asOffset:orientToPath:speed:),children,colorBlendFactor,reversed,for case let,motionBegan(_:with:),shake
ps: checkTouches 的寫法有更新,請改成以下寫法。
func checkTouches(_ touches: Set<UITouch>) {
guard let touch = touches.first else { return }
let location = touch.location(in: self)
let nodesAtPoint = nodes(at: location)
for case let node as SKSpriteNode in nodesAtPoint {
guard node.name == "firework" else { return }
for parent in fireworks {
guard let firework = parent.children.first as? SKSpriteNode else {
continue
}
if firework.name == "selected" && firework.color != node.color {
firework.name = "firework"
firework.colorBlendFactor = 1
}
}
node.name = "selected"
node.colorBlendFactor = 0
}
}
Project 21: Local Notifications
關鍵技術:
local notification,UserNotifications,UNUserNotificationCenter,current,requestAuthorization(options:completionHandler:),alert,badge,sound,UNMutableNotificationContent,title,body,userInfo,UNNotificationSound,categoryIdentifier,DateComponents,UNCalendarNotificationTrigger,UNTimeIntervalNotificationTrigger,UNNotificationRequest,removeAllPendingNotificationRequests,UNNotificationAction,UNNotificationAction(identifier:title:options:),UNNotificationCategory,setNotificationCategories,UNUserNotificationCenterDelegate,userNotificationCenter(_:didReceive:withCompletionHandler:),UNNotificationResponse,actionIdentifier
Project 22: Detect-a-Beacon
關鍵技術:
CoreLocation,CLLocationManager,CLLocationManagerDelegate,requestAlwaysAuthorization,requestWhenInUseAuthorization,locationManager(_:didChangeAuthorization:),locationManagerDidChangeAuthorization(_:),CLAuthorizationStatus,authorizedAlways,isMonitoringAvailable(for:),CLBeaconRegion,isRangingAvailable,iBeacon,CLBeaconRegion(uuid:major:minor:identifier:),startMonitoring(for:),startRangingBeacons(in:),CLBeacon,proximity,CLProximity,unknown,far,near,immediate,locationManager(_:didRangeBeacons:in:),requestLocation,locationManager(_:didUpdateLocations:),locationManager(_:didFailWithError:),startMonitoringVisits,locationManager(_:didVisit:)
ps:
locationManager(_:didChangeAuthorization:)
可改成以下新版寫法
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
if manager.authorizationStatus == .authorizedAlways {
if CLLocationManager.isMonitoringAvailable(for: CLBeaconRegion.self) {
if CLLocationManager.isRangingAvailable() {
startScanning()
}
}
}
}
let beaconRegion = CLBeaconRegion(proximityUUID: uuid, major: 123, minor: 456, identifier: "MyBeacon")
可改成以下新版寫法
let beaconRegion = CLBeaconRegion(uuid: uuid, major: 123, minor: 456, identifier: "MyBeacon")
locationManager.startRangingBeacons(in: beaconRegion)
可改成以下新版寫法
locationManager.startRangingBeacons(satisfying: CLBeaconIdentityConstraint(uuid: uuid, major: 123, minor: 456))
Project 23: Swifty Ninja(Game)
關鍵技術:
SKShapeNode,strokeColor,touchesEnded(_:with:),touchesCancelled(_:with:),fadeOut(withDuration:),CGPath,run(_:completion:),AVFoundation,AVAudioPlayer,play,stop,CaseIterable,allCases,scale(to:duration:),group,removeAllActions,index(of:),removeFirst
ps:
- GameViewController 裡的 scaleMode 請改成 fill。
scene.scaleMode = .fill
- redrawActiveSlice 裡的
while activeSlicePoints.count > 12 {
請改成以下程式。
activeSlicePoints.remove(at: 0) }
if activeSlicePoints.count > 12 {
activeSlicePoints.removeFirst(activeSlicePoints.count - 12)
}
Project 24: Swift Strings
關鍵技術:
playground,index(_:offsetBy:),hasPrefix,hasSuffix,dropFirst,dropLast,capitalized,Character,contains(where:),NSAttributedString,NSMutableAttributedString,addAttribute(_:value:range:),underlineStyle,attributedText
Project 25: Selfie Share
關鍵技術:
MultipeerConnectivity,viewWithTag,MCPeerID,UIDevice,MCSession,MCSession(peer:securityIdentity:encryptionPreference:),MCAdvertiserAssistant,MCAdvertiserAssistant(serviceType:discoveryInfo:session:),start,MCBrowserViewController,MCBrowserViewController(serviceType:session:),MCSessionDelegate,MCBrowserViewControllerDelegate,session(_:didReceive:withName:fromPeer:),session(_:didStartReceivingResourceWithName:fromPeer:with:),session(_:didFinishReceivingResourceWithName:fromPeer:at:withError:),session(_:peer:didChange:),MCSessionState,connected,session(_:didReceive:fromPeer:),browserViewControllerDidFinish(_:),browserViewControllerWasCancelled(_:),connectedPeers,pngData,send(_:toPeers:with:),reliable
Project 26: Marble Maze(Game)
關鍵技術:
bitmask,UInt32,categoryBitMask,rawValue,allowsRotation,CoreMotion,CMMotionManager,startAccelerometerUpdates,accelerometerData,acceleration,#if targetEnvironment(simulator),#if swift(>=5.0),compiler directives
ps: GameViewController 裡的 scaleMode 請改成 fill。
scene.scaleMode = .fill
Project 27: Core Graphics
關鍵技術:
Core Graphics,draw 2D,UIGraphicsImageRenderer,image(actions:),UIGraphicsImageRendererContext,CGContext,setFillColor,setStrokeColor,setLineWidth,addRect,drawPath(using:),addEllipse(in:),insetBy(dx:dy:),fill,translateBy,rotate,strokePath,move(to:),addLine(to:),NSMutableParagraphStyle,draw(with:options:attributes:context:),draw(at:)
Project 28: Secret Swift
關鍵技術:
keychain,KeychainWrapper,resignFirstResponder,UIApplication.willResignActiveNotification,Touch ID,Face ID,LocalAuthentication,LAContext,canEvaluatePolicy(_:error:),deviceOwnerAuthenticationWithBiometrics,evaluatePolicy(_:localizedReason:reply:),Privacy — Face ID Usage Description
ps: adjustForKeyboard 裡的 script.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardViewEndFrame.height, right: 0)
請改成以下寫法。
script.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardViewEndFrame.height - view.safeAreaInsets.bottom, right: 0)
Project 29: Exploding Monkeys(Game)
關鍵技術:
SKPhysicsBody(texture:size:),stride(from:to:by:),setFill,texture atlases,usesPreciseCollisionDetection,setTexture,applyImpulse,SKTransition,crossFade(withDuration:),presentScene(_:transition:),doorway(withDuration:),setBlendMode,UIColor(hue:saturation:brightness:alpha:),clear,mix UIKit and SpriteKit
ps: 將 drawBuilding 裡的 ctx.cgContext.setFillColor(color.cgColor)
,ctx.cgContext.setFillColor(lightOnColor.cgColor)
,ctx.cgContext.setFillColor(lightOffColor.cgColor)
改成以下程式
color.setFill()
lightOnColor.setFill()
lightOffColor.setFill()
Project 30: Instruments
關鍵技術:
Instrument,profiling,shadow,image caching,Time Profiler,clip,shadowColor,shadowOpacity,shadowRadius,shadowOffset,setShadow(offset:blur:color:),shadowPath,Allocations,register(_:forCellReuseIdentifier:),UIImage(contentsOfFile:)
Project 31: Multibrowser
關鍵技術:
UIStackView,axis,vertical,horizontal,Distribution: (Fill,Fill Equally,Fill Proportionally,Equal Spacing,Equal Centering),arrangedSubviews,UITextFieldDelegate,UIGestureRecognizer,UITapGestureRecognizer,addGestureRecognizer,UIGestureRecognizerDelegate,gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:),textFieldShouldReturn(_:),iPad multitasking,traitCollectionDidChange(_:),UITraitCollection,horizontalSizeClass,verticalSizeClass,compact,regular,absoluteString
ps: 網頁的教學有更新,請移除 deleteWebView 裡的 stackView.removeArrangedSubview(webView)
Project 32: SwiftSearcher
關鍵技術:
automatic UITableViewCell sizing, Dynamic Type,preferredFont(forTextStyle:),SafariServices,SFSafariViewController,entersReaderIfAvailable,SFSafariViewController.Configuration,allowsSelectionDuringEditing,isEditing,editingAccessoryType,checkmark,tableView(_:editingStyleForRowAt:),UITableViewCell.EditingStyle,delete,insert,tableView(_:commit:forRowAt:),reloadRows(at:with:),CoreSpotlight,MobileCoreServices,CSSearchableItemAttributeSet,kUTTypeText,CSSearchableItem,CSSearchableIndex,indexSearchableItems(_:completionHandler:),deleteSearchableItems(withIdentifiers:completionHandler:),application(_:continue:restorationHandler:),NSUserActivity,activityType,CSSearchableItemActionType
Project 33: What’s that Whistle?
關鍵技術:
AVAudioSession,AVAudioRecorder,sharedInstance,setCategory(_:mode:options:),playAndRecord,setActive,requestRecordPermission(_:),numberOfLines,AVFormatIDKey,record,stop,AVAudioRecorderDelegate,audioRecorderDidFinishRecording(_:successfully:),accessoryType,disclosureIndicator,iCloud,CloudKit,hidesBackButton,popToRootViewController(animated:),CKRecord,CKRecord(recordType:),CKRecordValue,CKAsset,CKAsset(fileURL:),fileURL,CKContainer,publicCloudDatabase,save(_:completionHandler:),CloudKit dashboard,deselectRow(at:animated:),NSPredicate,NSPredicate(value:),NSSortDescriptor,NSSortDescriptor(key:ascending:),CKQuery,CKQuery(recordType:predicate:),sortDescriptors,CKQueryOperation,CKQueryOperation(query:),desiredKeys,resultsLimit,recordFetchedBlock,queryCompletionBlock,selectionStyle,CKRecord.Reference,CKRecord.Reference(recordID: action:),perform(_:inZoneWith:completionHandler:),startAnimating,fetch(withRecordID:completionHandler:),push notification,fetchAllSubscriptions(completionHandler:),delete(withSubscriptionID:completionHandler:),CKQuerySubscription,CKQuerySubscription(recordType:predicate:options:),CKSubscription.NotificationInfo,alertBody,registerForRemoteNotifications,userNotificationCenter(_:willPresent:withCompletionHandler:)
project 34 ~ 37 大部分是跟遊戲相關的技術,彼得潘先偷懶跳過,之後有空再研究。
Project 34: Four in a Row(Game)
Project 35: Generating random numbers
Project 36: Crashy Plane(Game)
Project 37: Psychic Tester(Game)
Project 38: GitHub Commits
關鍵技術:
CoreData,Data Model,xcdatamodeld,entity,attribute,NSPersistentContainer,loadPersistentStores(completionHandler:),NSManagedObjectContext,viewContext,NSManagedObject, @NSManaged,@nonobjc,NSFetchRequest,fetch,SwiftyJSON,ISO8601DateFormatter,NSMergeByPropertyObjectTrumpMergePolicy,mergePolicy,NSPredicate(format:),Core Data entity relationship,delete,deleteRows(at:with:),fetchLimit,NSFetchedResultsController,NSFetchedResultsController(fetchRequest:managedObjectContext:sectionNameKeyPath:cacheName:),fetchRequest,performFetch,NSFetchedResultsControllerDelegate,sections,NSFetchedResultsSectionInfo,object(at:)
https://api.github.com/repos/apple/swift/commits?per_page=100
Project 39: Unit testing with XCTest
關鍵技術:
unit test,XCTest,XCTestCase,@testable,setUp,tearDown,XCTAssertEqual,filter,measure(_:),keys,NSCountedSet,sorted(by:),UI test,XCUIApplication