내가 프로그래머스 사이트의 서비스를 잘못알았다 swift가 없는게 아니라 해당문제에 없는거였다.

추가로 일일 도전과제를 재밌어 보이는 시스템이 있어서 이걸 목표로 전환해볼거다.

반응형

'iOS > 프로그래머스 - 코딩테스트 문제' 카테고리의 다른 글

4. day3 연산, day4 연산 조건문  (0) 2024.06.25
3. day2 출력,연산  (0) 2024.06.24
2. day1 출력  (0) 2024.06.24
1. [PCCE 기출문제] 1번 / 출력  (0) 2024.06.24
0. 시작  (0) 2024.06.24

swift를 연습하려고 문제를 켜봤지만 언어 선택에 swift가 없다!

이 처참함에 눈물을 금치 못하고 일단 있는 언어로 한번 하고 다시 swift로 해보는식으로 간다

 

1번 / 출력

빈칸 채우기 문제로 그냥 출력문에 들어갈 값을 넣는 문제 ~

출력예시:

Spring is beginning
13
310
        String msg =  
        int val1 =  
        String val2 =  

        System.out.println(msg);
        System.out.println(val1 + 10);
        System.out.println(val2 + "10");

 

swift > 

let msg: String = "Spring is beginning"
let val1: Int = 3
let val2: String = "3"

print(msg)
print(val1 + 10)
print(val2 + "10")
반응형

'iOS > 프로그래머스 - 코딩테스트 문제' 카테고리의 다른 글

4. day3 연산, day4 연산 조건문  (0) 2024.06.25
3. day2 출력,연산  (0) 2024.06.24
2. day1 출력  (0) 2024.06.24
1-1. 잡담  (0) 2024.06.24
0. 시작  (0) 2024.06.24

길어진 백수생활에 이제 슬슬 뭐라도 해야할듯하여 다시 코딩을 좀 해야겠다

요새 모바일은 swift를 안쓴지도 오래되서 swift를 연습할겸 프로그래머스 사이트에 있는 코딩 테스트문제들을 swift 작성 해볼까한다.

우선 swift 언어 문법이 기억이 잘 안나서 lv0부터 시작~

 

떨어지는 통장잔고에 취직 해야하긴하는데라 생각이 들어도 왜이리 하기 싫을까?

 

반응형

'iOS > 프로그래머스 - 코딩테스트 문제' 카테고리의 다른 글

4. day3 연산, day4 연산 조건문  (0) 2024.06.25
3. day2 출력,연산  (0) 2024.06.24
2. day1 출력  (0) 2024.06.24
1-1. 잡담  (0) 2024.06.24
1. [PCCE 기출문제] 1번 / 출력  (0) 2024.06.24

뱃지카운트 자체는 서버에서 내려준대로 해야되서 난감했는데 

따로 설정가능한 기능이있었다

      application.applicationIconBadgeNumber = 0

이거 인데 설정해줬더니

디플리케이션 경고가 뜬다.

해서 권장해주는 방법 대로 변경

  if #available(iOS 16.0, *) {
      UNUserNotificationCenter.current().setBadgeCount(0) { _ in }
    } else {
      application.applicationIconBadgeNumber = 0
    }

 

17부터 디플인데 왜 16으로 해주라는건지는 모르겠다.

반응형

스위프트3을 접하고 몇 년이 지나고 ... 정들었던 UIkit의 자리를 swiftUI가 점점 뺏고 있는와중

나도 swiftUI를 공부해야겠다 싶어 시작한다.

uikit의 내용을 swiftUI와 대조하며 파악해보려한다.

이글은 내 개인의 학습하면서 쓰는 글이라 틀린 정보가 있을 수 있다.

UIWindow -> windowGroup

WindowGroup {
    ContentView()
}


UILabel ->

Text("hello world")


UIButton ->

init(action: @escaping () - Void, @ViewBuilder label: () -> Label)

var body: some View {
    Button {
        print("Tap")
    } label: {
       Text("Tap me!")
    }
}


UITextField ->

init(LocalizedStringKey, text: Binding<String>)

@State private var textValue: String = ""

var body: some View {
    TextField("PlaceHolder...", text: $textValue)
}


UIImageView ->

init(_ name: String, bundle: Bundle? = nil)

var body: some View {
    Image(systemName: "star") // systemImage
}


UITableView ->

init(@ViewBuilder content: () -> Content)

var body: some View {
    List {
        ForEach(0 ..< 10, id: \.self) { i in
            Text("item \(i)")
        }
    }
}


UICollectionView ->

ScrollView + 
init(columns: [GridItem], alignment: HorizontalAlignment = .center, spacing: CGFloat? = nil, pinnedViews: PinnedScrollableViews = .init(), @ViewBuilder content: () -> Content)

let layout: [GridItem] = [
    GridItem(.flexible(minimum: 40, maximum: 100)),
    GridItem(.flexible(minimum: 40, maximum: 100)),
]

