ã¿ãªããããã«ã¡ã¯ïŒ
ç§ã®ååã¯ããããªãŒã§ãã ç§ã¯éå»2幎éã13人ã®iOSéçºè
ã®ããŒã ã®ããŒã ãªãŒããŒã§ããããšãããŸããŸãããŸããã ãããŠãäžç·ã«Tinkoff Businessã¢ããªã±ãŒã·ã§ã³ã«åãçµãã§ããŸãã
æå€§ã®æ©èœã»ãããŸãã¯ãã°ä¿®æ£ã䜿çšããŠãäºæããªãç¬éã«ã¢ããªã±ãŒã·ã§ã³ããªãªãŒã¹ããããã§ãç°è²ã«ãªããªãæ¹æ³ã«é¢ããçµéšãå
±æããããšæããŸãã
ããŒã ãéçºãšãã¹ãã倧å¹
ã«å éããäºå®å€ã®ãªãªãŒã¹ãç·æ¥ãªãªãŒã¹ã«äŒŽãã¹ãã¬ã¹ããã°ãåé¡ã®éã倧å¹
ã«åæžããã®ã«åœ¹ç«ã€ãã©ã¯ãã£ã¹ãšã¢ãããŒãã«ã€ããŠèª¬æããŸãã #MakeReleaseWithoutStress ã
è¡ããïŒ
åé¡ã®èª¬æ
次ã®ç¶æ³ãæ³åããŠãã ããã
å¥ã®ãªãªãŒã¹ããããŸãã ååž°ãã¹ããå
è¡ãããã¹ã¿ãŒã¯åã³ã¢ããªã±ãŒã·ã§ã³å
ã®ããã¹ãã®ä»£ããã«è¡IDã衚瀺ããå ŽæãèŠã€ããŸããã

