๐๐ปโโ๏ธ๐๐ปโโ๏ธ ๋ฌ๋์คํ์ด iOS "์ง์ฌ" ๋ ํฌ ๐๐ปโโ๏ธ๐๐ปโโ๏ธ
- ์งํ๊ธฐ๊ฐ : 2020๋ 6์ 27์ผ ~ 7์ 18์ผ 26th โSOPTโ APPJAM
- ์ฝ๋ ๋ฆฌํฉํ ๋ง ๊ธฐ๊ฐ : 2021๋ 3์ 25์ผ ~
์ฐ๋ฆฌ๋ 'ํจ๊ป' ๋ธ ๋ ๋ ๋ง์ ์๋์ง๋ฅผ ๋ง๋ค์ด๋ ๋๋ค. ์์ฆ ์ธ๋๋ค์ ๋ฌ๋ ํฌ๋ฃจ์ ์์๋์ด ๋ฌ๋์ ์ฆ๊ธฐ๊ณค ํ์ง๋ง, Offline ๋ฌ๋ํฌ๋ฃจ๋ ๊ณ ์ ๋ ์๊ฐ๊ณผ ์ฅ์๋ผ๋ ํ๊ณ์ ์ ๊ฐ์ง๊ณ ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ๊ฐ์ด ๋ฌ๋ฆฌ๊ณ ์ถ์ง๋ง, ๋ฌ๋ฆด ์ ์๋ ์๊ฐ๋ค์ด ์กด์ฌํ๋ค๋ ์ ์ ์ง์คํ๊ณ ์ ํฉ๋๋ค. ์ฐ๋ฆฌ์ ์๋น์ค๋ฅผ ํตํด ์๊ณต๊ฐ์ ์ ์ฝ์์ด ๋ค์ํ ์ฌ๋๋ค๊ณผ ํจ๊ป ๋ฌ๋ฆผ์ผ๋ก์จ ๊ฑด๊ฐํ ๋ผ์ดํ ์คํ์ผ์ ๋ง๋ค์ด๋๊ฐ๊ธธ ๋ฐ๋๋๋ค.
: ๊ธฐ์กด ๋ฌ๋ ์ดํ๋ฆฌ์ผ์ด์ ๊ณผ์ ํ์คํ ์ฐจ๋ณํ ์์๋ฅผ ์ ์ฉํ์ต๋๋ค.
: ์ด๋ค ๋จ์ฒด์ ์์๋์ง ์์๋, ๊ตณ์ด ์น๊ตฌ์ ์ฝ์์ ์ก๊ณ ๋ง๋์ง ์์๋, ์ฌ์ฉ์๋ ์ธ์ ์ด๋์๋ ๋์ ํจ๊ป ๋ธ ์๋๋ฅผ ์ฐพ์ ๊ฐ์ด ๋ฌ๋์ ์ฆ๊ธธ ์ ์์ต๋๋ค.
โญ๏ธ ํธ๋ ๋ํ ๋์์ธ์ ์์๋ฅผ ํตํด ์๊ฐ์ ์ธ ์ฆ๊ฑฐ์์ ์ป์ ์ ์์ต๋๋ค.
: ํน์ ๋ชฉํ๋ฅผ ๋ฌ์ฑํ๋ฉด ๊ฐ์ฑ์๋ ์ฌ๋ฌ ๊ฐ์ง ๋ฑ์ง๋ฅผ ํ๋ํ ์ ์์๊ณผ ๋์์ ๋ค์ํ ๋ฌ๋ ๋ญํน์ ํตํด ์ฌ์ฉ์์ ์ฆ๊ฑฐ์์ ๋๋ชจํ๊ณ ์ ํฉ๋๋ค. ๋, ๋๊ตฌ๋ ์ฌ์ฉํ๊ธฐ ์ฌ์ด UX ์์๋ ์ฆ๊ฑฐ์์ ๋ฐฐ๋ก ํฅ์์์ผ ์ค๊ฑฐ์์.
| ์ฐ์ ์์ | ํ๋ฉด ์ด๋ฆ | ๊ธฐ๋ฅ ์ด๋ฆ | ๊ตฌํ | ๋ด๋น์ |
|---|---|---|---|---|
| P1 | ํ์ ๊ฐ์ | ๊ธฐ๋ณธ ๋ฐ์ดํฐ(๋๋ค์/์์ด๋/๋น๋ฐ๋ฒํธ/์ฑ๋ณ/๋ ๋ฒจ) ๋ฐ๊ธฐ | ๐ต | ์ต์์ฌ |
| P2 | ํํ ๋ฆฌ์ผ | ์คํ๋์ฌ | ๐ต | ๊น๋ฏผํฌ |
| P1 | ๋งค์นญํ๋ฉด | ๋งค์นญ ๋ฐ์ดํฐ(๋ชฉํ์๊ฐ/์๋ ์ฑ๋ณ)๋ฐ๊ธฐ | ๐ต | ๊น๋ฏผํฌ |
| P1 | ๋งค์นญํ๋ฉด | ๋งค์นญ ๊ธฐ์ค(๋ชฉํ์๊ฐ/์ฑ๋ณ/๋ ๋ฒจ)์ ๋ฐ๋ผ ๋งค์นญ๋ฌ๋ ์ฐพ๊ธฐ | ๐ต | ๊น๋ฏผํฌ |
| P1 | ๋งค์นญ์ฑ๊ณตํ๋ฉด | ์๋๋ฌ๋ ํ๋กํ, ๋ ๋ฒจ, ์ ์ ๋ณด์ฌ์ฃผ๊ธฐ | ๐ต | ๊น๋ฏผํฌ |
| P1 | ๋ก๊ทธ์ธ | ๋ก๊ทธ์ธ ๊ธฐ๋ฅ | ๐ต | ์ต์์ฌ |
| P1 | ๋ฌ๋์คํ๋ฉด | ์ค์๊ฐ์ผ๋ก ๋ฌ๋๊ฑฐ๋ฆฌ, ํ์ด์ค, ๋จ์ ์๊ฐ ๋ณด์ฌ์ฃผ๊ธฐ | ๐ต | ๊น๋ฏผํฌ |
| P1 | ๋ฌ๋์คํ๋ฉด | ์นด์ดํธ๋ค์ด | ๐ต | ๊น๋ฏผํฌ |
| P1 | ๋ฌ๋์คํ๋ฉด | ํด๋ํฐ ์ฌ์ฉ์ ๋์ ๋ฐ ํผํธ๋์ค ํ๋ ์ ๊ทผ | ๐ต | ๊น๋ฏผํฌ |
| P2 | ๋ฌ๋์คํ๋ฉด | ํ์ฌ ์์น ํ์ | ๐ต | ๊น๋ฏผํฌ |
| P2 | ๋ฌ๋๋ญํนํ๋ฉด | 1) ์ด๋๊ฑฐ๋ฆฌ ๋์์ 2)์น์ด ๋ง์ ์ 3)ํจ๊ฐ ๋ง์ ์ ์ฌ์ฉ์ ๋ญํน | ๐ต | ์ต์์ฌ |
| P2 | ๋ฌ๋๊ธฐ๋กํ๋ฉด | ๋์ ๋ฌ๋๋ฐ์ดํฐ ๋ชจ์์ ๋ณด์ฌ์ฃผ๊ธฐ ๊ธฐ๋ฅ | ๐ต | ์ต์์ฌ |
| P2 | ๋ฌ๋๊ธฐ๋กํ๋ฉด | ๋ฌ๋ ๋ฑ์ง ๋ชจ์์ ๋ณด์ฌ์ฃผ๊ธฐ ๊ธฐ๋ฅ | ๐ต | ์ต์์ฌ |
| P2 | ๋ฌ๋๊ฒฐ๊ณผํ๋ฉด | ๋ ๋ฌ๋์ ์ด๋๊ฑฐ๋ฆฌ ๋น๊ต ๊ธฐ๋ฅ | ๐ต | ๊น๋ฏผํฌ |
| P1 | ๋ฌ๋๊ฒฐ๊ณผํ๋ฉด | ๋์ ๊ธฐ๋ก/์๋๋ฌ๋ ๊ธฐ๋ก ๋ชจ์์ ๋ณด์ฌ์ฃผ๊ธฐ ๊ธฐ๋ฅ | ๐ต | ๊น๋ฏผํฌ |
| P2 | ๋ง์ดํ์ด์ง | ๋์ ํ๋กํ ์ด๋ฏธ์ง/๋๋ค์/์นํจ/๋ ๋ฒจ/๋ฑ์ง ํ์ | ๐ต | ์ต์์ฌ |
: Tab Bar์ ์ด์ฉํด ๊ฐ ์คํ ๋ฆฌ๋ณด๋๋ฅผ ์ด์ด์ฃผ๋ฉฐ ์ด๋ ๊ฐ๋ฅ
๐ฅณ ๋ก๊ทธ์ธ, ํ์๊ฐ์
ํ๋ฉด. ์ ๊ทํํ์ ๊ฒ์ฌ์ ์์ด๋, ๋๋ค์ ์ค๋ณต ๊ฒ์ฌ ์๋๋ก๊ทธ์ธ ๊ธฐ๋ฅ์ ํฌํจํ๋ค.
๐ฅณ Main ํ๋ฉด. ์ผ๋ฌ์คํธ๋กค ํฌํจํ๋ฉฐ, RUN NOW ๋ฒํผ ํด๋ฆญ์ ์ฃผ์ ๊ธฐ๋ฅ์ ๋งค์นญ ์๋น์ค๊ฐ ์์๋๋ค. ์ํ๋ ๋งค์นญ ๋ฌ๋์ ์กฐ๊ฑด์ ์ค์ ํ๊ณ ๋งค์นญ์ด ๋๋ฉด ์๋๋ฐฉ ํ๋กํ์ ํ์ธํ ํ, ๋ฌ๋์ด ์์๋๋ค.
๐ค ์ถํ develop์ผ๋ก ํผ์ ๋ฌ๋ฆฌ๊ธฐ๋ฅผ ํตํด ๋งค์นญ์ด ์๋๋ ์ฌ๋๋ค ํน์ ํผ์ ๋ฌ๋์ ์ธก์ ํด๋ณด๊ณ ์ถ์ ์ฌ๋๋ค์ ์ํ ์๋น์ค๋ฅผ ์ ๊ณตํ๊ณ ์ ํ๋ค.

