일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- swift sms
- flutter rotate
- FlutterView MethodChannel
- Swift flutterviewcontroller
- Swift flutterview
- 스위프트 앨범
- 스위프트 테이블 뷰 셀
- silent push
- 노티피케이션 익스텐션
- native flutter view
- 안드로이드 앨범
- 안드로이드 숏컷
- swift autolayout
- 푸시 데이터 저장
- 안드로이드 에러
- 앱 꺼졌을 때 푸시 데이터 저장
- NotificationService Extension
- Flutter NativeView
- 안드로이드 FCM
- 스위프트 UserDefaults
- 스위프트 카메라
- 스위프트 웹뷰
- Flutter UIKitView MethodChannel
- 플러터 뷰 컨트롤러
- flutter 회전
- 스위프트 푸시
- 안드로이드 바로가기
- swift 문자
- 스위프트
- 앱 백그라운드 푸시 데이터 저장
- Today
- Total
Things take time
[SWIFT] 마지막 : 스위프트 기본 앱 본문
** Segue 생성 시 참고
화면에 만든 버튼을 마우스 우클릭 드래그로 뷰 컨트롤러와 연결하면 해당 버튼 클릭시 연결된 뷰 컨트롤러로 이동
뷰 컨트롤러위의 뷰 컨트롤러 버튼을 우클릭 드래그로 뷰 컨트롤러와 연결하면 생성된 세그에 id를 부여하여 해당 id를 통해 이동하는 코드를 작성하면 됨
위의 뷰 컨트롤러는 CREATE ACCOUNT라는 버튼과 연결된 것이고 하단의 뷰 컨트롤러는 뷰컨트롤러 버튼으로 연결된 것이라 오른쪽 상단에 id를 부여했고, 코드로 따로 작성해야 함 (CREATE 버튼은 ACTION으로 연결할 필요 없음)
1. 데이터 저장하기
예제 : 계정 생성 후 UserDefault로 값 저장하기
UserDefaults : Android의 SharedPreference와 같은 기본적인 사용자의 정보를 저장하는 기본 데이터베이스, 앱의 업데이트와 같은 경우에도 데이터는 저장되며, 앱 삭제시에만 삭제 되는 데이터
보통 계정 정보보다는 앱의 버전 값이나 기타 앱의 설정 값을 저장할 때 사용함
Util.swift는 기본 swift파일로 생성하며 싱글톤 객체를 이용한 경고창 만들때 사용
import UIKit // 싱글톤 만들기, 가장 상위의 NSObject형으로 한다(문법) class Util:NSObject { // 싱글톤 객체는 static let을 통해 만든다 static let sharedInstance = Util() func showAlert(viewController:UIViewController, title:String, message:String) { let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) viewController.present(alert, animated: true, completion: nil) } }
계정 생성 뷰 컨트롤러
import UIKit class AccountViewController: UIViewController { @IBOutlet weak var idTextField: UITextField! @IBOutlet weak var pwTextField: UITextField! @IBOutlet weak var pwConfirmTextField: UITextField! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destinationViewController. // Pass the selected object to the new view controller. } */ @IBAction func submitClicked(_ sender: UIButton) { if idTextField.text?.isEmpty == false && pwTextField.text?.isEmpty == false && pwConfirmTextField.text?.isEmpty == false && pwTextField.text == pwConfirmTextField.text { // UserDafaults 사용 // 싱글톤 패턴으로 하나의 객체만 모든 클래스 전역적으로 사용하는 개념 UserDefaults.standard.set(idTextField.text, forKey: "id") UserDefaults.standard.set(pwTextField.text, forKey: "password") // 이전 페이지 이동 navigationController?.popViewController(animated: true) } else { // 싱글톤 객체 호출 Util.sharedInstance.showAlert(viewController: self, title: "알림", message: "계정 정보가 부족합니다") } } }
메인 뷰 컨트롤러
@IBAction func loginClicked(_ sender: UIButton) { print("aaa") if idTextField.text?.isEmpty == false && pwTextField.text?.isEmpty == false { if idTextField.text == UserDefaults.standard.value(forKey: "id") as? String && pwTextField.text == UserDefaults.standard.value(forKey: "password") as? String{ performSegue(withIdentifier: "LoginSegue", sender: self) print("aa") } } else { Util.sharedInstance.showAlert(viewController: self, title: "알림", message: "ID/PW 부분을 모두 입력하세요.") } } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let vc = segue.destination as? UserViewController { vc.userId = idTextField.text! } }
나머지 : 첨부파일
2. 앱 버전, 이름 정보 가져오기 및 체크하기
let infoDic = Bundle.main.infoDictionary! let appName = infoDic["CFBundleName"] as! String let appVersion = infoDic["CFBundleShortVersionString"] as! String let appBuild = infoDic["CFBundleVersion"] as! String print("appName = \(appName)") print("appVersion = \(appVersion)") print("appBuild - \(appBuild)")
override func viewDidLoad() { super.viewDidLoad() if let savedVersion = UserDefaults.standard.value(forKey: "appVersion") as? String { let newVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as! String if savedVersion != newVersion { Util.sharedInstance.showAlert(viewController: self, title: "알림", message: "앱 업데이트") saveCurrentVersion() } } else { Util.sharedInstance.showAlert(viewController: self, title: "알림", message: "최초 실행(앱 삭제 후, 혹은 설치 후 최초 실행)") saveCurrentVersion() } } func saveCurrentVersion(){ let currentVer = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as! String UserDefaults.standard.set(currentVer, forKey: "appVersion") }
3. 키체인
앱과 다른 앱사이의 통신을 위한 데이터로 앱을 삭제하더라도 데이터가 유지되는 특징이 있음 (같은 팀으로 개발된 다른 앱을 의미함, 모든 앱을 의미하는게 아님)
테스트할 때는 Capabilities 의 Keychain Sharing을 On하고 사용할 앱 정보와 공유할 앱의 패키지 명을 입력
테스트
하나의 앱에서 키체인 값 저장 및 가져오기
import UIKit // 키 체인 사용시 import import Security // 높은 보안 수준의 값 저장이 필요한 경우 사용 // 키체인 그룹 설정을 통해 앱간 설정값 공유가 가능함 class Keychain { class func save(key: String, data: Data) -> Bool { let query = [ kSecClass as String : kSecClassGenericPassword as String, kSecAttrAccount as String : key, kSecValueData as String : data ] as [String : Any] SecItemDelete(query as CFDictionary) let status: OSStatus = SecItemAdd(query as CFDictionary, nil) return status == noErr } class func load(key: String) -> Data? { let query = [ kSecClass as String : kSecClassGenericPassword, kSecAttrAccount as String : key, kSecReturnData as String : kCFBooleanTrue, kSecMatchLimit as String : kSecMatchLimitOne ] as [String : Any] var dataTypeRef: AnyObject? let status = withUnsafeMutablePointer(to: &dataTypeRef) { SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0)) } if status == errSecSuccess { if let data = dataTypeRef as! Data? { return data } } return nil } class func delete(key: String) -> Bool { let query = [ kSecClass as String : kSecClassGenericPassword, kSecAttrAccount as String : key ] as [String : Any] let status: OSStatus = SecItemDelete(query as CFDictionary) return status == noErr } class func clear() -> Bool { let query = [ kSecClass as String : kSecClassGenericPassword ] let status: OSStatus = SecItemDelete(query as CFDictionary) return status == noErr } }
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() /* 처음 실행 // 테스트용 계정 let id = "schidsi" let password = "1234abcd" // 키체인 저장 -> print : true true if let idData = id.data(using: String.Encoding.utf8), let passwordData = password.data(using: String.Encoding.utf8) { print(Keychain.save(key: "id", data: idData)) print(Keychain.save(key: "password", data: passwordData)) } */ // 처음 실행 후 처음 실행 부분 주석하고 실행 // 키체인에서 데이터 가져오기 -> print -> id : schidsi / pw : 1234abcd if let idData = Keychain.load(key: "id"), let passwordData = Keychain.load(key: "password"){ if let id = String(data: idData, encoding: .utf8), let password = String(data: passwordData, encoding: .utf8){ print("id : \(id) / pw : \(password)") } } } }
공유할 앱에서는 아래와 같이 사용 : 팀, 개발 타겟 등을 맞춰주고 Capabilities의 keyChain Sharing을 On한 뒤, 공유할 앱들의 리스트를 생성한 패키지 포함하여 입력
KeyChain.swift를 넣고, 위의 예제에서 키체인에서 데이터 가져오는 소스를 그대로 복사하여 viewDidLoad()에서 하면, 같은 결과 값을 얻어올 수 있음
키체인의 경우 앱이 삭제되어도 키체인에서 저장이 되기때문에, 유지가 되나 OS를 새로 설치할 경우는 날아가게 됨, 이런 경우 또 다른 저장 방법을 생각할 수 있는데 그 것은 바로 서버에 저장하는 경우
4. Firebase를 이용한 데이터 베이스 이용하기 : https://firebase.google.com/docs/ & https://firebase.google.com/docs/database/ios/start
설명 그대로 하면 간단함, FCM 하듯이..
5. Framework 생성 후 다른 프로젝트에서 가져다 쓰기
프레임워크 생성시엔 Cocoa Touch Framework로 생성후 코드 작성 후 Products 밑에 있는 Framework파일을 사용할 프로젝트에서 General의 Embeded Binaries에 드래그하여 가져다 쓰면 됨 -> 안될 경우 해당 프레임워크를 Show Finder로 열어 복사 후, 옮길 프로젝트에 붙여넣기로 넣은 뒤에 드래그
그리고 사용할 때는 import로 해당 프레임워크명 입력하고 가져다 씀 : Util.framework라는 프레임워크를 넣고 사용한 화면
6. Object-C -> Swift에서 사용하기
.h와 .m파일을 넣었다면, 팝업창으로 Configure관련 메시지가 뜨면 브릿지를 연결하겠다는 버튼을 클릭하고, 브릿지 헤더.h 파일에 아래처럼 입력 (해당 헤더파일만 include)
// // Use this file to import your target's public headers that you would like to expose to Swift. // #include "DLRadiobutton.h"
만약 .h, .m파일을 넣지 않고 해당 파일이 있는 폴더 자체를 넣으면 브릿지 관련 메시지가 뜨지 않음, 이럴 때는 헤더파일을 따로 생성하고 Build Settings -> Swift Compiler - General의 Object-C Bridgind Header의 해당 파일을 알려줘야함
'iOS (교육)' 카테고리의 다른 글
[SWIFT] 6일차 : 스위프트 기본 앱 (0) | 2017.04.29 |
---|---|
[SWIFT] 5일차 : 스위프트 기본 앱 (0) | 2017.04.15 |
[SWIFT] 4일차 : 스위프트 기본 앱 (0) | 2017.04.08 |
[SWIFT] 3일차 : 스위프트 기본 앱 (3) | 2017.04.01 |
[SWIFT] 2일차 : 스위프트 기본 앱 (0) | 2017.03.25 |