이번글에서는 좀 더 근간이 되는.. SwiftLint 자체를 프로젝트에 어떻게 적용하는지? 에 대한 방법을 정리해보도록 하겠습니다.
우선 프로젝트에 vi Podfile 한 후 SwiftLint를 추가해줍니다. > pod install
pod 'SwiftLint'
그리고 프로젝트로 돌아와 Target > build phase > + > new run script phase 절차를 밟아줍니다.
그리고 아래 사진처럼 run script에 해당 코드를 추가해 주세요.
${PODS_ROOT}/SwiftLint/swiftlint
그리고 빌드를 해줍니다…
그러면 에러든.. 경고든… 뭔가가…우수수… 나타나게 될 것입니다..
이 swiftLint에는 정말 다양하고도 많고 많은 규칙들이 나오게 되는데요.
이 모든것들을 제가 다 컨트롤 하지못하고 그저 시키는대로만 해야한다면.. 그건 또 너무 힘들겠죠?
그래서 사실 이 규칙들을 또 제가 컨트롤 할수도 있습니다.
하는 방법은 아래와 같습니다.
새로운 파일을 만듭니다. Empty 파일로 만들어주세요.
여기서 중요한 뽀인트는 프로젝트에 파일을 추가해야 하는 것입니다. 프로젝트 > 앱 이름 폴더 안이 아니구요!
프로젝트 자체에 추가!!!!!!!!!!!!!
그리고 이름은 무조건 .swiftlint.yml 로 지어주세요. 무 족 권
그러면 경고창으로 파일 이름 앞에 .을 붙이면 숨김 파일 되는데 너 쓸거야? 라고 물어봅니다. 응~ 쓸거야(Use “.”) 버튼 눌러줍니다.
그리고 이곳에서 각자 예외를 만들어줄 것들을 추가해줍니다.
# 파일 length
file_length:1200
# 깊이
nesting:
type_level:3
# 한줄 길이
line_length:300
# 함수 길이
function_body_length:160
# body 길이
type_body_length:500
# 함수 복잡성
cyclomatic_complexity:60
# 변수명
identifier_name:
min_length:2
# 튜플 최소갯수
large_tuple:3
# 타입길이
type_name:
min_length:2
max_length:
warning:100
error:150
# 규칙제거 - 축약
disabled_rules:- syntactic_sugar
- trailing_whitespace
- compiler_protocol_init
# 제외 경로
excluded:- Pods
저는 대략적으로 이렇게 짜놓았습니다.
여기서 집고 넘어갈 부분은 disabled_rules, excluded 정도가 있겠네요.
1. disabled_rules
swiftLint에서 디폴트로 적용되는 규칙들을 내 프로젝트에서는 아닌 상태로 만들어줍니다.
2. excluded
swiftLint가 검사하지 않을 영역을 지정해주는 것입니다.
특정 파일에서 경고가 뜨는데, 별로 보고싶지 않다면 이 특정 폴더 혹은 파일을 제외시킬 수도 있게 됩니다.
저 같은 경우는 코코아팟 라이브러리들에서 나는 에러와 경고는 모두 무시할 수 있도록 지정해놓았습니다.
3. included
추가로 included같은 경우는 유추 가능하듯 반드시 검사가 필요한 영역에 사용해볼 수 있겠습니다.
근데 저는 이 included는 사용하지 않을 것 같네욤..ㅎ..
이번 프로젝트에서 저는 UIPageControl을 UICollecionView와 함께 사용한 경험이 있습니다.
정확히는 테이블뷰 셀 위에 컬렉션뷰를 놓았고, 그 컬렉션뷰 셀에 대한 페이지 컨트롤을 동작하게 만들어 놓았습니다.
다음 사용방법은 아래와 같습니다.
classHomeTableViewCell:UITableViewCell{@IBOutletweakvarcollectionView:UICollectionView!@IBOutletweakvarpageControl:UIPageControl!overridefuncawakeFromNib(){super.awakeFromNib()// pageControl pageControl.numberOfPages=2pageControl.currentPage=0pageControl.pageIndicatorTintColor=UIColor.white.withAlphaComponent(0.3)pageControl.currentPageIndicatorTintColor=UIColor(named:"7A7BDA")pageControl.transform=CGAffineTransform(scaleX:1.3,y:1.3)}}extensionHomeTableViewCell:UICollectionViewDelegate,UICollectionViewDataSource{funcscrollViewWillEndDragging(_scrollView:UIScrollView,withVelocityvelocity:CGPoint,targetContentOffset:UnsafeMutablePointer<CGPoint>){// 현재까지 스크롤된 크기를 구함letpage=Int(targetContentOffset.pointee.x/self.frame.width)self.pageControl.currentPage=page}funcscrollViewDidScroll(_scrollView:UIScrollView){letwidth=scrollView.bounds.size.widthletx=scrollView.contentOffset.x+(width/2)letnewPage=Int(x/width)ifpageControl.currentPage!=newPage{pageControl.currentPage=newPage}}}
이때 여기서 가장 중요한 포인트는 코드에 있지않습니다.
일반적으로 생각해보면 페이지컨트롤이 컬렉션뷰 안에 존재할것같다고 생각할수도 있습니다.
그렇지만 그렇지 않습니다. 컬렉션뷰 바깥에 같은 동일선상에 존재하고 있어야 합니다.
그리고 이 홈페이지에 접속을 하면 준비된 이미지를 드래그 해놓기만 하면 이미지들이 형성이 됩니다.
이렇게 다운로드 파일에 들어가 AppIcon 파일이 저장되어있는 것을 확인했다면 AppIcon.appiconset 안에 생성된 이미들이 종류별로 있음을 확인 가능할 것입니다.
이때 이 AppIcon.appiconset 파일을 통째로 프로젝트 내 assets에 임포트(import) 해줍니다.
그리고 Xcode를 재실행(빌드) 해보고 나면 원했던 앱 아이콘이 제대로 적용 되어있음을 볼수있을 것 입니다.
만약 반영이 안된다면, Target > Build settings > Asset Catalog compiler - Options - Primary App Icon Set Name 이 AppIcon 으로 되어있는지 확인을 해봅시다!
혹은 Assets에 있는 기본 AppIcon 파일을 지우고 직접 만들어 이미지를 임포트 해주면 추가가 되기도 합니다!
셀 안에 컨테이너 뷰로 뷰 하나를 만들어놓고 해당 뷰 내부에 라벨 하나를 넣어주었습니다.
그리고 아래 코드는 테이블뷰 셀 안에서 직접 달력을 그려주는 코드들이 진행되어집니다.
classWeekTableViewCell:UITableViewCell{letnow=Date()varcal=Calendar.currentletdateFormatter=DateFormatter()varcomponents=DateComponents()varweeks:[String]=["일","월","화","수","목","금","토"]vardays:[String]=[]// 해당 월이 몇일까지 있는지vardaysCountInMonth=0// 시작일varweekdayAdding=0@IBOutletweakvaryearMonthLbl:UILabel!@IBOutletweakvarcollectionView:UICollectionView!overridefuncawakeFromNib(){super.awakeFromNib()initUI()}funcinitUI(){self.collectionView.delegate=selfself.collectionView.dataSource=selfself.collectionView.isScrollEnabled=falseletlayout=UICollectionViewFlowLayout()layout.scrollDirection=.verticallayout.minimumLineSpacing=0layout.minimumInteritemSpacing=0self.collectionView.collectionViewLayout=layoutdateFormatter.dateFormat="yyyy년 M월"components.year=cal.component(.year,from:now)components.month=cal.component(.month,from:now)components.day=1self.calculation()self.collectionView.reloadData()}/*
1 일요일 2 - 1 -> 0번 인덱스부터 1일 시작
2 월요일 2 - 2 -> 1번 인덱스부터 1일 시작
3 화요일 2 - 3 -> 2번 인덱스부터 1일 시작
4 수요일 2 - 4 -> 3번 인덱스부터 1일 시작
5 목요일 2 - 5 -> 4번 인덱스부터 1일 시작
6 금요일 2 - 6 -> 5번 인덱스부터 1일 시작
7 토요일 2 - 7 -> 6번 인덱스부터 1일 시작
*/funccalculation(){letfirstDayOfMonth=cal.date(from:components)// 해당 수로 변환 > 1은 일요일 ~ 7은 토요일letfirstWeeakDay=cal.component(.weekday,from:firstDayOfMonth!)daysCountInMonth=cal.range(of:.day,in:.month,for:firstDayOfMonth!)!.count// 이 과정을 해주는 이유는// 예로 2020년 4월이라하면 4월 1일은 수요일, 수요일이 달의 첫 날이 됨// 수요일은 components의 4이기 때문에 collectionView에서 앞의 3일은 비울 필요가 있음// 따라서 index가 1일부터 시작할 수 있도록 해줌// 따라서 2-4해서 -2부터 시작하게 되어 정확히 3일후부터 1일이 시작weekdayAdding=2-firstWeeakDayself.yearMonthLbl.text=dateFormatter.string(from:firstDayOfMonth!)self.days.removeAll()fordayinweekdayAdding...daysCountInMonth{// 1보다 작은경우는 비워줘야함ifday<1{self.days.append("")}else{self.days.append(String(day))}}}@IBActionfuncprevBtnClicked(_sender:UIButton){components.month=components.month!-1self.calculation()self.collectionView.reloadData()}@IBActionfuncnextBtnClicked(_sender:UIButton){components.month=components.month!+1self.calculation()self.collectionView.reloadData()}}extensionWeekTableViewCell:UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout{funcnumberOfSections(incollectionView:UICollectionView)->Int{return2}funccollectionView(_collectionView:UICollectionView,numberOfItemsInSectionsection:Int)->Int{switchsection{case0:// 요일 수는 고정return7default:// 일의 수returnself.days.count}}funccollectionView(_collectionView:UICollectionView,cellForItemAtindexPath:IndexPath)->UICollectionViewCell{letcell=self.collectionView.dequeueReusableCell(withReuseIdentifier:"CalendarCell",for:indexPath)as!CalendarCollectionViewCellswitchindexPath.section{case0:// 요일cell.dateLbl.text=weeks[indexPath.row]default:// 일cell.dateLbl.text=days[indexPath.row]}ifindexPath.row%7==0{cell.dateLbl.textColor=.red}elseifindexPath.row%7==6{cell.dateLbl.textColor=.blue}else{cell.dateLbl.textColor=.white}returncell}}