iOS 11주차 수업 내용 및 수업 후 과제

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

반응형

기존의 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️⃣ 주요 기능

✅ 기본 기능

  1. BMI 계산
    • 입력: 키, 체중, 성별, 연령
    • 결과: BMI 수치 + 상태 범주(저체중/정상/과체중/비만)
    • 단위 전환 지원 (cm ↔ inch / kg ↔ lbs)
    • 실시간 계산 & 색상 변화 게이지로 시각화
  2. BMR(기초대사량) 계산
    • Mifflin-St Jeor, Harris-Benedict 공식 선택 가능
    • 하루 권장 칼로리 자동 표시
  3. 결과 그래프
    • BMI 변화를 라인차트로 시각화
    • 주/월 단위 변화 추세 확인
  4. HealthKit 연동
    • Apple Health의 키, 체중 자동 연동
    • Apple Watch로 측정된 데이터 자동 반영

🚀 확장 기능 (프리미엄)

  1. 목표 체중 설정 및 진행도 표시
    → “이번 주 -0.5kg 목표 달성까지 ○○%” 게이지 표시
  2. 체지방률 추정 및 신체비율 시각화 (BMI+ 계산법 적용)
  3. 리마인더 알림 (체중 입력 알림, 수분 섭취 알림 등)
  4. 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️⃣ 향후 확장 방향

  1. AI 분석 기능
    • “당신의 BMI 패턴에 따라 수면·식습관 개선 팁 제공”
  2. 친구 비교/챌린지 기능
    • 가족·친구 간 BMI 비교, 함께 목표 관리
  3. 소셜 연동 (선택)
    • Instagram/카카오 공유 카드 자동 생성
  4. 다른 지표 통합
    • 체중 외 허리둘레·체지방률·혈압 데이터 통합

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️⃣ 새 프로젝트 생성

  1. Xcode 실행 → “Create a new Xcode project” 클릭
  2. iOS → App → Next
  3. Product Name: BMIApp
    Interface: Storyboard
    Language: Swift
  4. 저장 위치 선택 후 프로젝트 생성

2️⃣ 스토리보드 구성

📱 Main.storyboard

  1. ViewController 선택 → 오른쪽 상단 [+] 버튼 → 아래 컴포넌트 추가
    • Label (제목: “BMI 계산기”)
    • TextField 2개 (Placeholder: “키(cm) 입력”, “몸무게(kg) 입력”)
    • Button 1개 (Title: “BMI 계산하기”)
    • Label 2개 (결과용: “BMI 결과:”, “판정:”)
  2. Auto Layout (간단히 Center 정렬)
    • 모든 요소를 Stack View로 묶어도 좋습니다.
    • Constraint 예시:
      • Center X, Center Y
      • Width 고정 300, Height 자동
  3. 각 요소의 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️⃣ 스토리보드와 코드 연결하기

  1. Main.storyboard 열기
  2. ViewController 선택 후 오른쪽 상단 Identity Inspector → Class = ViewController 설정
  3. 각 요소를 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.
    }
    
    
}

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

앱 아이콘 변경

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

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

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

ㅡㅡㅡㅡㅡㅡㅡㅡㅡ

 

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