iPad에서 UIAlertController의 actionSheet사용시 발생하는 오류

오류 메세지

'Your application has presented a UIAlertController (<UIAlertController: xxx>) of style UIAlertControllerStyleActionSheet.
The modalPresentationStyle of a UIAlertController with this style is UIModalPresentationPopover.
You must provide location information for this popover through the alert controller's popoverPresentationController.
You must provide either a sourceView and sourceRect or a barButtonItem.
If this information is not known when you present the alert controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation.'

영어를 해석해보면 actionSheet의 모달스타일은 UIModalPresentationPopover라고 설명을 해주면서 UIModalPresentationPopover을 사용 할 때는 barButtonItem또는 팝업에 대한 위치를 설정해줘야 된다고 명시 되어 있습니다.

해결 방법

해결방법은 만약 앱이 iPhone과 iPad를 같이 지워하는 앱이라면 디바이스에 따라 분개해주고 iPad만 사용 가능하다면 따로 설정은 안 해주셔도 됩니다.

  • 위치를 정해주는 방법

    if UIDevice.current.userInterfaceIdiom == .pad { //디바이스 타입이 iPad일때
      if let popoverController = alertController.popoverPresentationController {
          // ActionSheet가 표현되는 위치를 저장해줍니다.
          popoverController.sourceView = self.view
          popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
          popoverController.permittedArrowDirections = []
          self.present(alertController, animated: true, completion: nil)
      }
    } else {
      self.present(alertController, animated: true, completion: nil)
    }
    
  • UIBarButtonItem에 추가해주는 방법

    if UIDevice.current.userInterfaceIdiom == .pad { //디바이스 타입이 iPad일때
      if let popoverController = alertController.popoverPresentationController {
          // ActionSheet가 표현되는 위치를 저장해줍니다.
          popoverController.barButtonItem = sender as? UIBarButtonItem에
          self.present(alertController, animated: true, completion: nil)
      }
    } else {
      self.present(alertController, animated: true, completion: nil)
    }
    

마치며

당연히 문제 없이 되는 줄 알았는데 뜻밖에 오류를 확인하고 당황했었습니다. 보통은 iPhone 작업만 하다보니 확인하지 못했던 문제였습니다. 그리고 뿜어내는 오류를 일단 해석하고 이해하는게 중요하다는걸 또 깨달았습니다.감사합니다. 틀린점이 물어보실게 있다면 댓글로 남겨 주시면 적극 반영하겠습니다.





안녕하세요. 개발자 myoung입니다.
Custom FrameWork 만들어 사용할때 클래스를 찾을 수 없을 때 해결 방안입니다.
Custom FrameWork를 만들어서 빌드후 프로젝트에 추가를 하게되면 시뮬레이터에서 돌렸을 때는 실제 프로젝트에서 시뮬레이터에서만 사용이 가능하고, 실제기기에서 돌렸을 때는 실제기기로 빌드를 할때만 사용이 가능합니다.

BUild Phases에 Run Script를 추가해준 다음 추가해 주시면 됩니다.


######################
# Options
######################

REVEAL_ARCHIVE_IN_FINDER=false

FRAMEWORK_NAME="${PROJECT_NAME}"

SIMULATOR_LIBRARY_PATH="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${FRAMEWORK_NAME}.framework"

DEVICE_LIBRARY_PATH="${BUILD_DIR}/${CONFIGURATION}-iphoneos/${FRAMEWORK_NAME}.framework"

UNIVERSAL_LIBRARY_DIR="${BUILD_DIR}/${CONFIGURATION}-iphoneuniversal"

FRAMEWORK="${UNIVERSAL_LIBRARY_DIR}/${FRAMEWORK_NAME}.framework"


######################
# Build Frameworks
######################

xcodebuild -workspace ${PROJECT_NAME}.xcworkspace -scheme ${PROJECT_NAME} -sdk iphonesimulator -configuration ${CONFIGURATION} clean build CONFIGURATION_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-iphonesimulator 2>&1

xcodebuild -workspace ${PROJECT_NAME}.xcworkspace -scheme ${PROJECT_NAME} -sdk iphoneos -configuration ${CONFIGURATION} clean build CONFIGURATION_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-iphoneos 2>&1

######################
# Create directory for universal
######################

rm -rf "${UNIVERSAL_LIBRARY_DIR}"

mkdir "${UNIVERSAL_LIBRARY_DIR}"

mkdir "${FRAMEWORK}"


######################
# Copy files Framework
######################

cp -r "${DEVICE_LIBRARY_PATH}/." "${FRAMEWORK}"


######################
# Make an universal binary
######################

