List of iOS font names - ios

If you look at this nice list of preinstalled fonts that Apple compiled, you'll notice 2 things missing.
iOS and macOS System Fonts
Visual representation of the font. (would be nice, Apple)
More importantly, the actual font name that you need to use.
As an example, in Xcode/Swift if I want to use Apple SD Gothic Neo Heavy I can't use:
contactNameLabel.font = UIFont(name: "Apple SD Gothic Neo Heavy", size: 13)
I would have to use:
contactNameLabel.font = UIFont(name: "AppleSDGothicNeo-Heavy", size: 13)
Just wanted to see if anyone has a link that shows these names, or otherwise, what the best practice is for easily finding them.
I apologize that my question is not strictly code related. This is my first Stack Overflow question, and I wish it could be more technical, but I think the answer to this could be helpful to people, including myself.
Thanks all.

You can print out all fonts and families available using this code:
for family in UIFont.familyNames {
print("family:", family)
for font in UIFont.fontNames(forFamilyName: family) {
print("font:", font)
}
}

By modifying the print statements using the for loops in the other answers, I made an extension of UIFont that allows you to access the font name string using the rawValue of an enum.
let myNewFont = UIFont(name: UIFont.nameOf.Thonburi_Light.rawValue, size: 30)!
extension UIFont {
public enum nameOf: String {
case Copperplate_Light = "Copperplate-Light"
case Copperplate = "Copperplate"
case Copperplate_Bold = "Copperplate-Bold"
case AppleSDGothicNeo_Thin = "AppleSDGothicNeo-Thin"
case AppleSDGothicNeo_Light = "AppleSDGothicNeo-Light"
case AppleSDGothicNeo_Regular = "AppleSDGothicNeo-Regular"
case AppleSDGothicNeo_Bold = "AppleSDGothicNeo-Bold"
case AppleSDGothicNeo_SemiBold = "AppleSDGothicNeo-SemiBold"
case AppleSDGothicNeo_UltraLight = "AppleSDGothicNeo-UltraLight"
case AppleSDGothicNeo_Medium = "AppleSDGothicNeo-Medium"
case Thonburi = "Thonburi"
case Thonburi_Light = "Thonburi-Light"
case Thonburi_Bold = "Thonburi-Bold"
case GillSans_Italic = "GillSans-Italic"
case GillSans_SemiBold = "GillSans-SemiBold"
case GillSans_UltraBold = "GillSans-UltraBold"
case GillSans_Light = "GillSans-Light"
case GillSans_Bold = "GillSans-Bold"
case GillSans = "GillSans"
case GillSans_SemiBoldItalic = "GillSans-SemiBoldItalic"
case GillSans_BoldItalic = "GillSans-BoldItalic"
case GillSans_LightItalic = "GillSans-LightItalic"
case MarkerFelt_Thin = "MarkerFelt-Thin"
case MarkerFelt_Wide = "MarkerFelt-Wide"
case HiraMaruProN_W4 = "HiraMaruProN-W4"
case CourierNewPS_ItalicMT = "CourierNewPS-ItalicMT"
case CourierNewPSMT = "CourierNewPSMT"
case CourierNewPS_BoldItalicMT = "CourierNewPS-BoldItalicMT"
case CourierNewPS_BoldMT = "CourierNewPS-BoldMT"
case KohinoorTelugu_Regular = "KohinoorTelugu-Regular"
case KohinoorTelugu_Medium = "KohinoorTelugu-Medium"
case KohinoorTelugu_Light = "KohinoorTelugu-Light"
case AvenirNextCondensed_Heavy = "AvenirNextCondensed-Heavy"
case AvenirNextCondensed_MediumItalic = "AvenirNextCondensed-MediumItalic"
case AvenirNextCondensed_Regular = "AvenirNextCondensed-Regular"
case AvenirNextCondensed_UltraLightItalic = "AvenirNextCondensed-UltraLightItalic"
case AvenirNextCondensed_Medium = "AvenirNextCondensed-Medium"
case AvenirNextCondensed_HeavyItalic = "AvenirNextCondensed-HeavyItalic"
case AvenirNextCondensed_DemiBoldItalic = "AvenirNextCondensed-DemiBoldItalic"
case AvenirNextCondensed_Bold = "AvenirNextCondensed-Bold"
case AvenirNextCondensed_DemiBold = "AvenirNextCondensed-DemiBold"
case AvenirNextCondensed_BoldItalic = "AvenirNextCondensed-BoldItalic"
case AvenirNextCondensed_Italic = "AvenirNextCondensed-Italic"
case AvenirNextCondensed_UltraLight = "AvenirNextCondensed-UltraLight"
case TamilSangamMN = "TamilSangamMN"
case TamilSangamMN_Bold = "TamilSangamMN-Bold"
case HelveticaNeue_UltraLightItalic = "HelveticaNeue-UltraLightItalic"
case HelveticaNeue_Medium = "HelveticaNeue-Medium"
case HelveticaNeue_MediumItalic = "HelveticaNeue-MediumItalic"
case HelveticaNeue_UltraLight = "HelveticaNeue-UltraLight"
case HelveticaNeue_Italic = "HelveticaNeue-Italic"
case HelveticaNeue_Light = "HelveticaNeue-Light"
case HelveticaNeue_ThinItalic = "HelveticaNeue-ThinItalic"
case HelveticaNeue_LightItalic = "HelveticaNeue-LightItalic"
case HelveticaNeue_Bold = "HelveticaNeue-Bold"
case HelveticaNeue_Thin = "HelveticaNeue-Thin"
case HelveticaNeue_CondensedBlack = "HelveticaNeue-CondensedBlack"
case HelveticaNeue = "HelveticaNeue"
case HelveticaNeue_CondensedBold = "HelveticaNeue-CondensedBold"
case HelveticaNeue_BoldItalic = "HelveticaNeue-BoldItalic"
case TimesNewRomanPS_ItalicMT = "TimesNewRomanPS-ItalicMT"
case TimesNewRomanPS_BoldItalicMT = "TimesNewRomanPS-BoldItalicMT"
case TimesNewRomanPS_BoldMT = "TimesNewRomanPS-BoldMT"
case TimesNewRomanPSMT = "TimesNewRomanPSMT"
case Georgia_BoldItalic = "Georgia-BoldItalic"
case Georgia_Italic = "Georgia-Italic"
case Georgia = "Georgia"
case Georgia_Bold = "Georgia-Bold"
case SinhalaSangamMN_Bold = "SinhalaSangamMN-Bold"
case SinhalaSangamMN = "SinhalaSangamMN"
case ArialRoundedMTBold = "ArialRoundedMTBold"
case Kailasa_Bold = "Kailasa-Bold"
case Kailasa = "Kailasa"
case KohinoorDevanagari_Regular = "KohinoorDevanagari-Regular"
case KohinoorDevanagari_Light = "KohinoorDevanagari-Light"
case KohinoorDevanagari_Semibold = "KohinoorDevanagari-Semibold"
case KohinoorBangla_Regular = "KohinoorBangla-Regular"
case KohinoorBangla_Semibold = "KohinoorBangla-Semibold"
case KohinoorBangla_Light = "KohinoorBangla-Light"
case NotoSansOriya_Bold = "NotoSansOriya-Bold"
case NotoSansOriya = "NotoSansOriya"
case ChalkboardSE_Bold = "ChalkboardSE-Bold"
case ChalkboardSE_Light = "ChalkboardSE-Light"
case ChalkboardSE_Regular = "ChalkboardSE-Regular"
case NotoSansKannada_Bold = "NotoSansKannada-Bold"
case NotoSansKannada_Light = "NotoSansKannada-Light"
case NotoSansKannada_Regular = "NotoSansKannada-Regular"
case AppleColorEmoji = "AppleColorEmoji"
case PingFangTC_Regular = "PingFangTC-Regular"
case PingFangTC_Thin = "PingFangTC-Thin"
case PingFangTC_Medium = "PingFangTC-Medium"
case PingFangTC_Semibold = "PingFangTC-Semibold"
case PingFangTC_Light = "PingFangTC-Light"
case PingFangTC_Ultralight = "PingFangTC-Ultralight"
case GeezaPro_Bold = "GeezaPro-Bold"
case GeezaPro = "GeezaPro"
case DamascusBold = "DamascusBold"
case DamascusLight = "DamascusLight"
case Damascus = "Damascus"
case DamascusMedium = "DamascusMedium"
case DamascusSemiBold = "DamascusSemiBold"
case Noteworthy_Bold = "Noteworthy-Bold"
case Noteworthy_Light = "Noteworthy-Light"
case Avenir_Oblique = "Avenir-Oblique"
case Avenir_HeavyOblique = "Avenir-HeavyOblique"
case Avenir_Heavy = "Avenir-Heavy"
case Avenir_BlackOblique = "Avenir-BlackOblique"
case Avenir_BookOblique = "Avenir-BookOblique"
case Avenir_Roman = "Avenir-Roman"
case Avenir_Medium = "Avenir-Medium"
case Avenir_Black = "Avenir-Black"
case Avenir_Light = "Avenir-Light"
case Avenir_MediumOblique = "Avenir-MediumOblique"
case Avenir_Book = "Avenir-Book"
case Avenir_LightOblique = "Avenir-LightOblique"
case KohinoorGujarati_Light = "KohinoorGujarati-Light"
case KohinoorGujarati_Bold = "KohinoorGujarati-Bold"
case KohinoorGujarati_Regular = "KohinoorGujarati-Regular"
case DiwanMishafi = "DiwanMishafi"
case AcademyEngravedLetPlain = "AcademyEngravedLetPlain"
case PartyLetPlain = "PartyLetPlain"
case Futura_CondensedExtraBold = "Futura-CondensedExtraBold"
case Futura_Medium = "Futura-Medium"
case Futura_Bold = "Futura-Bold"
case Futura_CondensedMedium = "Futura-CondensedMedium"
case Futura_MediumItalic = "Futura-MediumItalic"
case ArialHebrew_Bold = "ArialHebrew-Bold"
case ArialHebrew_Light = "ArialHebrew-Light"
case ArialHebrew = "ArialHebrew"
case Farah = "Farah"
case MuktaMahee_Light = "MuktaMahee-Light"
case MuktaMahee_Bold = "MuktaMahee-Bold"
case MuktaMahee_Regular = "MuktaMahee-Regular"
case NotoSansMyanmar_Regular = "NotoSansMyanmar-Regular"
case NotoSansMyanmar_Bold = "NotoSansMyanmar-Bold"
case NotoSansMyanmar_Light = "NotoSansMyanmar-Light"
case Arial_BoldMT = "Arial-BoldMT"
case Arial_BoldItalicMT = "Arial-BoldItalicMT"
case Arial_ItalicMT = "Arial-ItalicMT"
case ArialMT = "ArialMT"
case Chalkduster = "Chalkduster"
case Kefa_Regular = "Kefa-Regular"
case HoeflerText_Italic = "HoeflerText-Italic"
case HoeflerText_Black = "HoeflerText-Black"
case HoeflerText_Regular = "HoeflerText-Regular"
case HoeflerText_BlackItalic = "HoeflerText-BlackItalic"
case Optima_ExtraBlack = "Optima-ExtraBlack"
case Optima_BoldItalic = "Optima-BoldItalic"
case Optima_Italic = "Optima-Italic"
case Optima_Regular = "Optima-Regular"
case Optima_Bold = "Optima-Bold"
case Galvji_Bold = "Galvji-Bold"
case Galvji = "Galvji"
case Palatino_Italic = "Palatino-Italic"
case Palatino_Roman = "Palatino-Roman"
case Palatino_BoldItalic = "Palatino-BoldItalic"
case Palatino_Bold = "Palatino-Bold"
case MalayalamSangamMN_Bold = "MalayalamSangamMN-Bold"
case MalayalamSangamMN = "MalayalamSangamMN"
case AlNile = "AlNile"
case AlNile_Bold = "AlNile-Bold"
case LaoSangamMN = "LaoSangamMN"
case BradleyHandITCTT_Bold = "BradleyHandITCTT-Bold"
case HiraMinProN_W3 = "HiraMinProN-W3"
case HiraMinProN_W6 = "HiraMinProN-W6"
case PingFangHK_Medium = "PingFangHK-Medium"
case PingFangHK_Thin = "PingFangHK-Thin"
case PingFangHK_Regular = "PingFangHK-Regular"
case PingFangHK_Ultralight = "PingFangHK-Ultralight"
case PingFangHK_Semibold = "PingFangHK-Semibold"
case PingFangHK_Light = "PingFangHK-Light"
case Helvetica_Oblique = "Helvetica-Oblique"
case Helvetica_BoldOblique = "Helvetica-BoldOblique"
case Helvetica = "Helvetica"
case Helvetica_Light = "Helvetica-Light"
case Helvetica_Bold = "Helvetica-Bold"
case Helvetica_LightOblique = "Helvetica-LightOblique"
case Courier_BoldOblique = "Courier-BoldOblique"
case Courier_Oblique = "Courier-Oblique"
case Courier = "Courier"
case Courier_Bold = "Courier-Bold"
case Cochin_Italic = "Cochin-Italic"
case Cochin_Bold = "Cochin-Bold"
case Cochin = "Cochin"
case Cochin_BoldItalic = "Cochin-BoldItalic"
case TrebuchetMS_Bold = "TrebuchetMS-Bold"
case TrebuchetMS_Italic = "TrebuchetMS-Italic"
case Trebuchet_BoldItalic = "Trebuchet-BoldItalic"
case TrebuchetMS = "TrebuchetMS"
case DevanagariSangamMN = "DevanagariSangamMN"
case DevanagariSangamMN_Bold = "DevanagariSangamMN-Bold"
case Rockwell_Italic = "Rockwell-Italic"
case Rockwell_Regular = "Rockwell-Regular"
case Rockwell_Bold = "Rockwell-Bold"
case Rockwell_BoldItalic = "Rockwell-BoldItalic"
case SnellRoundhand = "SnellRoundhand"
case SnellRoundhand_Bold = "SnellRoundhand-Bold"
case SnellRoundhand_Black = "SnellRoundhand-Black"
case ZapfDingbatsITC = "ZapfDingbatsITC"
case BodoniSvtyTwoITCTT_Bold = "BodoniSvtyTwoITCTT-Bold"
case BodoniSvtyTwoITCTT_BookIta = "BodoniSvtyTwoITCTT-BookIta"
case BodoniSvtyTwoITCTT_Book = "BodoniSvtyTwoITCTT-Book"
case Verdana_Italic = "Verdana-Italic"
case Verdana = "Verdana"
case Verdana_Bold = "Verdana-Bold"
case Verdana_BoldItalic = "Verdana-BoldItalic"
case AmericanTypewriter_CondensedBold = "AmericanTypewriter-CondensedBold"
case AmericanTypewriter_Condensed = "AmericanTypewriter-Condensed"
case AmericanTypewriter_CondensedLight = "AmericanTypewriter-CondensedLight"
case AmericanTypewriter = "AmericanTypewriter"
case AmericanTypewriter_Bold = "AmericanTypewriter-Bold"
case AmericanTypewriter_Semibold = "AmericanTypewriter-Semibold"
case AmericanTypewriter_Light = "AmericanTypewriter-Light"
case AvenirNext_Medium = "AvenirNext-Medium"
case AvenirNext_DemiBoldItalic = "AvenirNext-DemiBoldItalic"
case AvenirNext_DemiBold = "AvenirNext-DemiBold"
case AvenirNext_HeavyItalic = "AvenirNext-HeavyItalic"
case AvenirNext_Regular = "AvenirNext-Regular"
case AvenirNext_Italic = "AvenirNext-Italic"
case AvenirNext_MediumItalic = "AvenirNext-MediumItalic"
case AvenirNext_UltraLightItalic = "AvenirNext-UltraLightItalic"
case AvenirNext_BoldItalic = "AvenirNext-BoldItalic"
case AvenirNext_Heavy = "AvenirNext-Heavy"
case AvenirNext_Bold = "AvenirNext-Bold"
case AvenirNext_UltraLight = "AvenirNext-UltraLight"
case Baskerville_SemiBoldItalic = "Baskerville-SemiBoldItalic"
case Baskerville_SemiBold = "Baskerville-SemiBold"
case Baskerville_BoldItalic = "Baskerville-BoldItalic"
case Baskerville = "Baskerville"
case Baskerville_Bold = "Baskerville-Bold"
case Baskerville_Italic = "Baskerville-Italic"
case KhmerSangamMN = "KhmerSangamMN"
case Didot_Bold = "Didot-Bold"
case Didot = "Didot"
case Didot_Italic = "Didot-Italic"
case SavoyeLetPlain = "SavoyeLetPlain"
case BodoniOrnamentsITCTT = "BodoniOrnamentsITCTT"
case Symbol = "Symbol"
case Charter_BlackItalic = "Charter-BlackItalic"
case Charter_Bold = "Charter-Bold"
case Charter_Roman = "Charter-Roman"
case Charter_Black = "Charter-Black"
case Charter_BoldItalic = "Charter-BoldItalic"
case Charter_Italic = "Charter-Italic"
case Menlo_BoldItalic = "Menlo-BoldItalic"
case Menlo_Bold = "Menlo-Bold"
case Menlo_Italic = "Menlo-Italic"
case Menlo_Regular = "Menlo-Regular"
case NotoNastaliqUrdu = "NotoNastaliqUrdu"
case NotoNastaliqUrdu_Bold = "NotoNastaliqUrdu-Bold"
case BodoniSvtyTwoSCITCTT_Book = "BodoniSvtyTwoSCITCTT-Book"
case DINAlternate_Bold = "DINAlternate-Bold"
case Papyrus_Condensed = "Papyrus-Condensed"
case Papyrus = "Papyrus"
case HiraginoSans_W3 = "HiraginoSans-W3"
case HiraginoSans_W6 = "HiraginoSans-W6"
case HiraginoSans_W7 = "HiraginoSans-W7"
case PingFangSC_Medium = "PingFangSC-Medium"
case PingFangSC_Semibold = "PingFangSC-Semibold"
case PingFangSC_Light = "PingFangSC-Light"
case PingFangSC_Ultralight = "PingFangSC-Ultralight"
case PingFangSC_Regular = "PingFangSC-Regular"
case PingFangSC_Thin = "PingFangSC-Thin"
case MyanmarSangamMN = "MyanmarSangamMN"
case MyanmarSangamMN_Bold = "MyanmarSangamMN-Bold"
case AppleSymbols = "AppleSymbols"
case Zapfino = "Zapfino"
case BodoniSvtyTwoOSITCTT_BookIt = "BodoniSvtyTwoOSITCTT-BookIt"
case BodoniSvtyTwoOSITCTT_Book = "BodoniSvtyTwoOSITCTT-Book"
case BodoniSvtyTwoOSITCTT_Bold = "BodoniSvtyTwoOSITCTT-Bold"
case EuphemiaUCAS = "EuphemiaUCAS"
case EuphemiaUCAS_Italic = "EuphemiaUCAS-Italic"
case EuphemiaUCAS_Bold = "EuphemiaUCAS-Bold"
case DINCondensed_Bold = "DINCondensed-Bold"
}
}

