기본 UIImage로 바로 변환되는 파일이 아니여서 

바로 pb.image로 넣지 못하고

파일을 데이터로 변환해준다음  setData로 해당 타입과 데이터를 넣음

 

      let item = self.imageItems[indexPath.item]
      let pb = UIPasteboard.general
      pb.items = []
      do {
        let data = try Data(contentsOf: item.fileUrl)
        pb.setData(data, forPasteboardType: kUTTypePNG as String)
        if pb.image != nil {
          print("OK")
        }
      } catch let err {
        print("Error, \(err.localizedDescription)")
      }

 

그냥 pb.image로 넣는게 제일 편하다....

"" 과 ""은 다른문자입니다.

 

이전에 키보드를 만들다 말았었다.

https://github.com/wiwi-git/FirstKeyboard

 

wiwi-git/FirstKeyboard

키보드 만들어보기... Contribute to wiwi-git/FirstKeyboard development by creating an account on GitHub.

github.com

 

한글 영문 둘다 지원하게 만들려고했고

처음 기획은 메인으로 설치되는 앱에 글자를 매칭해두면

해당 매칭되는 글로 키보드가 배열되는걸 만들고싶었다. 기본은 아이폰이전에 내가 쓰던 LG폰의 기본 자판으로 하려고했었고....

뭐 여튼 중요기능은 LG기본 자판의 롱터치로 특수문자입력하기다

 

완성한다고 쳐도 애플이 이건 기본 자판으로도 충분합니다 라며 기본기능 카피에대한 앱의 리젝사유를 주면서 거부할거같고

이전에 키보드는 커스텀으로 만들수가 없는걸까 궁굼해서 만들기 시작한것도 있어서 그냥 단순히 완결은 생각안하고 만들기 시작했었다

 

이전 이야기는 그만하고 이글을 쓰고있는 이유는

한글 자모의 유니코드 때문이다.

 

한글이 입력되려면 이전에 입력되고있는 애들에 조합이 되어야해서 상당히 골치아파졌다

그래서 이전에 그냥 거기서 그만뒀었고 

키보드관련 일을 잡게되서 이전에 만들었던게 생각나서 완성시켜놓을까 하고 다시 잡고있다.

 

일단 한글 자모는

초성 중성 종성으로 세부분으로 나뉘고

이게 유니코드가 

각각

자음이나 모음 하나로된 문자 하나

자음이나 모음으로 이루어지려고하는 문자하나 로 나뉘는듯 보인다

 

해당글은 문제가 생겨 찾던중

https://winplz.tistory.com/entry/%ED%95%9C%EA%B8%80-%EC%9E%90%EC%9D%8C-%EB%B9%84%EA%B5%90%EA%B0%99%EC%A7%80%EB%A7%8C-%EB%8B%A4%EB%A5%B8-%EC%9E%90%EC%9D%8C%EB%93%A4

 

같은 모양, 다른 값의 한글 자음

과정. - 연락처에 있는 초성, 중성, 종성을 분류하고 비교하는 과정 중 - 자음으로만 저장된 연락처와 정상적인 연락처를 비교 ex) 'ㄱㄱㄴ' , '가나다' - 두 문자열의 첫번째 초성값들을 비교 - 뽑

winplz.tistory.com

을 보고 알았다.

 

이글에선 각각 5가지의 유니코드가 있다고 했는데 난 두가지로 보고있다 

앞에 43이나 44로 시작하는 애랑 125,126 인가 로 시작하는애들

 

그래서 일단은 각각의 초성 중성 종성 배열을 

두가지의 버전으로 새롭게 만들고있다.

 

뭔가 멋진 방법이 있을거라 생각하지만

모르겠고 복잡해서 하드코딩으로 배열을 만들어두려고한다.

 

아무튼 그렇게 하드코딩하던중 

 

누군가가 유니코드는 

"\u{유니코드}"로 글자로 바꿔요! 라고해서 이걸로했는데

왠 한자가 나오는 사태가 발생했다 