ããã¯ãç§ãã¡ãééããæãé »ç¹ãªåé¡ã®1ã€ã§ããã
ã¢ããªã±ãŒã·ã§ã³ãå¥ã®èšèªã«ããŒã«ã©ã€ãºããŠããªãå ŽåããŸãã¯ãã¹ãŠã®ããŒã«ã©ã€ãºãLocalizable.stringsãã¡ã€ã«ã䜿çšããã«ã³ãŒãå
ã®è¡ã«çŽæ¥èšè¿°ãããŠããå Žåããã®åé¡ã¯çºçããŸããã
ãã ãã解決ã«åœ¹ç«ã€ä»ã®åé¡ãçºçããå ŽåããããŸãã
çç±â广
ãªãããããã¹ãŠèµ·ãã£ãŠããã®ã§ããïŒ
ã³ã³ãã€ã«ããããã°ã©ã ã³ãŒãããããŸãã ééã£ãèšè¿°ãããå ŽåïŒæ§æçã«ããŸãã¯åŒã³åºããããšãã«é¢æ°åãæ£ãããªãå ŽåïŒããããžã§ã¯ãã¯åã«ã¢ã»ã³ãã«ãããŸããã ããã¯çè§£å¯èœã§ãæçœã§è«ççã§ãã
ãããããªãœãŒã¹ã®ãããªãã®ã¯ã©ãã§ããïŒ
ãããã¯ã³ã³ãã€ã«ããããã³ãŒãã®ã³ã³ãã€ã«åŸã«ãã³ãã«ã«è¿œå ãããã ãã§ãã ãã®ç¹ã§ãå®è¡æã«å€æ°ã®åé¡ãçºçããå¯èœæ§ããããŸããããšãã°ãåè¿°ã®ããŒã«ã©ã€ãºã®æååã®å Žåãªã©ã§ãã
ãœãªã¥ãŒã·ã§ã³ãæ€çŽ¢ãã
ãã®ãããªåé¡ãäžè¬çã«ã©ã®ããã«è§£æ±ºãããã©ã®ããã«ä¿®æ£ã§ããããèããŸããã mail.ruã®CocoaheadsäŒè°ã®1ã€ãæãåºããŸããã ã³ãŒãçæããŒã«ã®æ¯èŒã«ã€ããŠã®è¬æŒããããŸããã
ãããã®ããŒã«ïŒã©ã€ãã©ãª/ãã¬ãŒã ã¯ãŒã¯ïŒãäœã§ããããããäžåºŠèŠãŠãæçµçã«å¿
èŠãªãã®ãèŠã€ãããŸããã
åæã«ãAndroidã®éçºè
ãåæ§ã®ã¢ãããŒããäœå¹Žã䜿çšããŠããŸãã Googleã¯ãããã«ã€ããŠèããããããç®±ããåºããŠãã®ãããªããŒã«ã«ããŸããã ããããAppleã¯ãå®å®ããXcodeã§ãããç§ãã¡ã«ã§ããªã...
ãããèŠã€ããããã«æ®ã£ã-ã©ã®ããŒã«ãéžæãããïŒ ãã¿ãªãŒ ã SwiftGenãŸãã¯R.swift ïŒ
ãã¿ãªãŒã¯ããŒã«ã©ã€ãºããµããŒãããŠããªãã£ããããããã«æŸæ£ããããšã«ããŸããã SwiftGenãšR.swiftã®æ©èœã¯éåžžã«äŒŒãŠããŸããã R.swiftãéžæããŸãããããã¯ãæã®æ°ã«åºã¥ããŠããããã€ã§ãSwiftGenã«å€æŽã§ããããšãç¥ã£ãŠããŸãã
R.swiftã®ä»çµã¿
ããªã³ã³ãã€ã«ãã«ããã§ãŒãºã¹ã¯ãªãããèµ·åãããããžã§ã¯ãæ§é ãå®è¡ãããããžã§ã¯ãã«è¿œå ããå¿
èŠãããR.generated.swift
ãšãããã¡ã€ã«ãçæããŸãïŒæåŸã«ãããè¡ãæ¹æ³ã«ã€ããŠè©³ãã説æããŸãïŒã
ãã¡ã€ã«ã®æ§é ã¯æ¬¡ã®ãšããã§ãã
import Foundation import Rswift import UIKit /// This `R` struct is generated and contains references to static resources. struct R: Rswift.Validatable { fileprivate static let applicationLocale = hostingBundle.preferredLocalizations.first.flatMap(Locale.init) ?? Locale.current fileprivate static let hostingBundle = Bundle(for: R.Class.self) static func validate() throws { try intern.validate() } // ... /// This `R.string` struct is generated, and contains static references to 2 localization tables. struct string { /// This `R.string.localizable` struct is generated, and contains static references to 1196 localization keys. struct localizable { /// en translation: Apple Pay /// /// Locales: en, ru static let card_actions_activate_apple_pay = Rswift.StringResource(key: "card_actions_activate_apple_pay", tableName: "Localizable", bundle: R.hostingBundle, locales: ["en", "ru"], comment: nil) // ... /// en translation: Apple Pay /// /// Locales: en, ru static func card_actions_activate_apple_pay(_: Void = ()) -> String { return NSLocalizedString("card_actions_activate_apple_pay", bundle: R.hostingBundle, comment: "") } } } }
äœ¿çšæ³ïŒ
let str = R.string.localizable.card_actions_activate_apple_pay() print(str) > Apple Pay
ããªãRswift.StringResource
ãå¿
èŠRswift.StringResource
ã§ããïŒããšããªãã¯å°ããŸãã ç§èªèº«ã¯ãããçæããçç±ãçè§£ããŠããŸããããèè
ã説æããŠããããã«ãããã¯æ¬¡ã®ããã«å¿
èŠã§ãïŒ ãªã³ã¯
å®äžçã®ã¢ããªã±ãŒã·ã§ã³
以äžã®å
容ã®ç°¡åãªèª¬æïŒ
*ããã¯-圌ãã¯ãã°ããã®éã¢ãããŒãã䜿çšããæçµçã«ã¯åœŒãããããå»ã£ã
*ãªã£ã-æ°ããã³ãŒããæžããšãã«äœ¿çšããã¢ãããŒã
*ããã¯ããã§ã¯ãããŸããã§ããããããã¯å¯èœã§ã-ç§ãã¡ã®ã¢ããªã±ãŒã·ã§ã³ã«ã¯ååšããªãã£ãã¢ãããŒãã§ãããç§ã¯Tinkoff.ruã§ãŸã åããŠããªãã£ãåœæã®ããŸããŸãªãããžã§ã¯ãã§ãããæºãããŸããã
ããŒã«ãªãŒãŒã·ã§ã³
ããŒã«ã©ã€ãºã«R.swift
ã䜿çšãå§ããã®ã§ãæåã«æžããåé¡ããç§ãã¡ãæãããšãã§ããŸããã ããã§ãããŒã«ã©ã€ãºã®IDã倿Žãããå Žåããããžã§ã¯ãã¯ã¢ã»ã³ãã«ãããŸããã
*ããã¯ããã¹ãŠã®ããŒã«ãªãŒãŒã·ã§ã³ã§IDãå¥ã®ããŒã«ã©ã€ãºã«å€æŽããå Žåã«ã®ã¿æ©èœããŸãã ããŒã«ãªãŒãŒã·ã§ã³ã®ããããã«æååãæ®ã£ãŠããå Žåãã³ã³ãã€ã«æã«ããã®IDããã¹ãŠã®èšèªã§ããŒã«ã©ã€ãºãããŠããªããšããèŠåã衚瀺ãããŸãã