lipo "${SIMULATOR_LIBRARY_PATH}/${FRAMEWORK_NAME}" "${DEVICE_LIBRARY_PATH}/${FRAMEWORK_NAME}" -create -output "${FRAMEWORK}/${FRAMEWORK_NAME}" | echo

# For Swift framework, Swiftmodule needs to be copied in the universal framework
if [ -d "${SIMULATOR_LIBRARY_PATH}/Modules/${FRAMEWORK_NAME}.swiftmodule/" ]; then
cp -f ${SIMULATOR_LIBRARY_PATH}/Modules/${FRAMEWORK_NAME}.swiftmodule/* "${FRAMEWORK}/Modules/${FRAMEWORK_NAME}.swiftmodule/" | echo
                                                                      fi

                                                                      if [ -d "${DEVICE_LIBRARY_PATH}/Modules/${FRAMEWORK_NAME}.swiftmodule/" ]; then
                                                                      cp -f ${DEVICE_LIBRARY_PATH}/Modules/${FRAMEWORK_NAME}.swiftmodule/* "${FRAMEWORK}/Modules/${FRAMEWORK_NAME}.swiftmodule/" | echo
                                                                      fi

                                                                      ######################
                                                                      # On Release, copy the result to release directory
                                                                      ######################
                                                                      OUTPUT_DIR="${PROJECT_DIR}/Output/${FRAMEWORK_NAME}-${CONFIGURATION}-iphoneuniversal/"

                                                                      rm -rf "$OUTPUT_DIR"
                                                                      mkdir -p "$OUTPUT_DIR"

                                                                      cp -r "${FRAMEWORK}" "$OUTPUT_DIR"

                                                                      if [ ${REVEAL_ARCHIVE_IN_FINDER} = true ]; then
                                                                      open "${OUTPUT_DIR}/"
                                                                      fi

이렇게 되면 Custom Framework가 universal 형태로 만들어져서 프로젝트에 적용 하면 시뮬레이터나 실제기기에서도 상관없이 사용이 가능합니다.





안녕하세요. 개발자 myoung입니다.

개발을 완료 한 후 정말 역사적으로 앱스토어에 앱을 올릴려고 하는데 ENABLE_BITCODE 오류가 나서 당황할때가 있습니다.

그냥 개발을 할때는 문제가 없는데 말입니다.ㅠㅠ 이럴때는 당황하시지 말고

'Build Settings'에 있는 'Enable Bitcode'를 YES로 바꿔주시면 됩니다.


반대로 이런 오류가 난다면

You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64...

'Enable Bitcode' 옵션을 NO로 해주시면 됩니다.


BitCode 란?

Bitcode is an intermediate representation of a compiled program. Apps you upload to iTunes Connect that contain bitcode will be compiled and linked on the store. Including bitcode will allow Apple to re-optimize your app binary in the future without the need to submit a new version of your app to the store. For iOS apps, bitcode is the default, but optional. For watchOS and tvOS apps, bitcode is required. If you provide bitcode, all apps and frameworks in the app bundle (all targets in the project) need to include bitcode


비트 코드는 컴파일  프로그램의 중간 표현입니다비트 코드를 포함하면 아이튠즈 커넥트에 업로드앱은 컴파일 저장소에 연결됩니다비트 코드를 포함하면 애플 스토어에 앱의  버전을 제출할 필요 없이 미래에  바이너리를 다시 최적화할  있고iOS 앱의 경우 비트 코드 옵션은 선택 사항이고, watchOS  tvOS 앱의 비트 코드가 필수로 적용되어야 한다.  - iOS Developer Library



  1. 1466891376 2016.06.26 06:49

    제 블로그도 놀러오세요~



안녕하세요 개발자 myoung 입니다. Swift 기준으로 설명을 하겠습니다.


URL nil 오류 나는 문제에 대해서 해결 방안을 알아보겠습니다.

보통 URL을 정의 할때는 이렇게 정의를 합니다.

1
2
let urlPath: String = "www.naver.com"
let url: NSURL = NSURL(string: urlPath)!
cs

물론 URL 자체가 비어 있어서 nil오류가 나는 경우도 있지만 주소 자체에 한글이 포함된 경우 nil 오류가 나는 경우가 있습니다.

그런경우 해결 방법은

1
2
3
4
let str_temp = "http://devsc.tistory.com/admin/entry/post/한글"
let str_url = str_temp.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
 
let url: NSURL = NSURL(string: str_url)!
cs

이런식으로 String URLQueryAllowedCharacterSet을 통해 인코딩을 하면 간단하게 해결됩니다.


궁금한점이나 오류가 있으면 댓글을 달아주세요 :)



+ Recent posts