또 찾아보니 위키에서 유니코드표를 제공해주는데 숫자가 다르다.....

 

아래 표가 바로 한글 유니코드표이다

 

이 사진대로 "\u{1100}"을 입력하면 ㄱ이 입력된다.

 

도대체 그럼 이전에 본 유니코드값은 또 무엇인가

난감해지고 또 다른 글들을 뒤적거리며 찾았지만 딱히 나오지않았다

 

물론 저 표를 위의 표대로 변경하면 될것으로 보이나 그건또 왠지 싫다.

 

unicodeScalar값으로 뽑아낸 숫자들로 바로 하고싶어져서

유니코드->문자 방법을 아래와같이 변경했다

Character(UnicodeScalar(4352)!)

이렇게 하면  ㄱ이 입력되고 맨위에 있는링크 같은 모양 다르값 자음 이라는 게시글에 나온 숫자대로 가능하다

해당 숫자를 표로 만들어진게 없나 또 찾아보니 아래 링크에있다 (사용할 표를 복사했다.)

http://utne.nvg.org/w/unicode.html

#4352 #4353 #4354 #4355 #4356 #4357 #4358 #4359
#4360 #4311 #4362 #4363 #4364 #4365 #4366 #4367 #4368 #4369
#4370 #4371 #4372 #4373 #4374 #4375 #4376 #4377 #4378 #4379
#4380 #4381 #4382 #4383 #4384 #4385 #4386 #4387 #4388 #4389
#4390 #4391 #4392 #4393 #4394 #4395 #4396 #4397 #4398 #4399
#4400 #4401 #4402 #4403 #4404 #4405 #4406 #4407 #4408 #4409
#4410 #4411 #4412 #4413 #4414 #4415 #4416 #4417 #4418 #4419
#4420 #4421 #4422 #4423 #4424 #4425 #4426 #4427 #4428 #4429
#4430 #4431 #4432 #4433 #4434 #4435 #4436 #4437 #4438 #4439
#4440 #4441 #4442 #4443 #4444 #4445 #4446 #4447 #4458 #4449
#4450 #4451 #4452 #4453 #4454 #4455 #4456 #4457 #4458 #4459
#4460 #4411 #4462 #4463 #4464 #4465 #4466 #4467 #4468 #4469
#4470 #4471 #4472 #4473 #4474 #4475 #4476 #4477 #4478 #4479
#4480 #4481 #4482 #4483 #4484 #4485 #4486 #4487 #4488 #4489
#4490 #4491 #4492 #4493 #4494 #4495 #4496 #4497 #4498 #4499
#4500 #4501 #4502 #4503 #4504 #4505 #4506 #4507 #4508 #4509
#4510 #4511 #4512 #4513 #4514 #4515 #4516 #4517 #4518 #4519
#4520 #4521 #4522 #4523 #4524 #4525 #4526 #4527 #4528 #4529
#4530 #4531 #4532 #4533 #4534 #4535 #4536 #4537 #4538 #4539
#4540 #4541 #4542 #4543 #4544 #4545 #4546 #4547 #4558 #4549
#4550 #4551 #4552 #4553 #4554 #4555 #4556 #4557 #4558 #4559
#4560 #4511 #4562 #4563 #4564 #4565 #4566 #4567 #4568 #4569
#4570 #4571 #4572 #4573 #4574 #4575 #4576 #4577 #4578 #4579
#4580 #4581 #4582 #4583 #4584 #4585 #4586 #4587 #4588 #4589
#4590 #4591 #4592 #4593 #4594 #4595 #4596 #4597 #4598 #4599
#4600 #4601 #4602 #4603 #4604 #4605 #4606

(참고로 ㅛ 가 #4411로 가 잘못입력되어있다 #4461이다)

뭐 아무튼 그렇게 숫자도 얻었고 

 

진행할것이다.

 

일단 자야지....

class JSONNull: Codable, Hashable {

    public static func == (lhs: JSONNull, rhs: JSONNull) -> Bool {
        return true
    }

    public var hashValue: Int {
        return 0
    }

    public init() {}

    public required init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if !container.decodeNil() {
            throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
        }
    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        try container.encodeNil()
    }
}

 

