2025. 11. 11. 17:47ㆍiOS 기초/수업 내용 및 수업 후 과제

기존의 bmi앱
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
iOS용 BMI 계산기 앱 제작을 앞두고 있으니, 현재 앱스토어에서 인기 있는 BMI 계산기 앱들을 분석해서 강점과 약점을 정리해드릴게요.
참고하셔서 기획 방향이나 차별화 포인트 잡는 데 도움이 되면 좋겠습니다.
분석 대상 앱
아래 두 앱을 중심으로 살펴봤습니다.
- BMI Calculator – Weight Loss (App Store) (App Store)
- BMI Calculator – BMR Manager (App Store) (App Store)
1. BMI Calculator – Weight Loss
강점
- 사용자 인터페이스가 깔끔하고 직관적입니다. 예컨대 “애니메이션 게이지”를 통해 BMI 수치 변화나 범주(저체중, 정상, 과체중 등)를 시각적으로 보여줍니다. (App Store)
- 단위(kg/cm, lbs/ft, 영국식 스톤) 등을 다양하게 지원하고 있어서 국제 사용자 대비용으로 좋습니다. (App Store)
- 연령 및 성별을 고려한 계산이나 아동(7세 이상) 지원 옵션까지 갖춘 버전이 있다는 점이 차별화 요소입니다. (구글 플레이)
- 오프라인에서도 동작 가능하다는 설명이 있어서, 네트워크 없어도 사용 가능하다는 점이 장점입니다. (구글 플레이)
약점
- BMI 계산 자체는 단순하므로 “계산만” 하고 끝나는 앱이 많습니다. 사용자가 지속해서 앱을 켜도록 만드는 동기가 약할 수 있습니다.
- BMI의 한계(예: 근육량이나 골격 등을 고려하지 않음)를 인지하고 있는 사용자에게는 “이 수치만으로 건강을 판단한다”는 인상으로 비판받을 수 있습니다. 실제로 이런 지적이 Reddit 등에서 나옵니다:
- “BMI is very, very flawed… It should probably not just straight up say ‘healthy’ or simplistic answers like that.” (Reddit)
- 무료/유료 모델이나 광고 삽입 방식이 사용자 경험을 저해할 수 있습니다. 예컨대 어떤 앱은 유료 구독을 강하게 제안합니다. (App Store)
2. BMI Calculator – BMR Manager
강점
- BMI뿐만 아니라 BMR(기초대사량) 계산 기능을 포함하고 있어, 단순 BMI 값보다 “하루 칼로리 필요량/기초대사량”까지 보여주는 등 확장된 기능이 있다는 점이 장점입니다. (App Store)
- 연령, 성별, 키, 몸무게 등 다양한 입력값을 통한 계산 공식(예: Mifflin-St Jeor, Harris-Benedict)도 선택 가능하다는 설명이 있습니다. (App Store)
- Apple HealthKit 연동 가능하다는 언급이 있어, iOS 환경에서 생태계 연계 측면이 좋습니다. (App Store)
약점
- 기능이 많아지는 만큼 사용자 입장에서 복잡하게 느껴질 수 있고, 단순히 BMI만 알고 싶은 사용자에게는 진입장벽이 될 수 있습니다.
- “계산 + 기록” 기능 위주라면 사용자가 입력을 귀찮아할 가능성이 높습니다 — 지속 사용을 유도하기 위한 UX/UX 요소(리마인더, 목표 설정, 알림 등)가 중요합니다.
- 유료 모델이나 인앱 구매가 포함되어 있을 가능성이 있고, 일부 사용자 리뷰에서는 광고/구독 관련 불만이 보입니다.
3. 공통적으로 발견되는 기획 포인트 및 체크리스트
좋은 요소
- 단위 선택(미터/센티미터 vs 피트/인치 vs 스톤) 지원
- 연령/성별/아동 지원 여부
- Apple Health 또는 건강 생태계(HealthKit) 연동
- 시각적 피드백(게이지, 색깔 변화, 그래프)
- 기록(history) 기능 + 진행 추적(track) 기능
- 지원 언어 및 지역화 고려
개선 또는 차별화 가능 요소
- BMI의 한계를 사용자에게 교육하는 기능: “근육량/골격량 고려되지 않음” 등의 안내 포함
- 목표 설정 + 동기 부여 기능 (알림, 목표 달성 뱃지, 커뮤니티 공유)
- 자동화/입력 부담 최소화: 스마트 저울, HealthKit 자동 연동
- 한국 사용자 특화: 한국인 체형/기준 적용, 한국어 UI/UX, 한국어 콘텐츠
- 무료 체험 + 명확한 유료 기능 구분: 가급적 사용자에게 긍정적 경험 제공 후 유료 제안
- 디자인/브랜딩 차별화: 많은 앱이 “계산기” 기능만 있으므로, 감성 UX/브랜딩으로 포지셔닝 가능
- 개인정보·데이터 보안 명확히 표시: 헬스 관련 앱이기 때문에 사용자 신뢰 확보 중요
제안: 당신의 앱 기획에 적용해볼 만한 아이디어
- 기본 BMI 계산 기능은 무료로 제공하고, 추가 기능(예: 체지방률 예측, 근육량 추적, 목표 설정 리마인더)은 프리미엄으로 제안
- 한국 사용자 특화: 한국 키/몸무게 평균 기준, 한국어 UI/UX, 한국 연령별 성장 차트(아동용)
- “입력 최소화” 전략: HealthKit 연동 + 혹은 Apple Watch/저울 연동 → 사용자가 직접 많이 입력하지 않아도 되게
- “교육/정보” 섹션 탑재: BMI만으로 건강을 판단하면 안 된다는 정보를 제공하고, 체형·근력·생활습관 등 고려하라는 안내
- 시각적 UX 강화: 예컨대 ‘내 BMI 게이지’가 실시간 변화하는 애니메이션, 목표달성에 따라 색이 바뀌는 등
- 커뮤니티/챌린지 요소 추가 가능: “이번 주 몸무게 변화 챌린지”, 친구 초대 등
- 데이터 보안 및 프라이버시 정책을 명확하게 표기하여 신뢰 확보
아래는 방금 분석한 App Store 인기 BMI 계산기 앱의 장단점을 바탕으로 정리한,
신규 iOS 앱 “BMI+ (가칭)” 기획서 초안입니다.
📱 iOS 앱 기획서
앱 이름
BMI+ (비엠아이 플러스)
단순 BMI 계산을 넘어, 건강 인사이트와 동기부여를 제공하는 iOS용 스마트 BMI 관리 앱
1️⃣ 개발 개요
항목 내용
| 앱 목적 | 사용자의 키·체중·연령·성별 등을 기반으로 BMI 및 건강지수를 계산하고, 건강 목표 설정 및 진행 상황을 시각적으로 관리 |
| 개발 플랫폼 | iOS (SwiftUI or UIKit + HealthKit) |
| 대상 사용자 | 10~50대 건강관리 관심층, 다이어트/체중관리 사용자 |
| 핵심 가치 | 단순 계산이 아닌 “지속적인 건강 피드백과 동기부여” 제공 |
| 수익모델 | 무료 기본 기능 + 프리미엄 구독 (광고 제거 / 체지방률 예측 / 알림 기능 등) |
2️⃣ 주요 기능
✅ 기본 기능
- BMI 계산
- 입력: 키, 체중, 성별, 연령
- 결과: BMI 수치 + 상태 범주(저체중/정상/과체중/비만)
- 단위 전환 지원 (cm ↔ inch / kg ↔ lbs)
- 실시간 계산 & 색상 변화 게이지로 시각화
- BMR(기초대사량) 계산
- Mifflin-St Jeor, Harris-Benedict 공식 선택 가능
- 하루 권장 칼로리 자동 표시
- 결과 그래프
- BMI 변화를 라인차트로 시각화
- 주/월 단위 변화 추세 확인
- HealthKit 연동
- Apple Health의 키, 체중 자동 연동
- Apple Watch로 측정된 데이터 자동 반영
🚀 확장 기능 (프리미엄)
- 목표 체중 설정 및 진행도 표시
→ “이번 주 -0.5kg 목표 달성까지 ○○%” 게이지 표시 - 체지방률 추정 및 신체비율 시각화 (BMI+ 계산법 적용)
- 리마인더 알림 (체중 입력 알림, 수분 섭취 알림 등)
- AI 건강 코멘트 제공
→ BMI 변화 추이에 따른 맞춤 코멘트 (예: “현재 속도로 2주 후 정상 체중 예상!”)
3️⃣ 디자인 컨셉
항목 내용
| UI 스타일 | 미니멀 & 클린 (흰색 배경, 파스텔 그래프 컬러) |
| 메인 화면 | 원형 게이지 그래프 + “당신의 BMI는 22.3 (정상)” 표시 |
| 보조 화면 | 그래프 탭(추세), 목표 탭, 설정 탭으로 구성 |
| 폰트/아이콘 | SF Pro, SF Symbols (Apple 기본 디자인 통일) |
| 애니메이션 효과 | BMI 변화 시 게이지 바가 부드럽게 이동, HealthKit 동기화 시 로딩 애니메이션 표시 |
4️⃣ 차별화 포인트 (경쟁 앱 대비)
구분 기존 앱 문제점 BMI+의 개선 방향
| 단순 계산만 제공 | 반복 사용 유인이 부족 | 목표관리 + 그래프 + 알림으로 “지속사용성” 강화 |
| BMI의 한계 인식 부족 | “비현실적”이라는 비판 존재 | BMI 외 체지방률·BMR까지 함께 표시 |
| 복잡한 UX | 초보자에게 부담 | 키·몸무게만 입력해도 자동 계산, HealthKit 자동 연동 |
| 글로벌 기준만 제공 | 한국인 기준 없음 | 한국인 평균체형 데이터 기반 BMI 해석 |
| 광고 과다 | UX 방해 | 무료는 최소 광고, 프리미엄은 완전 무광고 |
| 디자인 구식 | 계산기 형태로 단조로움 | 게이지 그래프 + 컬러 피드백 + 깔끔한 iOS 디자인 |
5️⃣ 화면 구성 예시
화면 주요 구성 요소
| 홈 (Main) | BMI 게이지, 현재 상태 문구, “기록하기” 버튼 |
| 결과 (Result) | BMI 수치, 체중 변화 그래프, BMR/권장 칼로리 |
| 목표 (Goal) | 목표 체중, 진행률, 동기부여 문구 |
| 설정 (Settings) | 단위 선택, 알림 설정, HealthKit 연동, 테마 변경 |
6️⃣ 기술 스택
구성 요소 사용 기술
| 프론트엔드(UI) | Swift / SwiftUI 또는 UIKit |
| 데이터 관리 | CoreData 또는 UserDefaults |
| 헬스 연동 | HealthKit Framework |
| 그래프 시각화 | Swift Charts / CoreAnimation |
| 로컬화 | 한국어 + 영어 지원 |
| 버전 관리 | Xcode + GitHub |
| 배포 | Apple App Store Connect |
7️⃣ 향후 확장 방향
- AI 분석 기능
- “당신의 BMI 패턴에 따라 수면·식습관 개선 팁 제공”
- 친구 비교/챌린지 기능
- 가족·친구 간 BMI 비교, 함께 목표 관리
- 소셜 연동 (선택)
- Instagram/카카오 공유 카드 자동 생성
- 다른 지표 통합
- 체중 외 허리둘레·체지방률·혈압 데이터 통합
8️⃣ 기대 효과
- 일반 계산기 앱 대비 사용자 유지율 향상
→ 목표 및 알림 기능을 통한 지속 사용 유도 - 한국 사용자 맞춤형 건강 앱 시장 공략
→ BMI 해석을 한국인 기준으로 제공 - 헬스 데이터 기반 확장성 확보
→ HealthKit 기반 앱 생태계 진입
9️⃣ 개발 일정 (예시)
단계 기간 주요 내용
| 기획/디자인 | 1주 | 와이어프레임, UI 시안 |
| 1차 개발 | 2주 | BMI 계산, UI 기본 구성 |
| 2차 개발 | 2주 | BMR, 그래프, 목표 관리 |
| HealthKit 연동 | 1주 | Apple Health 데이터 동기화 |
| 테스트/디버깅 | 1주 | QA, UX 수정 |
| 앱스토어 제출 | 1주 | 빌드 등록 및 심사 준비 |
📌 결론 요약
“BMI+”는 기존 BMI 계산 앱의 단조로움을 극복하고,
시각적 재미 + 동기부여 + HealthKit 연동을 결합한 iOS 전용 스마트 건강지표 앱입니다.단순 계산에서 ‘지속적 건강관리 도우미’로 발전시키는 것을 목표로 합니다.
iOS 초보 개발자가 **스토리보드 기반으로 “BMI 계산기 앱”**을 만드는 절차를 아래처럼 단계별로 정리해드릴게요.
👉 Xcode에서 바로 따라 하면 완성 가능한 수준으로 코드 + 화면 구성 + 관련 자료 링크까지 모두 포함했습니다.
🧩 프로젝트 목표
키(cm)와 몸무게(kg)를 입력하면 BMI 지수와 판정 결과(저체중/정상/과체중/비만) 를 보여주는 간단한 iOS 앱 만들기
(스토리보드 기반 UIKit 방식)
1️⃣ 새 프로젝트 생성
- Xcode 실행 → “Create a new Xcode project” 클릭
- iOS → App → Next
- Product Name: BMIApp
Interface: Storyboard
Language: Swift - 저장 위치 선택 후 프로젝트 생성
2️⃣ 스토리보드 구성
📱 Main.storyboard
- ViewController 선택 → 오른쪽 상단 [+] 버튼 → 아래 컴포넌트 추가
- Label (제목: “BMI 계산기”)
- TextField 2개 (Placeholder: “키(cm) 입력”, “몸무게(kg) 입력”)
- Button 1개 (Title: “BMI 계산하기”)
- Label 2개 (결과용: “BMI 결과:”, “판정:”)
- Auto Layout (간단히 Center 정렬)
- 모든 요소를 Stack View로 묶어도 좋습니다.
- Constraint 예시:
- Center X, Center Y
- Width 고정 300, Height 자동
- 각 요소의 Accessibility Identifier 또는 IBOutlet 연결용 이름 정하기 (예: txtHeight, txtWeight, lblResult, lblComment 등)
3️⃣ IBOutlet & IBAction 연결
👉 ViewController.swift 열고 코드 작성
import UIKit
class ViewController: UIViewController {
// MARK: - 아웃렛 연결
@IBOutlet weak var txtHeight: UITextField!
@IBOutlet weak var txtWeight: UITextField!
@IBOutlet weak var lblResult: UILabel!
@IBOutlet weak var lblComment: UILabel!
// MARK: - 버튼 액션
@IBAction func calcBMI(_ sender: UIButton) {
// 키와 몸무게 값 가져오기
guard let h = Double(txtHeight.text ?? ""), let w = Double(txtWeight.text ?? "") else {
lblResult.text = "숫자를 입력하세요."
lblComment.text = ""
return
}
// BMI 계산: 체중(kg) / (신장(m))²
let meterHeight = h / 100
let bmi = w / (meterHeight * meterHeight)
lblResult.text = String(format: "BMI: %.1f", bmi)
// 판정 문구 표시
switch bmi {
case ..<18.5:
lblComment.text = "저체중입니다 ⚠️"
lblComment.textColor = .systemBlue
case 18.5..<23:
lblComment.text = "정상 체중입니다 ✅"
lblComment.textColor = .systemGreen
case 23..<25:
lblComment.text = "과체중입니다 ⚠️"
lblComment.textColor = .systemOrange
default:
lblComment.text = "비만입니다 ❌"
lblComment.textColor = .systemRed
}
}
}
4️⃣ 스토리보드와 코드 연결하기
- Main.storyboard 열기
- ViewController 선택 후 오른쪽 상단 Identity Inspector → Class = ViewController 설정
- 각 요소를 Ctrl+드래그해서 코드에 연결
- txtHeight → 키 입력 필드
- txtWeight → 몸무게 입력 필드
- lblResult, lblComment → 결과 라벨
- “BMI 계산하기” 버튼 → calcBMI() 액션에 연결
5️⃣ 실행 및 테스트
- 상단의 ▶️ Run 버튼 클릭
- 시뮬레이터에서 앱 실행
- 예:
- 키 = 170
- 몸무게 = 65
→ 결과: “BMI: 22.5 / 정상 체중입니다 ✅”
6️⃣ 추가 기능 아이디어 (선택사항)
기능 구현 팁
| BMI 결과 색상 게이지 | UIProgressView 또는 UIView의 width를 BMI에 따라 변경 |
| 키보드 자동 내리기 | view.endEditing(true) 호출 |
| BMI 공식 안내 팝업 | UIAlertController 사용 |
| HealthKit 연동 | import HealthKit 후 체중 자동 불러오기 (고급) |
| Dark Mode 지원 | 시스템 색상(.label, .systemBackground) 사용 |
7️⃣ 디자인 팁 (초보자용)
- 폰트: Title에는 “SF Pro Display Bold 28pt”, 결과는 “SF Pro Regular 17pt”
- 버튼 색상: System Blue
- TextField 배경: System Gray5 + 둥근 모서리 8pt
- 라벨 정렬: Center Align
- StackView 사용 시 깔끔한 자동 정렬 가능
8️⃣ 관련 학습자료
주제 링크
| iOS Storyboard 기본 사용법 | Apple 공식 UIKit Tutorial |
| IBAction / IBOutlet 연결 방법 | Hacking with Swift - Storyboards |
| Auto Layout 기초 | Apple Auto Layout Guide |
| BMI 계산 공식 참고 | WHO BMI Classification |
✅ 완성 결과 예시 화면
---------------------------
| BMI 계산기 |
| |
| 키(cm): [ 170 ] |
| 몸무게(kg): [ 65 ] |
| |
| [ BMI 계산하기 ] |
| |
| BMI: 22.5 |
| 정상 체중입니다 ✅ |
---------------------------
iOS 앱을 만들 때 스토리보드(Storyboard) 방식과 스위프트 코드(UI 프로그래밍) 방식 중
어느 걸 쓸지 고민하는 건 아주 중요한 선택이에요.
아래는 두 방식을 기능·개발·유지보수 측면에서 정리한 비교표입니다 👇
🧩 iOS UI 개발 방식 비교표
구분 스토리보드 방식 (Storyboard / UIKit Designer) 스위프트 코드 방식 (Programmatic UI / SwiftUI)
| UI 구성 방법 | 드래그 & 드롭으로 시각적으로 구성 (Interface Builder 사용) |
코드로 직접 View, StackView, Constraint 등을 작성 |
| 학습 난이도 | 초보자에게 매우 쉬움 👶 | 익숙해지면 빠르지만 초보자에겐 어려움 😅 |
| 장점 | - UI 시각화가 쉬워 디자인 확인 용이 - 연결(IBOutlet/IBAction) 직관적 - 빠른 프로토타이핑 가능 - AutoLayout을 시각적으로 조절 가능 |
- 코드로 완벽한 제어 가능 - Git 충돌 적음 (XML 파일 없음)- 재사용성 높음 (Custom View 구성 가능) - 팀 협업,버전 관리에 유리 |
| 단점 | - Storyboard 파일이 커지면 충돌 발생 (특히 협업 시) - 앱 규모 커질수록 유지보수 어려움 - 복잡한 UI의 제약 많음 (동적 UI 불편) - 코드 리팩토링 시 연결 끊김 위험 |
- UI 결과를 바로 눈으로 보기 어렵다 - Constraint 코드가 길고 복잡- 초보자는 레이아웃 디버깅이 어려움 |
| 빌드 속도 | 대형 스토리보드는 빌드 느림 ⚠️ | 상대적으로 빠름 ⚡ |
| 협업 효율성 | 충돌 잦음 (하나의 .storyboard 파일 공유 시) | 각 View를 독립 파일로 관리 가능 |
| 코드 가독성 | UI는 눈으로, 로직은 코드로 분리 → 직관적 | UI와 로직이 한 곳에 섞이지만 명확한 흐름 제어 가능 |
| 동적 UI 구현 | 제약 많음 (Storyboard 수정 필요) | 런타임 조건에 맞게 동적 UI 자유롭게 생성 |
| 테스트 및 리팩토링 | Storyboard 연결이 깨질 수 있어 위험 | 코드만 수정하면 돼서 안전하고 추적 쉬움 |
| 추천 상황 | ✅ iOS 입문자✅ 빠른 UI 프로토타입✅ 단일 화면 앱 | ✅ 중·대형 프로젝트✅ 협업 환경✅ 동적·반응형 UI 앱 |
| 대표 예시 | BMI 계산기, 할 일 메모장, 계산기 등 | SNS 피드, 쇼핑몰, 동적 콘텐츠 앱 등 |
💡 요약 정리
초보자 추천 ✅ 스토리보드 방식
| 협업 / 유지보수 / 동적UI 중심 | ✅ 스위프트 코드 방식 (UIKit/SwiftUI) |
| 장기 프로젝트 (확장성 중시) | ✅ 코드 기반이 더 안정적 |
📚 참고
- Storyboard → UIKit 기반, Xcode 인터페이스 빌더 사용
- SwiftUI → 선언형 UI (코드로 디자인), iOS 13 이상부터 적극 권장
- 실무 추세 → SwiftUI 또는 UIKit Programmatic UI로 점차 전환 중
Swift 문자열 서식(swift string format 자리수)
import Foundation
let weight = 60.0
let height = 170.0
let bmi = weight / (height*height*0.0001) // kg/m*m
let shortenedBmi = String(format: "%.1f", bmi)
var body = ""
if bmi >= 40 {
body = "3단계 비만"
} else if bmi >= 30 && bmi < 40 {
body = "2단계 비만"
} else if bmi >= 25 && bmi < 30 {
body = "1단계 비만"
} else if bmi >= 18.5 && bmi < 25 {
body = "정상"
} else {
body = "저체중"
}
print("BMI:\(shortenedBmi), 판정:\(body)")
------------
BMI:20.8, 판정:정상
-------------------------