ããã«ã¯ãããŸããããããªãã¯æã£ãŠãããããããŸããïŒ final class NewsViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() titleLabel.text = NSLocalizedString("news_title", comment: "News title") } }
ããã¯ïŒ extension String { public func localized(in bundle: Bundle = .main, value: String = "", comment: String = "") -> String { return NSLocalizedString(self, tableName: nil, bundle: bundle, value: value, comment: comment) } } final class NewsViewController: UIViewController { private enum Localized { static let newsTitle = "news_title".localized() } override func viewDidLoad() { super.viewDidLoad() titleLabel.text = Localized.newsTitle } }
次ã®ããã«ãªããŸããïŒ titleLabel.text = R.string.localizable.newsTitle()
ç»å
ããã§ã* .xcassetsã®ååã倿Žããã³ãŒãã倿Žããªãã£ãå Žåããããžã§ã¯ãã¯åã«ã¢ã»ã³ãã«ãããŸããã
ããã¯ïŒ imageView.image = UIImage(named: "NotExist") // imageView.image = UIImage(named: "NotExist")! // crash imageView.image = #imageLiteral(resourceName: "NotExist") // crash
次ã®ããã«ãªããŸããïŒ imageView.image = R.image.tinkoffLogo() //
çµµã³ã³ã
ããã¯ïŒ let someStoryboardName = "SomeStoryboard" // Change to something else (eg: "somestoryboard") - get nil or crash in else let someVCIdentifier = "SomeViewController" // Change to something else (eg: "someviewcontroller") - get nil or crash in else let storyboard = UIStoryboard(name: someStoryboardName, bundle: .main) let _vc = storyboard.instantiateViewController(withIdentifier: someVCIdentifier) guard let vc = _vc as? SomeViewController else { // - , Fabric Firebase // fatalError() ¯\_(ã)_/¯}
次ã®ããã«ãªããŸããïŒ guard let vc = R.storyboard.someStoryboard.someViewController() else { // - , Fabric Firebase // fatalError() ¯\_(ã)_/¯ }
ãªã©ãªã©ã
æ€èšŒã¹ããŒãªãŒããŒã
R.validateïŒïŒã¯ãã¹ããŒãªãŒããŒããŸãã¯xibãã¡ã€ã«ã§äœãééã£ãããšãããå Žåã«æãæã€ïŒãŸãã¯ãåã«catchãããã¯ã«ãšã©ãŒãæããïŒçŽ æŽãããããŒã«ã§ãã
äŸïŒ
- ãããžã§ã¯ãã«ãªãåçã®ååã瀺ãã
- 圌ãã¯ãã©ã³ãã瀺ããããã䜿çšã忢ãããããžã§ã¯ãããåé€ããŸããïŒinfo.plistããïŒ
äœ¿çšæ³ïŒ
final class AppDelegate: UIResponder { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? = nil) -> Bool { #if DEBUG do { try R.validate() } catch { // fatalError // debug // - , production fatalError(error.localizedDescription) } #endif return true } }
ããã§ã2ã€è³Œå
¥ããæºåãã§ããŸããïŒ

å®è£
æ¹æ³
*ã³ã³ããŒãã³ãããŒã¹ã®ã·ã¹ãã -wiki ïŒã³ãŒãéçºã®æŠå¿µïŒãã³ã³ããŒãã³ãïŒçžäºæ¥ç¶ãããç»é¢/ã¢ãžã¥ãŒã«ã®ã»ããïŒã¯ãã³ãŒãããŒã¹ã®äžè²«æ§ãæžããããã«éããç°å¢ïŒãã®å ŽåãããŒã«ã«ãããïŒã§éçºãããŸãã å€ãã®äººã
ã¯ããã®æŠå¿µã«åºã¥ããŠããããã¯ãšã³ãã®ã¢ãããŒããç¥ã£ãŠããŸã-ãã€ã¯ããµãŒãã¹ã
* Monolith- wiki ãã³ãŒãéçºã®æŠå¿µãã³ãŒãããŒã¹å
šäœã1ã€ã®ãªããžããªã«ãããã³ãŒãã¯å¯æ¥ã«é¢é£ããŠããŸãã ãã®æŠå¿µã¯ãæéã®æ©èœã»ãããæã€å°èŠæš¡ãããžã§ã¯ãã«é©ããŠããŸãã
ã¢ããªã·ãã¯ã¢ããªã±ãŒã·ã§ã³ãéçºããŠããå ŽåããŸãã¯ãµãŒãããŒãã£ã®äŸåé¢ä¿ã®ã¿ã䜿çšããŠããå Žåã¯ã幞éã§ãïŒãã ããããã¯æ£ç¢ºã§ã¯ãããŸããïŒã ãã¥ãŒããªã¢ã«ãå®è¡ããå³å¯ã«ãã¹ãŠãè¡ã£ãŠãã ããã
ããã¯ç§ãã¡ã®å Žåã§ã¯ãããŸããã§ããã ç§ãã¡ã¯é¢äžããŸããã ã¡ã€ã³ã¢ããªã±ãŒã·ã§ã³ã«R.swift
åã蟌ãããš
ãã³ã³ããŒãã³ãããŒã¹ã®ã·ã¹ãã ã䜿çšãããããããŒã«ã«ãããïŒã³ã³ããŒãã³ãïŒã«åã蟌ãããšã«ããŸããã
ããŒã«ã©ã€ãºãç»åãããã³R.generated.swiftãã¡ã€ã«ã«åœ±é¿ãããã¹ãŠã®èŠçŽ ãçµ¶ããæŽæ°ãããŠãããããå
±éãã©ã³ãã«ããŒãžãããšãçæããããã¡ã€ã«ã«å€ãã®ç«¶åããããŸãã ãããåé¿ããã«ã¯ãgitãªããžããªããR.generated.swiftãåé€ããå¿
èŠããããŸãã ãŸããèè
ã¯ãããããããšãå§ããŸãã
.gitignore
次ã®è¡ã远å ããŸãã
# R.Swift generated files *.generated.swift
ãŸããäžéšã®ãªãœãŒã¹ã®ã³ãŒããçæããããªãå Žåã¯ãåã
ã®ãã¡ã€ã«ãŸãã¯ãã©ã«ããŒå
šäœãç¡èŠããŠãã€ã§ã䜿çšã§ããŸãã
"${PODS_ROOT}/R.swift/rswift" generate "${SRCROOT}/Example" "--rswiftignore" "Example/.rswiftignore"
.rswiftignoreã®èª¬æ
ã¡ã€ã³ãããžã§ã¯ããšåæ§ã«ãããŒã«ã«ãããããR.generated.swiftãã¡ã€ã«ãgitãªããžããªã«è¿œå ããªãããšãéèŠã§ããã ç§ãã¡ã¯ãããã©ã®ããã«è¡ããã®éžæè¢ãæ€èšãå§ããŸããã
- ãããŠå¥ã®ãªãã·ã§ã³...ãŸã R.generated.swiftãgitã«è¿œå ããŸã
ããã€ãã®æ¬ ç¹ããã£ãã«ãããããããäžæçã«ãPodfileã®éæ³ããšãããªãã·ã§ã³ã«æ±ºããŸããã
- ãããžã§ã¯ãã®ã«ãŒãããã®ã¿èµ·åã§ããŸãïŒãã ããã³ã³ã¢ãããã¯ãããžã§ã¯ãã®ã»ãŒãã¹ãŠã®ãã©ã«ããŒããèµ·åã§ããŸãïŒ
- ãã¹ãŠã®ãããã«ã¯Sourcesãšããååã®ãã©ã«ããŒãå¿
èŠã§ãïŒãã ããããããæŽé ãããŠããå Žåãããã¯éèŠã§ã¯ãããŸããïŒ
- ããã¯å¥åŠã§çè§£ãããããã®ã§ããããé
ããæ©ãããµããŒããããªããã°ãªããŸããã§ããïŒããã§ãæŸèæã§ãïŒ
- ããã€ãã®ãµãŒãããŒãã£ã©ã€ãã©ãªããã¹ã«ãLocalPodsããå«ããã©ã«ããŒã«ããå Žåãããã«R.generated.swiftãã¡ã€ã«ã远å ããããšãããããšã©ãŒã§ã¯ã©ãã·ã¥ããŸã
prepare_command
ãã°ããã®éå°æ¬ãšèŠãã¿ãæ±ããŠç掻ããŠããç§ã¯ããã®ãããã¯ãããåºãç ç©¶ããããšã決ããå¥ã®éžæè¢ãèŠã€ããŸããã
Podspecã«ã¯prepare_commandããããŸã ãããã¯ããœãŒã¹ãäœæããã³å€æŽããããã ãã®ãã®ã§ããããžã§ã¯ãã«è¿œå ãããŸãã
*ãã¥ãŒã¹-ãããã®ååãããŒã«ã«ãããã®ååã«çœ®ãæããå¿
èŠããããŸã
* touch-ãã¡ã€ã«ãäœæããã³ãã³ãã åŒæ°ã¯ããã¡ã€ã«ãžã®çžå¯Ÿãã¹ã§ãïŒæ¡åŒµåãæã€ãã¡ã€ã«ã®ååãå«ãïŒ
次ã«ãNews.podspecã§è©æ¬ºãè¡ããŸã
ãã®ã¹ã¯ãªããã¯ã pod install
åããŠå®è¡ããããšãã«åŒã³åºãããå¿
èŠãªãã¡ã€ã«ãçå
ã®ãœãŒã¹ãã©ã«ããŒã«è¿œå ããŸãã
Pod::Spec.new do |s|
次ã¯ããã1ã€ã®ãè³ã®ãã§ã€ã³ããã§ããããŒã«ã«ã®å²çè£ã§R.swiftãåŒã³åºãã¹ã¯ãªãããäœæããå¿
èŠããããŸãã
Pod::Spec.new do |s|
確ãã«ã1ã€ã®ãããããããããŸãã prepare_command
ã¯ããŒã«ã«ãããã§ã¯æ©èœããŸãããããããæ©èœããŸãããç¹æ®ãªå ŽåããããŸãã Githubã§ãã®ãããã¯ã«é¢ããè°è«ããããŸãã
æ»äº¡è
*æ»äº¡-wikiãMortal Kombatã®æçµãããã
ããå°ã調æ»ããçµæãå¥ã®è§£æ±ºçãèŠã€ãããŸãã-ã¢ãããŒãc prepare_command
ãšpre_install
ãã€ããªããã
Podfileããã®éæ³ã®å°ããªå€æŽïŒ
pre_install do |installer|
ãããŠãå°å
ã®å²çè£ã§å®è¡ãããªãã£ãåãã¹ã¯ãªãã
Pod::Spec.new do |s|
æçµçã«ãããã¯æåŸ
ã©ããã«æ©èœããŸãã
ã€ãã«ïŒ
PSïŒ
prepare_command
代ããã«å¥ã®ã«ã¹ã¿ã ã³ãã³ããäœæããããšããŸãããã pod lib lint
ïŒpodspecã®ã³ã³ãã³ããšããŒã¹èªäœãæ€èšŒããã³ãã³ãïŒãäœåãªå€æ°ãèªã£ãŠãã¹ããŸããã
éå°å
ã®å²çè£
ãªã¢ãŒããããïŒãããããç¬èªã®ãªããžããªã«ãããã®ïŒã§ã¯ãã³ãŒãããŒã¹ãäŸåããŒãžã§ã³ã«å³å¯ã«çµã³ä»ããããŠãããããäžèšã®ãã¹ãŠã®ã¹ã¯ãªããããžãã¯ã¯å¿
èŠãããŸããã
R.swiftã¹ã¯ãªããããµã³ãã«èªäœïŒpod lib create <Name>ã³ãã³ãã®åŸã«çæããããããžã§ã¯ãïŒã«åã蟌ã¿ãR.generated.swiftãã©ã€ãã©ãªããã±ãŒãžïŒäžïŒã«è¿œå ããã ãã§ååã§ãã ãããžã§ã¯ãã«ãµã³ãã«ããªãå Žåã¯ãç§ãåŒçšããã¹ã¯ãªããã«äŒŒãã¹ã¯ãªãããäœæããå¿
èŠããããŸãã
PSïŒ
ã¡ãã£ãšãã説æããããŸãïŒ
R.swift + Xcode 10 +æ°ãããã«ãã·ã¹ãã +ã€ã³ã¯ãªã¡ã³ã¿ã«ãã«ãïŒ= <3
åé¡ã®è©³çްã«ã€ããŠã¯ãã©ã€ãã©ãªã®ã¡ã€ã³ããŒãžãŸãã¯ãã¡ããã芧ãã ãã
R.swift v4.0.0ã¯ãcocoapods 1.6.0ã§ã¯åäœããŸãã:(
ç§ã¯ããã«ãã¹ãŠã®åé¡ãä¿®æ£ããããšæããŸãã
ãããã«
åžžã«å質ããŒãå¯èœãªéãé«ãä¿ã€å¿
èŠããããŸãã ããã¯ã財åã§åäœããã¢ããªã±ãŒã·ã§ã³ã«ãšã£ãŠç¹ã«éèŠã§ãã
ãã¹ãããªãŒããŒããŒãããŠããã°ãã§ããã ãæ©ãèŠã€ããå¿
èŠã¯ãããŸããã ç§ãã¡ã®å Žåãããã¯éçºè
ãã³ãŒããã³ã³ãã€ã«ããæç¹ããŸãã¯ãã«ãªã¯ãšã¹ãã®ãã¹ãå®è¡äžã®ããããã§ãã ãããã£ãŠãããŒã«ãªãŒãŒã·ã§ã³ã®æ¬ åŠã¯ããã¹ã¿ãŒãèªååããããã¹ãã®æ³šææ·±ãç®ã§ã¯ãªããã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããéåžžã®ããã»ã¹ã«ãããã®ã§ãã
ãŸããããã¯ãããžã§ã¯ãã®æ§é ã«é¢é£ä»ãããããã®ã³ã³ãã³ããè§£æãããµãŒãããŒãã£ã®ããŒã«ã§ãããšããäºå®ãèæ
®ããå¿
èŠããããŸãã ãããžã§ã¯ããã¡ã€ã«ã®æ§é ã倿Žãããå ŽåãããŒã«ã倿Žããå¿
èŠããããŸãã
ç§ãã¡ã¯ãã®ãªã¹ã¯ãè² ããŸããããã®å Žåããã®ããŒã«ãä»ã®ããŒã«ãšäº€æããããç¬èªã®ããŒã«ãäœæãããããæºåãã§ããŠããŸãã
ãŸããR.swiftããåŸãããã¡ãªããã¯ãããŒã ãã¯ããã«éèŠãªããšã«è²»ããããšãã§ããèšå€§ãªå·¥æ°ã§ãïŒæ°æ©èœãæ°ããæè¡ãœãªã¥ãŒã·ã§ã³ãå質æ¹åãªã©ã R.swiftã¯ãçµ±åã«è²»ããããæéãå®å
šã«è¿ããå°æ¥çã«åæ§ã®å¥ã®ãœãªã¥ãŒã·ã§ã³ã«çœ®ãæããããå¯èœæ§ãèæ
®ããŸããã
R.ã¹ãŠã£ãã
ããŒãã¹
äŸã詊ããŠããªãœãŒã¹ã®ã³ãŒãçæã«ããå©çãããã«èªåã®ç®ã§ç¢ºèªã§ããŸãã ã éã³åã ããããžã§ã¯ãã®ãœãŒã¹ã³ãŒãïŒ GitHub
èšäºãèªãã§ããããããã®å Žæã«ç§»åããŠãããŠããããšãã
ããã ãã§ãã