๐ฅณ ๋งค์นญ์ด ๋๋ฉด ์๋๋ฐฉ ํ๋กํ์ ํ์ธํ ํ, ๋ฌ๋์ด ์์๋๋ค. ์ค์๊ฐ์ผ๋ก ์์ ์ ์๋(km), ํ์ด์ค(pace), ๋จ์ ์๊ฐ์ด ํ์๋๊ณ ํ์ฌ ์์ ์ด ๋ฐ๊ณ ์๋ ์์น๊ฐ ์ง๋(๋ค์ด๋ฒ)๋ฅผ ํตํด ํ์๋๋ค.
๐ค ํ์ฌ๋ ์์ ์ด ์๋ ์์น๋ง ํ์๋์ง๋ง, ์ถํ ์์ ์ด ๋ฌ๋ํ ๊ฒฝ๋ก๊ฐ ๋จ๊ฒ ํ ์๊ฐ์ด๋ค. (ํ์ฌ ๋ค์ด๋ฒ์ธก์์ points ์์ฑ์ ๋ง์๋๊ฒ์ผ๋ก ๋ณด์ฌ ๊ตฌํํ์ง ๋ชปํ ์์ฌ์์ด ์๋ค.)๋ค์ด๋ฒ ์ง๋ iOS SDK
: ์์ ์ด ์ง๊ธ๊น์ง ์์์จ ๋ฌ๋ ๊ธฐ๋ก๊ณผ ๋ชจ์์จ ๋ฌ๋๋ฑ์ง๋ฅผ ํ์ธํ ์ ์๋ค.
: ํ์ฌ ์ด ์ดํ์์ '์ด๋ฌ์ ๋ฌ๋', '๋ช ์์ ์ ๋น', '์ก.์.์ธ' ๋ก ๋๋ ์ง 3๊ฐ์ ๋ญํน ์์๋ฅผ ํ์ธํ ์ ์๋ค.
: ์์ ์ ๊ธฐ๋ณธ ์ ๋ณด(ํ๋กํ ์ฌ์ง, ๋๋ค์, ๋ ๋ฒจ, ์ ์ )์ ํ์ธํ ์ ์๊ณ ๋ชจ์๋ ๋ฑ์ง๋ฅผ ๊ฐ๋ตํ ํ์ธํ ์ ์๋ค.
๐ช๐ป์ด๋ ์ดํ์ ๊ธฐ๋ณธ! '๊ฑด๊ฐ' ์ดํ๋ฆฌ์ผ์ด์ ์ฐ๋ํด์ ๊ฐ ๊ฐ์ ธ์ค๊ธฐ ! ๋์ !๐ช๐ป
- ๋จผ์ ๊ฑด๊ฐ ์ดํ๋ฆฌ์ผ์ด์ ์ ์ฐ๋ํ๋ ค๋ฉด Apple Developer Program Membership ์ด ํ์ํฉ๋๋ค (์ ๋ฃ)
- Capability์์ Healthkit๋ฅผ ์ถ๊ฐํด ํ์ฑํ ์์ผ์ค๋๋ค.
- info.plist ํ์ผ์์ Information Property List Key Reference๋ฅผ ์ถ๊ฐํด์ค๋๋ค.
- HealthKit ์ก์ธ์ค๋ฅผ ํ์ฉํ๋ ์ฝ๋๋ฅผ ์ง์ผํฉ๋๋ค.
- ์ด ๊ธฐ๊ธฐ์์ HealthKit๋ฅผ ์ฌ์ฉํ ์ ์๋์ง ํ์ธํ๊ธฐ.
guard HKHealthStore.isHealthDataAvailable() else {
completion(false, HealthkitSetupError.notAvailableOnDevice)
return
}- HealthKit๊ณผ ์ํธ ์์ฉํ ๋ฐ์ดํฐ ์ ํ ์ค๋นํ๊ธฐ.
guard let walkAddRun = HKObjectType.quantityType(forIdentifier: .distanceWalkingRunning),
//๊ฑท๊ธฐ+๋ฌ๋ฆฌ๊ธฐ ๊ฑฐ๋ฆฌ(walkAddRun)
let step = HKObjectType.quantityType(forIdentifier: .stepCount),
// ์ฌ๋ฐ์
let activeEnergy = HKObjectType.quantityType(forIdentifier: .activeEnergyBurned)
//ํ๋์๋์ง
else {
let activeEnergy = HKObjectType.quantityType(forIdentifier: .activeEnergyBurned) else {
completion(false, HealthkitSetupError.dataTypeNotAvailable)
return
}(๋ฐ์ดํฐ ์ ํ์ https://developer.apple.com/documentation/healthkit/hkquantitytypeidentifier ์์ ์ฐธ๊ณ ํ ์ ์์ต๋๋ค.)
- HealthKit์ด ์ฝ๊ณ ์ธ ์ ํ ๋ชฉ๋ก ์์ฑํ๊ธฐ
let healthKitTypesToWrite: Set<HKSampleType> = [walkAddRun,
activeEnergy,
step,
HKObjectType.workoutType()
]
let healthKitTypesToRead: Set<HKObjectType> = [walkAddRun,
activeEnergy,
HKObjectType.workoutType()
]healthKitTypesToWrite๋ ์ดํ์ด ๋ค์ ๋ฐ์ดํฐ๋ฅผ ์ฐ๊ธฐ ํ์ฉํ๋ ๋ชฉ๋ก, healthKitTypesToRead๋ ์ดํ์ด ๋ค์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ธฐ ํ์ฉํ๋ ๋ชฉ๋ก์ ๋๋ค.
- ์์ฒญ ์น์ธ ๋ฐ๊ธฐ
HKHealthStore().requestAuthorization(toShare: healthKitTypesToWrite,
read: healthKitTypesToRead) { (success, error) in
completion(success, error)
}import SocketIO
static let shared = SocketIOManager()
var manager = SocketManager(socketURL: URL(string: "์์ผ์ฃผ์")!, config: [.log(true), .compress])
var socket: SocketIOClient!
FindRunnerVC.socket = FindRunnerVC.self.manager.socket(forNamespace: "/matching"): ์ดํ์์ ์์ผ ํต์ ์ ์ฐ๋ ๋ฒ์๋ ๋งค์นญ ๋ฌ๋๋ ์ฐพ์ ๋๋ถํฐ ๊ฒ์์ด ๋๋๊ณ ๊ฒฐ๊ณผ ๋น๊ต ์ ๊น์ง ์์ผ ํต์ ์ ์ฌ์ฉํ์ต๋๋ค.
ํ ๋ทฐ์์๋ง ์์ผ ํต์ ์ด ์ฐ์ด๋ ๊ฒ์ด ์๋๋ผ ์์ผ์ด ์ฐ๊ฒฐ๋ผ์ ์ฌ๋ฌ ๋ทฐ๋ฅผ ํต๊ณผํ๊ธฐ ๋๋ฌธ์ ์ฑ๊ธํค์ ์ฌ์ฉํด์ ํต์ ์ ์ด์ด๊ฐ์ต๋๋ค.
FindRunnerVC.socket.on("start", callback: { (data, ack) in
FindRunnerVC.self.socket.emit("joinRoom",myToken,myGoal,myWantGender,self.leftTime)
}): ์๋ฒ๋ ์์ํด๋ ์ข๋ค๋ ์๋ต -> ํด๋ผ๋ ๋ด ์ ๋ณด์ ๋ด๊ฐ ์ํ๋ ์๋์ ์กฐ๊ฑด์ ๋ณด๋ด์ค๋๋ค.
FindRunnerVC.socket.on("roomCreated", callback: { (data, ack) in
FindRunnerVC.self.socket.emit("startCount",data[0] as! SocketData)
}): ๋ด๊ฐ ์ํ๋ ์กฐ๊ฑด์ ์๋๋ฅผ ์ฐพ์ง ๋ชปํ๋ค๋ฉด ์๋ฒ๋ ์๋ก์ด ๋ฐ์ ๋ง๋ค์ด์ ๋๋ฅผ ๋ฃ์ด์ฃผ๊ณ -> ํด๋ผ๋ ์๊ฐ ์นด์ดํธ๋ฅผ ํ๋ผ๊ณ ์๋ ค์ค๋๋ค. roomCreated ๋ ๋ฐ๋ ์ ๋ณด์ธ data[0]์ ๋ด๊ฐ ์ํด์๋ ๋ฐฉ์ ๋ฒํธ๊ฐ ๋ฉ๋๋ค.
FindRunnerVC.socket.on("matched", callback: { (data, ack) in
FindRunnerVC.self.socket.emit("endCount",data[0] as! SocketData)
}): ๋๊ธฐ์ค์ ์๋๋ฅผ ์ฐพ์์๋๋ ์๋ฒ๋ matched์ data[0]์ผ๋ก ๋ด๊ฐ ์ํ ๋ฐฉ ์ด๋ฆ์ ๋ณด๋ด์ฃผ๊ณ , ํด๋ผ์์๋ ์ฌ์ฉ์๊ฐ ์ํ ๋ฐฉ์ ์ด๋ฆ๊ณผ endCount๋ฅผ ๋ณด๋ด์ค๋๋ค.
FindRunnerVC.socket.emit("compareResult",UserDefaults.standard.object(forKey: "opponentRoom") as? String ?? " ",UserDefaults.standard.object(forKey: "opponetDistance") as? Int ?? 2,UserDefaults.standard.object(forKey: "myGoalTime") as? Int ?? 0,array2,UserDefaults.standard.object(forKey: "createdTime") as? String ?? " ",UserDefaults.standard.object(forKey: "endTime") as? String ?? " "): ๋ฌ๋ ๊ฒ์์ด ๋๋๋ฉด ๋์ ๋ฐฉ ๋ฒํธ, ๋ฌ๋ฆฐ ๊ฑฐ๋ฆฌ, ๋ฌ๋ฆฐ ์๊ฐ, ๋ฐฉ ๋ฒํธ, ์ง๋ ์์น, ์์ํ ์๊ฐ, ๋๋ ์๊ฐ์ ํจ๊ป ๋ณด๋ด์ค๋๋ค.
- ์ ๊ทํํ์๊ณผ ์ค์๊ฐ ์ ๋ ฅ ์ฒดํฌ
private func loginCheck() {
idTextField.addTarget(self, action: #selector(idTextChecked(_:)), for: .editingChanged)
nickTextField.addTarget(self, action: #selector(nickTextChecked(_:)), for: .editingChanged)
pwTextField.addTarget(self, action: #selector(pwTextChecked(_:)), for: .editingChanged)
pwReTextField.addTarget(self, action: #selector(pwReTextChecked(_:)), for: .editingChanged)
}editingChanged๋ฅผ ํ์ฉํ ํจ์๋ฅผ ์ ์ธํด์ฃผ์ด ์ค์๊ฐ์ผ๋ก ์กฐ๊ฑด์ ๋ง๋ ์ ๋ ฅ์ด ๋ค์ด์ค๋์ง ์ฒดํฌํ๊ณ , ๊ทธ์ ๋ฐ๋ฅธ ํ ์คํธ๋ฅผ ๋์ฐ๊ฑฐ๋, ์กฐ๊ฑด์ ๋ง์์ผ ๋ค๋ฅธ ๋์๋ค์ ์คํํ ์ ์๋๋ก ํ๋ค.
func isValidNick(nick: String?) -> Bool {
guard nick != nil else { return false }
let regEx = "[ใฑ-ใ
ใ
-ใ
ฃ๊ฐ-ํฃA-Za-z0-9]{2,6}"
let pred = NSPredicate(format:"SELF MATCHES %@", regEx)
return pred.evaluate(with: nick)
}๋๋ค์ ์ ๊ทํํ ์กฐ๊ฑด
ํ ์คํธ ํ๋๊ฐ ์กฐ๊ฑด์ ๋ง์ง ์๋๋ค๋ฉด, ์ค๋ฅ ๋ฉ์ธ์ง์ ํจ๊ฒ ํ ์คํธ ํ๋์ ๋์์ธ์ ๋ณ๊ฒฝํด์ฃผ๊ณ ๋ค์์ผ๋ก ๋์ด๊ฐ ์ ์๋ ๋ฒํผ์ ๋นํ์ฑํ ์ํค๋ ๋ฑ์ ๊ตฌํ์ ํ๋ค. ์ ๊ทํํ์ ์์ฒด๋ณด๋ค๋ ์ค์๊ฐ์ผ๋ก ์ฌ์ฉ์์ ์ ๋ ฅ์ ํ์ธํ์ฌ ์กฐ๊ฑด์ ๊ฒ์ฌํด์ฃผ๋ ๋ถ๋ถ์ด ์ด๋ ค์ ๋๋ฐ, ์ฐ๋ฆฌ ํ์ ๊ฒฝ์ฐ์๋ ํ์๊ฐ์ ์์ ์ฒดํฌํด์ผํ๋ ์กฐ๊ฑด์ด ๋ค์ํ๊ธฐ ๋๋ฌธ์ ๋ทฐ๋ฅผ ์ง๋ ๊ณผ์ ์ด ๊น๋ค๋กญ๊ณ ์๊ฐ์ด ์ค๋๊ฑธ๋ ธ๋ค.
-
์ปฌ๋ ์ ๋ทฐ์ IsSelected๋ฅผ ํ์ฉํ ์ ํ์ง ๊ตฌํ
override var isSelected: Bool { willSet { self.genderActionLabel.backgroundColor = newValue ? UIColor.lightishBlue : UIColor.brownishGrey print(genderActionLabel.text ?? nil!)
ํ์๊ฐ์ ์์ ์ฌ์ฉ์์ ์ถ๊ฐ ์ ๋ณด๋ฅผ ์ ๋ ฅํด์ผํ๋ ๋ถ๋ถ์ ์ฒ์์๋ ๋จ์ํ๊ฒ ๋ฒํผ์ผ๋ก ๊ตฌํํ๋ ค๊ณ ํ์๋ค. ๊ทธ๋ฌ๋ ์ฌ์ฉ์๊ฐ ํ๋์ ์ ํ์ง๋ง์ ์ ํํด์ผํ๊ณ , ๊ทธ ๊ฐ๋ง์ ์๋ฒ์ ์ ๋ฌํด์ผํ๋ ์กฐ๊ฑด ํ์ ์ผ๋ฐ ๋ฒํผ์ผ๋ก๋ ๊ธฐํ์ ๊ตฌํํ ์๊ฐ ์์๋ค. ๊ทธ๋ ๊ธฐ์ ์ปฌ๋ ์ ๋ทฐ์์ IsSelected๋ฅผ ํ์ฉํ์ฌ ์ฌ์ฉ์๊ฐ ํ๋๋ง์ ์ ํ์ง๋ฅผ ๊ณ ๋ฅผ ์ ์๊ฒ ๊ตฌํํ์๋ค. ์๋๋ก์ด๋์์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณต๋๋ ๊ธฐ๋ฅ์ด์ง๋ง, iOS์์๋ ์ผ์ผ์ด ๊ตฌํํด์ฃผ์ด์ผํ๋ ๊ธฐ๋ฅ์ด์๋ค. ์ ํ ์์ง ๋ชปํ๋ ๊ธฐ๋ฅ์ด์๊ธฐ์ ๋ง์ ์ฌ๋๋ค์ ๋์์ ๋ฐ์๊ณ , ๊ตฌ๊ธ๋ง๊ณผ ์์ ์ ํ๋๋ฐ์ ๋ง์ ์๊ฐ์ด ๋ค์๋ค.
- CoreMotion์ ํด๋ํฐ์ ์ผ์๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค. ์๋ Healthkit๋ฅผ ์ฌ์ฉํ์ง๋ง, Healthkit๋ ๋ง์ ์ ๋ณด๋ฅผ ์ ๊ณตํด์ฃผ์ง๋ง ์
๋ฐ์ดํธ๊ฐ ์ค์๊ฐ(๋ช ์ด ๋จ์)๋ก ๋์ง์๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํด์ CoreMotion์ผ๋ก ์์ ํ์๋ค.coremotion์ ์ด์ฉํด์ ์ค์๊ฐ ๊ฑฐ๋ฆฌ๋ฅผ ๋ฐ์์๋ค. ๋ฌผ๋ก ์ฌ๊ธฐ์๋ ํ์ด์ค๋ฅผ ๊ณ์ฐํด์ฃผ์ง๋ง ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๋จ์์๋ ๋ฌ๋๊ธฐ๋๋ฌธ์ ํ์ด์ค๋ ์ง์ ๊ณ์ฐํ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ค.
CoreMotion
pedometer = CMPedometer(): CMPedometer๋ ์ค์๊ฐ ๊ฑท๊ธฐ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํ ๊ฐ์ฒด์ด๋ค. ์ฆ ๋ง๋ณด๊ธฐ์ ์ญํ ์ ํ๋ค. ๋ง๋ณด๊ธฐ๋ฅผ ํตํด ๊ฑธ์ ์ ๋ฐ ์ด๋ ํ ๊ฑฐ๋ฆฌ์ ์์น ๋๋ ํ๊ฐ ํ ์ธต ์์ ๋ํ ๊ธฐํ ์ ๋ณด๋ฅผ ๊ฒ์ํ ์ ์๋ค.
pedometer.startUpdates(from: Date(), withHandler: {
(pedometerData, error) in
if let pedData = pedometerData{
self.numberOfSteps = Int(pedData.numberOfSteps)
if let distance = pedData.distance{
self.distance = Double(distance)
}
if let averageActivePace = pedData.averageActivePace {
self.averagePace = Double(averageActivePace)
}
if let currentPace = pedData.currentPace {
self.pace = Double(currentPace)
}
} else {
self.numberOfSteps = nil
}
}): startUpdates ํจ์๋ฅผ ํตํด ๋ณดํ์ ๊ด๋ จ ๋ฐ์ดํฐ๋ฅผ ์ฑ์ ๋๊ณ ์จ๋ค. distance๋ ์ฌ์ฉ์๊ฐ ๊ฑท๊ฑฐ๋ ๋ฐ๋ ๋์ ์ด๋ํ ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐ์ ธ์์ค๋ค. averageActivePace๋ ๋ฏธํฐ๋น ์ด ๋จ์๋ก ํ์ฐํ ํ๊ท ํ์ด์ค์ด๋ค. currentPace๋ ๋ฏธํฐ๋น ์ด ๋จ์๋ก ์ธก์ ํ ํ์ฌ ์๋์ด๋ค. ์ด๋ ๊ฒ CoreData์์๋ ๋ฌ๋ฆฌ๊ธฐ์์ ํ์ํ ๋ง์ ์ ๋ณด๋ค์ ์ ๊ณตํ๋ค.
- ๊น๋ฏผํฌ Repo : ๋ฌ๋์คํ์ด iOS ๋ฆฌ๋๊ฐ๋ฐ์, MainTab ๊ตฌํ ๋ฐ ์์ผ ํต์ ๋ด๋น
- ์ต์์ฌ Repo : ๋ฌ๋์คํ์ด iOS ์๋ธ๊ฐ๋ฐ์, RankTab / RecordTab / MyPabeTab / SignTab ๋ด๋น ๋ฐ http ํต์ ๋ด๋น
: IT ์ฐฝ์
๋์๋ฆฌ 26th โSOPTโ APPJAM ๋์ ์์, ํ์ฌ ์ฑ์คํ ์ด ์ถ์ ์ค๋น ์ค.