이건 Swift에서 String(format:_:) 초기화 구문(initializer)의 정의 일부예요.
🔍코드의 의미
init(
format: String,
_ arguments: any CVarArg...
)
이건 문자열 포매팅(String Formatting) 을 위한 String의 이니셜라이저(initializer)입니다.
즉, C 언어의 printf() 형식 문자열처럼
지정한 형식(format)에 맞춰 값을 삽입해서 새로운 문자열을 만드는 기능이에요.
💡 사용 예시
let name = "정상연"
let age = 24
let message = String(format: "안녕하세요, %@님! 나이는 %d세입니다.", name, age)
print(message)
출력 결과 👇
안녕하세요, 정상연님! 나이는 24세입니다.
📘 매개변수 설명
매개변수 타입 설명
| format | String | 문자열 형식 지정자 (%@, %d, %.1f 등) |
| _ arguments | any CVarArg... | 삽입할 값(가변 인자: 여러 개 가능) |
CVarArg는 “C 언어 스타일의 가변 인자(argument)”를 의미해요.
즉, Swift에서도 C처럼 여러 값을 순서대로 넣을 수 있게 해주는 타입이에요.
📊 대표적인 서식(format) 기호
서식 의미 예시
| %@ | 문자열(String) | "이름: %@" → "이름: 홍길동" |
| %d | 정수(Int) | "나이: %d" → "나이: 20" |
| %f | 실수(Double/Float) | "%.2f" → "3.14" |
| %ld | Long Int | 긴 정수 출력 시 |
| %c | 문자(Character) | "문자: %c" |
🧠 한 줄 요약
String(format:_:) 은 C의 printf 문법을 Swift에서 문자열 생성에 사용하는 함수예요.
format은 서식 문자열, CVarArg...는 그 자리에 들어갈 값들이에요.
어떻게 어디서 사용하는지 -> 시험에 많이 냄
지금 보고 계신 init(format:_:) (즉 String(format:_:))은
👉 문자열 안에 변수나 숫자를 포맷(서식) 맞춰 넣을 때 사용하는 함수예요.
iOS 앱이나 Swift 코드에서 아주 자주 쓰입니다.
아래에 단계별로 예제 보여드릴게요.
✅ 1. 기본 사용법
let name = "정상연"
let age = 24
let message = String(format: "안녕하세요, %@님! 나이는 %d세입니다.", name, age)
print(message)
🟢 출력 결과:
안녕하세요, 정상연님! 나이는 24세입니다.
💡 %@ → 문자열(String)
💡 %d → 정수(Int)
✅ 2. 소수점 자리 지정 (BMI 계산 예시)
BMI 계산기 만들 때 결과를 소수점 한 자리로 출력하고 싶을 때 이렇게 써요 👇
let height: Double = 170
let weight: Double = 65
let bmi = weight / pow(height / 100, 2) // BMI 계산식
// String(format:) 사용
let result = String(format: "당신의 BMI는 %.1f 입니다.", bmi)
print(result)
🟢 출력 결과:
당신의 BMI는 22.5 입니다.
💡 %.1f → 실수(float/double)를 소수점 1자리까지 표시
💡 %.2f → 소수점 2자리
💡 %.0f → 소수점 없이 정수로 표시
✅ 3. 여러 값 포맷팅
let math = 95
let english = 88
let avg = Double(math + english) / 2
let report = String(format: "수학: %d, 영어: %d, 평균: %.1f", math, english, avg)
print(report)
🟢 출력 결과:
수학: 95, 영어: 88, 평균: 91.5
✅ 4. iOS 앱 (UILabel에 표시할 때)
스토리보드에서 라벨(UILabel)을 연결했다면 이렇게 쓸 수 있어요 👇
@IBOutlet weak var lblResult: UILabel!
@IBAction func calcBMI(_ sender: UIButton) {
let height = Double(txtHeight.text ?? "") ?? 0
let weight = Double(txtWeight.text ?? "") ?? 0
let bmi = weight / pow(height / 100, 2)
// String(format:)을 사용해서 깔끔하게 표시
lblResult.text = String(format: "BMI: %.1f", bmi)
}
🟢 라벨에는 예를 들어
BMI: 22.3
이렇게 깔끔하게 표시됩니다.
✅ 5. 자주 쓰는 포맷 기호 요약표
서식 의미 예시 입력 결과
| %@ | 문자열 | "Swift" | Swift |
| %d | 정수 | 25 | 25 |
| %f | 실수 | 3.14159 | 3.141590 |
| %.1f | 소수점 1자리 | 3.14159 | 3.1 |
| %.2f | 소수점 2자리 | 3.14159 | 3.14 |
| %ld | Long Int | 1000000 | 1000000 |
🧠 요약
String(format:)은
👉 숫자나 문자열을 형식(format) 에 맞게
깔끔하게 문자열로 만들어주는 함수예요.
import Foundation
let weight = 60.0
let height = 170.0
let bmi = weight / (height*height*0.0001) // kg/m*m
let shortenedBmi = String(format: "%.1f", bmi)
var body = ""
if bmi >= 40 {
body = "3단계 비만"
} else if bmi >= 30 && bmi < 40 {
body = "2단계 비만"
} else if bmi >= 25 && bmi < 30 {
body = "1단계 비만"
} else if bmi >= 18.5 && bmi < 25 {
body = "정상"
} else {
body = "저체중"
}
print("BMI:\(shortenedBmi), 판정:\(body)")
이 소스에서
let bmi = weight / (height*height*0.0001) // kg/m*m
let shortenedBmi = String(format: "%.1f", bmi)
이 소스에 대한 설명
이 두 줄은 “BMI(체질량지수)”를 계산하고 보기 좋게 표시 문자열로 만드는 코드입니다.
하나씩 자세히 설명해드릴게요👇
✅ 1️⃣ 첫 번째 줄
let bmi = weight / (height * height * 0.0001) // kg/m*m
👉 하는 일
- BMI(Body Mass Index) 계산식이에요.
- weight는 몸무게(kg),
height는 키(cm) 값입니다.
📘 BMI 공식
BMI = 체중(kg) / (신장(m) × 신장(m))
그런데 대부분 앱에서는 키를 cm 단위로 입력받기 때문에,
이를 미터 단위로 바꾸기 위해 ×0.0001을 곱해줍니다.
예시로 보면 👇
항목 값
| 키(height) | 170 cm |
| 몸무게(weight) | 65 kg |
| 계산 | 65 / (170×170×0.0001) = 65 / 2.89 = 22.49 |
➡️ bmi 변수에는 22.49가 저장됩니다.
✅ 2️⃣ 두 번째 줄
let shortenedBmi = String(format: "%.1f", bmi)
👉 하는 일
- 계산된 BMI 값(22.49)을
소수점 첫째 자리까지만 표시한 문자열로 바꿉니다. - "%.1f" → 소수점 1자리 형식(format)
예시 👇
String(format: "%.1f", 22.49) // "22.5"
즉, shortenedBmi에는
"22.5" 라는 문자열이 들어갑니다.
✅ 정리하면
변수 역할 예시 값
| bmi | 실제 계산된 BMI (Double 타입) | 22.49 |
| shortenedBmi | 소수점 1자리로 만든 문자열 | "22.5" |
✅ 전체 예시
let height = 170.0
let weight = 65.0
let bmi = weight / (height * height * 0.0001) // 계산
let shortenedBmi = String(format: "%.1f", bmi) // 소수점 한 자리
print("당신의 BMI는 \(shortenedBmi) 입니다.")
🟢 출력 결과:
당신의 BMI는 22.5 입니다.
🧠 요약
첫 줄은 BMI 계산 공식,
두 번째 줄은 결과를 보기 좋게(소수점 1자리) 문자열로 만드는 코드입니다.

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
BMI를 판정하는 calcBMI()함수 정의
import Foundation
func calcBMI(weight : Double, height : Double) -> String{
let bmi = weight / (height*height*0.0001) // kg/m*m
let shortenedBmi = String(format: "%.1f", bmi)
var body = ""
if bmi >= 40{
body = "3단계 비만"
} else if bmi >= 30 && bmi < 40 {
body = "2단계 비만"
} else if bmi >= 25 && bmi < 30 {
body = "1단계 비만"
} else if bmi >= 18.5 && bmi < 25 {
body = "정상"
} else {
body = "저체중"
}
return "BMI:\(shortenedBmi), 판정:\(body)"
}
print(calcBMI(weight:62.5, height: 172.3))
---------------
BMI:21.1, 판정:정상
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
BMI 결과 판정하는 클래스 만들기
// bmiMode.swift
import Foundation
class BMI {
var weight : Double
var height : Double
init(weight:Double, height:Double){
self.height = height
self.weight = weight
}
func calcBMI() -> String {
let bmi=weight/(height*height*0.0001)// kg/m*m
let shortenedBmi = String(format: "%.1f", bmi)
var body = ""
if bmi >= 40 {
body = "3단계 비만"
} else if bmi >= 30 && bmi < 40 {
body = "2단계 비만"
} else if bmi >= 25 && bmi < 30 {
body = "1단계 비만"
} else if bmi >= 18.5 && bmi < 25 {
body = "정상"
} else {
body = "저체중"
}
return "BMI:\(shortenedBmi), 판정:\(body)"
}
}
var han = BMI(weight:62.5, height:172.3)
print(han.calcBMI())
--------------
BMI:21.1, 판정:정상
-----------------------------