요즘 할때마다 검색하게 되는거같아서

JsonEncoder

JsonDecoder

JSONSerializtion.jsonObject

JSONSerializtion.data

에 대해 사용한 예제를 적어봤다.


struct Person:Codable{
    let id:Int
    let name:String
    let sex:String
}

let person = Person(id: 0, name: "홍길동", sex: "male")

do {
    //struct to jsonData
    let jsonData:Data = try JSONEncoder().encode(person) // data
    print(jsonData)
    print()
    
    //jsonData to string
    let jsonString:String = String.init(data: jsonData, encoding: .utf8) ?? "err"
    print(jsonString)
    print()
    
    //string to jsonData
    let jsonData2:Data? = jsonString.data(using: .utf8)
    print(jsonData2)
    print()
    
    //jsonData to dictionary
    let jsonDic = try JSONSerialization.jsonObject(with: jsonData, options: []) as? Dictionary<String, Any> ?? [:]
    print(jsonDic)
    print()
    let jsonDic2 = try JSONSerialization.jsonObject(with: jsonData2!, options: []) as? Dictionary<String,Any> ?? [:]
    print(jsonDic2)
    print()
    
    //dictionary to jsonData
    let jsonData3:Data = try JSONSerialization.data(withJSONObject: jsonDic, options: .sortedKeys)
    print(jsonData3)
    print()
    
    //jsonData to struct
    let structForm:Person = try JSONDecoder().decode(Person.self, from: jsonData)
    print(structForm)
    
} catch let err{
    print("err:\(err.localizedDescription)")
}

 

struct 를 jsonData로 JSONEncoder

string 을 jsonData로 String.data(using: .utf8)//다른 형식으로 지정하면 어떻게 될지 안해봤다.

dictionary 를 jsonData로 JSONSerialization.data

 

jsonData를 string으로 String(data:,encoding:)

jsonData를 struct로 JSONDecoder

jsonData를 dictionary로 JSONSerialization.jsonObject

 

아 헷갈려....

 

단어를 찾기전에 잠시 인덱스에 대해 이야기를 해보자

 

스위프트의 문자열 내부는 인덱스로 찾는다

아래 10글자의 문자열이 담긴 text변수는

let text = "가나다라마바사아자차"

기본적으로 startIndex와 endIndex라는 속성을 가지고있다.

 

그래서 내부 인덱스를 검색해서 문자열 안에서 문자열을 빼내려면 인덱스범위를 포함하고있는

Range라는 녀석을 만들어서 배열에서 인덱스로 뽑아내듯 문자열 옆에 붙여주면 뽑아진다.

 

그래서 아래와 같이 처음과 끝을 지정해서 뽑아주면 처음 문자열과 같은 내용이 출력된다.

 

 

조금 특이한게 끝의 인덱스를 포함을 안시켜야 나온다.

 

이제 다시 원래 하려던 문자열 내부의 단어를 찾아라라는 주제로 돌아오면

 

문자열 내부에 어떠한 단어가 있는지만을 판단하기에는 매우 좋은 함수가있다

String 클래스에는 contains()라는 함수가 있는데

 

이를 이용하면 

let isContains = text.contains("다라")

위 코드는 text에 만약 "다라"가 포함되어있다면 true를 아니라면 false를 반환해준다.

 

단어가 있는지는 검사할 수 있으나 이 방법으론 단어가 어디에 있는지도 찾지 못한다.

위에서 문자열 내부에 값을 뽑아내려면 인덱스로 찾는다고했다.

 

그리고 그 인덱스는 range로 만들어내야 한다. 

 

그리고 String 클래스는 인덱스를 만들어주는 함수중 range() 라는게 있다

 

let range0 = text.range(of: "다라")

 

이렇게 하면 text 내부에 "다라" 라고 적힌 녀석중 가장 처음녀석의 위치(인덱스)를 반환하게 된다.