var body: some View {
    VStack(alignment: .center) {
        ScrollView(.vertical) {
            LazyVGrid(columns: layout) {
                ForEach(0 ..< 100, id: \.self) { index in
                    Text("item \(index)")
                        .frame(height: 30)
                }
            }
        }
        .frame(maxHeight: .infinity)
        .background(.yellow)

        ScrollView(.horizontal) {
            LazyHGrid(rows: layout) {
                ForEach(0 ..< 100, id: \.self) { index in
                    Text("item \(index)")
                        .frame(height: 30)
                }
            }
        }
        .frame(maxHeight: .infinity)
    }
}


UIAlertController style.alert->

View().alert(isPresented: Binding<Bool>, content: () -> Alert) -> some View
View().alert<A>(_ titleKey: LocalizedStringKey, isPresented: Binding<Bool>, @ViewBuilder actions: () -> A) -> some View where A : View

@State private var showingAlert = false

var body: some View {
    Button(action: {
        self.showingAlert = true
    }) {
        Text("Show Alert")
    }
    .alert("title", isPresented: $showingAlert) {
        Button("OK", role: .cancel) {
            print("tap ok")
        }
        Button("NO", role: .destructive) {
            print("tap no")
        }
    }
    /*
    .alert(isPresented: $showingAlert) {
        Alert(title: Text("Title"), message: Text("This is a alert message"), dismissButton: .default(Text("Dismiss")))
    }
    */
}


UIAlertController style.actionSheet

View().actionSheet(isPresented: Binding<Bool>, content: () -> ActionSheet) -> some View

@State var showActionSheet = false
var body: some View {
    Button("sheet") {
        showActionSheet = true
    }
    .buttonStyle(.bordered)

    .actionSheet(isPresented: $showActionSheet) {
        ActionSheet(title: Text("Title"), buttons: [
            ActionSheet.Button.default(Text("text"), action: {
                print("tap text")
            }),
            .default(Text("default")),
            .cancel()
        ])
    }
}


UISwitch ->

init(isOn: Binding<Bool>, @ViewBuilder label: () -> Label)

@State private var toggleValue: Bool = false

var body: some View {
    Toggle(isOn: $toggleValue) {
        Text("토글 텍스트")
    }
}


UIPickerView + UISegmenetedControl( style segmented ) ->

init(_ titleKey: LocalizedStringKey, selection: Binding<SelectionValue>, @ViewBuilder content: () -> Content)
init(selection: Binding<SelectionValue>, label: Label, @ViewBuilder content: () -> Content)

@State var select = "Apple"

var fruits = ["Apple", "Apricot", "Banana", "Pear"]

var body: some View {
    VStack(alignment: .leading) {
        Picker("picker 타이틀", selection: $select) {
            ForEach(fruits, id: \.self) { fruit in
                Text(fruit)
            }
        }
        .pickerStyle(.inline)
        .background(.red)

        Picker(selection: $select, label: Text("Fruit")) {
            ForEach(fruits, id: \.self) {
                Text($0)
            }
        }
        .background(.green)

        NavigationView {
            Picker(selection: $select, label: Text("Fruit")) {
                ForEach(fruits, id: \.self) {
                    Text($0)
                }
            }
            .pickerStyle(.navigationLink)
            .background(Color.mint)
        }

        Picker("title", selection: $select) {
            ForEach(fruits, id: \.self) { fruit in
                Text(fruit)
            }
        }
        .pickerStyle(.segmented)
        .background(Color.orange)

    }.padding()
}


UIViewcontroller().present ->

View().sheet<Content>(isPresented: Binding<Bool>, onDismiss: (() -> Void)? = nil, @ViewBuilder content: @escaping () -> Content) -> some View where Content : View
View().fullScreenCover<Content>(isPresented: Binding<Bool>, onDismiss: (() -> Void)? = nil, @ViewBuilder content: @escaping () -> Content) -> some View where Content : View

struct ModalView: View {
    @Binding var isShow: Bool
    var body: some View {
        ZStack {
            Color.yellow.ignoresSafeArea()
            VStack {
                Button("close") {
                    isShow = false
                }
                .frame(height: 50)

                Text("hello world")
            }
            .background(.green)
        }
    }
}

struct TestPresent: View {
    @State private var fullShow = false
    @State private var modalShow = false

    var body: some View {

        VStack {
            Button("Present0") {
                self.fullShow = true
            }
            .padding()

            Button("Present1") {
                self.modalShow = true
            }
            .padding()

            .sheet(isPresented: $modalShow) {
                ModalView(isShow: $modalShow)
            } // 아직도 애네들이 어떻게 붙어서 동작하는지 이해가 안간다.
        }
        .fullScreenCover(isPresented: $fullShow) {
            ModalView(isShow: $fullShow)
        } // 도대체 넌 어떻게 붙어서 동작하는거니 안에 View 아무곳에 붙여도 동작함
    }
}

\

반응형