identity inspector기말고사에 무조건 나오는 내용



표시한 부분 시험에 나옴

수정전 코드
//
// ViewController.swift
// BMIA
//
// Created by 소프트웨어컴퓨터 on 2025/11/11.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var txtHeight: UITextField!
@IBOutlet weak var txtWeight: UITextField!
@IBOutlet weak var lblResult: UILabel!
@IBAction func calcBmi(_ sender: UIButton) {
let height = Double(txtHeight.text!)! //과제
let weight = Double(txtWeight.text!)!
print(height,weight)
let bmi = weight/(height*height*0.0001)
let shortenedBmi = String(format: "%.1f", bmi)
var body = ""
if bmi >= 40 {
body = "3단계 비만"
} else if bmi >= 30 && bmi < 40 {
body = "2단계 비만"
} else if bmi >= 25 && bmi < 30 {
body = "1단계 비만"
} else if bmi >= 18.5 && bmi < 25 {
body = "정상"
} else {
body = "저체중"
}
print("BMI:\(shortenedBmi), 판정:\(body)")
lblResult.text = "BMI:\(shortenedBmi), 판정:\(body)"
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
let height = Double(txtHeight.text!)! //과제
let weight = Double(txtWeight.text!)! swift소스인데 !가 왜 이렇게 많은지 중요- 시험에 나옴
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

//
// ViewController.swift
// BMIA
//
// Created by 소프트웨어컴퓨터 on 2025/11/11.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var txtHeight: UITextField!
@IBOutlet weak var txtWeight: UITextField!
@IBOutlet weak var lblResult: UILabel!
@IBAction func calcBmi(_ sender: UIButton) {
let height = Double(txtHeight.text!)! //과제
let weight = Double(txtWeight.text!)!
print(height,weight)
let bmi = weight/(height*height*0.0001)
let shortenedBmi = String(format: "%.1f", bmi)
print(txtHeight.text, txtWeight.text, height, weight)
var body = ""
if bmi >= 40 {
body = "3단계 비만"
} else if bmi >= 30 && bmi < 40 {
body = "2단계 비만"
} else if bmi >= 25 && bmi < 30 {
body = "1단계 비만"
} else if bmi >= 18.5 && bmi < 25 {
body = "정상"
} else {
body = "저체중"
}
print("BMI:\(shortenedBmi), 판정:\(body)")
lblResult.text = "BMI:\(shortenedBmi), 판정:\(body)"
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
----------------------
2025-11-11 16:48:39.911734+0900 BMIA[4047:109215] Can't find keyplane that supports type 8 for keyboard iPhone-PortraitChoco-DecimalPad; using 27248_PortraitChoco_iPhone-Simple-Pad_Default
170.0 60.0
Optional("170") Optional("60") 170.0 60.0
BMI:20.8, 판정:정상
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
//
// ViewController.swift
// BMIA
//
// Created by 소프트웨어컴퓨터 on 2025/11/11.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var txtHeight: UITextField!
@IBOutlet weak var txtWeight: UITextField!
@IBOutlet weak var lblResult: UILabel!
@IBAction func calcBmi(_ sender: UIButton) {
let height = Double(txtHeight.text!)! //과제
let weight = Double(txtWeight.text!)!
print(height,weight)
let bmi = weight/(height*height*0.0001)
let shortenedBmi = String(format: "%.1f", bmi)
print(txtHeight.text!, txtWeight.text!, height, weight)
var body = ""
if bmi >= 40 {
body = "3단계 비만"
} else if bmi >= 30 && bmi < 40 {
body = "2단계 비만"
} else if bmi >= 25 && bmi < 30 {
body = "1단계 비만"
} else if bmi >= 18.5 && bmi < 25 {
body = "정상"
} else {
body = "저체중"
}
print("BMI:\(shortenedBmi), 판정:\(body)")
lblResult.text = "BMI:\(shortenedBmi), 판정:\(body)"
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
------------
170 60 170.0 60.0
BMI:20.8, 판정:정상
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

//
// ViewController.swift
// BMIA
//
// Created by 소프트웨어컴퓨터 on 2025/11/11.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var txtHeight: UITextField!
@IBOutlet weak var txtWeight: UITextField!
@IBOutlet weak var lblResult: UILabel!
@IBAction func calcBmi(_ sender: UIButton) {
let height = Double(txtHeight.text!)! //과제
let weight = Double(txtWeight.text!)!
print(height,weight)
let bmi = weight/(height*height*0.0001)
let shortenedBmi = String(format: "%.1f", bmi)
print(Double(txtHeight.text!), Double(txtWeight.text!), height, weight)
var body = ""
if bmi >= 40 {
body = "3단계 비만"
} else if bmi >= 30 && bmi < 40 {
body = "2단계 비만"
} else if bmi >= 25 && bmi < 30 {
body = "1단계 비만"
} else if bmi >= 18.5 && bmi < 25 {
body = "정상"
} else {
body = "저체중"
}
print("BMI:\(shortenedBmi), 판정:\(body)")
lblResult.text = "BMI:\(shortenedBmi), 판정:\(body)"
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
-----------
2025-11-11 17:05:29.718267+0900 BMIA[4575:121360] Can't find keyplane that supports type 8 for keyboard iPhone-PortraitChoco-DecimalPad; using 27248_PortraitChoco_iPhone-Simple-Pad_Default
170.0 60.0
Optional(170.0) Optional(60.0) 170.0 60.0
BMI:20.8, 판정:정상
-------------------------------------

값이 한개가 없는데 nil을 강제로 풀었기 때문에(강제언랩핑을 했기 때문에)앱이 멈추는 문제가 생긴다

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

//
// ViewController.swift
// BMIA
//
// Created by 소프트웨어컴퓨터 on 2025/11/11.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var txtHeight: UITextField!
@IBOutlet weak var txtWeight: UITextField!
@IBOutlet weak var lblResult: UILabel!
@IBAction func calcBmi(_ sender: UIButton) {
if txtHeight.text == "" || txtWeight.text == "" {
lblResult.textColor = .red
lblResult.text = "키와 체중을 입력하세요!"
return
} else {
let height = Double(txtHeight.text!)! //과제
let weight = Double(txtWeight.text!)!
let bmi = weight/(height*height*0.0001)
let shortenedBmi = String(format: "%.1f", bmi)
var body = ""
if bmi >= 40 {
body = "3단계 비만"
} else if bmi >= 30 && bmi < 40 {
body = "2단계 비만"
} else if bmi >= 25 && bmi < 30 {
body = "1단계 비만"
} else if bmi >= 18.5 && bmi < 25 {
body = "정상"
} else {
body = "저체중"
}
print("BMI:\(shortenedBmi), 판정:\(body)")
lblResult.text = "BMI:\(shortenedBmi), 판정:\(body)"
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
-------------------
!(강제 언래핑)을 모두 제거하고 안전한 옵셔널 바인딩 방식으로 수정한 버전을 보여드릴게요.
입력이 비어 있거나 숫자가 아닐 때도 앱이 절대 꺼지지 않도록 처리했습니다 ✅
//
// ViewController.swift
// BMIA
//
// Created by 소프트웨어컴퓨터 on 2025/11/11.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var txtHeight: UITextField!
@IBOutlet weak var txtWeight: UITextField!
@IBOutlet weak var lblResult: UILabel!
@IBAction func calcBmi(_ sender: UIButton) {
// 공백 제거 후 안전하게 옵셔널 바인딩
guard let heightText = txtHeight.text?.trimmingCharacters(in: .whitespaces),
let weightText = txtWeight.text?.trimmingCharacters(in: .whitespaces),
!heightText.isEmpty, !weightText.isEmpty else {
lblResult.textColor = .red
lblResult.text = "키와 체중을 입력하세요!"
return
}
// 문자열을 Double로 변환 (변환 실패 시 메시지 표시)
guard let height = Double(heightText),
let weight = Double(weightText) else {
lblResult.textColor = .red
lblResult.text = "숫자만 입력하세요!"
return
}
// BMI 계산
let bmi = weight / (height * height * 0.0001)
let shortenedBmi = String(format: "%.1f", bmi)
// 판정 구분
var body = ""
if bmi >= 40 {
body = "3단계 비만"
} else if bmi >= 30 {
body = "2단계 비만"
} else if bmi >= 25 {
body = "1단계 비만"
} else if bmi >= 18.5 {
body = "정상"
} else {
body = "저체중"
}
// 결과 출력
lblResult.textColor = .black
lblResult.text = "BMI: \(shortenedBmi), 판정: \(body)"
print("BMI: \(shortenedBmi), 판정: \(body)")
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
판정 결과에 따라 출력 레이블에 다른 배경색 지정




//
// ViewController.swift
// BMIA
//
// Created by 소프트웨어컴퓨터 on 2025/11/11.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var txtHeight: UITextField!
@IBOutlet weak var txtWeight: UITextField!
@IBOutlet weak var lblResult: UILabel!
@IBAction func calcBmi(_ sender: UIButton) {
if txtHeight.text == "" || txtWeight.text == "" {
lblResult.textColor = .red
lblResult.text = "키와 체중을 입력하세요!"
return
} else {
let height = Double(txtHeight.text!)! //과제
let weight = Double(txtWeight.text!)!
let bmi = weight/(height*height*0.0001)
let shortenedBmi = String(format: "%.1f", bmi)
var body = ""
var color = UIColor.white
if bmi >= 40 {
color = UIColor(displayP3Red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)
body = "3단계 비만"
} else if bmi >= 30 && bmi < 40 {
color = UIColor(displayP3Red: 0.7, green: 0.0, blue: 0.0, alpha: 1.0)
body = "2단계 비만"
} else if bmi >= 25 && bmi < 30 {
color = UIColor(displayP3Red: 0.4, green: 0.0, blue: 0.0, alpha: 1.0)
body = "1단계 비만"
} else if bmi >= 18.5 && bmi < 25 {
color = UIColor(displayP3Red: 0.0, green: 0.0, blue: 1.0, alpha: 1.0)
body = "정상"
} else {
color = UIColor(displayP3Red: 0.0, green: 1.0, blue: 0.0, alpha: 1.0)
body = "저체중"
}
//print("BMI:\(shortenedBmi), 판정:\(body)")
lblResult.backgroundColor = color
lblResult.clipsToBounds = true // 모서리를 둥굴게
lblResult.layer.cornerRadius = 15 // 모서리를 둥굴게
lblResult.text = "BMI:\(shortenedBmi), 판정:\(body)"
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

앱 아이콘 변경

실행할때 잠깐 나왔다가 사라지는 화면 (런치스크린 만들기)
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ



ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

'iOS 기초 > 수업 내용 및 수업 후 과제' 카테고리의 다른 글
| iOS 12주차 수업 내용 및 수업 후 과제 (0) | 2025.11.25 |
|---|---|
| iOS 12주차 수업 내용 및 수업 후 과제 (0) | 2025.11.18 |
| iOS 수업 내용 및 수업 후 과제 (0) | 2025.11.11 |
| iOS 9주차 수업 내용 및 수업 후 과제 (0) | 2025.10.28 |
| iOS 6,7주차 (0) | 2025.10.14 |