Финал той самой истории.
Первая часть, вторая, третья, четвертая.
4,5 года назад я имел неосторожность начать писать свою криптовалюту на совсем неподходящем для этого дела языке — на PHP. В итоге, конечно, написал (я упрямый), но получился костыль на костыле и то, что оно вообще работало было просто какой-то магией.
Сразу хочу предупредить, программер я самоучка-недоучка и пишу код, мягко сказать, неидеально.
Началось всё с того, что я расстался с девушкой, по имени Катя и в этот же день (4 апреля 2015-го) решил изучить Go и переписать свою криптовалюту. Писать про Катю не под спойлерами не могу, т.к. хабр всё же для IT-шных статей, а не для любовных рассказов и суровые айтишники, которым интересна тема Go, могут просто не обращать внимание на спойлеры «про Катю» и «про Машу».
Итог 8 месяцев: приложение работает на Win, OSX, Linux, FreeBSD, Android, IOS
Общего кода ~73к строк, кода под разные ОС где-то несколько сотен строчек.
40к — обработка/генерация блоков/тр-ий, 17.5к — контроллеры для интерфейса, 15.5к — шаблоны.
Поддерживаются PostgreSQL, SQLite, MySQL.
Тех, кто будет тестировать мое творение, предупреждаю — могут быть баги, и если у Вас есть время, черкните о них, пожалуйста, на darwin@dcoin.club или в личку на хабре. Пожелания и советы тоже приветствуются.
В первых четырех частях я рассказал про то, как в dcoin функционирует веб-сервер, про html/template, базы данных, плавное завершение приложения, шифрование и парсинг блоков, Android-приложение.
В этой части я расскажу про компиляцию под IOS.
Начало
Первой сложностью было то, что у меня не было сертификата разработчика. А без него скомпилировать приложение не получалось. Айфона у меня тоже не было, также как и Мака. Дня 3 возился с установкой osx на virualbox, в итоге смог поставить только на vmware и наладить сеть с virtualbox, чтобы в консоле работать.
Выяснил, что в моему счастью, в xcode 7 появилась возможность компилить приложения с фришным сертификатом, который может создать любой желающий. И айфон 4s мне очень вовремя одолжили. Можно было с головой погрузиться в разработку.
В итоге Катя так и не приехала. Опять были какие-то отмазки. Закончилось тем, что она меня снова послала. На этот раз я не думал сразу уходить, т.к. чувствовал, что нужен ей. Но Катя слишком сильно хотела, чтобы я ушел и мне пришлось оставить её в покое. И пообещать больше никогда не звонить и не писать ей.
Скомпилировалось и запустилось всё без особых проблем. Открыл в браузере и… ничего. Но зато если зайти по сети на 127.0.0.1:8089 то выдавало кошелек. Стало очевидным, что при нажатии кнопки home приложение переходит в какой-то спящий режим.
По аналогии с андроидом решил сделать сервис. Но, оказывается сервисы на ios невозможны. Максимум что можно сделать — это повисеть в бэкграунде 600 секунд. Так то оно, конечно, логично — борьба за сохранность заряда аккумулятора. В общем, пришлось изучать, как там вообще работают приложения в ios.
Создал простенькое приложение в xcode, кинул на тел, работает. Начал копать структуру файлов и параллельно искать что-то похожее в gomobile, нашел вот этот файлик. Узнал про NSLog, определил место, куда он выдает инфу
Помню свою радость, когда увидел строки в логе, которые выводило мое приложение. Это было круто, связь налажена, дальше будет проще. Для меня возможность писать и читать логи — это, наверное, самое важное при разработке приложения.
Objectve-C я не знал, да и сейчас толком не знаю. Но было очевидно, что без понимания, как минимум, синтаксиса ничего не получится. Немного почитал уроки про Objectve-C, стало проще понимать код.
Погуглил про фоновый режим, выяснил, что надо в didFinishLaunchingWithOptions добавить вот такой код
// UIApplicationBackgroundFetchIntervalMinimum - чтобы наше приложение запустилось в бэкграунде при любом возможном случае [[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
И добавить в info.plist
<key>UIBackgroundModes</key> <array> <string>fetch</string> </array>
Gomobile генерит свой info.plist. Внести в него правки можно тут.
webView
То, что в браузере всё работало было конечно круто, но этого хватало лишь на 3 минуты, ведь когда открывается браузер приложение идет в фоновый режим и через 3 минуты падает. Без webView тут никак. Довольно долго разбирался, куда и как вставить webView, чтобы оно отображалось. GUI-то нет, всё в текстовом файле надо писать, а учитывая, что с разработкой под IOS я был вообще не знаком, мне было очень тяжко
В итоге, конечно, всё получилось и оказалось крайне просто.
Через день написала, что боится ехать на ночь к малознакомому парню. Я сказал, что думал что она пропала с концами и уже чуть не начал назначать свидания другим девушкам на эти выходные. Она разозлилась, ругалась.
На следующий день отправил шутки ради смс-ку «Весь день на свиданках, катаюсь на лодке, в мозолях руки и не только». Шутку она не поняла, разозлилась пуще прежнего, пришлось объяснить, что мол шутка это, дома я весь день был, код писал.
- (void)viewDidLoad { // в фоновом потоке спим 3 сек, чтобы веб-сервер мог успеть запуститься, к БД подключиться и пр. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [NSThread sleepForTimeInterval:3.0f]; // Переходим к выполнению кода в главном потоке dispatch_async(dispatch_get_main_queue(), ^{ // собвственно сам webView self.webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)]; NSMutableURLRequest * request =[NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://127.0.0.1:8089"]]; self.webView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; self.webView.scrollView.bounces = NO; self.webView.scalesPageToFit = NO; self.view = self.webView; self.webView.delegate = self; [self.webView loadRequest:request]; }); }); [super viewDidLoad]; }
В интерфейс ViewController надо добавить наш webView
@interface ViewController : UIViewController<UIWebViewDelegate,UIScrollViewDelegate,UITextFieldDelegate> { IBOutlet UIWebView *webView; ..... } @property(nonatomic,retain)UIWebView *webView;
Уведомления
«Раз всё так просто, то надо сделать и уведомления» — подумал я.
Objectiv-C код пришлось внедрять в Go
// +build darwin // +build arm arm64 package sendnotif /* #cgo CFLAGS: -x objective-c #cgo LDFLAGS: -framework Foundation -framework GLKit -framework UIKit #import <UIKit/UIKit.h> #import <Foundation/Foundation.h> #import <GLKit/GLKit.h> void ShowMessM(char* title, char* text) { UILocalNotification* localNotification = [[UILocalNotification alloc] init]; localNotification.soundName = UILocalNotificationDefaultSoundName; localNotification.alertTitle = [NSString stringWithUTF8String:title]; localNotification.alertBody = [NSString stringWithUTF8String:text]; localNotification.timeZone = [NSTimeZone systemTimeZone]; localNotification.applicationIconBadgeNumber = 1; localNotification.repeatInterval = NSCalendarUnitMinute; [[UIApplication sharedApplication] scheduleLocalNotification:localNotification]; [localNotification release]; } */ import "C" func SendMobileNotification(title, text string) { C.ShowMessM(C.CString(title), C.CString(text)) }
В Go коде использовать так: sendnotif.SendMobileNotification(«Заголовок», «Текст уведомления»)
И в didFinishLaunchingWithOptions надо добавить:
if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)]) { // iOS 8 Notifications [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]]; [application registerForRemoteNotifications]; } else { // iOS < 8 Notifications [application registerForRemoteNotificationTypes: (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)]; }
Это чтобы при запуске у пользователя вылезло сообщение с запросом прав на использование уведомлений.
Заключение
На примере Dcoin можно понять, что почти любой человек может писать на GO приложения, которые будут работать на всех основых ОС, в том числе и на мобильных.
Сейчас уже 6-й месяц живу с Машей. Недавно завели кота.
P.S.
1. 21 апреля едем в Нью-Йорк на выставку стартапов TechDay, если будете там же, велкам к нашему стенду.
2. В Dcoin сейчас можно получить бесплатные монеты (хватит на оплату инета на несколько месяцев).
ссылка на оригинал статьи https://habrahabr.ru/post/281677/
Добавить комментарий