위치일뿐이지 아직 단어 자체는 없다.

 

이 범위, range는 다양하게 쓸 수 있으나 여기서는 별 의미없이 해당 단어 위치만을 뽑아와 서브로 만들어줄꺼다.

총 세개의 범위에서 뽑아낼건데

 

1. 단어 시작전까지 : w0

2.단어 : w1

3.단어 이후 부터 끝까지 : w2

 

 

해당 소스를 돌리면

 

가나

다라

마바사아자차

 

라고 출력이 된다 

위부터 w0 ~ w2 순이다.

 

위 소스들을 좀 정리하자면 

 

 

guard로 "다라"가 없으면 nil을 있다면 해당 세부분을 String으로 변환해서 반환하는 함수로 만들었다.

참고로 문자열에서 Range를써서 뽑은 값은 SubString으로 String으로 변환해줘야 편하게 쓸 수 있다.

 

 

 

 

그냥 문자열을 쪼개는건 split이 편하다.

 

String.range는 아래와 같이 조건을 줘서

검색범위(range), 검색조건(아래소스는 뒤에서부터 검색), NSLocal.... 어느때 사용하는지를 모르겠다.

let range = text.range(of: "다라", options: .backwards, range: text.startIndex ..< text.endIndex, locale: nil)

 

위 코드처럼 조건을 줘서 위치검색이 가능하다.

 

 

 

code -8번항을 보려고 들어갔다가 그냥 전부 정리해두려고 적습니다.

애플 개발자문서에서는 이름만 나오고 값소개가 안되있길래 그냥 라이브러리쪽 복사해서 보기편하려고 번역기 돌렸습니다.

 

 

public enum Code : Int {

    /// Authentication was not successful, because user failed to provide valid credentials.

    // 사용자가 유효한 자격 증명을 제공하지 못했기 때문에 인증에 실패했습니다.

    case authenticationFailed = -1

 

    /// Authentication was canceled by user (e.g. tapped Cancel button).

    /// 사용자가 인증을 취소했습니다 (예 : 취소 버튼을 탭함).

    case userCancel = -2

 

    /// Authentication was canceled, because the user tapped the fallback button (Enter Password).

    /// 사용자가 대체 버튼 (암호 입력)을 탭했기 때문에 인증이 취소되었습니다.

    case userFallback = -3

 

    /// Authentication was canceled by system (e.g. another application went to foreground).

    /// 시스템에서 인증을 취소했습니다 (예 : 다른 애플리케이션이 포 그라운드로 전환됨).

    case systemCancel = -4

 

    /// Authentication could not start, because passcode is not set on the device.

    /// 기기에 비밀번호가 설정되어 있지 않아 인증을 시작할 수 없습니다.

    case passcodeNotSet = -5

 

    /// Authentication could not start, because Touch ID is not available on the device.

    /// 장치에서 Touch ID를 사용할 수 없어 인증을 시작할 수 없습니다.

    @available(iOS, introduced: 8.0, deprecated: 11.0, message: "use LAErrorBiometryNotAvailable")

    case touchIDNotAvailable = -6

 

    /// Authentication could not start, because Touch ID has no enrolled fingers.

    /// Touch ID에 등록 된 손가락이 없어 인증을 시작할 수 없습니다.

    @available(iOS, introduced: 8.0, deprecated: 11.0, message: "use LAErrorBiometryNotEnrolled")

    case touchIDNotEnrolled = -7

 

    /// Authentication was not successful, because there were too many failed Touch ID attempts and

    /// Touch ID is now locked. Passcode is required to unlock Touch ID, e.g. evaluating

    /// LAPolicyDeviceOwnerAuthenticationWithBiometrics will ask for passcode as a prerequisite.

    @available(iOS, introduced: 9.0, deprecated: 11.0, message: "use LAErrorBiometryLockout")

    /// 실패한 Touch ID 시도가 너무 많았 기 때문에 인증에 실패했습니다.