기존 pod을 이용한 프로젝트에서 tuist와 spm을 이용해 모듈화를 하고있다 

서비스 분리 자체를 완전히 하지는 않았지만 common과 main 두가지 정도로 분리하여 나중에 서비스를 추가할때 하나씩 늘려가는식으로 진행하고 좀 더 시간이 많이 남을때 main에서의 서비스를 분리하는식으로 진행하려고 했었다

그렇게 진행한 부분을 업데이트를 하려고 업로드를 시켜보니...

Asset validation failed

Missing App Icon. The bundle doesn’t contain an iMessage app icon. iMessage app icons must be 54x40 pixels in .png format. (ID: 3f448328-3fc2-4036-be0e-7d0eacf9ca41)

주루루룩.

Asset validation failed 가 뜨면서 올라가지 않는다.

achive까진 됐는데 업로드가 안된다.

이전까지 멀쩡히 올라가던 앱이라 이미지가 부족할리도 없다

해당 사이즈는 아이콘으로 요구하지도 않는 이미지다

왜 저런 에러가 나왔는지도 의문이다

 

tuist로 옴기면서 글은 안남겼지만 가장 많이 나는 오류에 대한 해답은 tuist 프로젝트 구성 정의에 대한 문제였다

이번에도 문제가 있겠거늘 하고 검색도 해보고 여러가지도 해봤지만 영 안나왔고 결국 찾아낸 문제는

기존 프로젝트의 Build Settings의 Asset Catalog Compiler - Options의 값이 다르게 나온다.

tuist가 생성해주는 기본값과 다른가보다

Target을 생성할때

setttings를 항목이 있는데 이를 다시 기존 프로젝트 설정과 동일하게 적어주고

( 참고로 Target -> Build Settings 에서 원하는 항목을 클릭하면 우측 메뉴에서 Declaration 라고 된 부분에서 키값이 나온다. )

tuist generaral > 이후 혹시 모르니 빌드 클린 > achive > upload

완료!

 

tuist 로 생성되는 기본값이 너무나 적다 힘들다

 

반응형

다른 라이브러리 문제가 생겨 lock파일을 버리고 새로 업데이트좀 했더니

구글 signin라이브러리가 에러를 내뱉는다.

signIn(with) 이 없단다

이 무슨 개소린가 하고 공식 문서를 살펴보지만 안보인다 swiftUI 문서가 생기기전에 만들어놓은 소스들이라 그런가 싶다

공식문서에서 말해주는데로 다시 짜본다

 

https://developers.google.com/identity/sign-in/ios/reference/Classes/GIDSignIn#-signinwithpresentingviewcontroller:hint:additionalscopes:completion:

func signIn(withPresenting presentingViewController: UIViewController, hint: String?, additionalScopes: [String]?) async throws -> GIDSignInResult

 

이게
GIDSignIn.sharedInstance.signIn(with: config, presenting: vc) { user, error in }

 

config설정과 presentingvc설정을 해줘야한다.

config를 넣어서 하는 함수는 보이지 않는다

sharedInstance.configuration 항목이 셋업도 할 수 있는거 같아 여기에 넣어줬다

GIDSignIn.sharedInstance.configuration = .init(clientID: clientID)

GIDSignIn.sharedInstance.signIn(withPresenting: vc){ result, error in

//에러처리 로그인 실패 처리

// result는 GIDSignInReuslt 라 기존에 idToken을 뽑아내려면 좀더 들어가야있더라

let idToken = result.user.idToken.tokenString

// idToken이 기존에는 그냥 String으로 줬는데 IDToken이라는게 또 따로있더라

// 로그인 성공 처리

}
반응형

cocoapod으로 Snapkit 5.6.0 버전을 다운받아 사용중이였는데

작업 pc변경이후 계속 모듈을 찾을 수 없다는 빌드 에러가 떠서 곤란하게되었다.

실제로 다운받은 파일을 확인해보면 pod으로 받은 다른 파일들은 확인되나 Snapkit만이 폴더만 생성되고 라이브러리의 정보만 담은 파일이 있을뿐 실 코드들이 없다.

이 문제때문에 우선적으로 많이 하는 해결책으로

clean build folder를 돌려보았고.

pod로 받는 파일들을 새롭게 받아보아보았고

DerivedData 폴더를 비워보았으나 역시나 되지 않는다.

 

이런 문제로 사용한 해결방법 아래와같다

1. pod repo update ( podsepc 업데이트 ) 

2. clean build folder ( 기본 단축키 cmd + shift + k )

3. Podfile.lock 삭제

4. Pods폴더 삭제

5. DerivedData 폴더 내부 비움 ( 설정된 DerivedData 폴더의 경로는 xcode의 Preferences... -> Locations 에서 Derived Data 항목으로 알 수 있다.

6. pod install

이제 다시 Pods의 Snapkit 폴더를 찾아보면 무사히 코드들이 다운받아졌음을 알 수 있다

 

 

반응형

+ Recent posts