Open Font Book application, find your font, select and switch to font info preview mode ( i button on topbar) and use the PostScript name of the font.

I did a Google search and found a list here. It seems to be what you are looking for, it has the visual representation, and should work with Xcode.

Try this to get all available iOS fonts
let familyNames = UIFont.familyNames
for family in familyNames {
print("Family name " + family)
let fontNames = UIFont.fontNames(forFamilyName: family)
for font in fontNames {
print(" Font name: " + font)
}
}

Related

CallKit Call Extension error with non existent error value 102

From examining some crashes in crashlytics I can see that for a smattering of users there is a problem occuring when using CallKit's Call Extension, however the error code is one which isn't documented.
The crash is reported as:
libswiftCore.dylib
_diagnoseUnexpectedEnumCaseValue<A, B>(type:rawValue:) + 1272
And crash_info_entry_0 is
CXErrorCodeCallDirectoryManagerError(rawValue: 102)
The Apple documentation for CXErrorCodeCallDirectoryManagerError lists the same as in the code (https://developer.apple.com/documentation/callkit/cxerrorcodecalldirectorymanagererror)
And here are the error codes which have values 0 to 8
public enum Code : Int {
public typealias _ErrorType = CXErrorCodeCallDirectoryManagerError
case unknown = 0
case noExtensionFound = 1
case loadingInterrupted = 2
case entriesOutOfOrder = 3
case duplicateEntries = 4
case maximumEntriesExceeded = 5
case extensionDisabled = 6
#available(iOS 10.3, *)
case currentlyLoading = 7
#available(iOS 11.0, *)
case unexpectedIncrementalRemoval = 8
}
So what is error 102 and why is it not documented?
Here is my code dealing with the error codes:
CXCallDirectoryManager.sharedInstance.reloadExtension(withIdentifier: Config.callExtensionIdentifier()) { error in
if let err = error as NSError? {
self.setLastAttemptToUpdateFailedKey(failed: true)
if let cdError = error as? CXErrorCodeCallDirectoryManagerError {
var debugString = ""
var seriousError = false
switch (cdError.code)
{
case .unknown: debugString = "Unknown error"
case .noExtensionFound: debugString = "No extension found"
case .loadingInterrupted: debugString = "Loading interrupted"
seriousError = true
case .entriesOutOfOrder: debugString = "Entries out of order"
seriousError = true
case .duplicateEntries: debugString = "Duplicate Entries"
seriousError = true
case .maximumEntriesExceeded: debugString = "Maximum entries exceeded"
case .extensionDisabled: debugString = "Extension disabled"
case .currentlyLoading: debugString = "Currently Loading"
case .unexpectedIncrementalRemoval: debugString = "Unexpected Incremental Removal"
}

Output in Zapier for States to UF's Javascript code

I'm trying to convert an input text, for example: "São Paulo" into an acronym "SP" within Zapier. I'm using Code by Zapier - Run Javascript.
The Code I'm using is:
var ConverterEstados = function(inputData) {
var data;
switch (inputData) {
/* Estados */
case "Acre" : data = "AC"; break;
case "Alagoas" : data = "AL"; break;
case "Amazonas" : data = "AM"; break;
case "Amapá" : data = "AP"; break;
case "Bahia" : data = "BA"; break;
case "Ceará" : data = "CE"; break;
case "Distrito Federal" : data = "DF"; break;
case "Espírito Santo" : data = "ES"; break;
case "Goiás" : data = "GO"; break;
case "Maranhão" : data = "MA"; break;
case "Minas Gerais" : data = "MG"; break;
case "Mato Grosso Do Sul" : data = "MS"; break;
case "Mato Grosso" : data = "MT"; break;
case "Pará" : data = "PA"; break;
case "Paraíba" : data = "PB"; break;
case "Pernambuco" : data = "PE"; break;
case "Piauí" : data = "PI"; break;
case "Paraná" : data = "PR"; break;
case "Rio De Janeiro" : data = "RJ"; break;
case "Rio Grande Do Norte" : data = "RN"; break;
case "Rondônia" : data = "RO"; break;
case "Roraima" : data = "RR"; break;
case "Rio Grande Do Sul" : data = "RS"; break;
case "Santa Catarina" : data = "SC"; break;
case "Sergipe" : data = "SE"; break;
case "São Paulo" : data = "SP"; break;
case "Tocatíns" : data = "TO"; break;
}
return data;
};
I need this code to return two letters for example "SP", it must be returned inside the output variable, which is an object.
Zapier gives an example of output
output = {id: 1, hello: "world"};
Could anyone help?
To fix your existing code, you need only return an object (aka wrapped in {} from the whole text box:
// your function here
// ...
// ...
return {twoLetterCode: ConverterEstados(inputData)}
It's also worth noting you can simplify your function by using an object instead:
const ConverterEstados = {
"Acre": "AC",
"Alagoas": "AL",
// ...
}
return {twoLetterCode: ConverterEstados[inputData.state]}
In that last part, i'm assuming your input has mapped in a variable called state, but it can be named whatever you want.

Unknown column 'product_code' in 'field list on my prestashop

Sir when i go to save any product then i see this error. so can any help how can i fix it
Unknown column 'product_code' in 'field list
UPDATE ps_product SET id_product = '430',id_shop_default = '1',id_manufacturer = '0',id_supplier = '0',reference = '',supplier_reference = '',location = '',width = '0',height = '0',depth = '0',weight = '0',quantity_discount = '0',ean13 = '',upc = '',cache_is_pack = '0',cache_has_attachments = '0',is_virtual = '0',id_category_default = '12',id_tax_rules_group = '0',on_sale = '0',online_only = '0',ecotax = '0',minimal_quantity = '1',price = '49.99',wholesale_price = '29.99',unity = '',unit_price_ratio = '0',additional_shipping_cost = '0',customizable = '0',text_fields = '0',uploadable_files = '0',active = '1',redirect_type = '404',id_product_redirected = '0',available_for_order = '1',available_date = '0000-00-00',condition = 'new',show_price = '1',indexed = '0',visibility = 'both',cache_default_attribute = '0',advanced_stock_management = '0',date_add = '2017-06-29 23:34:25',date_upd = '2017-07-04 00:41:34',pack_stock_type = '3',product_code = '' WHERE id_product = 430

HKBiologicalSexObject.biologicalSex returns HKBiologicalSex instead of .Male or .Female

I have already authorized HealthKit, and I am getting BiologicalSex from HealthKitStore like this:
let healthKitStore:HKHealthStore = HKHealthStore()
var biologicalSexObject: HKBiologicalSexObject?
var biologicalSex: HKBiologicalSex?
do {
biologicalSexObject = try healthKitStore.biologicalSex()
biologicalSex = biologicalSexObject!.biologicalSex
} catch _ as NSError {
biologicalSex = nil
print("error reading biological sex")
}
However, when I try to print biologicalSex it returns HKBiologicalSex instead of .Male or .Female.
I have seen more or less this exact code in several tutorials, so I'm wondering if there have been any syntax changes I should be aware of in Swift 2. (The error handling has changed, so I'm curious if anything else of note has.)
The rawValue of biologicalSex = biologicalSexObject!.biologicalSex is required to do this. The enum for BiologicalSex looks like this:
typedef enum : NSInteger {
HKBiologicalSexNotSet = 0,
HKBiologicalSexFemale,
HKBiologicalSexMale,
HKBiologicalSexOther,
} HKBiologicalSex;
Using this information it is easy to design a switch statement to cover all of the possible values:
switch biologicalSex.rawValue{
case 0:
biologicalSex = nil
case 1:
biologicalSex = "Female"
case 2:
biologicalSex = "Male"
case 3:
biologicalSex = "Other"
default:
biologicalSex = nil
}

Swift: How to get the last integer from a NSString array?

var LabelAQI = "-"
var LabelExtraInfo = "-"
var arrAQI = [NSString]()
var AQI1:NSString = "55a"
var AQI2:NSString = "95a"
var AQI3:NSString = "66"
var AQI4:NSString = "25"
var AQI5:NSString = "88b"
var AQI6:NSString = "#"
arrAQI[0...5] = [AQI1, AQI2, AQI3, AQI4, AQI5, AQI6]
Using Swift, I'm getting AQI (Air Quality Index) data from a website in the form of NSString. AQI1 to AQI6 is essentially AQI data for every hour (e.g. 12am to 5am, I'm having up to AQI24 in the actual code though). "#" means data is not yet available. The integer is the AQI, and sometimes there may be associated extra information represented by "a"/"b" with the integers which means "Carbon Monoxide present"/"Sulphur Dioxide present". What I'm trying to do is to:
1) Display the last integer from arrAQI (excluding "#", and not displaying "a"/"b", which is "88") on LabelAQI
2) Display "Carbon Monoxide present"/"Sulphur Dioxide present" on LabelExtraInfo if there is "a"/"b" with the last integer from arrAQI, if not, leave LabelExtraInfo.text = "-"
I'm only a few weeks into programming. Can anybody help with this? Is there a better way to do what I want to do? Thank you so much in advance.
It usually helps to break the problem down into multiple functions. Here, you need to do two things – process the string, extracting a number and possible extra info. Then, loop over the array of strings until you find a suitable entry.
First the string processing. Given a string, you want to return either a pair (the reading and the extra info), or “not found”. Whenever you need to return something or not found, an optional is a good choice. So you want a function that takes a string and returns an optional (Int,String) pair:
func extractData(input: String) -> (Int,String)?
But you could go one step further and define an enum to represent the different bits of extra info:
enum AirQualityInfo {
case CarbonMonoxide,
SulphurDioxide,
NoInfo
}
func extractData(input: String) -> (Int,AirQualityInfo)?
This way, all your nasty string processing is contained within extractData.
Within that function, you want to check for a known trailing character, then strip that off, and if what remains is a number, return the two values. But if what remains isn’t a number, return nil:
func extractData(input: String) -> (Int,AirQualityInfo)? {
let stripped: String
let extraInfo: AirQualityInfo
switch last(input) {
case .Some("a"):
stripped = dropLast(input)
extraInfo = .CarbonMonoxide
case .Some("b"):
stripped = dropLast(input)
extraInfo = .SulphurDioxide
default:
stripped = input
extraInfo = .NoInfo
}
return stripped.toInt().map { ($0,extraInfo) }
}
You could, as others have suggested, use regular expressions for this, but personally I think this is overkill given your data parsing needs are so specific.
Once you have this function, you can loop over the array in reverse order, checking each value using the function, until you find a valid value:
for idx in reverse(indices(arrAQI)) {
if let (index, extraInfo) = extractData(arrAQI[idx]) {
LabelAQI = toString(index)
switch extraInfo {
case .CarbonMonoxide:
LabelExtraInfo = "Carbon Monoxide Present"
case .SulphurDioxide:
LabelExtraInfo = "SulphurDioxide Present"
case .NoInfo:
LabelExtraInfo = "-"
}
// stop going around the loop
break
}
}
You could also factor out that conversion of the string out further as well:
extension AirQualityInfo {
var displayString: String {
switch self {
case .CarbonMonoxide:
return "Carbon Monoxide Present"
case .SulphurDioxide:
return "SulphurDioxide Present"
case .NoInfo:
return "-"
}
}
}
for idx in reverse(indices(arrAQI)) {
if let (index, extraInfo) = extractData(arrAQI[idx]) {
LabelAQI = toString(index)
LabelExtraInfo = extraInfo.displayString
break
}
}
Finally, if you’re feeling super-adventurous, you could write a function that does that finding and mapping operation in one shot:
func findSome<C: CollectionType, T>
(source: C, match: C.Generator.Element -> T?)
-> T? {
for element in source {
if let x = match(element) {
return x
}
}
return nil
}
if let (index, extraInfo) = findSome(reverse(arrAQI),extractData) {
LabelAQI = toString(index)
LabelExtraInfo = extraInfo.displayString
}
By the way, a few other Swift tips: it’s generally better to use String rather than NSString unless you have a specific need for something to be an NSString (which it doesn’t look like here); you don’t have to name the types when declaring them – you can write let str = "hello" rather than let str: String = "hello" which tends to make code look a little cleaner and easier to read; and it’s best to use let rather than var unless you explicitly need to change (“mutate”) the value later in the code… so given all that, here’s how you could declare your original array:
let AQI1 = "55a"
let AQI2 = "95a"
let AQI3 = "66"
let AQI4 = "25"
let AQI5 = "88b"
let AQI6 = "#"
let arrAQI = [AQI1,AQI2,AQI3,AQI4,AQI5,AQI6,]
This could by done by exploding string into array of objects, and then check each of them:
var LabelAQI = "-"
var LabelExtraInfo = "-"
var stringFromServer = "55a 95a 66 25 88b #"
var objectsSeparated = stringFromServer.componentsSeparatedByString(" ")
for object in objectsSeparated
{
if object.hasSuffix("a")
{
LabelAQI = object.substringToIndex(object.endIndex.predecessor())
LabelExtraInfo = "Carbon Monoxide present"
}
else if object.hasSuffix("b")
{
LabelAQI = object.substringToIndex(object.endIndex.predecessor())
LabelExtraInfo = "Sulphur Dioxide present"
}
else if object.hasSuffix("#")
{
LabelAQI = object.substringToIndex(object.endIndex.predecessor())
LabelExtraInfo = "-"
}
else
{
LabelAQI = object
LabelExtraInfo = "-"
}
}
UPDATE
To find the last object, that doesn't have '#' suffix you could use following code:
var LabelAQI = "-"
var LabelExtraInfo = "-"
var stringFromServer = "55a 95a 66 25 88b #"
var objectsSeparated = stringFromServer.componentsSeparatedByString(" ")
var index = objectsSeparated.count
while 0 >= index
{
var object = objectsSeparated[index]
index--
if object.hasSuffix("#")
{
//this object has '#' suffix -> skip it
continue
}
else
{
//found non '#' object
if object.hasSuffix("a")
{
LabelAQI = object.substringToIndex(object.endIndex.predecessor())
LabelExtraInfo = "Carbon Monoxide present"
}
else if object.hasSuffix("b")
{
LabelAQI = object.substringToIndex(object.endIndex.predecessor())
LabelExtraInfo = "Sulphur Dioxide present"
}
else
{
LabelAQI = object
LabelExtraInfo = "-"
}
break
}
}
There are a number of ways you could do this, here's one suggestion using NSScanner:
var LabelAQI = "-"
var LabelExtraInfo = "-"
var arrAQI = [NSString]()
let AQI1:NSString = "55a", AQI2 = "95a", AQI3 = "66", AQI4 = "25", AQI5 = "88b", AQI6 = "#"
arrAQI.extend([AQI1, AQI2, AQI3, AQI4, AQI5, AQI6])
for AQI in reverse(arrAQI) {
if AQI != "#" {
var str:NSString?
let numberSet = NSCharacterSet.decimalDigitCharacterSet()
let letterSet = NSCharacterSet(charactersInString: "ab")
let scanner = NSScanner(string: AQI as String)
if scanner.scanCharactersFromSet(numberSet, intoString:&str) {
LabelAQI = str as! String
if scanner.scanCharactersFromSet(letterSet, intoString: &str) {
switch str as! String {
case "a":
LabelExtraInfo = "Carbon Monoxide present"
case "b":
LabelExtraInfo = "Sulphur Dioxide present"
default:
break
}
}
break
}
}
}
LabelAQI // "88"
LabelExtraInfo // "Sulphur Dioxide present"
I first of all reverse the array and loop through it for the last non-hash symbol entry. I then scan the string first for a number and second for the letters a/b using NSCharacterSet searches. Once found we can break out of the loop and all is done.
Note: this line of code arrAQI[0...5] = [AQI1, AQI2, AQI3, AQI4, AQI5, AQI6] didn't work, so I replaced it with arrAQI.extend([AQI1, AQI2, AQI3, AQI4, AQI5, AQI6]).
Using regular expressions, you can easily get the numbers out of a string. You probably want to do something along these lines:
let regex = NSRegularExpression(pattern: "[\a-z\s]", options: nil, error: nil)
let aq1value = regex?.stringByReplacingMatchesInString(arrAQI[0], options: nil, range: NSMakeRange(0, count(arrAQI[0])), withTemplate: "")
This will take your string and remove all alphabetic characters, leaving you with only numbers. You can then cast the string as an integer as you wish!

Resources