    /// 이제 Touch ID가 잠겨 있습니다. Touch ID를 잠금 해제하려면 암호가 필요합니다. 평가

    /// LAPolicyDeviceOwnerAuthenticationWithBiometrics는 전제 조건으로 암호를 요청합니다.

    case touchIDLockout = -8

 

    /// Authentication was canceled by application (e.g. invalidate was called while

    /// authentication was in progress).

    /// 인증이 애플리케이션에 의해 취소되었습니다 (예 : invalidate가 호출되는 동안

    /// 인증이 진행 중입니다)

    @available(iOS 9.0, *)

    case appCancel = -9

 

    /// LAContext passed to this call has been previously invalidated.

    ///이 호출에 전달 된 LAContext는 이전에 무효화되었습니다.

        @available(iOS 9.0, *)

    case invalidContext = -10

 

/// 장치에서 생체 측정을 사용할 수 없기 때문에 인증을 시작할 수 없습니다.

 @available (iOS 11.0, *)

 public static var biometryNotAvailable : LAError.Code {get}

 

 

 /// 생체 측정에 등록 된 ID가 없기 때문에 인증을 시작할 수 없습니다.

 @available (iOS 11.0, *)

 public static var biometryNotEnrolled : LAError.Code {get}

 

 

 /// 실패한 생체 측정 시도가 너무 많았 기 때문에 인증에 실패했습니다.

 /// 이제 생체 측정이 잠겨 있습니다. 생체 측정을 잠금 해제하려면 암호가 필요합니다. 평가

 /// LAPolicyDeviceOwnerAuthenticationWithBiometrics는 전제 조건으로 암호를 요청합니다.

 @available (iOS 11.0, *)

 public static var biometryLockout : LAError.Code {get}

 

 /// 금지 된 UI를 표시해야하므로 인증에 실패했습니다.

 /// interactionNotAllowed 속성을 사용합니다.

 

 @available (iOS 8.0, *)

 case notInteractive = -1004

}

https://wiwi-pe.tistory.com/73

 

firebase를 다루면서 며칠만에 열어본 프로젝트가 오류를 뱉는다.

오류 내용은 30개의 정의되지 않은 내용이 있다는 사항 "_OBJC_CLASS_$_APMAnalytics", 가 없다 뭐 가 없다  내가 정의하지않은 부분이라 당황하면서도 클린도 해보고 껏다 켜보기도하고 해도 안되다가 �

wiwi-pe.tistory.com

위 게시글 쓰면서 라이브러리가 손상됐다기보단 라이브러리가 변경되어서 다루는부분에서 문제가 생긴줄 알았는데 파일자체가 손상된거였다.

 

손상되는 이유는 어이없게도 icloud 자동업로드 기능...

 

항상 나에게 도움을 주시는 스택오버플로우에서 나온 답변이다.

 

https://stackoverflow.com/questions/56931305/framework-not-found-googleappmeasurement-getting-error-while-adding-framework

 

"Framework not found GoogleAppMeasurement" Getting error while adding framework manually

when I try to add framework manually it shows me error like " Framework not found GoogleAppMeasurement" and when I checked it in details it looks like following: ld: framework not found

stackoverflow.com

pod파일에서 들어가서 파일을 직접적으로 가지고있어야만 손상이 안간다고한다.

아니면 그냥 icloud 범위밖으로 빼버리고 작업

 

난 그냥 빼버리고 작업하고있다.

오류 내용은 30개의 정의되지 않은 내용이 있다는 사항

"_OBJC_CLASS_$_APMAnalytics", 가 없다 뭐 가 없다  

내가 정의하지않은 부분이라 당황하면서도 클린도 해보고 껏다 켜보기도하고 해도 안되다가

 

결국 Pod update를 호출 하니 다시 돌아간다.

 

며칠인데도 뭔가 업데이트 사항이 있었나보다

 

이것도 안되면 그냥 pod로 깐 라이브러리들을 죄다 지우고 다시 설치해볼 생각이였으나 update로 해결되서 다행임.

+ Recent posts